(function webpackUniversalModuleDefinition(root, factory) {
    if(typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if(typeof define === 'function' && define.amd)
        define("babylonjs", [], factory);
    else if(typeof exports === 'object')
        exports["babylonjs"] = factory();
    else
        root["BABYLON"] = factory();
})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function() {
return /******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/        }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/        }
/******/        Object.defineProperty(exports, '__esModule', { value: true });
/******/    };
/******/
/******/    // create a fake namespace object
/******/    // mode & 1: value is a module id, require it
/******/    // mode & 2: merge all properties of value into the ns
/******/    // mode & 4: return value when already ns object
/******/    // mode & 8|1: behave like require
/******/    __webpack_require__.t = function(value, mode) {
/******/        if(mode & 1) value = __webpack_require__(value);
/******/        if(mode & 8) return value;
/******/        if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/        var ns = Object.create(null);
/******/        __webpack_require__.r(ns);
/******/        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/        if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/        return ns;
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./Legacy/legacy.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "../node_modules/tslib/tslib.es6.js":
/*!******************************************!*\
  !*** ../node_modules/tslib/tslib.es6.js ***!
  \******************************************/
/*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__extends", function() { return __extends; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__assign", function() { return __assign; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__rest", function() { return __rest; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__decorate", function() { return __decorate; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__param", function() { return __param; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__spread", function() { return __spread; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__await", function() { return __await; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncGenerator", function() { return __asyncGenerator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncDelegator", function() { return __asyncDelegator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__asyncValues", function() { return __asyncValues; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; });
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */

var extendStatics = function(d, b) {
    extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return extendStatics(d, b);
};

function __extends(d, b) {
    extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

var __assign = function() {
    __assign = Object.assign || function __assign(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
    }
    return __assign.apply(this, arguments);
}

function __rest(s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
}

function __decorate(decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
}

function __param(paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
}

function __metadata(metadataKey, metadataValue) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}

function __awaiter(thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

function __generator(thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
}

function __exportStar(m, exports) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}

function __values(o) {
    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
    if (m) return m.call(o);
    return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
}

function __read(o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
}

function __spread() {
    for (var ar = [], i = 0; i < arguments.length; i++)
        ar = ar.concat(__read(arguments[i]));
    return ar;
}

function __await(v) {
    return this instanceof __await ? (this.v = v, this) : new __await(v);
}

function __asyncGenerator(thisArg, _arguments, generator) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var g = generator.apply(thisArg, _arguments || []), i, q = [];
    return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
    function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
    function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
    function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
    function fulfill(value) { resume("next", value); }
    function reject(value) { resume("throw", value); }
    function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}

function __asyncDelegator(o) {
    var i, p;
    return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
    function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}

function __asyncValues(o) {
    if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
    var m = o[Symbol.asyncIterator], i;
    return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
    function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
    function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}

function __makeTemplateObject(cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};

function __importStar(mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result.default = mod;
    return result;
}

function __importDefault(mod) {
    return (mod && mod.__esModule) ? mod : { default: mod };
}


/***/ }),

/***/ "../node_modules/webpack/buildin/global.js":
/*!*************************************************!*\
  !*** ../node_modules/webpack/buildin/global.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

var g;

// This works in non-strict mode
g = (function() {
    return this;
})();

try {
    // This works if eval is allowed (see CSP)
    g = g || new Function("return this")();
} catch (e) {
    // This works if the window reference is available
    if (typeof window === "object") g = window;
}

// g can still be undefined, but nothing to do about it...
// We return undefined, instead of nothing here, so it's
// easier to handle this case. if(!global) { ...}

module.exports = g;


/***/ }),

/***/ "./Actions/abstractActionManager.ts":
/*!******************************************!*\
  !*** ./Actions/abstractActionManager.ts ***!
  \******************************************/
/*! exports provided: AbstractActionManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractActionManager", function() { return AbstractActionManager; });
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");

/**
 * Abstract class used to decouple action Manager from scene and meshes.
 * Do not instantiate.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var AbstractActionManager = /** @class */ (function () {
    function AbstractActionManager() {
        /** Gets the cursor to use when hovering items */
        this.hoverCursor = '';
        /** Gets the list of actions */
        this.actions = new Array();
        /**
         * Gets or sets a boolean indicating that the manager is recursive meaning that it can trigger action from children
         */
        this.isRecursive = false;
    }
    Object.defineProperty(AbstractActionManager, "HasTriggers", {
        /**
         * Does exist one action manager with at least one trigger
         **/
        get: function () {
            for (var t in AbstractActionManager.Triggers) {
                if (AbstractActionManager.Triggers.hasOwnProperty(t)) {
                    return true;
                }
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractActionManager, "HasPickTriggers", {
        /**
         * Does exist one action manager with at least one pick trigger
         **/
        get: function () {
            for (var t in AbstractActionManager.Triggers) {
                if (AbstractActionManager.Triggers.hasOwnProperty(t)) {
                    var t_int = parseInt(t);
                    if (t_int >= _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].ACTION_OnPickTrigger && t_int <= _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].ACTION_OnPickUpTrigger) {
                        return true;
                    }
                }
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Does exist one action manager that handles actions of a given trigger
     * @param trigger defines the trigger to be tested
     * @return a boolean indicating whether the trigger is handeled by at least one action manager
    **/
    AbstractActionManager.HasSpecificTrigger = function (trigger) {
        for (var t in AbstractActionManager.Triggers) {
            if (AbstractActionManager.Triggers.hasOwnProperty(t)) {
                var t_int = parseInt(t);
                if (t_int === trigger) {
                    return true;
                }
            }
        }
        return false;
    };
    /** Gets the list of active triggers */
    AbstractActionManager.Triggers = {};
    return AbstractActionManager;
}());



/***/ }),

/***/ "./Actions/action.ts":
/*!***************************!*\
  !*** ./Actions/action.ts ***!
  \***************************/
/*! exports provided: Action */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Action", function() { return Action; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");




/**
 * The action to be carried out following a trigger
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions#available-actions
 */
var Action = /** @class */ (function () {
    /**
     * Creates a new Action
     * @param triggerOptions the trigger, with or without parameters, for the action
     * @param condition an optional determinant of action
     */
    function Action(
    /** the trigger, with or without parameters, for the action */
    triggerOptions, condition) {
        this.triggerOptions = triggerOptions;
        /**
        * An event triggered prior to action being executed.
        */
        this.onBeforeExecuteObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        if (triggerOptions.parameter) {
            this.trigger = triggerOptions.trigger;
            this._triggerParameter = triggerOptions.parameter;
        }
        else if (triggerOptions.trigger) {
            this.trigger = triggerOptions.trigger;
        }
        else {
            this.trigger = triggerOptions;
        }
        this._nextActiveAction = this;
        this._condition = condition;
    }
    /**
     * Internal only
     * @hidden
     */
    Action.prototype._prepare = function () {
    };
    /**
     * Gets the trigger parameters
     * @returns the trigger parameters
     */
    Action.prototype.getTriggerParameter = function () {
        return this._triggerParameter;
    };
    /**
     * Internal only - executes current action event
     * @hidden
     */
    Action.prototype._executeCurrent = function (evt) {
        if (this._nextActiveAction._condition) {
            var condition = this._nextActiveAction._condition;
            var currentRenderId = this._actionManager.getScene().getRenderId();
            // We cache the current evaluation for the current frame
            if (condition._evaluationId === currentRenderId) {
                if (!condition._currentResult) {
                    return;
                }
            }
            else {
                condition._evaluationId = currentRenderId;
                if (!condition.isValid()) {
                    condition._currentResult = false;
                    return;
                }
                condition._currentResult = true;
            }
        }
        this.onBeforeExecuteObservable.notifyObservers(this);
        this._nextActiveAction.execute(evt);
        this.skipToNextActiveAction();
    };
    /**
     * Execute placeholder for child classes
     * @param evt optional action event
     */
    Action.prototype.execute = function (evt) {
    };
    /**
     * Skips to next active action
     */
    Action.prototype.skipToNextActiveAction = function () {
        if (this._nextActiveAction._child) {
            if (!this._nextActiveAction._child._actionManager) {
                this._nextActiveAction._child._actionManager = this._actionManager;
            }
            this._nextActiveAction = this._nextActiveAction._child;
        }
        else {
            this._nextActiveAction = this;
        }
    };
    /**
     * Adds action to chain of actions, may be a DoNothingAction
     * @param action defines the next action to execute
     * @returns The action passed in
     * @see https://www.babylonjs-playground.com/#1T30HR#0
     */
    Action.prototype.then = function (action) {
        this._child = action;
        action._actionManager = this._actionManager;
        action._prepare();
        return action;
    };
    /**
     * Internal only
     * @hidden
     */
    Action.prototype._getProperty = function (propertyPath) {
        return this._actionManager._getProperty(propertyPath);
    };
    /**
     * Internal only
     * @hidden
     */
    Action.prototype._getEffectiveTarget = function (target, propertyPath) {
        return this._actionManager._getEffectiveTarget(target, propertyPath);
    };
    /**
     * Serialize placeholder for child classes
     * @param parent of child
     * @returns the serialized object
     */
    Action.prototype.serialize = function (parent) {
    };
    /**
     * Internal only called by serialize
     * @hidden
     */
    Action.prototype._serialize = function (serializedAction, parent) {
        var serializationObject = {
            type: 1,
            children: [],
            name: serializedAction.name,
            properties: serializedAction.properties || []
        };
        // Serialize child
        if (this._child) {
            this._child.serialize(serializationObject);
        }
        // Check if "this" has a condition
        if (this._condition) {
            var serializedCondition = this._condition.serialize();
            serializedCondition.children.push(serializationObject);
            if (parent) {
                parent.children.push(serializedCondition);
            }
            return serializedCondition;
        }
        if (parent) {
            parent.children.push(serializationObject);
        }
        return serializationObject;
    };
    /**
     * Internal only
     * @hidden
     */
    Action._SerializeValueAsString = function (value) {
        if (typeof value === "number") {
            return value.toString();
        }
        if (typeof value === "boolean") {
            return value ? "true" : "false";
        }
        if (value instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"]) {
            return value.x + ", " + value.y;
        }
        if (value instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]) {
            return value.x + ", " + value.y + ", " + value.z;
        }
        if (value instanceof _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"]) {
            return value.r + ", " + value.g + ", " + value.b;
        }
        if (value instanceof _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"]) {
            return value.r + ", " + value.g + ", " + value.b + ", " + value.a;
        }
        return value; // string
    };
    /**
     * Internal only
     * @hidden
     */
    Action._GetTargetProperty = function (target) {
        return {
            name: "target",
            targetType: target._isMesh ? "MeshProperties"
                : target._isLight ? "LightProperties"
                    : target._isCamera ? "CameraProperties"
                        : "SceneProperties",
            value: target._isScene ? "Scene" : target.name
        };
    };
    return Action;
}());

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Action"] = Action;


/***/ }),

/***/ "./Actions/actionEvent.ts":
/*!********************************!*\
  !*** ./Actions/actionEvent.ts ***!
  \********************************/
/*! exports provided: ActionEvent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ActionEvent", function() { return ActionEvent; });
/**
 * ActionEvent is the event being sent when an action is triggered.
 */
var ActionEvent = /** @class */ (function () {
    /**
     * Creates a new ActionEvent
     * @param source The mesh or sprite that triggered the action
     * @param pointerX The X mouse cursor position at the time of the event
     * @param pointerY The Y mouse cursor position at the time of the event
     * @param meshUnderPointer The mesh that is currently pointed at (can be null)
     * @param sourceEvent the original (browser) event that triggered the ActionEvent
     * @param additionalData additional data for the event
     */
    function ActionEvent(
    /** The mesh or sprite that triggered the action */
    source,
    /** The X mouse cursor position at the time of the event */
    pointerX,
    /** The Y mouse cursor position at the time of the event */
    pointerY,
    /** The mesh that is currently pointed at (can be null) */
    meshUnderPointer,
    /** the original (browser) event that triggered the ActionEvent */
    sourceEvent,
    /** additional data for the event */
    additionalData) {
        this.source = source;
        this.pointerX = pointerX;
        this.pointerY = pointerY;
        this.meshUnderPointer = meshUnderPointer;
        this.sourceEvent = sourceEvent;
        this.additionalData = additionalData;
    }
    /**
     * Helper function to auto-create an ActionEvent from a source mesh.
     * @param source The source mesh that triggered the event
     * @param evt The original (browser) event
     * @param additionalData additional data for the event
     * @returns the new ActionEvent
     */
    ActionEvent.CreateNew = function (source, evt, additionalData) {
        var scene = source.getScene();
        return new ActionEvent(source, scene.pointerX, scene.pointerY, scene.meshUnderPointer || source, evt, additionalData);
    };
    /**
     * Helper function to auto-create an ActionEvent from a source sprite
     * @param source The source sprite that triggered the event
     * @param scene Scene associated with the sprite
     * @param evt The original (browser) event
     * @param additionalData additional data for the event
     * @returns the new ActionEvent
     */
    ActionEvent.CreateNewFromSprite = function (source, scene, evt, additionalData) {
        return new ActionEvent(source, scene.pointerX, scene.pointerY, scene.meshUnderPointer, evt, additionalData);
    };
    /**
     * Helper function to auto-create an ActionEvent from a scene. If triggered by a mesh use ActionEvent.CreateNew
     * @param scene the scene where the event occurred
     * @param evt The original (browser) event
     * @returns the new ActionEvent
     */
    ActionEvent.CreateNewFromScene = function (scene, evt) {
        return new ActionEvent(null, scene.pointerX, scene.pointerY, scene.meshUnderPointer, evt);
    };
    /**
     * Helper function to auto-create an ActionEvent from a primitive
     * @param prim defines the target primitive
     * @param pointerPos defines the pointer position
     * @param evt The original (browser) event
     * @param additionalData additional data for the event
     * @returns the new ActionEvent
     */
    ActionEvent.CreateNewFromPrimitive = function (prim, pointerPos, evt, additionalData) {
        return new ActionEvent(prim, pointerPos.x, pointerPos.y, null, evt, additionalData);
    };
    return ActionEvent;
}());



/***/ }),

/***/ "./Actions/actionManager.ts":
/*!**********************************!*\
  !*** ./Actions/actionManager.ts ***!
  \**********************************/
/*! exports provided: ActionManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ActionManager", function() { return ActionManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _condition__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./condition */ "./Actions/condition.ts");
/* harmony import */ var _action__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./action */ "./Actions/action.ts");
/* harmony import */ var _directActions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./directActions */ "./Actions/directActions.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _abstractActionManager__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./abstractActionManager */ "./Actions/abstractActionManager.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");












/**
 * Action Manager manages all events to be triggered on a given mesh or the global scene.
 * A single scene can have many Action Managers to handle predefined actions on specific meshes.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var ActionManager = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ActionManager, _super);
    /**
     * Creates a new action manager
     * @param scene defines the hosting scene
     */
    function ActionManager(scene) {
        var _this = _super.call(this) || this;
        _this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__["EngineStore"].LastCreatedScene;
        scene.actionManagers.push(_this);
        return _this;
    }
    // Methods
    /**
     * Releases all associated resources
     */
    ActionManager.prototype.dispose = function () {
        var index = this._scene.actionManagers.indexOf(this);
        for (var i = 0; i < this.actions.length; i++) {
            var action = this.actions[i];
            ActionManager.Triggers[action.trigger]--;
            if (ActionManager.Triggers[action.trigger] === 0) {
                delete ActionManager.Triggers[action.trigger];
            }
        }
        if (index > -1) {
            this._scene.actionManagers.splice(index, 1);
        }
    };
    /**
     * Gets hosting scene
     * @returns the hosting scene
     */
    ActionManager.prototype.getScene = function () {
        return this._scene;
    };
    /**
     * Does this action manager handles actions of any of the given triggers
     * @param triggers defines the triggers to be tested
     * @return a boolean indicating whether one (or more) of the triggers is handled
     */
    ActionManager.prototype.hasSpecificTriggers = function (triggers) {
        for (var index = 0; index < this.actions.length; index++) {
            var action = this.actions[index];
            if (triggers.indexOf(action.trigger) > -1) {
                return true;
            }
        }
        return false;
    };
    /**
     * Does this action manager handles actions of any of the given triggers. This function takes two arguments for
     * speed.
     * @param triggerA defines the trigger to be tested
     * @param triggerB defines the trigger to be tested
     * @return a boolean indicating whether one (or more) of the triggers is handled
     */
    ActionManager.prototype.hasSpecificTriggers2 = function (triggerA, triggerB) {
        for (var index = 0; index < this.actions.length; index++) {
            var action = this.actions[index];
            if (triggerA == action.trigger || triggerB == action.trigger) {
                return true;
            }
        }
        return false;
    };
    /**
     * Does this action manager handles actions of a given trigger
     * @param trigger defines the trigger to be tested
     * @param parameterPredicate defines an optional predicate to filter triggers by parameter
     * @return whether the trigger is handled
     */
    ActionManager.prototype.hasSpecificTrigger = function (trigger, parameterPredicate) {
        for (var index = 0; index < this.actions.length; index++) {
            var action = this.actions[index];
            if (action.trigger === trigger) {
                if (parameterPredicate) {
                    if (parameterPredicate(action.getTriggerParameter())) {
                        return true;
                    }
                }
                else {
                    return true;
                }
            }
        }
        return false;
    };
    Object.defineProperty(ActionManager.prototype, "hasPointerTriggers", {
        /**
         * Does this action manager has pointer triggers
         */
        get: function () {
            for (var index = 0; index < this.actions.length; index++) {
                var action = this.actions[index];
                if (action.trigger >= ActionManager.OnPickTrigger && action.trigger <= ActionManager.OnPointerOutTrigger) {
                    return true;
                }
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ActionManager.prototype, "hasPickTriggers", {
        /**
         * Does this action manager has pick triggers
         */
        get: function () {
            for (var index = 0; index < this.actions.length; index++) {
                var action = this.actions[index];
                if (action.trigger >= ActionManager.OnPickTrigger && action.trigger <= ActionManager.OnPickUpTrigger) {
                    return true;
                }
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Registers an action to this action manager
     * @param action defines the action to be registered
     * @return the action amended (prepared) after registration
     */
    ActionManager.prototype.registerAction = function (action) {
        if (action.trigger === ActionManager.OnEveryFrameTrigger) {
            if (this.getScene().actionManager !== this) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_7__["Logger"].Warn("OnEveryFrameTrigger can only be used with scene.actionManager");
                return null;
            }
        }
        this.actions.push(action);
        if (ActionManager.Triggers[action.trigger]) {
            ActionManager.Triggers[action.trigger]++;
        }
        else {
            ActionManager.Triggers[action.trigger] = 1;
        }
        action._actionManager = this;
        action._prepare();
        return action;
    };
    /**
     * Unregisters an action to this action manager
     * @param action defines the action to be unregistered
     * @return a boolean indicating whether the action has been unregistered
     */
    ActionManager.prototype.unregisterAction = function (action) {
        var index = this.actions.indexOf(action);
        if (index !== -1) {
            this.actions.splice(index, 1);
            ActionManager.Triggers[action.trigger] -= 1;
            if (ActionManager.Triggers[action.trigger] === 0) {
                delete ActionManager.Triggers[action.trigger];
            }
            delete action._actionManager;
            return true;
        }
        return false;
    };
    /**
     * Process a specific trigger
     * @param trigger defines the trigger to process
     * @param evt defines the event details to be processed
     */
    ActionManager.prototype.processTrigger = function (trigger, evt) {
        for (var index = 0; index < this.actions.length; index++) {
            var action = this.actions[index];
            if (action.trigger === trigger) {
                if (evt) {
                    if (trigger === ActionManager.OnKeyUpTrigger
                        || trigger === ActionManager.OnKeyDownTrigger) {
                        var parameter = action.getTriggerParameter();
                        if (parameter && parameter !== evt.sourceEvent.keyCode) {
                            if (!parameter.toLowerCase) {
                                continue;
                            }
                            var lowerCase = parameter.toLowerCase();
                            if (lowerCase !== evt.sourceEvent.key) {
                                var unicode = evt.sourceEvent.charCode ? evt.sourceEvent.charCode : evt.sourceEvent.keyCode;
                                var actualkey = String.fromCharCode(unicode).toLowerCase();
                                if (actualkey !== lowerCase) {
                                    continue;
                                }
                            }
                        }
                    }
                }
                action._executeCurrent(evt);
            }
        }
    };
    /** @hidden */
    ActionManager.prototype._getEffectiveTarget = function (target, propertyPath) {
        var properties = propertyPath.split(".");
        for (var index = 0; index < properties.length - 1; index++) {
            target = target[properties[index]];
        }
        return target;
    };
    /** @hidden */
    ActionManager.prototype._getProperty = function (propertyPath) {
        var properties = propertyPath.split(".");
        return properties[properties.length - 1];
    };
    /**
     * Serialize this manager to a JSON object
     * @param name defines the property name to store this manager
     * @returns a JSON representation of this manager
     */
    ActionManager.prototype.serialize = function (name) {
        var root = {
            children: new Array(),
            name: name,
            type: 3,
            properties: new Array() // Empty for root but required
        };
        for (var i = 0; i < this.actions.length; i++) {
            var triggerObject = {
                type: 0,
                children: new Array(),
                name: ActionManager.GetTriggerName(this.actions[i].trigger),
                properties: new Array()
            };
            var triggerOptions = this.actions[i].triggerOptions;
            if (triggerOptions && typeof triggerOptions !== "number") {
                if (triggerOptions.parameter instanceof Node) {
                    triggerObject.properties.push(_action__WEBPACK_IMPORTED_MODULE_4__["Action"]._GetTargetProperty(triggerOptions.parameter));
                }
                else {
                    var parameter = {};
                    _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_8__["DeepCopier"].DeepCopy(triggerOptions.parameter, parameter, ["mesh"]);
                    if (triggerOptions.parameter && triggerOptions.parameter.mesh) {
                        parameter._meshId = triggerOptions.parameter.mesh.id;
                    }
                    triggerObject.properties.push({ name: "parameter", targetType: null, value: parameter });
                }
            }
            // Serialize child action, recursively
            this.actions[i].serialize(triggerObject);
            // Add serialized trigger
            root.children.push(triggerObject);
        }
        return root;
    };
    /**
     * Creates a new ActionManager from a JSON data
     * @param parsedActions defines the JSON data to read from
     * @param object defines the hosting mesh
     * @param scene defines the hosting scene
     */
    ActionManager.Parse = function (parsedActions, object, scene) {
        var actionManager = new ActionManager(scene);
        if (object === null) {
            scene.actionManager = actionManager;
        }
        else {
            object.actionManager = actionManager;
        }
        // instanciate a new object
        var instanciate = function (name, params) {
            var internalClassType = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_9__["_TypeStore"].GetClass("BABYLON." + name);
            if (internalClassType) {
                var newInstance = Object.create(internalClassType.prototype);
                newInstance.constructor.apply(newInstance, params);
                return newInstance;
            }
        };
        var parseParameter = function (name, value, target, propertyPath) {
            if (propertyPath === null) {
                // String, boolean or float
                var floatValue = parseFloat(value);
                if (value === "true" || value === "false") {
                    return value === "true";
                }
                else {
                    return isNaN(floatValue) ? value : floatValue;
                }
            }
            var effectiveTarget = propertyPath.split(".");
            var values = value.split(",");
            // Get effective Target
            for (var i = 0; i < effectiveTarget.length; i++) {
                target = target[effectiveTarget[i]];
            }
            // Return appropriate value with its type
            if (typeof (target) === "boolean") {
                return values[0] === "true";
            }
            if (typeof (target) === "string") {
                return values[0];
            }
            // Parameters with multiple values such as Vector3 etc.
            var split = new Array();
            for (var i = 0; i < values.length; i++) {
                split.push(parseFloat(values[i]));
            }
            if (target instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]) {
                return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(split);
            }
            if (target instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"]) {
                return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(split);
            }
            if (target instanceof _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"]) {
                return _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"].FromArray(split);
            }
            if (target instanceof _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"]) {
                return _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"].FromArray(split);
            }
            return parseFloat(values[0]);
        };
        // traverse graph per trigger
        var traverse = function (parsedAction, trigger, condition, action, combineArray) {
            if (combineArray === void 0) { combineArray = null; }
            if (parsedAction.detached) {
                return;
            }
            var parameters = new Array();
            var target = null;
            var propertyPath = null;
            var combine = parsedAction.combine && parsedAction.combine.length > 0;
            // Parameters
            if (parsedAction.type === 2) {
                parameters.push(actionManager);
            }
            else {
                parameters.push(trigger);
            }
            if (combine) {
                var actions = new Array();
                for (var j = 0; j < parsedAction.combine.length; j++) {
                    traverse(parsedAction.combine[j], ActionManager.NothingTrigger, condition, action, actions);
                }
                parameters.push(actions);
            }
            else {
                for (var i = 0; i < parsedAction.properties.length; i++) {
                    var value = parsedAction.properties[i].value;
                    var name = parsedAction.properties[i].name;
                    var targetType = parsedAction.properties[i].targetType;
                    if (name === "target") {
                        if (targetType !== null && targetType === "SceneProperties") {
                            value = target = scene;
                        }
                        else {
                            value = target = scene.getNodeByName(value);
                        }
                    }
                    else if (name === "parent") {
                        value = scene.getNodeByName(value);
                    }
                    else if (name === "sound") {
                        // Can not externalize to component, so only checks for the presence off the API.
                        if (scene.getSoundByName) {
                            value = scene.getSoundByName(value);
                        }
                    }
                    else if (name !== "propertyPath") {
                        if (parsedAction.type === 2 && name === "operator") {
                            value = _condition__WEBPACK_IMPORTED_MODULE_3__["ValueCondition"][value];
                        }
                        else {
                            value = parseParameter(name, value, target, name === "value" ? propertyPath : null);
                        }
                    }
                    else {
                        propertyPath = value;
                    }
                    parameters.push(value);
                }
            }
            if (combineArray === null) {
                parameters.push(condition);
            }
            else {
                parameters.push(null);
            }
            // If interpolate value action
            if (parsedAction.name === "InterpolateValueAction") {
                var param = parameters[parameters.length - 2];
                parameters[parameters.length - 1] = param;
                parameters[parameters.length - 2] = condition;
            }
            // Action or condition(s) and not CombineAction
            var newAction = instanciate(parsedAction.name, parameters);
            if (newAction instanceof _condition__WEBPACK_IMPORTED_MODULE_3__["Condition"] && condition !== null) {
                var nothing = new _directActions__WEBPACK_IMPORTED_MODULE_5__["DoNothingAction"](trigger, condition);
                if (action) {
                    action.then(nothing);
                }
                else {
                    actionManager.registerAction(nothing);
                }
                action = nothing;
            }
            if (combineArray === null) {
                if (newAction instanceof _condition__WEBPACK_IMPORTED_MODULE_3__["Condition"]) {
                    condition = newAction;
                    newAction = action;
                }
                else {
                    condition = null;
                    if (action) {
                        action.then(newAction);
                    }
                    else {
                        actionManager.registerAction(newAction);
                    }
                }
            }
            else {
                combineArray.push(newAction);
            }
            for (var i = 0; i < parsedAction.children.length; i++) {
                traverse(parsedAction.children[i], trigger, condition, newAction, null);
            }
        };
        // triggers
        for (var i = 0; i < parsedActions.children.length; i++) {
            var triggerParams;
            var trigger = parsedActions.children[i];
            if (trigger.properties.length > 0) {
                var param = trigger.properties[0].value;
                var value = trigger.properties[0].targetType === null ? param : scene.getMeshByName(param);
                if (value._meshId) {
                    value.mesh = scene.getMeshByID(value._meshId);
                }
                triggerParams = { trigger: ActionManager[trigger.name], parameter: value };
            }
            else {
                triggerParams = ActionManager[trigger.name];
            }
            for (var j = 0; j < trigger.children.length; j++) {
                if (!trigger.detached) {
                    traverse(trigger.children[j], triggerParams, null, null);
                }
            }
        }
    };
    /**
     * Get a trigger name by index
     * @param trigger defines the trigger index
     * @returns a trigger name
     */
    ActionManager.GetTriggerName = function (trigger) {
        switch (trigger) {
            case 0: return "NothingTrigger";
            case 1: return "OnPickTrigger";
            case 2: return "OnLeftPickTrigger";
            case 3: return "OnRightPickTrigger";
            case 4: return "OnCenterPickTrigger";
            case 5: return "OnPickDownTrigger";
            case 6: return "OnPickUpTrigger";
            case 7: return "OnLongPressTrigger";
            case 8: return "OnPointerOverTrigger";
            case 9: return "OnPointerOutTrigger";
            case 10: return "OnEveryFrameTrigger";
            case 11: return "OnIntersectionEnterTrigger";
            case 12: return "OnIntersectionExitTrigger";
            case 13: return "OnKeyDownTrigger";
            case 14: return "OnKeyUpTrigger";
            case 15: return "OnPickOutTrigger";
            default: return "";
        }
    };
    /**
     * Nothing
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.NothingTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_NothingTrigger;
    /**
     * On pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnPickTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnPickTrigger;
    /**
     * On left pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnLeftPickTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnLeftPickTrigger;
    /**
     * On right pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnRightPickTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnRightPickTrigger;
    /**
     * On center pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnCenterPickTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnCenterPickTrigger;
    /**
     * On pick down
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnPickDownTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnPickDownTrigger;
    /**
     * On double pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnDoublePickTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnDoublePickTrigger;
    /**
     * On pick up
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnPickUpTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnPickUpTrigger;
    /**
     * On pick out.
     * This trigger will only be raised if you also declared a OnPickDown
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnPickOutTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnPickOutTrigger;
    /**
     * On long press
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnLongPressTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnLongPressTrigger;
    /**
     * On pointer over
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnPointerOverTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnPointerOverTrigger;
    /**
     * On pointer out
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnPointerOutTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnPointerOutTrigger;
    /**
     * On every frame
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnEveryFrameTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnEveryFrameTrigger;
    /**
     * On intersection enter
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnIntersectionEnterTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnIntersectionEnterTrigger;
    /**
     * On intersection exit
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnIntersectionExitTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnIntersectionExitTrigger;
    /**
     * On key down
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnKeyDownTrigger = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ACTION_OnKeyDownTrigger;
    /**
     * On key up
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    ActionManager.OnKeyUpTrigger = 15;
    return ActionManager;
}(_abstractActionManager__WEBPACK_IMPORTED_MODULE_10__["AbstractActionManager"]));



/***/ }),

/***/ "./Actions/condition.ts":
/*!******************************!*\
  !*** ./Actions/condition.ts ***!
  \******************************/
/*! exports provided: Condition, ValueCondition, PredicateCondition, StateCondition */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Condition", function() { return Condition; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValueCondition", function() { return ValueCondition; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PredicateCondition", function() { return PredicateCondition; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StateCondition", function() { return StateCondition; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./action */ "./Actions/action.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");



/**
 * A Condition applied to an Action
 */
var Condition = /** @class */ (function () {
    /**
     * Creates a new Condition
     * @param actionManager the manager of the action the condition is applied to
     */
    function Condition(actionManager) {
        this._actionManager = actionManager;
    }
    /**
     * Check if the current condition is valid
     * @returns a boolean
     */
    Condition.prototype.isValid = function () {
        return true;
    };
    /**
     * Internal only
     * @hidden
     */
    Condition.prototype._getProperty = function (propertyPath) {
        return this._actionManager._getProperty(propertyPath);
    };
    /**
     * Internal only
     * @hidden
     */
    Condition.prototype._getEffectiveTarget = function (target, propertyPath) {
        return this._actionManager._getEffectiveTarget(target, propertyPath);
    };
    /**
     * Serialize placeholder for child classes
     * @returns the serialized object
     */
    Condition.prototype.serialize = function () {
    };
    /**
     * Internal only
     * @hidden
     */
    Condition.prototype._serialize = function (serializedCondition) {
        return {
            type: 2,
            children: [],
            name: serializedCondition.name,
            properties: serializedCondition.properties
        };
    };
    return Condition;
}());

/**
 * Defines specific conditional operators as extensions of Condition
 */
var ValueCondition = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ValueCondition, _super);
    /**
     * Creates a new ValueCondition
     * @param actionManager manager for the action the condition applies to
     * @param target for the action
     * @param propertyPath path to specify the property of the target the conditional operator uses
     * @param value the value compared by the conditional operator against the current value of the property
     * @param operator the conditional operator, default ValueCondition.IsEqual
     */
    function ValueCondition(actionManager, target,
    /** path to specify the property of the target the conditional operator uses  */
    propertyPath,
    /** the value compared by the conditional operator against the current value of the property */
    value,
    /** the conditional operator, default ValueCondition.IsEqual */
    operator) {
        if (operator === void 0) { operator = ValueCondition.IsEqual; }
        var _this = _super.call(this, actionManager) || this;
        _this.propertyPath = propertyPath;
        _this.value = value;
        _this.operator = operator;
        _this._target = target;
        _this._effectiveTarget = _this._getEffectiveTarget(target, _this.propertyPath);
        _this._property = _this._getProperty(_this.propertyPath);
        return _this;
    }
    Object.defineProperty(ValueCondition, "IsEqual", {
        /**
         * returns the number for IsEqual
         */
        get: function () {
            return ValueCondition._IsEqual;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ValueCondition, "IsDifferent", {
        /**
         * Returns the number for IsDifferent
         */
        get: function () {
            return ValueCondition._IsDifferent;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ValueCondition, "IsGreater", {
        /**
         * Returns the number for IsGreater
         */
        get: function () {
            return ValueCondition._IsGreater;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ValueCondition, "IsLesser", {
        /**
         * Returns the number for IsLesser
         */
        get: function () {
            return ValueCondition._IsLesser;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Compares the given value with the property value for the specified conditional operator
     * @returns the result of the comparison
     */
    ValueCondition.prototype.isValid = function () {
        switch (this.operator) {
            case ValueCondition.IsGreater:
                return this._effectiveTarget[this._property] > this.value;
            case ValueCondition.IsLesser:
                return this._effectiveTarget[this._property] < this.value;
            case ValueCondition.IsEqual:
            case ValueCondition.IsDifferent:
                var check;
                if (this.value.equals) {
                    check = this.value.equals(this._effectiveTarget[this._property]);
                }
                else {
                    check = this.value === this._effectiveTarget[this._property];
                }
                return this.operator === ValueCondition.IsEqual ? check : !check;
        }
        return false;
    };
    /**
     * Serialize the ValueCondition into a JSON compatible object
     * @returns serialization object
     */
    ValueCondition.prototype.serialize = function () {
        return this._serialize({
            name: "ValueCondition",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._GetTargetProperty(this._target),
                { name: "propertyPath", value: this.propertyPath },
                { name: "value", value: _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._SerializeValueAsString(this.value) },
                { name: "operator", value: ValueCondition.GetOperatorName(this.operator) }
            ]
        });
    };
    /**
     * Gets the name of the conditional operator for the ValueCondition
     * @param operator the conditional operator
     * @returns the name
     */
    ValueCondition.GetOperatorName = function (operator) {
        switch (operator) {
            case ValueCondition._IsEqual: return "IsEqual";
            case ValueCondition._IsDifferent: return "IsDifferent";
            case ValueCondition._IsGreater: return "IsGreater";
            case ValueCondition._IsLesser: return "IsLesser";
            default: return "";
        }
    };
    /**
     * Internal only
     * @hidden
     */
    ValueCondition._IsEqual = 0;
    /**
     * Internal only
     * @hidden
     */
    ValueCondition._IsDifferent = 1;
    /**
     * Internal only
     * @hidden
     */
    ValueCondition._IsGreater = 2;
    /**
     * Internal only
     * @hidden
     */
    ValueCondition._IsLesser = 3;
    return ValueCondition;
}(Condition));

/**
 * Defines a predicate condition as an extension of Condition
 */
var PredicateCondition = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PredicateCondition, _super);
    /**
     * Creates a new PredicateCondition
     * @param actionManager manager for the action the condition applies to
     * @param predicate defines the predicate function used to validate the condition
     */
    function PredicateCondition(actionManager,
    /** defines the predicate function used to validate the condition */
    predicate) {
        var _this = _super.call(this, actionManager) || this;
        _this.predicate = predicate;
        return _this;
    }
    /**
     * @returns the validity of the predicate condition
     */
    PredicateCondition.prototype.isValid = function () {
        return this.predicate();
    };
    return PredicateCondition;
}(Condition));

/**
 * Defines a state condition as an extension of Condition
 */
var StateCondition = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StateCondition, _super);
    /**
     * Creates a new StateCondition
     * @param actionManager manager for the action the condition applies to
     * @param target of the condition
     * @param value to compare with target state
     */
    function StateCondition(actionManager, target,
    /** Value to compare with target state  */
    value) {
        var _this = _super.call(this, actionManager) || this;
        _this.value = value;
        _this._target = target;
        return _this;
    }
    /**
     * Gets a boolean indicating if the current condition is met
     * @returns the validity of the state
     */
    StateCondition.prototype.isValid = function () {
        return this._target.state === this.value;
    };
    /**
     * Serialize the StateCondition into a JSON compatible object
     * @returns serialization object
     */
    StateCondition.prototype.serialize = function () {
        return this._serialize({
            name: "StateCondition",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._GetTargetProperty(this._target),
                { name: "value", value: this.value }
            ]
        });
    };
    return StateCondition;
}(Condition));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTypes["BABYLON.ValueCondition"] = ValueCondition;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTypes["BABYLON.PredicateCondition"] = PredicateCondition;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTypes["BABYLON.StateCondition"] = StateCondition;


/***/ }),

/***/ "./Actions/directActions.ts":
/*!**********************************!*\
  !*** ./Actions/directActions.ts ***!
  \**********************************/
/*! exports provided: SwitchBooleanAction, SetStateAction, SetValueAction, IncrementValueAction, PlayAnimationAction, StopAnimationAction, DoNothingAction, CombineAction, ExecuteCodeAction, SetParentAction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SwitchBooleanAction", function() { return SwitchBooleanAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SetStateAction", function() { return SetStateAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SetValueAction", function() { return SetValueAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IncrementValueAction", function() { return IncrementValueAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlayAnimationAction", function() { return PlayAnimationAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StopAnimationAction", function() { return StopAnimationAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DoNothingAction", function() { return DoNothingAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CombineAction", function() { return CombineAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExecuteCodeAction", function() { return ExecuteCodeAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SetParentAction", function() { return SetParentAction; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _action__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./action */ "./Actions/action.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");






/**
 * This defines an action responsible to toggle a boolean once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var SwitchBooleanAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchBooleanAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the object containing the boolean
     * @param propertyPath defines the path to the boolean property in the target object
     * @param condition defines the trigger related conditions
     */
    function SwitchBooleanAction(triggerOptions, target, propertyPath, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.propertyPath = propertyPath;
        _this._target = _this._effectiveTarget = target;
        return _this;
    }
    /** @hidden */
    SwitchBooleanAction.prototype._prepare = function () {
        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);
        this._property = this._getProperty(this.propertyPath);
    };
    /**
     * Execute the action toggle the boolean value.
     */
    SwitchBooleanAction.prototype.execute = function () {
        this._effectiveTarget[this._property] = !this._effectiveTarget[this._property];
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    SwitchBooleanAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "SwitchBooleanAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target),
                { name: "propertyPath", value: this.propertyPath }
            ]
        }, parent);
    };
    return SwitchBooleanAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to set a the state field of the target
 *  to a desired value once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var SetStateAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SetStateAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the object containing the state property
     * @param value defines the value to store in the state field
     * @param condition defines the trigger related conditions
     */
    function SetStateAction(triggerOptions, target, value, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.value = value;
        _this._target = target;
        return _this;
    }
    /**
     * Execute the action and store the value on the target state property.
     */
    SetStateAction.prototype.execute = function () {
        this._target.state = this.value;
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    SetStateAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "SetStateAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target),
                { name: "value", value: this.value }
            ]
        }, parent);
    };
    return SetStateAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to set a property of the target
 *  to a desired value once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var SetValueAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SetValueAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the object containing the property
     * @param propertyPath defines the path of the property to set in the target
     * @param value defines the value to set in the property
     * @param condition defines the trigger related conditions
     */
    function SetValueAction(triggerOptions, target, propertyPath, value, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.propertyPath = propertyPath;
        _this.value = value;
        _this._target = _this._effectiveTarget = target;
        return _this;
    }
    /** @hidden */
    SetValueAction.prototype._prepare = function () {
        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);
        this._property = this._getProperty(this.propertyPath);
    };
    /**
     * Execute the action and set the targetted property to the desired value.
     */
    SetValueAction.prototype.execute = function () {
        this._effectiveTarget[this._property] = this.value;
        if (this._target.markAsDirty) {
            this._target.markAsDirty(this._property);
        }
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    SetValueAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "SetValueAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target),
                { name: "propertyPath", value: this.propertyPath },
                { name: "value", value: _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._SerializeValueAsString(this.value) }
            ]
        }, parent);
    };
    return SetValueAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to increment the target value
 *  to a desired value once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var IncrementValueAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IncrementValueAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the object containing the property
     * @param propertyPath defines the path of the property to increment in the target
     * @param value defines the value value we should increment the property by
     * @param condition defines the trigger related conditions
     */
    function IncrementValueAction(triggerOptions, target, propertyPath, value, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.propertyPath = propertyPath;
        _this.value = value;
        _this._target = _this._effectiveTarget = target;
        return _this;
    }
    /** @hidden */
    IncrementValueAction.prototype._prepare = function () {
        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);
        this._property = this._getProperty(this.propertyPath);
        if (typeof this._effectiveTarget[this._property] !== "number") {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Warning: IncrementValueAction can only be used with number values");
        }
    };
    /**
     * Execute the action and increment the target of the value amount.
     */
    IncrementValueAction.prototype.execute = function () {
        this._effectiveTarget[this._property] += this.value;
        if (this._target.markAsDirty) {
            this._target.markAsDirty(this._property);
        }
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    IncrementValueAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "IncrementValueAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target),
                { name: "propertyPath", value: this.propertyPath },
                { name: "value", value: _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._SerializeValueAsString(this.value) }
            ]
        }, parent);
    };
    return IncrementValueAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to start an animation once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var PlayAnimationAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PlayAnimationAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the target animation or animation name
     * @param from defines from where the animation should start (animation frame)
     * @param end defines where the animation should stop (animation frame)
     * @param loop defines if the animation should loop or stop after the first play
     * @param condition defines the trigger related conditions
     */
    function PlayAnimationAction(triggerOptions, target, from, to, loop, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.from = from;
        _this.to = to;
        _this.loop = loop;
        _this._target = target;
        return _this;
    }
    /** @hidden */
    PlayAnimationAction.prototype._prepare = function () {
    };
    /**
     * Execute the action and play the animation.
     */
    PlayAnimationAction.prototype.execute = function () {
        var scene = this._actionManager.getScene();
        scene.beginAnimation(this._target, this.from, this.to, this.loop);
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    PlayAnimationAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "PlayAnimationAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target),
                { name: "from", value: String(this.from) },
                { name: "to", value: String(this.to) },
                { name: "loop", value: _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._SerializeValueAsString(this.loop) || false }
            ]
        }, parent);
    };
    return PlayAnimationAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to stop an animation once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var StopAnimationAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StopAnimationAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the target animation or animation name
     * @param condition defines the trigger related conditions
     */
    function StopAnimationAction(triggerOptions, target, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this._target = target;
        return _this;
    }
    /** @hidden */
    StopAnimationAction.prototype._prepare = function () {
    };
    /**
     * Execute the action and stop the animation.
     */
    StopAnimationAction.prototype.execute = function () {
        var scene = this._actionManager.getScene();
        scene.stopAnimation(this._target);
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    StopAnimationAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "StopAnimationAction",
            properties: [_action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target)]
        }, parent);
    };
    return StopAnimationAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible that does nothing once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var DoNothingAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DoNothingAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param condition defines the trigger related conditions
     */
    function DoNothingAction(triggerOptions, condition) {
        if (triggerOptions === void 0) { triggerOptions = _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].ACTION_NothingTrigger; }
        return _super.call(this, triggerOptions, condition) || this;
    }
    /**
     * Execute the action and do nothing.
     */
    DoNothingAction.prototype.execute = function () {
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    DoNothingAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "DoNothingAction",
            properties: []
        }, parent);
    };
    return DoNothingAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to trigger several actions once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var CombineAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CombineAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param children defines the list of aggregated animations to run
     * @param condition defines the trigger related conditions
     */
    function CombineAction(triggerOptions, children, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.children = children;
        return _this;
    }
    /** @hidden */
    CombineAction.prototype._prepare = function () {
        for (var index = 0; index < this.children.length; index++) {
            this.children[index]._actionManager = this._actionManager;
            this.children[index]._prepare();
        }
    };
    /**
     * Execute the action and executes all the aggregated actions.
     */
    CombineAction.prototype.execute = function (evt) {
        for (var index = 0; index < this.children.length; index++) {
            this.children[index].execute(evt);
        }
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    CombineAction.prototype.serialize = function (parent) {
        var serializationObject = _super.prototype._serialize.call(this, {
            name: "CombineAction",
            properties: [],
            combine: []
        }, parent);
        for (var i = 0; i < this.children.length; i++) {
            serializationObject.combine.push(this.children[i].serialize(null));
        }
        return serializationObject;
    };
    return CombineAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to run code (external event) once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var ExecuteCodeAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExecuteCodeAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param func defines the callback function to run
     * @param condition defines the trigger related conditions
     */
    function ExecuteCodeAction(triggerOptions, func, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this.func = func;
        return _this;
    }
    /**
     * Execute the action and run the attached code.
     */
    ExecuteCodeAction.prototype.execute = function (evt) {
        this.func(evt);
    };
    return ExecuteCodeAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

/**
 * This defines an action responsible to set the parent property of the target once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var SetParentAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SetParentAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the target containing the parent property
     * @param parent defines from where the animation should start (animation frame)
     * @param condition defines the trigger related conditions
     */
    function SetParentAction(triggerOptions, target, parent, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this._target = target;
        _this._parent = parent;
        return _this;
    }
    /** @hidden */
    SetParentAction.prototype._prepare = function () {
    };
    /**
     * Execute the action and set the parent property.
     */
    SetParentAction.prototype.execute = function () {
        if (this._target.parent === this._parent) {
            return;
        }
        var invertParentWorldMatrix = this._parent.getWorldMatrix().clone();
        invertParentWorldMatrix.invert();
        this._target.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinates(this._target.position, invertParentWorldMatrix);
        this._target.parent = this._parent;
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    SetParentAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "SetParentAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._target),
                _action__WEBPACK_IMPORTED_MODULE_3__["Action"]._GetTargetProperty(this._parent),
            ]
        }, parent);
    };
    return SetParentAction;
}(_action__WEBPACK_IMPORTED_MODULE_3__["Action"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.SetParentAction"] = SetParentAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.ExecuteCodeAction"] = ExecuteCodeAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.DoNothingAction"] = DoNothingAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.StopAnimationAction"] = StopAnimationAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.PlayAnimationAction"] = PlayAnimationAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.IncrementValueAction"] = IncrementValueAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.SetValueAction"] = SetValueAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.SetStateAction"] = SetStateAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.SetParentAction"] = SetParentAction;


/***/ }),

/***/ "./Actions/directAudioActions.ts":
/*!***************************************!*\
  !*** ./Actions/directAudioActions.ts ***!
  \***************************************/
/*! exports provided: PlaySoundAction, StopSoundAction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaySoundAction", function() { return PlaySoundAction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StopSoundAction", function() { return StopSoundAction; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./action */ "./Actions/action.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");



/**
 * This defines an action helpful to play a defined sound on a triggered action.
 */
var PlaySoundAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PlaySoundAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param sound defines the sound to play
     * @param condition defines the trigger related conditions
     */
    function PlaySoundAction(triggerOptions, sound, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this._sound = sound;
        return _this;
    }
    /** @hidden */
    PlaySoundAction.prototype._prepare = function () {
    };
    /**
     * Execute the action and play the sound.
     */
    PlaySoundAction.prototype.execute = function () {
        if (this._sound !== undefined) {
            this._sound.play();
        }
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    PlaySoundAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "PlaySoundAction",
            properties: [{ name: "sound", value: this._sound.name }]
        }, parent);
    };
    return PlaySoundAction;
}(_action__WEBPACK_IMPORTED_MODULE_1__["Action"]));

/**
 * This defines an action helpful to stop a defined sound on a triggered action.
 */
var StopSoundAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StopSoundAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param sound defines the sound to stop
     * @param condition defines the trigger related conditions
     */
    function StopSoundAction(triggerOptions, sound, condition) {
        var _this = _super.call(this, triggerOptions, condition) || this;
        _this._sound = sound;
        return _this;
    }
    /** @hidden */
    StopSoundAction.prototype._prepare = function () {
    };
    /**
     * Execute the action and stop the sound.
     */
    StopSoundAction.prototype.execute = function () {
        if (this._sound !== undefined) {
            this._sound.stop();
        }
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    StopSoundAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "StopSoundAction",
            properties: [{ name: "sound", value: this._sound.name }]
        }, parent);
    };
    return StopSoundAction;
}(_action__WEBPACK_IMPORTED_MODULE_1__["Action"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTypes["BABYLON.PlaySoundAction"] = StopSoundAction;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTypes["BABYLON.StopSoundAction"] = StopSoundAction;


/***/ }),

/***/ "./Actions/index.ts":
/*!**************************!*\
  !*** ./Actions/index.ts ***!
  \**************************/
/*! exports provided: AbstractActionManager, Action, ActionEvent, ActionManager, Condition, ValueCondition, PredicateCondition, StateCondition, SwitchBooleanAction, SetStateAction, SetValueAction, IncrementValueAction, PlayAnimationAction, StopAnimationAction, DoNothingAction, CombineAction, ExecuteCodeAction, SetParentAction, PlaySoundAction, StopSoundAction, InterpolateValueAction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _abstractActionManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./abstractActionManager */ "./Actions/abstractActionManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractActionManager", function() { return _abstractActionManager__WEBPACK_IMPORTED_MODULE_0__["AbstractActionManager"]; });

/* harmony import */ var _action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./action */ "./Actions/action.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Action", function() { return _action__WEBPACK_IMPORTED_MODULE_1__["Action"]; });

/* harmony import */ var _actionEvent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./actionEvent */ "./Actions/actionEvent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ActionEvent", function() { return _actionEvent__WEBPACK_IMPORTED_MODULE_2__["ActionEvent"]; });

/* harmony import */ var _actionManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./actionManager */ "./Actions/actionManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ActionManager", function() { return _actionManager__WEBPACK_IMPORTED_MODULE_3__["ActionManager"]; });

/* harmony import */ var _condition__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./condition */ "./Actions/condition.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Condition", function() { return _condition__WEBPACK_IMPORTED_MODULE_4__["Condition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ValueCondition", function() { return _condition__WEBPACK_IMPORTED_MODULE_4__["ValueCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PredicateCondition", function() { return _condition__WEBPACK_IMPORTED_MODULE_4__["PredicateCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StateCondition", function() { return _condition__WEBPACK_IMPORTED_MODULE_4__["StateCondition"]; });

/* harmony import */ var _directActions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./directActions */ "./Actions/directActions.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SwitchBooleanAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["SwitchBooleanAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetStateAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["SetStateAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetValueAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["SetValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IncrementValueAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["IncrementValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlayAnimationAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["PlayAnimationAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StopAnimationAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["StopAnimationAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DoNothingAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["DoNothingAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CombineAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["CombineAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExecuteCodeAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["ExecuteCodeAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetParentAction", function() { return _directActions__WEBPACK_IMPORTED_MODULE_5__["SetParentAction"]; });

/* harmony import */ var _directAudioActions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./directAudioActions */ "./Actions/directAudioActions.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaySoundAction", function() { return _directAudioActions__WEBPACK_IMPORTED_MODULE_6__["PlaySoundAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StopSoundAction", function() { return _directAudioActions__WEBPACK_IMPORTED_MODULE_6__["StopSoundAction"]; });

/* harmony import */ var _interpolateValueAction__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./interpolateValueAction */ "./Actions/interpolateValueAction.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InterpolateValueAction", function() { return _interpolateValueAction__WEBPACK_IMPORTED_MODULE_7__["InterpolateValueAction"]; });











/***/ }),

/***/ "./Actions/interpolateValueAction.ts":
/*!*******************************************!*\
  !*** ./Actions/interpolateValueAction.ts ***!
  \*******************************************/
/*! exports provided: InterpolateValueAction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InterpolateValueAction", function() { return InterpolateValueAction; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _action__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./action */ "./Actions/action.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Animations/animation */ "./Animations/animation.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");








/**
 * This defines an action responsible to change the value of a property
 * by interpolating between its current value and the newly set one once triggered.
 * @see http://doc.babylonjs.com/how_to/how_to_use_actions
 */
var InterpolateValueAction = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InterpolateValueAction, _super);
    /**
     * Instantiate the action
     * @param triggerOptions defines the trigger options
     * @param target defines the object containing the value to interpolate
     * @param propertyPath defines the path to the property in the target object
     * @param value defines the target value at the end of the interpolation
     * @param duration deines the time it will take for the property to interpolate to the value.
     * @param condition defines the trigger related conditions
     * @param stopOtherAnimations defines if the other scene animations should be stopped when the action has been triggered
     * @param onInterpolationDone defines a callback raised once the interpolation animation has been done
     */
    function InterpolateValueAction(triggerOptions, target, propertyPath, value, duration, condition, stopOtherAnimations, onInterpolationDone) {
        if (duration === void 0) { duration = 1000; }
        var _this = _super.call(this, triggerOptions, condition) || this;
        /**
         * Defines the time it will take for the property to interpolate to the value.
         */
        _this.duration = 1000;
        /**
         * Observable triggered once the interpolation animation has been done.
         */
        _this.onInterpolationDoneObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        _this.propertyPath = propertyPath;
        _this.value = value;
        _this.duration = duration;
        _this.stopOtherAnimations = stopOtherAnimations;
        _this.onInterpolationDone = onInterpolationDone;
        _this._target = _this._effectiveTarget = target;
        return _this;
    }
    /** @hidden */
    InterpolateValueAction.prototype._prepare = function () {
        this._effectiveTarget = this._getEffectiveTarget(this._effectiveTarget, this.propertyPath);
        this._property = this._getProperty(this.propertyPath);
    };
    /**
     * Execute the action starts the value interpolation.
     */
    InterpolateValueAction.prototype.execute = function () {
        var _this = this;
        var scene = this._actionManager.getScene();
        var keys = [
            {
                frame: 0,
                value: this._effectiveTarget[this._property]
            }, {
                frame: 100,
                value: this.value
            }
        ];
        var dataType;
        if (typeof this.value === "number") {
            dataType = _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONTYPE_FLOAT;
        }
        else if (this.value instanceof _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"]) {
            dataType = _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONTYPE_COLOR3;
        }
        else if (this.value instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"]) {
            dataType = _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONTYPE_VECTOR3;
        }
        else if (this.value instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"]) {
            dataType = _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONTYPE_MATRIX;
        }
        else if (this.value instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Quaternion"]) {
            dataType = _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONTYPE_QUATERNION;
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("InterpolateValueAction: Unsupported type (" + typeof this.value + ")");
            return;
        }
        var animation = new _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"]("InterpolateValueAction", this._property, 100 * (1000.0 / this.duration), dataType, _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        animation.setKeys(keys);
        if (this.stopOtherAnimations) {
            scene.stopAnimation(this._effectiveTarget);
        }
        var wrapper = function () {
            _this.onInterpolationDoneObservable.notifyObservers(_this);
            if (_this.onInterpolationDone) {
                _this.onInterpolationDone();
            }
        };
        scene.beginDirectAnimation(this._effectiveTarget, [animation], 0, 100, false, 1, wrapper);
    };
    /**
     * Serializes the actions and its related information.
     * @param parent defines the object to serialize in
     * @returns the serialized object
     */
    InterpolateValueAction.prototype.serialize = function (parent) {
        return _super.prototype._serialize.call(this, {
            name: "InterpolateValueAction",
            properties: [
                _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._GetTargetProperty(this._target),
                { name: "propertyPath", value: this.propertyPath },
                { name: "value", value: _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._SerializeValueAsString(this.value) },
                { name: "duration", value: _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._SerializeValueAsString(this.duration) },
                { name: "stopOtherAnimations", value: _action__WEBPACK_IMPORTED_MODULE_1__["Action"]._SerializeValueAsString(this.stopOtherAnimations) || false }
            ]
        }, parent);
    };
    return InterpolateValueAction;
}(_action__WEBPACK_IMPORTED_MODULE_1__["Action"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.InterpolateValueAction"] = InterpolateValueAction;


/***/ }),

/***/ "./Animations/animatable.ts":
/*!**********************************!*\
  !*** ./Animations/animatable.ts ***!
  \**********************************/
/*! exports provided: Animatable */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Animatable", function() { return Animatable; });
/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./animation */ "./Animations/animation.ts");
/* harmony import */ var _runtimeAnimation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./runtimeAnimation */ "./Animations/runtimeAnimation.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/precisionDate */ "./Misc/precisionDate.ts");
/* harmony import */ var _Bones_bone__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Bones/bone */ "./Bones/bone.ts");







/**
 * Class used to store an actual running animation
 */
var Animatable = /** @class */ (function () {
    /**
     * Creates a new Animatable
     * @param scene defines the hosting scene
     * @param target defines the target object
     * @param fromFrame defines the starting frame number (default is 0)
     * @param toFrame defines the ending frame number (default is 100)
     * @param loopAnimation defines if the animation must loop (default is false)
     * @param speedRatio defines the factor to apply to animation speed (default is 1)
     * @param onAnimationEnd defines a callback to call when animation ends if it is not looping
     * @param animations defines a group of animation to add to the new Animatable
     * @param onAnimationLoop defines a callback to call when animation loops
     */
    function Animatable(scene,
    /** defines the target object */
    target,
    /** defines the starting frame number (default is 0) */
    fromFrame,
    /** defines the ending frame number (default is 100) */
    toFrame,
    /** defines if the animation must loop (default is false)  */
    loopAnimation, speedRatio,
    /** defines a callback to call when animation ends if it is not looping */
    onAnimationEnd, animations,
    /** defines a callback to call when animation loops */
    onAnimationLoop) {
        if (fromFrame === void 0) { fromFrame = 0; }
        if (toFrame === void 0) { toFrame = 100; }
        if (loopAnimation === void 0) { loopAnimation = false; }
        if (speedRatio === void 0) { speedRatio = 1.0; }
        this.target = target;
        this.fromFrame = fromFrame;
        this.toFrame = toFrame;
        this.loopAnimation = loopAnimation;
        this.onAnimationEnd = onAnimationEnd;
        this.onAnimationLoop = onAnimationLoop;
        this._localDelayOffset = null;
        this._pausedDelay = null;
        this._runtimeAnimations = new Array();
        this._paused = false;
        this._speedRatio = 1;
        this._weight = -1.0;
        this._syncRoot = null;
        /**
         * Gets or sets a boolean indicating if the animatable must be disposed and removed at the end of the animation.
         * This will only apply for non looping animation (default is true)
         */
        this.disposeOnEnd = true;
        /**
         * Gets a boolean indicating if the animation has started
         */
        this.animationStarted = false;
        /**
         * Observer raised when the animation ends
         */
        this.onAnimationEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observer raised when the animation loops
         */
        this.onAnimationLoopObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        this._scene = scene;
        if (animations) {
            this.appendAnimations(target, animations);
        }
        this._speedRatio = speedRatio;
        scene._activeAnimatables.push(this);
    }
    Object.defineProperty(Animatable.prototype, "syncRoot", {
        /**
         * Gets the root Animatable used to synchronize and normalize animations
         */
        get: function () {
            return this._syncRoot;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animatable.prototype, "masterFrame", {
        /**
         * Gets the current frame of the first RuntimeAnimation
         * Used to synchronize Animatables
         */
        get: function () {
            if (this._runtimeAnimations.length === 0) {
                return 0;
            }
            return this._runtimeAnimations[0].currentFrame;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animatable.prototype, "weight", {
        /**
         * Gets or sets the animatable weight (-1.0 by default meaning not weighted)
         */
        get: function () {
            return this._weight;
        },
        set: function (value) {
            if (value === -1) { // -1 is ok and means no weight
                this._weight = -1;
                return;
            }
            // Else weight must be in [0, 1] range
            this._weight = Math.min(Math.max(value, 0), 1.0);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animatable.prototype, "speedRatio", {
        /**
         * Gets or sets the speed ratio to apply to the animatable (1.0 by default)
         */
        get: function () {
            return this._speedRatio;
        },
        set: function (value) {
            for (var index = 0; index < this._runtimeAnimations.length; index++) {
                var animation = this._runtimeAnimations[index];
                animation._prepareForSpeedRatioChange(value);
            }
            this._speedRatio = value;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /**
     * Synchronize and normalize current Animatable with a source Animatable
     * This is useful when using animation weights and when animations are not of the same length
     * @param root defines the root Animatable to synchronize with
     * @returns the current Animatable
     */
    Animatable.prototype.syncWith = function (root) {
        this._syncRoot = root;
        if (root) {
            // Make sure this animatable will animate after the root
            var index = this._scene._activeAnimatables.indexOf(this);
            if (index > -1) {
                this._scene._activeAnimatables.splice(index, 1);
                this._scene._activeAnimatables.push(this);
            }
        }
        return this;
    };
    /**
     * Gets the list of runtime animations
     * @returns an array of RuntimeAnimation
     */
    Animatable.prototype.getAnimations = function () {
        return this._runtimeAnimations;
    };
    /**
     * Adds more animations to the current animatable
     * @param target defines the target of the animations
     * @param animations defines the new animations to add
     */
    Animatable.prototype.appendAnimations = function (target, animations) {
        var _this = this;
        for (var index = 0; index < animations.length; index++) {
            var animation = animations[index];
            var newRuntimeAnimation = new _runtimeAnimation__WEBPACK_IMPORTED_MODULE_1__["RuntimeAnimation"](target, animation, this._scene, this);
            newRuntimeAnimation._onLoop = function () {
                _this.onAnimationLoopObservable.notifyObservers(_this);
                if (_this.onAnimationLoop) {
                    _this.onAnimationLoop();
                }
            };
            this._runtimeAnimations.push(newRuntimeAnimation);
        }
    };
    /**
     * Gets the source animation for a specific property
     * @param property defines the propertyu to look for
     * @returns null or the source animation for the given property
     */
    Animatable.prototype.getAnimationByTargetProperty = function (property) {
        var runtimeAnimations = this._runtimeAnimations;
        for (var index = 0; index < runtimeAnimations.length; index++) {
            if (runtimeAnimations[index].animation.targetProperty === property) {
                return runtimeAnimations[index].animation;
            }
        }
        return null;
    };
    /**
     * Gets the runtime animation for a specific property
     * @param property defines the propertyu to look for
     * @returns null or the runtime animation for the given property
     */
    Animatable.prototype.getRuntimeAnimationByTargetProperty = function (property) {
        var runtimeAnimations = this._runtimeAnimations;
        for (var index = 0; index < runtimeAnimations.length; index++) {
            if (runtimeAnimations[index].animation.targetProperty === property) {
                return runtimeAnimations[index];
            }
        }
        return null;
    };
    /**
     * Resets the animatable to its original state
     */
    Animatable.prototype.reset = function () {
        var runtimeAnimations = this._runtimeAnimations;
        for (var index = 0; index < runtimeAnimations.length; index++) {
            runtimeAnimations[index].reset(true);
        }
        this._localDelayOffset = null;
        this._pausedDelay = null;
    };
    /**
     * Allows the animatable to blend with current running animations
     * @see http://doc.babylonjs.com/babylon101/animations#animation-blending
     * @param blendingSpeed defines the blending speed to use
     */
    Animatable.prototype.enableBlending = function (blendingSpeed) {
        var runtimeAnimations = this._runtimeAnimations;
        for (var index = 0; index < runtimeAnimations.length; index++) {
            runtimeAnimations[index].animation.enableBlending = true;
            runtimeAnimations[index].animation.blendingSpeed = blendingSpeed;
        }
    };
    /**
     * Disable animation blending
     * @see http://doc.babylonjs.com/babylon101/animations#animation-blending
     */
    Animatable.prototype.disableBlending = function () {
        var runtimeAnimations = this._runtimeAnimations;
        for (var index = 0; index < runtimeAnimations.length; index++) {
            runtimeAnimations[index].animation.enableBlending = false;
        }
    };
    /**
     * Jump directly to a given frame
     * @param frame defines the frame to jump to
     */
    Animatable.prototype.goToFrame = function (frame) {
        var runtimeAnimations = this._runtimeAnimations;
        if (runtimeAnimations[0]) {
            var fps = runtimeAnimations[0].animation.framePerSecond;
            var currentFrame = runtimeAnimations[0].currentFrame;
            var adjustTime = frame - currentFrame;
            var delay = this.speedRatio !== 0 ? adjustTime * 1000 / (fps * this.speedRatio) : 0;
            if (this._localDelayOffset === null) {
                this._localDelayOffset = 0;
            }
            this._localDelayOffset -= delay;
        }
        for (var index = 0; index < runtimeAnimations.length; index++) {
            runtimeAnimations[index].goToFrame(frame);
        }
    };
    /**
     * Pause the animation
     */
    Animatable.prototype.pause = function () {
        if (this._paused) {
            return;
        }
        this._paused = true;
    };
    /**
     * Restart the animation
     */
    Animatable.prototype.restart = function () {
        this._paused = false;
    };
    Animatable.prototype._raiseOnAnimationEnd = function () {
        if (this.onAnimationEnd) {
            this.onAnimationEnd();
        }
        this.onAnimationEndObservable.notifyObservers(this);
    };
    /**
     * Stop and delete the current animation
     * @param animationName defines a string used to only stop some of the runtime animations instead of all
     * @param targetMask - a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)
     */
    Animatable.prototype.stop = function (animationName, targetMask) {
        if (animationName || targetMask) {
            var idx = this._scene._activeAnimatables.indexOf(this);
            if (idx > -1) {
                var runtimeAnimations = this._runtimeAnimations;
                for (var index = runtimeAnimations.length - 1; index >= 0; index--) {
                    var runtimeAnimation = runtimeAnimations[index];
                    if (animationName && runtimeAnimation.animation.name != animationName) {
                        continue;
                    }
                    if (targetMask && !targetMask(runtimeAnimation.target)) {
                        continue;
                    }
                    runtimeAnimation.dispose();
                    runtimeAnimations.splice(index, 1);
                }
                if (runtimeAnimations.length == 0) {
                    this._scene._activeAnimatables.splice(idx, 1);
                    this._raiseOnAnimationEnd();
                }
            }
        }
        else {
            var index = this._scene._activeAnimatables.indexOf(this);
            if (index > -1) {
                this._scene._activeAnimatables.splice(index, 1);
                var runtimeAnimations = this._runtimeAnimations;
                for (var index = 0; index < runtimeAnimations.length; index++) {
                    runtimeAnimations[index].dispose();
                }
                this._raiseOnAnimationEnd();
            }
        }
    };
    /**
     * Wait asynchronously for the animation to end
     * @returns a promise which will be fullfilled when the animation ends
     */
    Animatable.prototype.waitAsync = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this.onAnimationEndObservable.add(function () {
                resolve(_this);
            }, undefined, undefined, _this, true);
        });
    };
    /** @hidden */
    Animatable.prototype._animate = function (delay) {
        if (this._paused) {
            this.animationStarted = false;
            if (this._pausedDelay === null) {
                this._pausedDelay = delay;
            }
            return true;
        }
        if (this._localDelayOffset === null) {
            this._localDelayOffset = delay;
            this._pausedDelay = null;
        }
        else if (this._pausedDelay !== null) {
            this._localDelayOffset += delay - this._pausedDelay;
            this._pausedDelay = null;
        }
        if (this._weight === 0) { // We consider that an animation with a weight === 0 is "actively" paused
            return true;
        }
        // Animating
        var running = false;
        var runtimeAnimations = this._runtimeAnimations;
        var index;
        for (index = 0; index < runtimeAnimations.length; index++) {
            var animation = runtimeAnimations[index];
            var isRunning = animation.animate(delay - this._localDelayOffset, this.fromFrame, this.toFrame, this.loopAnimation, this._speedRatio, this._weight);
            running = running || isRunning;
        }
        this.animationStarted = running;
        if (!running) {
            if (this.disposeOnEnd) {
                // Remove from active animatables
                index = this._scene._activeAnimatables.indexOf(this);
                this._scene._activeAnimatables.splice(index, 1);
                // Dispose all runtime animations
                for (index = 0; index < runtimeAnimations.length; index++) {
                    runtimeAnimations[index].dispose();
                }
            }
            this._raiseOnAnimationEnd();
            if (this.disposeOnEnd) {
                this.onAnimationEnd = null;
                this.onAnimationLoop = null;
                this.onAnimationLoopObservable.clear();
                this.onAnimationEndObservable.clear();
            }
        }
        return running;
    };
    return Animatable;
}());

_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype._animate = function () {
    if (!this.animationsEnabled) {
        return;
    }
    var animatables = this._activeAnimatables;
    if (animatables.length === 0) {
        return;
    }
    // Getting time
    var now = _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_5__["PrecisionDate"].Now;
    if (!this._animationTimeLast) {
        if (this._pendingData.length > 0) {
            return;
        }
        this._animationTimeLast = now;
    }
    var deltaTime = this.useConstantAnimationDeltaTime ? 16.0 : (now - this._animationTimeLast) * this.animationTimeScale;
    this._animationTime += deltaTime;
    var animationTime = this._animationTime;
    this._animationTimeLast = now;
    for (var index = 0; index < animatables.length; index++) {
        var animatable = animatables[index];
        if (!animatable._animate(animationTime) && animatable.disposeOnEnd) {
            index--; // Array was updated
        }
    }
    // Late animation bindings
    this._processLateAnimationBindings();
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.beginWeightedAnimation = function (target, from, to, weight, loop, speedRatio, onAnimationEnd, animatable, targetMask, onAnimationLoop) {
    if (weight === void 0) { weight = 1.0; }
    if (speedRatio === void 0) { speedRatio = 1.0; }
    var returnedAnimatable = this.beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable, false, targetMask, onAnimationLoop);
    returnedAnimatable.weight = weight;
    return returnedAnimatable;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.beginAnimation = function (target, from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask, onAnimationLoop) {
    if (speedRatio === void 0) { speedRatio = 1.0; }
    if (stopCurrent === void 0) { stopCurrent = true; }
    if (from > to && speedRatio > 0) {
        speedRatio *= -1;
    }
    if (stopCurrent) {
        this.stopAnimation(target, undefined, targetMask);
    }
    if (!animatable) {
        animatable = new Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd, undefined, onAnimationLoop);
    }
    var shouldRunTargetAnimations = targetMask ? targetMask(target) : true;
    // Local animations
    if (target.animations && shouldRunTargetAnimations) {
        animatable.appendAnimations(target, target.animations);
    }
    // Children animations
    if (target.getAnimatables) {
        var animatables = target.getAnimatables();
        for (var index = 0; index < animatables.length; index++) {
            this.beginAnimation(animatables[index], from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask, onAnimationLoop);
        }
    }
    animatable.reset();
    return animatable;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.beginHierarchyAnimation = function (target, directDescendantsOnly, from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask, onAnimationLoop) {
    if (speedRatio === void 0) { speedRatio = 1.0; }
    if (stopCurrent === void 0) { stopCurrent = true; }
    var children = target.getDescendants(directDescendantsOnly);
    var result = [];
    result.push(this.beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask));
    for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
        var child = children_1[_i];
        result.push(this.beginAnimation(child, from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask));
    }
    return result;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.beginDirectAnimation = function (target, animations, from, to, loop, speedRatio, onAnimationEnd, onAnimationLoop) {
    if (speedRatio === undefined) {
        speedRatio = 1.0;
    }
    var animatable = new Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd, animations, onAnimationLoop);
    return animatable;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.beginDirectHierarchyAnimation = function (target, directDescendantsOnly, animations, from, to, loop, speedRatio, onAnimationEnd, onAnimationLoop) {
    var children = target.getDescendants(directDescendantsOnly);
    var result = [];
    result.push(this.beginDirectAnimation(target, animations, from, to, loop, speedRatio, onAnimationEnd, onAnimationLoop));
    for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
        var child = children_2[_i];
        result.push(this.beginDirectAnimation(child, animations, from, to, loop, speedRatio, onAnimationEnd, onAnimationLoop));
    }
    return result;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.getAnimatableByTarget = function (target) {
    for (var index = 0; index < this._activeAnimatables.length; index++) {
        if (this._activeAnimatables[index].target === target) {
            return this._activeAnimatables[index];
        }
    }
    return null;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.getAllAnimatablesByTarget = function (target) {
    var result = [];
    for (var index = 0; index < this._activeAnimatables.length; index++) {
        if (this._activeAnimatables[index].target === target) {
            result.push(this._activeAnimatables[index]);
        }
    }
    return result;
};
/**
 * Will stop the animation of the given target
 * @param target - the target
 * @param animationName - the name of the animation to stop (all animations will be stopped if both this and targetMask are empty)
 * @param targetMask - a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)
 */
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.stopAnimation = function (target, animationName, targetMask) {
    var animatables = this.getAllAnimatablesByTarget(target);
    for (var _i = 0, animatables_1 = animatables; _i < animatables_1.length; _i++) {
        var animatable = animatables_1[_i];
        animatable.stop(animationName, targetMask);
    }
};
/**
 * Stops and removes all animations that have been applied to the scene
 */
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype.stopAllAnimations = function () {
    if (this._activeAnimatables) {
        for (var i = 0; i < this._activeAnimatables.length; i++) {
            this._activeAnimatables[i].stop();
        }
        this._activeAnimatables = [];
    }
    for (var _i = 0, _a = this.animationGroups; _i < _a.length; _i++) {
        var group = _a[_i];
        group.stop();
    }
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype._registerTargetForLateAnimationBinding = function (runtimeAnimation, originalValue) {
    var target = runtimeAnimation.target;
    this._registeredForLateAnimationBindings.pushNoDuplicate(target);
    if (!target._lateAnimationHolders) {
        target._lateAnimationHolders = {};
    }
    if (!target._lateAnimationHolders[runtimeAnimation.targetPath]) {
        target._lateAnimationHolders[runtimeAnimation.targetPath] = {
            totalWeight: 0,
            animations: [],
            originalValue: originalValue
        };
    }
    target._lateAnimationHolders[runtimeAnimation.targetPath].animations.push(runtimeAnimation);
    target._lateAnimationHolders[runtimeAnimation.targetPath].totalWeight += runtimeAnimation.weight;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype._processLateAnimationBindingsForMatrices = function (holder) {
    var normalizer = 1.0;
    var finalPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Vector3[0];
    var finalScaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Vector3[1];
    var finalQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Quaternion[0];
    var startIndex = 0;
    var originalAnimation = holder.animations[0];
    var originalValue = holder.originalValue;
    var scale = 1;
    if (holder.totalWeight < 1.0) {
        // We need to mix the original value in
        originalValue.decompose(finalScaling, finalQuaternion, finalPosition);
        scale = 1.0 - holder.totalWeight;
    }
    else {
        startIndex = 1;
        // We need to normalize the weights
        normalizer = holder.totalWeight;
        originalAnimation.currentValue.decompose(finalScaling, finalQuaternion, finalPosition);
        scale = originalAnimation.weight / normalizer;
        if (scale == 1) {
            return originalAnimation.currentValue;
        }
    }
    finalScaling.scaleInPlace(scale);
    finalPosition.scaleInPlace(scale);
    finalQuaternion.scaleInPlace(scale);
    for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
        var runtimeAnimation = holder.animations[animIndex];
        var scale = runtimeAnimation.weight / normalizer;
        var currentPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Vector3[2];
        var currentScaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Vector3[3];
        var currentQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Quaternion[1];
        runtimeAnimation.currentValue.decompose(currentScaling, currentQuaternion, currentPosition);
        currentScaling.scaleAndAddToRef(scale, finalScaling);
        currentQuaternion.scaleAndAddToRef(scale, finalQuaternion);
        currentPosition.scaleAndAddToRef(scale, finalPosition);
    }
    var workValue = originalAnimation._animationState.workValue;
    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].ComposeToRef(finalScaling, finalQuaternion, finalPosition, workValue);
    return workValue;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype._processLateAnimationBindingsForQuaternions = function (holder, refQuaternion) {
    var originalAnimation = holder.animations[0];
    var originalValue = holder.originalValue;
    if (holder.animations.length === 1) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].SlerpToRef(originalValue, originalAnimation.currentValue, Math.min(1.0, holder.totalWeight), refQuaternion);
        return refQuaternion;
    }
    var normalizer = 1.0;
    var quaternions;
    var weights;
    if (holder.totalWeight < 1.0) {
        var scale = 1.0 - holder.totalWeight;
        quaternions = [];
        weights = [];
        quaternions.push(originalValue);
        weights.push(scale);
    }
    else {
        if (holder.animations.length === 2) { // Slerp as soon as we can
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].SlerpToRef(holder.animations[0].currentValue, holder.animations[1].currentValue, holder.animations[1].weight / holder.totalWeight, refQuaternion);
            return refQuaternion;
        }
        quaternions = [];
        weights = [];
        normalizer = holder.totalWeight;
    }
    for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
        var runtimeAnimation = holder.animations[animIndex];
        quaternions.push(runtimeAnimation.currentValue);
        weights.push(runtimeAnimation.weight / normalizer);
    }
    // https://gamedev.stackexchange.com/questions/62354/method-for-interpolation-between-3-quaternions
    var cumulativeAmount = 0;
    var cumulativeQuaternion = null;
    for (var index = 0; index < quaternions.length;) {
        if (!cumulativeQuaternion) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].SlerpToRef(quaternions[index], quaternions[index + 1], weights[index + 1] / (weights[index] + weights[index + 1]), refQuaternion);
            cumulativeQuaternion = refQuaternion;
            cumulativeAmount = weights[index] + weights[index + 1];
            index += 2;
            continue;
        }
        cumulativeAmount += weights[index];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].SlerpToRef(cumulativeQuaternion, quaternions[index], weights[index] / cumulativeAmount, cumulativeQuaternion);
        index++;
    }
    return cumulativeQuaternion;
};
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype._processLateAnimationBindings = function () {
    if (!this._registeredForLateAnimationBindings.length) {
        return;
    }
    for (var index = 0; index < this._registeredForLateAnimationBindings.length; index++) {
        var target = this._registeredForLateAnimationBindings.data[index];
        for (var path in target._lateAnimationHolders) {
            var holder = target._lateAnimationHolders[path];
            var originalAnimation = holder.animations[0];
            var originalValue = holder.originalValue;
            var matrixDecomposeMode = _animation__WEBPACK_IMPORTED_MODULE_0__["Animation"].AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
            var finalValue = target[path];
            if (matrixDecomposeMode) {
                finalValue = this._processLateAnimationBindingsForMatrices(holder);
            }
            else {
                var quaternionMode = originalValue.w !== undefined;
                if (quaternionMode) {
                    finalValue = this._processLateAnimationBindingsForQuaternions(holder, finalValue || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].Identity());
                }
                else {
                    var startIndex = 0;
                    var normalizer = 1.0;
                    if (holder.totalWeight < 1.0) {
                        // We need to mix the original value in
                        if (originalValue.scale) {
                            finalValue = originalValue.scale(1.0 - holder.totalWeight);
                        }
                        else {
                            finalValue = originalValue * (1.0 - holder.totalWeight);
                        }
                    }
                    else {
                        // We need to normalize the weights
                        normalizer = holder.totalWeight;
                        var scale_1 = originalAnimation.weight / normalizer;
                        if (scale_1 !== 1) {
                            if (originalAnimation.currentValue.scale) {
                                finalValue = originalAnimation.currentValue.scale(scale_1);
                            }
                            else {
                                finalValue = originalAnimation.currentValue * scale_1;
                            }
                        }
                        else {
                            finalValue = originalAnimation.currentValue;
                        }
                        startIndex = 1;
                    }
                    for (var animIndex = startIndex; animIndex < holder.animations.length; animIndex++) {
                        var runtimeAnimation = holder.animations[animIndex];
                        var scale = runtimeAnimation.weight / normalizer;
                        if (runtimeAnimation.currentValue.scaleAndAddToRef) {
                            runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
                        }
                        else {
                            finalValue += runtimeAnimation.currentValue * scale;
                        }
                    }
                }
            }
            target[path] = finalValue;
        }
        target._lateAnimationHolders = {};
    }
    this._registeredForLateAnimationBindings.reset();
};
_Bones_bone__WEBPACK_IMPORTED_MODULE_6__["Bone"].prototype.copyAnimationRange = function (source, rangeName, frameOffset, rescaleAsRequired, skelDimensionsRatio) {
    if (rescaleAsRequired === void 0) { rescaleAsRequired = false; }
    if (skelDimensionsRatio === void 0) { skelDimensionsRatio = null; }
    // all animation may be coming from a library skeleton, so may need to create animation
    if (this.animations.length === 0) {
        this.animations.push(new _animation__WEBPACK_IMPORTED_MODULE_0__["Animation"](this.name, "_matrix", source.animations[0].framePerSecond, _animation__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_MATRIX, 0));
        this.animations[0].setKeys([]);
    }
    // get animation info / verify there is such a range from the source bone
    var sourceRange = source.animations[0].getRange(rangeName);
    if (!sourceRange) {
        return false;
    }
    var from = sourceRange.from;
    var to = sourceRange.to;
    var sourceKeys = source.animations[0].getKeys();
    // rescaling prep
    var sourceBoneLength = source.length;
    var sourceParent = source.getParent();
    var parent = this.getParent();
    var parentScalingReqd = rescaleAsRequired && sourceParent && sourceBoneLength && this.length && sourceBoneLength !== this.length;
    var parentRatio = parentScalingReqd && parent && sourceParent ? parent.length / sourceParent.length : 1;
    var dimensionsScalingReqd = rescaleAsRequired && !parent && skelDimensionsRatio && (skelDimensionsRatio.x !== 1 || skelDimensionsRatio.y !== 1 || skelDimensionsRatio.z !== 1);
    var destKeys = this.animations[0].getKeys();
    // loop vars declaration
    var orig;
    var origTranslation;
    var mat;
    for (var key = 0, nKeys = sourceKeys.length; key < nKeys; key++) {
        orig = sourceKeys[key];
        if (orig.frame >= from && orig.frame <= to) {
            if (rescaleAsRequired) {
                mat = orig.value.clone();
                // scale based on parent ratio, when bone has parent
                if (parentScalingReqd) {
                    origTranslation = mat.getTranslation();
                    mat.setTranslation(origTranslation.scaleInPlace(parentRatio));
                    // scale based on skeleton dimension ratio when root bone, and value is passed
                }
                else if (dimensionsScalingReqd && skelDimensionsRatio) {
                    origTranslation = mat.getTranslation();
                    mat.setTranslation(origTranslation.multiplyInPlace(skelDimensionsRatio));
                    // use original when root bone, and no data for skelDimensionsRatio
                }
                else {
                    mat = orig.value;
                }
            }
            else {
                mat = orig.value;
            }
            destKeys.push({ frame: orig.frame + frameOffset, value: mat });
        }
    }
    this.animations[0].createRange(rangeName, from + frameOffset, to + frameOffset);
    return true;
};


/***/ }),

/***/ "./Animations/animation.ts":
/*!*********************************!*\
  !*** ./Animations/animation.ts ***!
  \*********************************/
/*! exports provided: _IAnimationState, Animation */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_IAnimationState", function() { return _IAnimationState; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Animation", function() { return Animation; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _animationKey__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./animationKey */ "./Animations/animationKey.ts");
/* harmony import */ var _animationRange__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./animationRange */ "./Animations/animationRange.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Maths/math.size */ "./Maths/math.size.ts");









/**
 * @hidden
 */
var _IAnimationState = /** @class */ (function () {
    function _IAnimationState() {
    }
    return _IAnimationState;
}());

/**
 * Class used to store any kind of animation
 */
var Animation = /** @class */ (function () {
    /**
     * Initializes the animation
     * @param name Name of the animation
     * @param targetProperty Property to animate
     * @param framePerSecond The frames per second of the animation
     * @param dataType The data type of the animation
     * @param loopMode The loop mode of the animation
     * @param enableBlending Specifies if blending should be enabled
     */
    function Animation(
    /**Name of the animation */
    name,
    /**Property to animate */
    targetProperty,
    /**The frames per second of the animation */
    framePerSecond,
    /**The data type of the animation */
    dataType,
    /**The loop mode of the animation */
    loopMode,
    /**Specifies if blending should be enabled */
    enableBlending) {
        this.name = name;
        this.targetProperty = targetProperty;
        this.framePerSecond = framePerSecond;
        this.dataType = dataType;
        this.loopMode = loopMode;
        this.enableBlending = enableBlending;
        /**
         * @hidden Internal use only
         */
        this._runtimeAnimations = new Array();
        /**
         * The set of event that will be linked to this animation
         */
        this._events = new Array();
        /**
         * Stores the blending speed of the animation
         */
        this.blendingSpeed = 0.01;
        /**
         * Stores the animation ranges for the animation
         */
        this._ranges = {};
        this.targetPropertyPath = targetProperty.split(".");
        this.dataType = dataType;
        this.loopMode = loopMode === undefined ? Animation.ANIMATIONLOOPMODE_CYCLE : loopMode;
    }
    /**
     * @hidden Internal use
     */
    Animation._PrepareAnimation = function (name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction) {
        var dataType = undefined;
        if (!isNaN(parseFloat(from)) && isFinite(from)) {
            dataType = Animation.ANIMATIONTYPE_FLOAT;
        }
        else if (from instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"]) {
            dataType = Animation.ANIMATIONTYPE_QUATERNION;
        }
        else if (from instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]) {
            dataType = Animation.ANIMATIONTYPE_VECTOR3;
        }
        else if (from instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"]) {
            dataType = Animation.ANIMATIONTYPE_VECTOR2;
        }
        else if (from instanceof _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"]) {
            dataType = Animation.ANIMATIONTYPE_COLOR3;
        }
        else if (from instanceof _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__["Size"]) {
            dataType = Animation.ANIMATIONTYPE_SIZE;
        }
        if (dataType == undefined) {
            return null;
        }
        var animation = new Animation(name, targetProperty, framePerSecond, dataType, loopMode);
        var keys = [{ frame: 0, value: from }, { frame: totalFrame, value: to }];
        animation.setKeys(keys);
        if (easingFunction !== undefined) {
            animation.setEasingFunction(easingFunction);
        }
        return animation;
    };
    /**
     * Sets up an animation
     * @param property The property to animate
     * @param animationType The animation type to apply
     * @param framePerSecond The frames per second of the animation
     * @param easingFunction The easing function used in the animation
     * @returns The created animation
     */
    Animation.CreateAnimation = function (property, animationType, framePerSecond, easingFunction) {
        var animation = new Animation(property + "Animation", property, framePerSecond, animationType, Animation.ANIMATIONLOOPMODE_CONSTANT);
        animation.setEasingFunction(easingFunction);
        return animation;
    };
    /**
     * Create and start an animation on a node
     * @param name defines the name of the global animation that will be run on all nodes
     * @param node defines the root node where the animation will take place
     * @param targetProperty defines property to animate
     * @param framePerSecond defines the number of frame per second yo use
     * @param totalFrame defines the number of frames in total
     * @param from defines the initial value
     * @param to defines the final value
     * @param loopMode defines which loop mode you want to use (off by default)
     * @param easingFunction defines the easing function to use (linear by default)
     * @param onAnimationEnd defines the callback to call when animation end
     * @returns the animatable created for this animation
     */
    Animation.CreateAndStartAnimation = function (name, node, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction, onAnimationEnd) {
        var animation = Animation._PrepareAnimation(name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction);
        if (!animation) {
            return null;
        }
        return node.getScene().beginDirectAnimation(node, [animation], 0, totalFrame, (animation.loopMode === 1), 1.0, onAnimationEnd);
    };
    /**
     * Create and start an animation on a node and its descendants
     * @param name defines the name of the global animation that will be run on all nodes
     * @param node defines the root node where the animation will take place
     * @param directDescendantsOnly if true only direct descendants will be used, if false direct and also indirect (children of children, an so on in a recursive manner) descendants will be used
     * @param targetProperty defines property to animate
     * @param framePerSecond defines the number of frame per second to use
     * @param totalFrame defines the number of frames in total
     * @param from defines the initial value
     * @param to defines the final value
     * @param loopMode defines which loop mode you want to use (off by default)
     * @param easingFunction defines the easing function to use (linear by default)
     * @param onAnimationEnd defines the callback to call when an animation ends (will be called once per node)
     * @returns the list of animatables created for all nodes
     * @example https://www.babylonjs-playground.com/#MH0VLI
     */
    Animation.CreateAndStartHierarchyAnimation = function (name, node, directDescendantsOnly, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction, onAnimationEnd) {
        var animation = Animation._PrepareAnimation(name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction);
        if (!animation) {
            return null;
        }
        var scene = node.getScene();
        return scene.beginDirectHierarchyAnimation(node, directDescendantsOnly, [animation], 0, totalFrame, (animation.loopMode === 1), 1.0, onAnimationEnd);
    };
    /**
     * Creates a new animation, merges it with the existing animations and starts it
     * @param name Name of the animation
     * @param node Node which contains the scene that begins the animations
     * @param targetProperty Specifies which property to animate
     * @param framePerSecond The frames per second of the animation
     * @param totalFrame The total number of frames
     * @param from The frame at the beginning of the animation
     * @param to The frame at the end of the animation
     * @param loopMode Specifies the loop mode of the animation
     * @param easingFunction (Optional) The easing function of the animation, which allow custom mathematical formulas for animations
     * @param onAnimationEnd Callback to run once the animation is complete
     * @returns Nullable animation
     */
    Animation.CreateMergeAndStartAnimation = function (name, node, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction, onAnimationEnd) {
        var animation = Animation._PrepareAnimation(name, targetProperty, framePerSecond, totalFrame, from, to, loopMode, easingFunction);
        if (!animation) {
            return null;
        }
        node.animations.push(animation);
        return node.getScene().beginAnimation(node, 0, totalFrame, (animation.loopMode === 1), 1.0, onAnimationEnd);
    };
    /**
     * Transition property of an host to the target Value
     * @param property The property to transition
     * @param targetValue The target Value of the property
     * @param host The object where the property to animate belongs
     * @param scene Scene used to run the animation
     * @param frameRate Framerate (in frame/s) to use
     * @param transition The transition type we want to use
     * @param duration The duration of the animation, in milliseconds
     * @param onAnimationEnd Callback trigger at the end of the animation
     * @returns Nullable animation
     */
    Animation.TransitionTo = function (property, targetValue, host, scene, frameRate, transition, duration, onAnimationEnd) {
        if (onAnimationEnd === void 0) { onAnimationEnd = null; }
        if (duration <= 0) {
            host[property] = targetValue;
            if (onAnimationEnd) {
                onAnimationEnd();
            }
            return null;
        }
        var endFrame = frameRate * (duration / 1000);
        transition.setKeys([{
                frame: 0,
                value: host[property].clone ? host[property].clone() : host[property]
            },
            {
                frame: endFrame,
                value: targetValue
            }]);
        if (!host.animations) {
            host.animations = [];
        }
        host.animations.push(transition);
        var animation = scene.beginAnimation(host, 0, endFrame, false);
        animation.onAnimationEnd = onAnimationEnd;
        return animation;
    };
    Object.defineProperty(Animation.prototype, "runtimeAnimations", {
        /**
         * Return the array of runtime animations currently using this animation
         */
        get: function () {
            return this._runtimeAnimations;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation.prototype, "hasRunningRuntimeAnimations", {
        /**
         * Specifies if any of the runtime animations are currently running
         */
        get: function () {
            for (var _i = 0, _a = this._runtimeAnimations; _i < _a.length; _i++) {
                var runtimeAnimation = _a[_i];
                if (!runtimeAnimation.isStopped) {
                    return true;
                }
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /**
     * Converts the animation to a string
     * @param fullDetails support for multiple levels of logging within scene loading
     * @returns String form of the animation
     */
    Animation.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name + ", property: " + this.targetProperty;
        ret += ", datatype: " + (["Float", "Vector3", "Quaternion", "Matrix", "Color3", "Vector2"])[this.dataType];
        ret += ", nKeys: " + (this._keys ? this._keys.length : "none");
        ret += ", nRanges: " + (this._ranges ? Object.keys(this._ranges).length : "none");
        if (fullDetails) {
            ret += ", Ranges: {";
            var first = true;
            for (var name in this._ranges) {
                if (first) {
                    ret += ", ";
                    first = false;
                }
                ret += name;
            }
            ret += "}";
        }
        return ret;
    };
    /**
     * Add an event to this animation
     * @param event Event to add
     */
    Animation.prototype.addEvent = function (event) {
        this._events.push(event);
    };
    /**
     * Remove all events found at the given frame
     * @param frame The frame to remove events from
     */
    Animation.prototype.removeEvents = function (frame) {
        for (var index = 0; index < this._events.length; index++) {
            if (this._events[index].frame === frame) {
                this._events.splice(index, 1);
                index--;
            }
        }
    };
    /**
     * Retrieves all the events from the animation
     * @returns Events from the animation
     */
    Animation.prototype.getEvents = function () {
        return this._events;
    };
    /**
     * Creates an animation range
     * @param name Name of the animation range
     * @param from Starting frame of the animation range
     * @param to Ending frame of the animation
     */
    Animation.prototype.createRange = function (name, from, to) {
        // check name not already in use; could happen for bones after serialized
        if (!this._ranges[name]) {
            this._ranges[name] = new _animationRange__WEBPACK_IMPORTED_MODULE_6__["AnimationRange"](name, from, to);
        }
    };
    /**
     * Deletes an animation range by name
     * @param name Name of the animation range to delete
     * @param deleteFrames Specifies if the key frames for the range should also be deleted (true) or not (false)
     */
    Animation.prototype.deleteRange = function (name, deleteFrames) {
        if (deleteFrames === void 0) { deleteFrames = true; }
        var range = this._ranges[name];
        if (!range) {
            return;
        }
        if (deleteFrames) {
            var from = range.from;
            var to = range.to;
            // this loop MUST go high to low for multiple splices to work
            for (var key = this._keys.length - 1; key >= 0; key--) {
                if (this._keys[key].frame >= from && this._keys[key].frame <= to) {
                    this._keys.splice(key, 1);
                }
            }
        }
        this._ranges[name] = null; // said much faster than 'delete this._range[name]'
    };
    /**
     * Gets the animation range by name, or null if not defined
     * @param name Name of the animation range
     * @returns Nullable animation range
     */
    Animation.prototype.getRange = function (name) {
        return this._ranges[name];
    };
    /**
     * Gets the key frames from the animation
     * @returns The key frames of the animation
     */
    Animation.prototype.getKeys = function () {
        return this._keys;
    };
    /**
     * Gets the highest frame rate of the animation
     * @returns Highest frame rate of the animation
     */
    Animation.prototype.getHighestFrame = function () {
        var ret = 0;
        for (var key = 0, nKeys = this._keys.length; key < nKeys; key++) {
            if (ret < this._keys[key].frame) {
                ret = this._keys[key].frame;
            }
        }
        return ret;
    };
    /**
     * Gets the easing function of the animation
     * @returns Easing function of the animation
     */
    Animation.prototype.getEasingFunction = function () {
        return this._easingFunction;
    };
    /**
     * Sets the easing function of the animation
     * @param easingFunction A custom mathematical formula for animation
     */
    Animation.prototype.setEasingFunction = function (easingFunction) {
        this._easingFunction = easingFunction;
    };
    /**
     * Interpolates a scalar linearly
     * @param startValue Start value of the animation curve
     * @param endValue End value of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated scalar value
     */
    Animation.prototype.floatInterpolateFunction = function (startValue, endValue, gradient) {
        return _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Lerp(startValue, endValue, gradient);
    };
    /**
     * Interpolates a scalar cubically
     * @param startValue Start value of the animation curve
     * @param outTangent End tangent of the animation
     * @param endValue End value of the animation curve
     * @param inTangent Start tangent of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated scalar value
     */
    Animation.prototype.floatInterpolateFunctionWithTangents = function (startValue, outTangent, endValue, inTangent, gradient) {
        return _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Hermite(startValue, outTangent, endValue, inTangent, gradient);
    };
    /**
     * Interpolates a quaternion using a spherical linear interpolation
     * @param startValue Start value of the animation curve
     * @param endValue End value of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated quaternion value
     */
    Animation.prototype.quaternionInterpolateFunction = function (startValue, endValue, gradient) {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Slerp(startValue, endValue, gradient);
    };
    /**
     * Interpolates a quaternion cubically
     * @param startValue Start value of the animation curve
     * @param outTangent End tangent of the animation curve
     * @param endValue End value of the animation curve
     * @param inTangent Start tangent of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated quaternion value
     */
    Animation.prototype.quaternionInterpolateFunctionWithTangents = function (startValue, outTangent, endValue, inTangent, gradient) {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Hermite(startValue, outTangent, endValue, inTangent, gradient).normalize();
    };
    /**
     * Interpolates a Vector3 linearl
     * @param startValue Start value of the animation curve
     * @param endValue End value of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated scalar value
     */
    Animation.prototype.vector3InterpolateFunction = function (startValue, endValue, gradient) {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(startValue, endValue, gradient);
    };
    /**
     * Interpolates a Vector3 cubically
     * @param startValue Start value of the animation curve
     * @param outTangent End tangent of the animation
     * @param endValue End value of the animation curve
     * @param inTangent Start tangent of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns InterpolatedVector3 value
     */
    Animation.prototype.vector3InterpolateFunctionWithTangents = function (startValue, outTangent, endValue, inTangent, gradient) {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Hermite(startValue, outTangent, endValue, inTangent, gradient);
    };
    /**
     * Interpolates a Vector2 linearly
     * @param startValue Start value of the animation curve
     * @param endValue End value of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated Vector2 value
     */
    Animation.prototype.vector2InterpolateFunction = function (startValue, endValue, gradient) {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Lerp(startValue, endValue, gradient);
    };
    /**
     * Interpolates a Vector2 cubically
     * @param startValue Start value of the animation curve
     * @param outTangent End tangent of the animation
     * @param endValue End value of the animation curve
     * @param inTangent Start tangent of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated Vector2 value
     */
    Animation.prototype.vector2InterpolateFunctionWithTangents = function (startValue, outTangent, endValue, inTangent, gradient) {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Hermite(startValue, outTangent, endValue, inTangent, gradient);
    };
    /**
     * Interpolates a size linearly
     * @param startValue Start value of the animation curve
     * @param endValue End value of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated Size value
     */
    Animation.prototype.sizeInterpolateFunction = function (startValue, endValue, gradient) {
        return _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__["Size"].Lerp(startValue, endValue, gradient);
    };
    /**
     * Interpolates a Color3 linearly
     * @param startValue Start value of the animation curve
     * @param endValue End value of the animation curve
     * @param gradient Scalar amount to interpolate
     * @returns Interpolated Color3 value
     */
    Animation.prototype.color3InterpolateFunction = function (startValue, endValue, gradient) {
        return _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].Lerp(startValue, endValue, gradient);
    };
    /**
     * @hidden Internal use only
     */
    Animation.prototype._getKeyValue = function (value) {
        if (typeof value === "function") {
            return value();
        }
        return value;
    };
    /**
     * @hidden Internal use only
     */
    Animation.prototype._interpolate = function (currentFrame, state) {
        if (state.loopMode === Animation.ANIMATIONLOOPMODE_CONSTANT && state.repeatCount > 0) {
            return state.highLimitValue.clone ? state.highLimitValue.clone() : state.highLimitValue;
        }
        var keys = this._keys;
        if (keys.length === 1) {
            return this._getKeyValue(keys[0].value);
        }
        var startKeyIndex = state.key;
        if (keys[startKeyIndex].frame >= currentFrame) {
            while (startKeyIndex - 1 >= 0 && keys[startKeyIndex].frame >= currentFrame) {
                startKeyIndex--;
            }
        }
        for (var key = startKeyIndex; key < keys.length; key++) {
            var endKey = keys[key + 1];
            if (endKey.frame >= currentFrame) {
                state.key = key;
                var startKey = keys[key];
                var startValue = this._getKeyValue(startKey.value);
                if (startKey.interpolation === _animationKey__WEBPACK_IMPORTED_MODULE_5__["AnimationKeyInterpolation"].STEP) {
                    return startValue;
                }
                var endValue = this._getKeyValue(endKey.value);
                var useTangent = startKey.outTangent !== undefined && endKey.inTangent !== undefined;
                var frameDelta = endKey.frame - startKey.frame;
                // gradient : percent of currentFrame between the frame inf and the frame sup
                var gradient = (currentFrame - startKey.frame) / frameDelta;
                // check for easingFunction and correction of gradient
                var easingFunction = this.getEasingFunction();
                if (easingFunction != null) {
                    gradient = easingFunction.ease(gradient);
                }
                switch (this.dataType) {
                    // Float
                    case Animation.ANIMATIONTYPE_FLOAT:
                        var floatValue = useTangent ? this.floatInterpolateFunctionWithTangents(startValue, startKey.outTangent * frameDelta, endValue, endKey.inTangent * frameDelta, gradient) : this.floatInterpolateFunction(startValue, endValue, gradient);
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                return floatValue;
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return state.offsetValue * state.repeatCount + floatValue;
                        }
                        break;
                    // Quaternion
                    case Animation.ANIMATIONTYPE_QUATERNION:
                        var quatValue = useTangent ? this.quaternionInterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.quaternionInterpolateFunction(startValue, endValue, gradient);
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                return quatValue;
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return quatValue.addInPlace(state.offsetValue.scale(state.repeatCount));
                        }
                        return quatValue;
                    // Vector3
                    case Animation.ANIMATIONTYPE_VECTOR3:
                        var vec3Value = useTangent ? this.vector3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.vector3InterpolateFunction(startValue, endValue, gradient);
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                return vec3Value;
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return vec3Value.add(state.offsetValue.scale(state.repeatCount));
                        }
                    // Vector2
                    case Animation.ANIMATIONTYPE_VECTOR2:
                        var vec2Value = useTangent ? this.vector2InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.vector2InterpolateFunction(startValue, endValue, gradient);
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                return vec2Value;
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return vec2Value.add(state.offsetValue.scale(state.repeatCount));
                        }
                    // Size
                    case Animation.ANIMATIONTYPE_SIZE:
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                return this.sizeInterpolateFunction(startValue, endValue, gradient);
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return this.sizeInterpolateFunction(startValue, endValue, gradient).add(state.offsetValue.scale(state.repeatCount));
                        }
                    // Color3
                    case Animation.ANIMATIONTYPE_COLOR3:
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                return this.color3InterpolateFunction(startValue, endValue, gradient);
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return this.color3InterpolateFunction(startValue, endValue, gradient).add(state.offsetValue.scale(state.repeatCount));
                        }
                    // Matrix
                    case Animation.ANIMATIONTYPE_MATRIX:
                        switch (state.loopMode) {
                            case Animation.ANIMATIONLOOPMODE_CYCLE:
                            case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                if (Animation.AllowMatricesInterpolation) {
                                    return this.matrixInterpolateFunction(startValue, endValue, gradient, state.workValue);
                                }
                            case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                return startValue;
                        }
                    default:
                        break;
                }
                break;
            }
        }
        return this._getKeyValue(keys[keys.length - 1].value);
    };
    /**
     * Defines the function to use to interpolate matrices
     * @param startValue defines the start matrix
     * @param endValue defines the end matrix
     * @param gradient defines the gradient between both matrices
     * @param result defines an optional target matrix where to store the interpolation
     * @returns the interpolated matrix
     */
    Animation.prototype.matrixInterpolateFunction = function (startValue, endValue, gradient, result) {
        if (Animation.AllowMatrixDecomposeForInterpolation) {
            if (result) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].DecomposeLerpToRef(startValue, endValue, gradient, result);
                return result;
            }
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].DecomposeLerp(startValue, endValue, gradient);
        }
        if (result) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].LerpToRef(startValue, endValue, gradient, result);
            return result;
        }
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Lerp(startValue, endValue, gradient);
    };
    /**
     * Makes a copy of the animation
     * @returns Cloned animation
     */
    Animation.prototype.clone = function () {
        var clone = new Animation(this.name, this.targetPropertyPath.join("."), this.framePerSecond, this.dataType, this.loopMode);
        clone.enableBlending = this.enableBlending;
        clone.blendingSpeed = this.blendingSpeed;
        if (this._keys) {
            clone.setKeys(this._keys);
        }
        if (this._ranges) {
            clone._ranges = {};
            for (var name in this._ranges) {
                var range = this._ranges[name];
                if (!range) {
                    continue;
                }
                clone._ranges[name] = range.clone();
            }
        }
        return clone;
    };
    /**
     * Sets the key frames of the animation
     * @param values The animation key frames to set
     */
    Animation.prototype.setKeys = function (values) {
        this._keys = values.slice(0);
    };
    /**
     * Serializes the animation to an object
     * @returns Serialized object
     */
    Animation.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.property = this.targetProperty;
        serializationObject.framePerSecond = this.framePerSecond;
        serializationObject.dataType = this.dataType;
        serializationObject.loopBehavior = this.loopMode;
        serializationObject.enableBlending = this.enableBlending;
        serializationObject.blendingSpeed = this.blendingSpeed;
        var dataType = this.dataType;
        serializationObject.keys = [];
        var keys = this.getKeys();
        for (var index = 0; index < keys.length; index++) {
            var animationKey = keys[index];
            var key = {};
            key.frame = animationKey.frame;
            switch (dataType) {
                case Animation.ANIMATIONTYPE_FLOAT:
                    key.values = [animationKey.value];
                    break;
                case Animation.ANIMATIONTYPE_QUATERNION:
                case Animation.ANIMATIONTYPE_MATRIX:
                case Animation.ANIMATIONTYPE_VECTOR3:
                case Animation.ANIMATIONTYPE_COLOR3:
                    key.values = animationKey.value.asArray();
                    break;
            }
            serializationObject.keys.push(key);
        }
        serializationObject.ranges = [];
        for (var name in this._ranges) {
            var source = this._ranges[name];
            if (!source) {
                continue;
            }
            var range = {};
            range.name = name;
            range.from = source.from;
            range.to = source.to;
            serializationObject.ranges.push(range);
        }
        return serializationObject;
    };
    Object.defineProperty(Animation, "ANIMATIONTYPE_FLOAT", {
        /**
         * Get the float animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_FLOAT;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONTYPE_VECTOR3", {
        /**
         * Get the Vector3 animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_VECTOR3;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONTYPE_VECTOR2", {
        /**
         * Get the Vector2 animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_VECTOR2;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONTYPE_SIZE", {
        /**
         * Get the Size animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_SIZE;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONTYPE_QUATERNION", {
        /**
         * Get the Quaternion animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_QUATERNION;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONTYPE_MATRIX", {
        /**
         * Get the Matrix animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_MATRIX;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONTYPE_COLOR3", {
        /**
         * Get the Color3 animation type
         */
        get: function () {
            return Animation._ANIMATIONTYPE_COLOR3;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONLOOPMODE_RELATIVE", {
        /**
         * Get the Relative Loop Mode
         */
        get: function () {
            return Animation._ANIMATIONLOOPMODE_RELATIVE;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONLOOPMODE_CYCLE", {
        /**
         * Get the Cycle Loop Mode
         */
        get: function () {
            return Animation._ANIMATIONLOOPMODE_CYCLE;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Animation, "ANIMATIONLOOPMODE_CONSTANT", {
        /**
         * Get the Constant Loop Mode
         */
        get: function () {
            return Animation._ANIMATIONLOOPMODE_CONSTANT;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    Animation._UniversalLerp = function (left, right, amount) {
        var constructor = left.constructor;
        if (constructor.Lerp) { // Lerp supported
            return constructor.Lerp(left, right, amount);
        }
        else if (constructor.Slerp) { // Slerp supported
            return constructor.Slerp(left, right, amount);
        }
        else if (left.toFixed) { // Number
            return left * (1.0 - amount) + amount * right;
        }
        else { // Blending not supported
            return right;
        }
    };
    /**
     * Parses an animation object and creates an animation
     * @param parsedAnimation Parsed animation object
     * @returns Animation object
     */
    Animation.Parse = function (parsedAnimation) {
        var animation = new Animation(parsedAnimation.name, parsedAnimation.property, parsedAnimation.framePerSecond, parsedAnimation.dataType, parsedAnimation.loopBehavior);
        var dataType = parsedAnimation.dataType;
        var keys = [];
        var data;
        var index;
        if (parsedAnimation.enableBlending) {
            animation.enableBlending = parsedAnimation.enableBlending;
        }
        if (parsedAnimation.blendingSpeed) {
            animation.blendingSpeed = parsedAnimation.blendingSpeed;
        }
        for (index = 0; index < parsedAnimation.keys.length; index++) {
            var key = parsedAnimation.keys[index];
            var inTangent;
            var outTangent;
            switch (dataType) {
                case Animation.ANIMATIONTYPE_FLOAT:
                    data = key.values[0];
                    if (key.values.length >= 1) {
                        inTangent = key.values[1];
                    }
                    if (key.values.length >= 2) {
                        outTangent = key.values[2];
                    }
                    break;
                case Animation.ANIMATIONTYPE_QUATERNION:
                    data = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray(key.values);
                    if (key.values.length >= 8) {
                        var _inTangent = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray(key.values.slice(4, 8));
                        if (!_inTangent.equals(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Zero())) {
                            inTangent = _inTangent;
                        }
                    }
                    if (key.values.length >= 12) {
                        var _outTangent = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray(key.values.slice(8, 12));
                        if (!_outTangent.equals(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Zero())) {
                            outTangent = _outTangent;
                        }
                    }
                    break;
                case Animation.ANIMATIONTYPE_MATRIX:
                    data = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].FromArray(key.values);
                    break;
                case Animation.ANIMATIONTYPE_COLOR3:
                    data = _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].FromArray(key.values);
                    break;
                case Animation.ANIMATIONTYPE_VECTOR3:
                default:
                    data = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(key.values);
                    break;
            }
            var keyData = {};
            keyData.frame = key.frame;
            keyData.value = data;
            if (inTangent != undefined) {
                keyData.inTangent = inTangent;
            }
            if (outTangent != undefined) {
                keyData.outTangent = outTangent;
            }
            keys.push(keyData);
        }
        animation.setKeys(keys);
        if (parsedAnimation.ranges) {
            for (index = 0; index < parsedAnimation.ranges.length; index++) {
                data = parsedAnimation.ranges[index];
                animation.createRange(data.name, data.from, data.to);
            }
        }
        return animation;
    };
    /**
     * Appends the serialized animations from the source animations
     * @param source Source containing the animations
     * @param destination Target to store the animations
     */
    Animation.AppendSerializedAnimations = function (source, destination) {
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_3__["SerializationHelper"].AppendSerializedAnimations(source, destination);
    };
    /**
     * Use matrix interpolation instead of using direct key value when animating matrices
     */
    Animation.AllowMatricesInterpolation = false;
    /**
     * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
     */
    Animation.AllowMatrixDecomposeForInterpolation = true;
    // Statics
    /**
     * Float animation type
     */
    Animation._ANIMATIONTYPE_FLOAT = 0;
    /**
     * Vector3 animation type
     */
    Animation._ANIMATIONTYPE_VECTOR3 = 1;
    /**
     * Quaternion animation type
     */
    Animation._ANIMATIONTYPE_QUATERNION = 2;
    /**
     * Matrix animation type
     */
    Animation._ANIMATIONTYPE_MATRIX = 3;
    /**
     * Color3 animation type
     */
    Animation._ANIMATIONTYPE_COLOR3 = 4;
    /**
     * Vector2 animation type
     */
    Animation._ANIMATIONTYPE_VECTOR2 = 5;
    /**
     * Size animation type
     */
    Animation._ANIMATIONTYPE_SIZE = 6;
    /**
     * Relative Loop Mode
     */
    Animation._ANIMATIONLOOPMODE_RELATIVE = 0;
    /**
     * Cycle Loop Mode
     */
    Animation._ANIMATIONLOOPMODE_CYCLE = 1;
    /**
     * Constant Loop Mode
     */
    Animation._ANIMATIONLOOPMODE_CONSTANT = 2;
    return Animation;
}());

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.Animation"] = Animation;
_node__WEBPACK_IMPORTED_MODULE_7__["Node"]._AnimationRangeFactory = function (name, from, to) { return new _animationRange__WEBPACK_IMPORTED_MODULE_6__["AnimationRange"](name, from, to); };


/***/ }),

/***/ "./Animations/animationEvent.ts":
/*!**************************************!*\
  !*** ./Animations/animationEvent.ts ***!
  \**************************************/
/*! exports provided: AnimationEvent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationEvent", function() { return AnimationEvent; });
/**
 * Composed of a frame, and an action function
 */
var AnimationEvent = /** @class */ (function () {
    /**
     * Initializes the animation event
     * @param frame The frame for which the event is triggered
     * @param action The event to perform when triggered
     * @param onlyOnce Specifies if the event should be triggered only once
     */
    function AnimationEvent(
    /** The frame for which the event is triggered **/
    frame,
    /** The event to perform when triggered **/
    action,
    /** Specifies if the event should be triggered only once**/
    onlyOnce) {
        this.frame = frame;
        this.action = action;
        this.onlyOnce = onlyOnce;
        /**
         * Specifies if the animation event is done
         */
        this.isDone = false;
    }
    /** @hidden */
    AnimationEvent.prototype._clone = function () {
        return new AnimationEvent(this.frame, this.action, this.onlyOnce);
    };
    return AnimationEvent;
}());



/***/ }),

/***/ "./Animations/animationGroup.ts":
/*!**************************************!*\
  !*** ./Animations/animationGroup.ts ***!
  \**************************************/
/*! exports provided: TargetedAnimation, AnimationGroup */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TargetedAnimation", function() { return TargetedAnimation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationGroup", function() { return AnimationGroup; });
/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./animation */ "./Animations/animation.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _animatable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./animatable */ "./Animations/animatable.ts");




/**
 * This class defines the direct association between an animation and a target
 */
var TargetedAnimation = /** @class */ (function () {
    function TargetedAnimation() {
    }
    /**
     * Serialize the object
     * @returns the JSON object representing the current entity
     */
    TargetedAnimation.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.animation = this.animation.serialize();
        serializationObject.targetId = this.target.id;
        return serializationObject;
    };
    return TargetedAnimation;
}());

/**
 * Use this class to create coordinated animations on multiple targets
 */
var AnimationGroup = /** @class */ (function () {
    /**
     * Instantiates a new Animation Group.
     * This helps managing several animations at once.
     * @see http://doc.babylonjs.com/how_to/group
     * @param name Defines the name of the group
     * @param scene Defines the scene the group belongs to
     */
    function AnimationGroup(
    /** The name of the animation group */
    name, scene) {
        if (scene === void 0) { scene = null; }
        this.name = name;
        this._targetedAnimations = new Array();
        this._animatables = new Array();
        this._from = Number.MAX_VALUE;
        this._to = -Number.MAX_VALUE;
        this._speedRatio = 1;
        this._loopAnimation = false;
        /**
         * This observable will notify when one animation have ended
         */
        this.onAnimationEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observer raised when one animation loops
         */
        this.onAnimationLoopObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * This observable will notify when all animations have ended.
         */
        this.onAnimationGroupEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * This observable will notify when all animations have paused.
         */
        this.onAnimationGroupPauseObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * This observable will notify when all animations are playing.
         */
        this.onAnimationGroupPlayObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["EngineStore"].LastCreatedScene;
        this.uniqueId = this._scene.getUniqueId();
        this._scene.animationGroups.push(this);
    }
    Object.defineProperty(AnimationGroup.prototype, "from", {
        /**
         * Gets the first frame
         */
        get: function () {
            return this._from;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "to", {
        /**
         * Gets the last frame
         */
        get: function () {
            return this._to;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "isStarted", {
        /**
         * Define if the animations are started
         */
        get: function () {
            return this._isStarted;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "isPlaying", {
        /**
         * Gets a value indicating that the current group is playing
         */
        get: function () {
            return this._isStarted && !this._isPaused;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "speedRatio", {
        /**
         * Gets or sets the speed ratio to use for all animations
         */
        get: function () {
            return this._speedRatio;
        },
        /**
         * Gets or sets the speed ratio to use for all animations
         */
        set: function (value) {
            if (this._speedRatio === value) {
                return;
            }
            this._speedRatio = value;
            for (var index = 0; index < this._animatables.length; index++) {
                var animatable = this._animatables[index];
                animatable.speedRatio = this._speedRatio;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "loopAnimation", {
        /**
         * Gets or sets if all animations should loop or not
         */
        get: function () {
            return this._loopAnimation;
        },
        set: function (value) {
            if (this._loopAnimation === value) {
                return;
            }
            this._loopAnimation = value;
            for (var index = 0; index < this._animatables.length; index++) {
                var animatable = this._animatables[index];
                animatable.loopAnimation = this._loopAnimation;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "targetedAnimations", {
        /**
         * Gets the targeted animations for this animation group
         */
        get: function () {
            return this._targetedAnimations;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AnimationGroup.prototype, "animatables", {
        /**
         * returning the list of animatables controlled by this animation group.
         */
        get: function () {
            return this._animatables;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Add an animation (with its target) in the group
     * @param animation defines the animation we want to add
     * @param target defines the target of the animation
     * @returns the TargetedAnimation object
     */
    AnimationGroup.prototype.addTargetedAnimation = function (animation, target) {
        var targetedAnimation = new TargetedAnimation();
        targetedAnimation.animation = animation;
        targetedAnimation.target = target;
        var keys = animation.getKeys();
        if (this._from > keys[0].frame) {
            this._from = keys[0].frame;
        }
        if (this._to < keys[keys.length - 1].frame) {
            this._to = keys[keys.length - 1].frame;
        }
        this._targetedAnimations.push(targetedAnimation);
        return targetedAnimation;
    };
    /**
     * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame
     * It can add constant keys at begin or end
     * @param beginFrame defines the new begin frame for all animations or the smallest begin frame of all animations if null (defaults to null)
     * @param endFrame defines the new end frame for all animations or the largest end frame of all animations if null (defaults to null)
     * @returns the animation group
     */
    AnimationGroup.prototype.normalize = function (beginFrame, endFrame) {
        if (beginFrame === void 0) { beginFrame = null; }
        if (endFrame === void 0) { endFrame = null; }
        if (beginFrame == null) {
            beginFrame = this._from;
        }
        if (endFrame == null) {
            endFrame = this._to;
        }
        for (var index = 0; index < this._targetedAnimations.length; index++) {
            var targetedAnimation = this._targetedAnimations[index];
            var keys = targetedAnimation.animation.getKeys();
            var startKey = keys[0];
            var endKey = keys[keys.length - 1];
            if (startKey.frame > beginFrame) {
                var newKey = {
                    frame: beginFrame,
                    value: startKey.value,
                    inTangent: startKey.inTangent,
                    outTangent: startKey.outTangent,
                    interpolation: startKey.interpolation
                };
                keys.splice(0, 0, newKey);
            }
            if (endKey.frame < endFrame) {
                var newKey = {
                    frame: endFrame,
                    value: endKey.value,
                    inTangent: endKey.outTangent,
                    outTangent: endKey.outTangent,
                    interpolation: endKey.interpolation
                };
                keys.push(newKey);
            }
        }
        this._from = beginFrame;
        this._to = endFrame;
        return this;
    };
    /**
     * Start all animations on given targets
     * @param loop defines if animations must loop
     * @param speedRatio defines the ratio to apply to animation speed (1 by default)
     * @param from defines the from key (optional)
     * @param to defines the to key (optional)
     * @returns the current animation group
     */
    AnimationGroup.prototype.start = function (loop, speedRatio, from, to) {
        var _this = this;
        if (loop === void 0) { loop = false; }
        if (speedRatio === void 0) { speedRatio = 1; }
        if (this._isStarted || this._targetedAnimations.length === 0) {
            return this;
        }
        this._loopAnimation = loop;
        var _loop_1 = function (targetedAnimation) {
            var animatable = this_1._scene.beginDirectAnimation(targetedAnimation.target, [targetedAnimation.animation], from !== undefined ? from : this_1._from, to !== undefined ? to : this_1._to, loop, speedRatio);
            animatable.onAnimationEnd = function () {
                _this.onAnimationEndObservable.notifyObservers(targetedAnimation);
                _this._checkAnimationGroupEnded(animatable);
            };
            animatable.onAnimationLoop = function () {
                _this.onAnimationLoopObservable.notifyObservers(targetedAnimation);
            };
            this_1._animatables.push(animatable);
        };
        var this_1 = this;
        for (var _i = 0, _a = this._targetedAnimations; _i < _a.length; _i++) {
            var targetedAnimation = _a[_i];
            _loop_1(targetedAnimation);
        }
        this._speedRatio = speedRatio;
        if (from !== undefined && to !== undefined) {
            if (from < to && this._speedRatio < 0) {
                var temp = to;
                to = from;
                from = temp;
            }
            else if (from > to && this._speedRatio > 0) {
                this._speedRatio = -speedRatio;
            }
        }
        this._isStarted = true;
        this._isPaused = false;
        this.onAnimationGroupPlayObservable.notifyObservers(this);
        return this;
    };
    /**
     * Pause all animations
     * @returns the animation group
     */
    AnimationGroup.prototype.pause = function () {
        if (!this._isStarted) {
            return this;
        }
        this._isPaused = true;
        for (var index = 0; index < this._animatables.length; index++) {
            var animatable = this._animatables[index];
            animatable.pause();
        }
        this.onAnimationGroupPauseObservable.notifyObservers(this);
        return this;
    };
    /**
     * Play all animations to initial state
     * This function will start() the animations if they were not started or will restart() them if they were paused
     * @param loop defines if animations must loop
     * @returns the animation group
     */
    AnimationGroup.prototype.play = function (loop) {
        // only if all animatables are ready and exist
        if (this.isStarted && this._animatables.length === this._targetedAnimations.length) {
            if (loop !== undefined) {
                this.loopAnimation = loop;
            }
            this.restart();
        }
        else {
            this.stop();
            this.start(loop, this._speedRatio);
        }
        this._isPaused = false;
        return this;
    };
    /**
     * Reset all animations to initial state
     * @returns the animation group
     */
    AnimationGroup.prototype.reset = function () {
        if (!this._isStarted) {
            return this;
        }
        for (var index = 0; index < this._animatables.length; index++) {
            var animatable = this._animatables[index];
            animatable.reset();
        }
        return this;
    };
    /**
     * Restart animations from key 0
     * @returns the animation group
     */
    AnimationGroup.prototype.restart = function () {
        if (!this._isStarted) {
            return this;
        }
        for (var index = 0; index < this._animatables.length; index++) {
            var animatable = this._animatables[index];
            animatable.restart();
        }
        this.onAnimationGroupPlayObservable.notifyObservers(this);
        return this;
    };
    /**
     * Stop all animations
     * @returns the animation group
     */
    AnimationGroup.prototype.stop = function () {
        if (!this._isStarted) {
            return this;
        }
        var list = this._animatables.slice();
        for (var index = 0; index < list.length; index++) {
            list[index].stop();
        }
        this._isStarted = false;
        return this;
    };
    /**
     * Set animation weight for all animatables
     * @param weight defines the weight to use
     * @return the animationGroup
     * @see http://doc.babylonjs.com/babylon101/animations#animation-weights
     */
    AnimationGroup.prototype.setWeightForAllAnimatables = function (weight) {
        for (var index = 0; index < this._animatables.length; index++) {
            var animatable = this._animatables[index];
            animatable.weight = weight;
        }
        return this;
    };
    /**
     * Synchronize and normalize all animatables with a source animatable
     * @param root defines the root animatable to synchronize with
     * @return the animationGroup
     * @see http://doc.babylonjs.com/babylon101/animations#animation-weights
     */
    AnimationGroup.prototype.syncAllAnimationsWith = function (root) {
        for (var index = 0; index < this._animatables.length; index++) {
            var animatable = this._animatables[index];
            animatable.syncWith(root);
        }
        return this;
    };
    /**
     * Goes to a specific frame in this animation group
     * @param frame the frame number to go to
     * @return the animationGroup
     */
    AnimationGroup.prototype.goToFrame = function (frame) {
        if (!this._isStarted) {
            return this;
        }
        for (var index = 0; index < this._animatables.length; index++) {
            var animatable = this._animatables[index];
            animatable.goToFrame(frame);
        }
        return this;
    };
    /**
     * Dispose all associated resources
     */
    AnimationGroup.prototype.dispose = function () {
        this._targetedAnimations = [];
        this._animatables = [];
        var index = this._scene.animationGroups.indexOf(this);
        if (index > -1) {
            this._scene.animationGroups.splice(index, 1);
        }
        this.onAnimationEndObservable.clear();
        this.onAnimationGroupEndObservable.clear();
        this.onAnimationGroupPauseObservable.clear();
        this.onAnimationGroupPlayObservable.clear();
        this.onAnimationLoopObservable.clear();
    };
    AnimationGroup.prototype._checkAnimationGroupEnded = function (animatable) {
        // animatable should be taken out of the array
        var idx = this._animatables.indexOf(animatable);
        if (idx > -1) {
            this._animatables.splice(idx, 1);
        }
        // all animatables were removed? animation group ended!
        if (this._animatables.length === 0) {
            this._isStarted = false;
            this.onAnimationGroupEndObservable.notifyObservers(this);
        }
    };
    /**
     * Clone the current animation group and returns a copy
     * @param newName defines the name of the new group
     * @param targetConverter defines an optional function used to convert current animation targets to new ones
     * @returns the new aniamtion group
     */
    AnimationGroup.prototype.clone = function (newName, targetConverter) {
        var newGroup = new AnimationGroup(newName || this.name, this._scene);
        for (var _i = 0, _a = this._targetedAnimations; _i < _a.length; _i++) {
            var targetAnimation = _a[_i];
            newGroup.addTargetedAnimation(targetAnimation.animation.clone(), targetConverter ? targetConverter(targetAnimation.target) : targetAnimation.target);
        }
        return newGroup;
    };
    /**
     * Serializes the animationGroup to an object
     * @returns Serialized object
     */
    AnimationGroup.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.from = this.from;
        serializationObject.to = this.to;
        serializationObject.targetedAnimations = [];
        for (var targetedAnimationIndex = 0; targetedAnimationIndex < this.targetedAnimations.length; targetedAnimationIndex++) {
            var targetedAnimation = this.targetedAnimations[targetedAnimationIndex];
            serializationObject.targetedAnimations[targetedAnimationIndex] = targetedAnimation.serialize();
        }
        return serializationObject;
    };
    // Statics
    /**
     * Returns a new AnimationGroup object parsed from the source provided.
     * @param parsedAnimationGroup defines the source
     * @param scene defines the scene that will receive the animationGroup
     * @returns a new AnimationGroup
     */
    AnimationGroup.Parse = function (parsedAnimationGroup, scene) {
        var animationGroup = new AnimationGroup(parsedAnimationGroup.name, scene);
        for (var i = 0; i < parsedAnimationGroup.targetedAnimations.length; i++) {
            var targetedAnimation = parsedAnimationGroup.targetedAnimations[i];
            var animation = _animation__WEBPACK_IMPORTED_MODULE_0__["Animation"].Parse(targetedAnimation.animation);
            var id = targetedAnimation.targetId;
            if (targetedAnimation.animation.property === "influence") { // morph target animation
                var morphTarget = scene.getMorphTargetById(id);
                if (morphTarget) {
                    animationGroup.addTargetedAnimation(animation, morphTarget);
                }
            }
            else {
                var targetNode = scene.getNodeByID(id);
                if (targetNode != null) {
                    animationGroup.addTargetedAnimation(animation, targetNode);
                }
            }
        }
        if (parsedAnimationGroup.from !== null && parsedAnimationGroup.from !== null) {
            animationGroup.normalize(parsedAnimationGroup.from, parsedAnimationGroup.to);
        }
        return animationGroup;
    };
    /**
     * Returns the string "AnimationGroup"
     * @returns "AnimationGroup"
     */
    AnimationGroup.prototype.getClassName = function () {
        return "AnimationGroup";
    };
    /**
     * Creates a detailled string about the object
     * @param fullDetails defines if the output string will support multiple levels of logging within scene loading
     * @returns a string representing the object
     */
    AnimationGroup.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name;
        ret += ", type: " + this.getClassName();
        if (fullDetails) {
            ret += ", from: " + this._from;
            ret += ", to: " + this._to;
            ret += ", isStarted: " + this._isStarted;
            ret += ", speedRatio: " + this._speedRatio;
            ret += ", targetedAnimations length: " + this._targetedAnimations.length;
            ret += ", animatables length: " + this._animatables;
        }
        return ret;
    };
    return AnimationGroup;
}());



/***/ }),

/***/ "./Animations/animationKey.ts":
/*!************************************!*\
  !*** ./Animations/animationKey.ts ***!
  \************************************/
/*! exports provided: AnimationKeyInterpolation */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationKeyInterpolation", function() { return AnimationKeyInterpolation; });
/**
 * Enum for the animation key frame interpolation type
 */
var AnimationKeyInterpolation;
(function (AnimationKeyInterpolation) {
    /**
     * Do not interpolate between keys and use the start key value only. Tangents are ignored
     */
    AnimationKeyInterpolation[AnimationKeyInterpolation["STEP"] = 1] = "STEP";
})(AnimationKeyInterpolation || (AnimationKeyInterpolation = {}));


/***/ }),

/***/ "./Animations/animationPropertiesOverride.ts":
/*!***************************************************!*\
  !*** ./Animations/animationPropertiesOverride.ts ***!
  \***************************************************/
/*! exports provided: AnimationPropertiesOverride */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationPropertiesOverride", function() { return AnimationPropertiesOverride; });
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Animations/animation */ "./Animations/animation.ts");

/**
 * Class used to override all child animations of a given target
 */
var AnimationPropertiesOverride = /** @class */ (function () {
    function AnimationPropertiesOverride() {
        /**
         * Gets or sets a value indicating if animation blending must be used
         */
        this.enableBlending = false;
        /**
         * Gets or sets the blending speed to use when enableBlending is true
         */
        this.blendingSpeed = 0.01;
        /**
         * Gets or sets the default loop mode to use
         */
        this.loopMode = _Animations_animation__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONLOOPMODE_CYCLE;
    }
    return AnimationPropertiesOverride;
}());



/***/ }),

/***/ "./Animations/animationRange.ts":
/*!**************************************!*\
  !*** ./Animations/animationRange.ts ***!
  \**************************************/
/*! exports provided: AnimationRange */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimationRange", function() { return AnimationRange; });
/**
 * Represents the range of an animation
 */
var AnimationRange = /** @class */ (function () {
    /**
     * Initializes the range of an animation
     * @param name The name of the animation range
     * @param from The starting frame of the animation
     * @param to The ending frame of the animation
     */
    function AnimationRange(
    /**The name of the animation range**/
    name,
    /**The starting frame of the animation */
    from,
    /**The ending frame of the animation*/
    to) {
        this.name = name;
        this.from = from;
        this.to = to;
    }
    /**
     * Makes a copy of the animation range
     * @returns A copy of the animation range
     */
    AnimationRange.prototype.clone = function () {
        return new AnimationRange(this.name, this.from, this.to);
    };
    return AnimationRange;
}());



/***/ }),

/***/ "./Animations/easing.ts":
/*!******************************!*\
  !*** ./Animations/easing.ts ***!
  \******************************/
/*! exports provided: EasingFunction, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase, BezierCurveEase */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EasingFunction", function() { return EasingFunction; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CircleEase", function() { return CircleEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BackEase", function() { return BackEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BounceEase", function() { return BounceEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubicEase", function() { return CubicEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ElasticEase", function() { return ElasticEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExponentialEase", function() { return ExponentialEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PowerEase", function() { return PowerEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuadraticEase", function() { return QuadraticEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuarticEase", function() { return QuarticEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "QuinticEase", function() { return QuinticEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SineEase", function() { return SineEase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BezierCurveEase", function() { return BezierCurveEase; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.path */ "./Maths/math.path.ts");


/**
 * Base class used for every default easing function.
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var EasingFunction = /** @class */ (function () {
    function EasingFunction() {
        this._easingMode = EasingFunction.EASINGMODE_EASEIN;
    }
    /**
     * Sets the easing mode of the current function.
     * @param easingMode Defines the willing mode (EASINGMODE_EASEIN, EASINGMODE_EASEOUT or EASINGMODE_EASEINOUT)
     */
    EasingFunction.prototype.setEasingMode = function (easingMode) {
        var n = Math.min(Math.max(easingMode, 0), 2);
        this._easingMode = n;
    };
    /**
     * Gets the current easing mode.
     * @returns the easing mode
     */
    EasingFunction.prototype.getEasingMode = function () {
        return this._easingMode;
    };
    /**
     * @hidden
     */
    EasingFunction.prototype.easeInCore = function (gradient) {
        throw new Error('You must implement this method');
    };
    /**
     * Given an input gradient between 0 and 1, this returns the corresponding value
     * of the easing function.
     * @param gradient Defines the value between 0 and 1 we want the easing value for
     * @returns the corresponding value on the curve defined by the easing function
     */
    EasingFunction.prototype.ease = function (gradient) {
        switch (this._easingMode) {
            case EasingFunction.EASINGMODE_EASEIN:
                return this.easeInCore(gradient);
            case EasingFunction.EASINGMODE_EASEOUT:
                return (1 - this.easeInCore(1 - gradient));
        }
        if (gradient >= 0.5) {
            return (((1 - this.easeInCore((1 - gradient) * 2)) * 0.5) + 0.5);
        }
        return (this.easeInCore(gradient * 2) * 0.5);
    };
    /**
     * Interpolation follows the mathematical formula associated with the easing function.
     */
    EasingFunction.EASINGMODE_EASEIN = 0;
    /**
     * Interpolation follows 100% interpolation minus the output of the formula associated with the easing function.
     */
    EasingFunction.EASINGMODE_EASEOUT = 1;
    /**
     * Interpolation uses EaseIn for the first half of the animation and EaseOut for the second half.
     */
    EasingFunction.EASINGMODE_EASEINOUT = 2;
    return EasingFunction;
}());

/**
 * Easing function with a circle shape (see link below).
 * @see https://easings.net/#easeInCirc
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var CircleEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CircleEase, _super);
    function CircleEase() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /** @hidden */
    CircleEase.prototype.easeInCore = function (gradient) {
        gradient = Math.max(0, Math.min(1, gradient));
        return (1.0 - Math.sqrt(1.0 - (gradient * gradient)));
    };
    return CircleEase;
}(EasingFunction));

/**
 * Easing function with a ease back shape (see link below).
 * @see https://easings.net/#easeInBack
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var BackEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BackEase, _super);
    /**
     * Instantiates a back ease easing
     * @see https://easings.net/#easeInBack
     * @param amplitude Defines the amplitude of the function
     */
    function BackEase(
    /** Defines the amplitude of the function */
    amplitude) {
        if (amplitude === void 0) { amplitude = 1; }
        var _this = _super.call(this) || this;
        _this.amplitude = amplitude;
        return _this;
    }
    /** @hidden */
    BackEase.prototype.easeInCore = function (gradient) {
        var num = Math.max(0, this.amplitude);
        return (Math.pow(gradient, 3.0) - ((gradient * num) * Math.sin(3.1415926535897931 * gradient)));
    };
    return BackEase;
}(EasingFunction));

/**
 * Easing function with a bouncing shape (see link below).
 * @see https://easings.net/#easeInBounce
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var BounceEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BounceEase, _super);
    /**
     * Instantiates a bounce easing
     * @see https://easings.net/#easeInBounce
     * @param bounces Defines the number of bounces
     * @param bounciness Defines the amplitude of the bounce
     */
    function BounceEase(
    /** Defines the number of bounces */
    bounces,
    /** Defines the amplitude of the bounce */
    bounciness) {
        if (bounces === void 0) { bounces = 3; }
        if (bounciness === void 0) { bounciness = 2; }
        var _this = _super.call(this) || this;
        _this.bounces = bounces;
        _this.bounciness = bounciness;
        return _this;
    }
    /** @hidden */
    BounceEase.prototype.easeInCore = function (gradient) {
        var y = Math.max(0.0, this.bounces);
        var bounciness = this.bounciness;
        if (bounciness <= 1.0) {
            bounciness = 1.001;
        }
        var num9 = Math.pow(bounciness, y);
        var num5 = 1.0 - bounciness;
        var num4 = ((1.0 - num9) / num5) + (num9 * 0.5);
        var num15 = gradient * num4;
        var num65 = Math.log((-num15 * (1.0 - bounciness)) + 1.0) / Math.log(bounciness);
        var num3 = Math.floor(num65);
        var num13 = num3 + 1.0;
        var num8 = (1.0 - Math.pow(bounciness, num3)) / (num5 * num4);
        var num12 = (1.0 - Math.pow(bounciness, num13)) / (num5 * num4);
        var num7 = (num8 + num12) * 0.5;
        var num6 = gradient - num7;
        var num2 = num7 - num8;
        return (((-Math.pow(1.0 / bounciness, y - num3) / (num2 * num2)) * (num6 - num2)) * (num6 + num2));
    };
    return BounceEase;
}(EasingFunction));

/**
 * Easing function with a power of 3 shape (see link below).
 * @see https://easings.net/#easeInCubic
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var CubicEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CubicEase, _super);
    function CubicEase() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /** @hidden */
    CubicEase.prototype.easeInCore = function (gradient) {
        return (gradient * gradient * gradient);
    };
    return CubicEase;
}(EasingFunction));

/**
 * Easing function with an elastic shape (see link below).
 * @see https://easings.net/#easeInElastic
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var ElasticEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ElasticEase, _super);
    /**
     * Instantiates an elastic easing function
     * @see https://easings.net/#easeInElastic
     * @param oscillations Defines the number of oscillations
     * @param springiness Defines the amplitude of the oscillations
     */
    function ElasticEase(
    /** Defines the number of oscillations*/
    oscillations,
    /** Defines the amplitude of the oscillations*/
    springiness) {
        if (oscillations === void 0) { oscillations = 3; }
        if (springiness === void 0) { springiness = 3; }
        var _this = _super.call(this) || this;
        _this.oscillations = oscillations;
        _this.springiness = springiness;
        return _this;
    }
    /** @hidden */
    ElasticEase.prototype.easeInCore = function (gradient) {
        var num2;
        var num3 = Math.max(0.0, this.oscillations);
        var num = Math.max(0.0, this.springiness);
        if (num == 0) {
            num2 = gradient;
        }
        else {
            num2 = (Math.exp(num * gradient) - 1.0) / (Math.exp(num) - 1.0);
        }
        return (num2 * Math.sin(((6.2831853071795862 * num3) + 1.5707963267948966) * gradient));
    };
    return ElasticEase;
}(EasingFunction));

/**
 * Easing function with an exponential shape (see link below).
 * @see https://easings.net/#easeInExpo
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var ExponentialEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExponentialEase, _super);
    /**
     * Instantiates an exponential easing function
     * @see https://easings.net/#easeInExpo
     * @param exponent Defines the exponent of the function
     */
    function ExponentialEase(
    /** Defines the exponent of the function */
    exponent) {
        if (exponent === void 0) { exponent = 2; }
        var _this = _super.call(this) || this;
        _this.exponent = exponent;
        return _this;
    }
    /** @hidden */
    ExponentialEase.prototype.easeInCore = function (gradient) {
        if (this.exponent <= 0) {
            return gradient;
        }
        return ((Math.exp(this.exponent * gradient) - 1.0) / (Math.exp(this.exponent) - 1.0));
    };
    return ExponentialEase;
}(EasingFunction));

/**
 * Easing function with a power shape (see link below).
 * @see https://easings.net/#easeInQuad
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var PowerEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PowerEase, _super);
    /**
     * Instantiates an power base easing function
     * @see https://easings.net/#easeInQuad
     * @param power Defines the power of the function
     */
    function PowerEase(
    /** Defines the power of the function */
    power) {
        if (power === void 0) { power = 2; }
        var _this = _super.call(this) || this;
        _this.power = power;
        return _this;
    }
    /** @hidden */
    PowerEase.prototype.easeInCore = function (gradient) {
        var y = Math.max(0.0, this.power);
        return Math.pow(gradient, y);
    };
    return PowerEase;
}(EasingFunction));

/**
 * Easing function with a power of 2 shape (see link below).
 * @see https://easings.net/#easeInQuad
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var QuadraticEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QuadraticEase, _super);
    function QuadraticEase() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /** @hidden */
    QuadraticEase.prototype.easeInCore = function (gradient) {
        return (gradient * gradient);
    };
    return QuadraticEase;
}(EasingFunction));

/**
 * Easing function with a power of 4 shape (see link below).
 * @see https://easings.net/#easeInQuart
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var QuarticEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QuarticEase, _super);
    function QuarticEase() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /** @hidden */
    QuarticEase.prototype.easeInCore = function (gradient) {
        return (gradient * gradient * gradient * gradient);
    };
    return QuarticEase;
}(EasingFunction));

/**
 * Easing function with a power of 5 shape (see link below).
 * @see https://easings.net/#easeInQuint
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var QuinticEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](QuinticEase, _super);
    function QuinticEase() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /** @hidden */
    QuinticEase.prototype.easeInCore = function (gradient) {
        return (gradient * gradient * gradient * gradient * gradient);
    };
    return QuinticEase;
}(EasingFunction));

/**
 * Easing function with a sin shape (see link below).
 * @see https://easings.net/#easeInSine
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var SineEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SineEase, _super);
    function SineEase() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /** @hidden */
    SineEase.prototype.easeInCore = function (gradient) {
        return (1.0 - Math.sin(1.5707963267948966 * (1.0 - gradient)));
    };
    return SineEase;
}(EasingFunction));

/**
 * Easing function with a bezier shape (see link below).
 * @see http://cubic-bezier.com/#.17,.67,.83,.67
 * @see http://doc.babylonjs.com/babylon101/animations#easing-functions
 */
var BezierCurveEase = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BezierCurveEase, _super);
    /**
     * Instantiates a bezier function
     * @see http://cubic-bezier.com/#.17,.67,.83,.67
     * @param x1 Defines the x component of the start tangent in the bezier curve
     * @param y1 Defines the y component of the start tangent in the bezier curve
     * @param x2 Defines the x component of the end tangent in the bezier curve
     * @param y2 Defines the y component of the end tangent in the bezier curve
     */
    function BezierCurveEase(
    /** Defines the x component of the start tangent in the bezier curve */
    x1,
    /** Defines the y component of the start tangent in the bezier curve */
    y1,
    /** Defines the x component of the end tangent in the bezier curve */
    x2,
    /** Defines the y component of the end tangent in the bezier curve */
    y2) {
        if (x1 === void 0) { x1 = 0; }
        if (y1 === void 0) { y1 = 0; }
        if (x2 === void 0) { x2 = 1; }
        if (y2 === void 0) { y2 = 1; }
        var _this = _super.call(this) || this;
        _this.x1 = x1;
        _this.y1 = y1;
        _this.x2 = x2;
        _this.y2 = y2;
        return _this;
    }
    /** @hidden */
    BezierCurveEase.prototype.easeInCore = function (gradient) {
        return _Maths_math_path__WEBPACK_IMPORTED_MODULE_1__["BezierCurve"].Interpolate(gradient, this.x1, this.y1, this.x2, this.y2);
    };
    return BezierCurveEase;
}(EasingFunction));



/***/ }),

/***/ "./Animations/index.ts":
/*!*****************************!*\
  !*** ./Animations/index.ts ***!
  \*****************************/
/*! exports provided: Animatable, _IAnimationState, Animation, TargetedAnimation, AnimationGroup, AnimationPropertiesOverride, EasingFunction, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase, BezierCurveEase, RuntimeAnimation, AnimationEvent, AnimationKeyInterpolation, AnimationRange */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _animatable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./animatable */ "./Animations/animatable.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Animatable", function() { return _animatable__WEBPACK_IMPORTED_MODULE_0__["Animatable"]; });

/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./animation */ "./Animations/animation.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_IAnimationState", function() { return _animation__WEBPACK_IMPORTED_MODULE_1__["_IAnimationState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Animation", function() { return _animation__WEBPACK_IMPORTED_MODULE_1__["Animation"]; });

/* harmony import */ var _animationGroup__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./animationGroup */ "./Animations/animationGroup.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TargetedAnimation", function() { return _animationGroup__WEBPACK_IMPORTED_MODULE_2__["TargetedAnimation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationGroup", function() { return _animationGroup__WEBPACK_IMPORTED_MODULE_2__["AnimationGroup"]; });

/* harmony import */ var _animationPropertiesOverride__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./animationPropertiesOverride */ "./Animations/animationPropertiesOverride.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationPropertiesOverride", function() { return _animationPropertiesOverride__WEBPACK_IMPORTED_MODULE_3__["AnimationPropertiesOverride"]; });

/* harmony import */ var _easing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./easing */ "./Animations/easing.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EasingFunction", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["EasingFunction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CircleEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["CircleEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["BackEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BounceEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["BounceEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubicEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["CubicEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ElasticEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["ElasticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExponentialEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["ExponentialEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PowerEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["PowerEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuadraticEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["QuadraticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuarticEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["QuarticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuinticEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["QuinticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SineEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["SineEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurveEase", function() { return _easing__WEBPACK_IMPORTED_MODULE_4__["BezierCurveEase"]; });

/* harmony import */ var _runtimeAnimation__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./runtimeAnimation */ "./Animations/runtimeAnimation.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RuntimeAnimation", function() { return _runtimeAnimation__WEBPACK_IMPORTED_MODULE_5__["RuntimeAnimation"]; });

/* harmony import */ var _animationEvent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./animationEvent */ "./Animations/animationEvent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationEvent", function() { return _animationEvent__WEBPACK_IMPORTED_MODULE_6__["AnimationEvent"]; });

/* empty/unused harmony star reexport *//* harmony import */ var _animationKey__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./animationKey */ "./Animations/animationKey.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationKeyInterpolation", function() { return _animationKey__WEBPACK_IMPORTED_MODULE_7__["AnimationKeyInterpolation"]; });

/* harmony import */ var _animationRange__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./animationRange */ "./Animations/animationRange.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationRange", function() { return _animationRange__WEBPACK_IMPORTED_MODULE_8__["AnimationRange"]; });













/***/ }),

/***/ "./Animations/runtimeAnimation.ts":
/*!****************************************!*\
  !*** ./Animations/runtimeAnimation.ts ***!
  \****************************************/
/*! exports provided: RuntimeAnimation */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RuntimeAnimation", function() { return RuntimeAnimation; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _animation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./animation */ "./Animations/animation.ts");
/* harmony import */ var _Maths_math_size__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.size */ "./Maths/math.size.ts");




// Static values to help the garbage collector
// Quaternion
var _staticOffsetValueQuaternion = Object.freeze(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"](0, 0, 0, 0));
// Vector3
var _staticOffsetValueVector3 = Object.freeze(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero());
// Vector2
var _staticOffsetValueVector2 = Object.freeze(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Zero());
// Size
var _staticOffsetValueSize = Object.freeze(_Maths_math_size__WEBPACK_IMPORTED_MODULE_3__["Size"].Zero());
// Color3
var _staticOffsetValueColor3 = Object.freeze(_Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].Black());
/**
 * Defines a runtime animation
 */
var RuntimeAnimation = /** @class */ (function () {
    /**
     * Create a new RuntimeAnimation object
     * @param target defines the target of the animation
     * @param animation defines the source animation object
     * @param scene defines the hosting scene
     * @param host defines the initiating Animatable
     */
    function RuntimeAnimation(target, animation, scene, host) {
        var _this = this;
        this._events = new Array();
        /**
         * The current frame of the runtime animation
         */
        this._currentFrame = 0;
        /**
         * The original value of the runtime animation
         */
        this._originalValue = new Array();
        /**
         * The original blend value of the runtime animation
         */
        this._originalBlendValue = null;
        /**
         * The offsets cache of the runtime animation
         */
        this._offsetsCache = {};
        /**
         * The high limits cache of the runtime animation
         */
        this._highLimitsCache = {};
        /**
         * Specifies if the runtime animation has been stopped
         */
        this._stopped = false;
        /**
         * The blending factor of the runtime animation
         */
        this._blendingFactor = 0;
        /**
         * The current value of the runtime animation
         */
        this._currentValue = null;
        this._currentActiveTarget = null;
        this._directTarget = null;
        /**
         * The target path of the runtime animation
         */
        this._targetPath = "";
        /**
         * The weight of the runtime animation
         */
        this._weight = 1.0;
        /**
         * The ratio offset of the runtime animation
         */
        this._ratioOffset = 0;
        /**
         * The previous delay of the runtime animation
         */
        this._previousDelay = 0;
        /**
         * The previous ratio of the runtime animation
         */
        this._previousRatio = 0;
        this._targetIsArray = false;
        this._animation = animation;
        this._target = target;
        this._scene = scene;
        this._host = host;
        this._activeTargets = [];
        animation._runtimeAnimations.push(this);
        // State
        this._animationState = {
            key: 0,
            repeatCount: 0,
            loopMode: this._getCorrectLoopMode()
        };
        if (this._animation.dataType === _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_MATRIX) {
            this._animationState.workValue = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Zero();
        }
        // Limits
        this._keys = this._animation.getKeys();
        this._minFrame = this._keys[0].frame;
        this._maxFrame = this._keys[this._keys.length - 1].frame;
        this._minValue = this._keys[0].value;
        this._maxValue = this._keys[this._keys.length - 1].value;
        // Add a start key at frame 0 if missing
        if (this._minFrame !== 0) {
            var newKey = { frame: 0, value: this._minValue };
            this._keys.splice(0, 0, newKey);
        }
        // Check data
        if (this._target instanceof Array) {
            var index = 0;
            for (var _i = 0, _a = this._target; _i < _a.length; _i++) {
                var target_1 = _a[_i];
                this._preparePath(target_1, index);
                this._getOriginalValues(index);
                index++;
            }
            this._targetIsArray = true;
        }
        else {
            this._preparePath(this._target);
            this._getOriginalValues();
            this._targetIsArray = false;
            this._directTarget = this._activeTargets[0];
        }
        // Cloning events locally
        var events = animation.getEvents();
        if (events && events.length > 0) {
            events.forEach(function (e) {
                _this._events.push(e._clone());
            });
        }
        this._enableBlending = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.enableBlending : this._animation.enableBlending;
    }
    Object.defineProperty(RuntimeAnimation.prototype, "currentFrame", {
        /**
         * Gets the current frame of the runtime animation
         */
        get: function () {
            return this._currentFrame;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RuntimeAnimation.prototype, "weight", {
        /**
         * Gets the weight of the runtime animation
         */
        get: function () {
            return this._weight;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RuntimeAnimation.prototype, "currentValue", {
        /**
         * Gets the current value of the runtime animation
         */
        get: function () {
            return this._currentValue;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RuntimeAnimation.prototype, "targetPath", {
        /**
         * Gets the target path of the runtime animation
         */
        get: function () {
            return this._targetPath;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RuntimeAnimation.prototype, "target", {
        /**
         * Gets the actual target of the runtime animation
         */
        get: function () {
            return this._currentActiveTarget;
        },
        enumerable: true,
        configurable: true
    });
    RuntimeAnimation.prototype._preparePath = function (target, targetIndex) {
        if (targetIndex === void 0) { targetIndex = 0; }
        var targetPropertyPath = this._animation.targetPropertyPath;
        if (targetPropertyPath.length > 1) {
            var property = target[targetPropertyPath[0]];
            for (var index = 1; index < targetPropertyPath.length - 1; index++) {
                property = property[targetPropertyPath[index]];
            }
            this._targetPath = targetPropertyPath[targetPropertyPath.length - 1];
            this._activeTargets[targetIndex] = property;
        }
        else {
            this._targetPath = targetPropertyPath[0];
            this._activeTargets[targetIndex] = target;
        }
    };
    Object.defineProperty(RuntimeAnimation.prototype, "animation", {
        /**
         * Gets the animation from the runtime animation
         */
        get: function () {
            return this._animation;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resets the runtime animation to the beginning
     * @param restoreOriginal defines whether to restore the target property to the original value
     */
    RuntimeAnimation.prototype.reset = function (restoreOriginal) {
        if (restoreOriginal === void 0) { restoreOriginal = false; }
        if (restoreOriginal) {
            if (this._target instanceof Array) {
                var index = 0;
                for (var _i = 0, _a = this._target; _i < _a.length; _i++) {
                    var target = _a[_i];
                    if (this._originalValue[index] !== undefined) {
                        this._setValue(target, this._activeTargets[index], this._originalValue[index], -1, index);
                    }
                    index++;
                }
            }
            else {
                if (this._originalValue[0] !== undefined) {
                    this._setValue(this._target, this._directTarget, this._originalValue[0], -1, 0);
                }
            }
        }
        this._offsetsCache = {};
        this._highLimitsCache = {};
        this._currentFrame = 0;
        this._blendingFactor = 0;
        // Events
        for (var index = 0; index < this._events.length; index++) {
            this._events[index].isDone = false;
        }
    };
    /**
     * Specifies if the runtime animation is stopped
     * @returns Boolean specifying if the runtime animation is stopped
     */
    RuntimeAnimation.prototype.isStopped = function () {
        return this._stopped;
    };
    /**
     * Disposes of the runtime animation
     */
    RuntimeAnimation.prototype.dispose = function () {
        var index = this._animation.runtimeAnimations.indexOf(this);
        if (index > -1) {
            this._animation.runtimeAnimations.splice(index, 1);
        }
    };
    /**
     * Apply the interpolated value to the target
     * @param currentValue defines the value computed by the animation
     * @param weight defines the weight to apply to this value (Defaults to 1.0)
     */
    RuntimeAnimation.prototype.setValue = function (currentValue, weight) {
        if (this._targetIsArray) {
            for (var index = 0; index < this._target.length; index++) {
                var target = this._target[index];
                this._setValue(target, this._activeTargets[index], currentValue, weight, index);
            }
            return;
        }
        this._setValue(this._target, this._directTarget, currentValue, weight, 0);
    };
    RuntimeAnimation.prototype._getOriginalValues = function (targetIndex) {
        if (targetIndex === void 0) { targetIndex = 0; }
        var originalValue;
        var target = this._activeTargets[targetIndex];
        if (target.getRestPose && this._targetPath === "_matrix") { // For bones
            originalValue = target.getRestPose();
        }
        else {
            originalValue = target[this._targetPath];
        }
        if (originalValue && originalValue.clone) {
            this._originalValue[targetIndex] = originalValue.clone();
        }
        else {
            this._originalValue[targetIndex] = originalValue;
        }
    };
    RuntimeAnimation.prototype._setValue = function (target, destination, currentValue, weight, targetIndex) {
        // Set value
        this._currentActiveTarget = destination;
        this._weight = weight;
        if (this._enableBlending && this._blendingFactor <= 1.0) {
            if (!this._originalBlendValue) {
                var originalValue = destination[this._targetPath];
                if (originalValue.clone) {
                    this._originalBlendValue = originalValue.clone();
                }
                else {
                    this._originalBlendValue = originalValue;
                }
            }
            if (this._originalBlendValue.m) { // Matrix
                if (_animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].AllowMatrixDecomposeForInterpolation) {
                    if (this._currentValue) {
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
                    }
                    else {
                        this._currentValue = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
                    }
                }
                else {
                    if (this._currentValue) {
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
                    }
                    else {
                        this._currentValue = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
                    }
                }
            }
            else {
                this._currentValue = _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"]._UniversalLerp(this._originalBlendValue, currentValue, this._blendingFactor);
            }
            var blendingSpeed = target && target.animationPropertiesOverride ? target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed;
            this._blendingFactor += blendingSpeed;
        }
        else {
            this._currentValue = currentValue;
        }
        if (weight !== -1.0) {
            this._scene._registerTargetForLateAnimationBinding(this, this._originalValue[targetIndex]);
        }
        else {
            destination[this._targetPath] = this._currentValue;
        }
        if (target.markAsDirty) {
            target.markAsDirty(this._animation.targetProperty);
        }
    };
    /**
     * Gets the loop pmode of the runtime animation
     * @returns Loop Mode
     */
    RuntimeAnimation.prototype._getCorrectLoopMode = function () {
        if (this._target && this._target.animationPropertiesOverride) {
            return this._target.animationPropertiesOverride.loopMode;
        }
        return this._animation.loopMode;
    };
    /**
     * Move the current animation to a given frame
     * @param frame defines the frame to move to
     */
    RuntimeAnimation.prototype.goToFrame = function (frame) {
        var keys = this._animation.getKeys();
        if (frame < keys[0].frame) {
            frame = keys[0].frame;
        }
        else if (frame > keys[keys.length - 1].frame) {
            frame = keys[keys.length - 1].frame;
        }
        // Need to reset animation events
        var events = this._events;
        if (events.length) {
            for (var index = 0; index < events.length; index++) {
                if (!events[index].onlyOnce) {
                    // reset events in the future
                    events[index].isDone = events[index].frame < frame;
                }
            }
        }
        this._currentFrame = frame;
        var currentValue = this._animation._interpolate(frame, this._animationState);
        this.setValue(currentValue, -1);
    };
    /**
     * @hidden Internal use only
     */
    RuntimeAnimation.prototype._prepareForSpeedRatioChange = function (newSpeedRatio) {
        var newRatio = this._previousDelay * (this._animation.framePerSecond * newSpeedRatio) / 1000.0;
        this._ratioOffset = this._previousRatio - newRatio;
    };
    /**
     * Execute the current animation
     * @param delay defines the delay to add to the current frame
     * @param from defines the lower bound of the animation range
     * @param to defines the upper bound of the animation range
     * @param loop defines if the current animation must loop
     * @param speedRatio defines the current speed ratio
     * @param weight defines the weight of the animation (default is -1 so no weight)
     * @param onLoop optional callback called when animation loops
     * @returns a boolean indicating if the animation is running
     */
    RuntimeAnimation.prototype.animate = function (delay, from, to, loop, speedRatio, weight) {
        if (weight === void 0) { weight = -1.0; }
        var animation = this._animation;
        var targetPropertyPath = animation.targetPropertyPath;
        if (!targetPropertyPath || targetPropertyPath.length < 1) {
            this._stopped = true;
            return false;
        }
        var returnValue = true;
        // Check limits
        if (from < this._minFrame || from > this._maxFrame) {
            from = this._minFrame;
        }
        if (to < this._minFrame || to > this._maxFrame) {
            to = this._maxFrame;
        }
        var range = to - from;
        var offsetValue;
        // Compute ratio which represents the frame delta between from and to
        var ratio = (delay * (animation.framePerSecond * speedRatio) / 1000.0) + this._ratioOffset;
        var highLimitValue = 0;
        this._previousDelay = delay;
        this._previousRatio = ratio;
        if (!loop && (to >= from && ratio >= range)) { // If we are out of range and not looping get back to caller
            returnValue = false;
            highLimitValue = animation._getKeyValue(this._maxValue);
        }
        else if (!loop && (from >= to && ratio <= range)) {
            returnValue = false;
            highLimitValue = animation._getKeyValue(this._minValue);
        }
        else if (this._animationState.loopMode !== _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONLOOPMODE_CYCLE) {
            var keyOffset = to.toString() + from.toString();
            if (!this._offsetsCache[keyOffset]) {
                this._animationState.repeatCount = 0;
                this._animationState.loopMode = _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONLOOPMODE_CYCLE;
                var fromValue = animation._interpolate(from, this._animationState);
                var toValue = animation._interpolate(to, this._animationState);
                this._animationState.loopMode = this._getCorrectLoopMode();
                switch (animation.dataType) {
                    // Float
                    case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_FLOAT:
                        this._offsetsCache[keyOffset] = toValue - fromValue;
                        break;
                    // Quaternion
                    case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_QUATERNION:
                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
                        break;
                    // Vector3
                    case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_VECTOR3:
                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
                    // Vector2
                    case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_VECTOR2:
                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
                    // Size
                    case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_SIZE:
                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
                    // Color3
                    case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_COLOR3:
                        this._offsetsCache[keyOffset] = toValue.subtract(fromValue);
                    default:
                        break;
                }
                this._highLimitsCache[keyOffset] = toValue;
            }
            highLimitValue = this._highLimitsCache[keyOffset];
            offsetValue = this._offsetsCache[keyOffset];
        }
        if (offsetValue === undefined) {
            switch (animation.dataType) {
                // Float
                case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_FLOAT:
                    offsetValue = 0;
                    break;
                // Quaternion
                case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_QUATERNION:
                    offsetValue = _staticOffsetValueQuaternion;
                    break;
                // Vector3
                case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_VECTOR3:
                    offsetValue = _staticOffsetValueVector3;
                    break;
                // Vector2
                case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_VECTOR2:
                    offsetValue = _staticOffsetValueVector2;
                    break;
                // Size
                case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_SIZE:
                    offsetValue = _staticOffsetValueSize;
                    break;
                // Color3
                case _animation__WEBPACK_IMPORTED_MODULE_2__["Animation"].ANIMATIONTYPE_COLOR3:
                    offsetValue = _staticOffsetValueColor3;
            }
        }
        // Compute value
        var currentFrame;
        if (this._host && this._host.syncRoot) {
            var syncRoot = this._host.syncRoot;
            var hostNormalizedFrame = (syncRoot.masterFrame - syncRoot.fromFrame) / (syncRoot.toFrame - syncRoot.fromFrame);
            currentFrame = from + (to - from) * hostNormalizedFrame;
        }
        else {
            currentFrame = (returnValue && range !== 0) ? from + ratio % range : to;
        }
        // Reset events if looping
        var events = this._events;
        if (range > 0 && this.currentFrame > currentFrame ||
            range < 0 && this.currentFrame < currentFrame) {
            this._onLoop();
            // Need to reset animation events
            if (events.length) {
                for (var index = 0; index < events.length; index++) {
                    if (!events[index].onlyOnce) {
                        // reset event, the animation is looping
                        events[index].isDone = false;
                    }
                }
            }
        }
        this._currentFrame = currentFrame;
        this._animationState.repeatCount = range === 0 ? 0 : (ratio / range) >> 0;
        this._animationState.highLimitValue = highLimitValue;
        this._animationState.offsetValue = offsetValue;
        var currentValue = animation._interpolate(currentFrame, this._animationState);
        // Set value
        this.setValue(currentValue, weight);
        // Check events
        if (events.length) {
            for (var index = 0; index < events.length; index++) {
                // Make sure current frame has passed event frame and that event frame is within the current range
                // Also, handle both forward and reverse animations
                if ((range > 0 && currentFrame >= events[index].frame && events[index].frame >= from) ||
                    (range < 0 && currentFrame <= events[index].frame && events[index].frame <= from)) {
                    var event = events[index];
                    if (!event.isDone) {
                        // If event should be done only once, remove it.
                        if (event.onlyOnce) {
                            events.splice(index, 1);
                            index--;
                        }
                        event.isDone = true;
                        event.action(currentFrame);
                    } // Don't do anything if the event has already be done.
                }
            }
        }
        if (!returnValue) {
            this._stopped = true;
        }
        return returnValue;
    };
    return RuntimeAnimation;
}());



/***/ }),

/***/ "./Audio/analyser.ts":
/*!***************************!*\
  !*** ./Audio/analyser.ts ***!
  \***************************/
/*! exports provided: Analyser */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Analyser", function() { return Analyser; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");

/**
 * Class used to work with sound analyzer using fast fourier transform (FFT)
 * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music
 */
var Analyser = /** @class */ (function () {
    /**
     * Creates a new analyser
     * @param scene defines hosting scene
     */
    function Analyser(scene) {
        /**
         * Gets or sets the smoothing
         * @ignorenaming
         */
        this.SMOOTHING = 0.75;
        /**
         * Gets or sets the FFT table size
         * @ignorenaming
         */
        this.FFT_SIZE = 512;
        /**
         * Gets or sets the bar graph amplitude
         * @ignorenaming
         */
        this.BARGRAPHAMPLITUDE = 256;
        /**
         * Gets or sets the position of the debug canvas
         * @ignorenaming
         */
        this.DEBUGCANVASPOS = { x: 20, y: 20 };
        /**
         * Gets or sets the debug canvas size
         * @ignorenaming
         */
        this.DEBUGCANVASSIZE = { width: 320, height: 200 };
        this._scene = scene;
        this._audioEngine = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine;
        if (this._audioEngine.canUseWebAudio && this._audioEngine.audioContext) {
            this._webAudioAnalyser = this._audioEngine.audioContext.createAnalyser();
            this._webAudioAnalyser.minDecibels = -140;
            this._webAudioAnalyser.maxDecibels = 0;
            this._byteFreqs = new Uint8Array(this._webAudioAnalyser.frequencyBinCount);
            this._byteTime = new Uint8Array(this._webAudioAnalyser.frequencyBinCount);
            this._floatFreqs = new Float32Array(this._webAudioAnalyser.frequencyBinCount);
        }
    }
    /**
     * Get the number of data values you will have to play with for the visualization
     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/frequencyBinCount
     * @returns a number
     */
    Analyser.prototype.getFrequencyBinCount = function () {
        if (this._audioEngine.canUseWebAudio) {
            return this._webAudioAnalyser.frequencyBinCount;
        }
        else {
            return 0;
        }
    };
    /**
     * Gets the current frequency data as a byte array
     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData
     * @returns a Uint8Array
     */
    Analyser.prototype.getByteFrequencyData = function () {
        if (this._audioEngine.canUseWebAudio) {
            this._webAudioAnalyser.smoothingTimeConstant = this.SMOOTHING;
            this._webAudioAnalyser.fftSize = this.FFT_SIZE;
            this._webAudioAnalyser.getByteFrequencyData(this._byteFreqs);
        }
        return this._byteFreqs;
    };
    /**
     * Gets the current waveform as a byte array
     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteTimeDomainData
     * @returns a Uint8Array
     */
    Analyser.prototype.getByteTimeDomainData = function () {
        if (this._audioEngine.canUseWebAudio) {
            this._webAudioAnalyser.smoothingTimeConstant = this.SMOOTHING;
            this._webAudioAnalyser.fftSize = this.FFT_SIZE;
            this._webAudioAnalyser.getByteTimeDomainData(this._byteTime);
        }
        return this._byteTime;
    };
    /**
     * Gets the current frequency data as a float array
     * @see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/getByteFrequencyData
     * @returns a Float32Array
     */
    Analyser.prototype.getFloatFrequencyData = function () {
        if (this._audioEngine.canUseWebAudio) {
            this._webAudioAnalyser.smoothingTimeConstant = this.SMOOTHING;
            this._webAudioAnalyser.fftSize = this.FFT_SIZE;
            this._webAudioAnalyser.getFloatFrequencyData(this._floatFreqs);
        }
        return this._floatFreqs;
    };
    /**
     * Renders the debug canvas
     */
    Analyser.prototype.drawDebugCanvas = function () {
        var _this = this;
        if (this._audioEngine.canUseWebAudio) {
            if (!this._debugCanvas) {
                this._debugCanvas = document.createElement("canvas");
                this._debugCanvas.width = this.DEBUGCANVASSIZE.width;
                this._debugCanvas.height = this.DEBUGCANVASSIZE.height;
                this._debugCanvas.style.position = "absolute";
                this._debugCanvas.style.top = this.DEBUGCANVASPOS.y + "px";
                this._debugCanvas.style.left = this.DEBUGCANVASPOS.x + "px";
                this._debugCanvasContext = this._debugCanvas.getContext("2d");
                document.body.appendChild(this._debugCanvas);
                this._registerFunc = function () {
                    _this.drawDebugCanvas();
                };
                this._scene.registerBeforeRender(this._registerFunc);
            }
            if (this._registerFunc && this._debugCanvasContext) {
                var workingArray = this.getByteFrequencyData();
                this._debugCanvasContext.fillStyle = 'rgb(0, 0, 0)';
                this._debugCanvasContext.fillRect(0, 0, this.DEBUGCANVASSIZE.width, this.DEBUGCANVASSIZE.height);
                // Draw the frequency domain chart.
                for (var i = 0; i < this.getFrequencyBinCount(); i++) {
                    var value = workingArray[i];
                    var percent = value / this.BARGRAPHAMPLITUDE;
                    var height = this.DEBUGCANVASSIZE.height * percent;
                    var offset = this.DEBUGCANVASSIZE.height - height - 1;
                    var barWidth = this.DEBUGCANVASSIZE.width / this.getFrequencyBinCount();
                    var hue = i / this.getFrequencyBinCount() * 360;
                    this._debugCanvasContext.fillStyle = 'hsl(' + hue + ', 100%, 50%)';
                    this._debugCanvasContext.fillRect(i * barWidth, offset, barWidth, height);
                }
            }
        }
    };
    /**
     * Stops rendering the debug canvas and removes it
     */
    Analyser.prototype.stopDebugCanvas = function () {
        if (this._debugCanvas) {
            if (this._registerFunc) {
                this._scene.unregisterBeforeRender(this._registerFunc);
                this._registerFunc = null;
            }
            document.body.removeChild(this._debugCanvas);
            this._debugCanvas = null;
            this._debugCanvasContext = null;
        }
    };
    /**
     * Connects two audio nodes
     * @param inputAudioNode defines first node to connect
     * @param outputAudioNode defines second node to connect
     */
    Analyser.prototype.connectAudioNodes = function (inputAudioNode, outputAudioNode) {
        if (this._audioEngine.canUseWebAudio) {
            inputAudioNode.connect(this._webAudioAnalyser);
            this._webAudioAnalyser.connect(outputAudioNode);
        }
    };
    /**
     * Releases all associated resources
     */
    Analyser.prototype.dispose = function () {
        if (this._audioEngine.canUseWebAudio) {
            this._webAudioAnalyser.disconnect();
        }
    };
    return Analyser;
}());



/***/ }),

/***/ "./Audio/audioEngine.ts":
/*!******************************!*\
  !*** ./Audio/audioEngine.ts ***!
  \******************************/
/*! exports provided: AudioEngine */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AudioEngine", function() { return AudioEngine; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");



// Sets the default audio engine to Babylon.js
_Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].AudioEngineFactory = function (hostElement) { return new AudioEngine(hostElement); };
/**
 * This represents the default audio engine used in babylon.
 * It is responsible to play, synchronize and analyse sounds throughout the  application.
 * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music
 */
var AudioEngine = /** @class */ (function () {
    /**
     * Instantiates a new audio engine.
     *
     * There should be only one per page as some browsers restrict the number
     * of audio contexts you can create.
     * @param hostElement defines the host element where to display the mute icon if necessary
     */
    function AudioEngine(hostElement) {
        var _this = this;
        if (hostElement === void 0) { hostElement = null; }
        this._audioContext = null;
        this._audioContextInitialized = false;
        this._muteButton = null;
        /**
         * Gets whether the current host supports Web Audio and thus could create AudioContexts.
         */
        this.canUseWebAudio = false;
        /**
         * Defines if Babylon should emit a warning if WebAudio is not supported.
         * @ignoreNaming
         */
        this.WarnedWebAudioUnsupported = false;
        /**
         * Gets whether or not mp3 are supported by your browser.
         */
        this.isMP3supported = false;
        /**
         * Gets whether or not ogg are supported by your browser.
         */
        this.isOGGsupported = false;
        /**
         * Gets whether audio has been unlocked on the device.
         * Some Browsers have strong restrictions about Audio and won t autoplay unless
         * a user interaction has happened.
         */
        this.unlocked = true;
        /**
         * Defines if the audio engine relies on a custom unlocked button.
         * In this case, the embedded button will not be displayed.
         */
        this.useCustomUnlockedButton = false;
        /**
         * Event raised when audio has been unlocked on the browser.
         */
        this.onAudioUnlockedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /**
         * Event raised when audio has been locked on the browser.
         */
        this.onAudioLockedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this._tryToRun = false;
        this._onResize = function () {
            _this._moveButtonToTopLeft();
        };
        if (typeof window.AudioContext !== 'undefined' || typeof window.webkitAudioContext !== 'undefined') {
            window.AudioContext = window.AudioContext || window.webkitAudioContext;
            this.canUseWebAudio = true;
        }
        var audioElem = document.createElement('audio');
        this._hostElement = hostElement;
        try {
            if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/mpeg; codecs="mp3"').replace(/^no$/, '')) {
                this.isMP3supported = true;
            }
        }
        catch (e) {
            // protect error during capability check.
        }
        try {
            if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) {
                this.isOGGsupported = true;
            }
        }
        catch (e) {
            // protect error during capability check.
        }
    }
    Object.defineProperty(AudioEngine.prototype, "audioContext", {
        /**
         * Gets the current AudioContext if available.
         */
        get: function () {
            if (!this._audioContextInitialized) {
                this._initializeAudioContext();
            }
            else {
                if (!this.unlocked && !this._muteButton) {
                    this._displayMuteButton();
                }
            }
            return this._audioContext;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Flags the audio engine in Locked state.
     * This happens due to new browser policies preventing audio to autoplay.
     */
    AudioEngine.prototype.lock = function () {
        this._triggerSuspendedState();
    };
    /**
     * Unlocks the audio engine once a user action has been done on the dom.
     * This is helpful to resume play once browser policies have been satisfied.
     */
    AudioEngine.prototype.unlock = function () {
        this._triggerRunningState();
    };
    AudioEngine.prototype._resumeAudioContext = function () {
        var result;
        if (this._audioContext.resume) {
            result = this._audioContext.resume();
        }
        return result || Promise.resolve();
    };
    AudioEngine.prototype._initializeAudioContext = function () {
        try {
            if (this.canUseWebAudio) {
                this._audioContext = new AudioContext();
                // create a global volume gain node
                this.masterGain = this._audioContext.createGain();
                this.masterGain.gain.value = 1;
                this.masterGain.connect(this._audioContext.destination);
                this._audioContextInitialized = true;
                if (this._audioContext.state === "running") {
                    // Do not wait for the promise to unlock.
                    this._triggerRunningState();
                }
            }
        }
        catch (e) {
            this.canUseWebAudio = false;
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Web Audio: " + e.message);
        }
    };
    AudioEngine.prototype._triggerRunningState = function () {
        var _this = this;
        if (this._tryToRun) {
            return;
        }
        this._tryToRun = true;
        this._resumeAudioContext()
            .then(function () {
            _this._tryToRun = false;
            if (_this._muteButton) {
                _this._hideMuteButton();
            }
        }).catch(function () {
            _this._tryToRun = false;
            _this.unlocked = false;
        });
        // Notify users that the audio stack is unlocked/unmuted
        this.unlocked = true;
        this.onAudioUnlockedObservable.notifyObservers(this);
    };
    AudioEngine.prototype._triggerSuspendedState = function () {
        this.unlocked = false;
        this.onAudioLockedObservable.notifyObservers(this);
        this._displayMuteButton();
    };
    AudioEngine.prototype._displayMuteButton = function () {
        var _this = this;
        if (this.useCustomUnlockedButton || this._muteButton) {
            return;
        }
        this._muteButton = document.createElement("BUTTON");
        this._muteButton.className = "babylonUnmuteIcon";
        this._muteButton.id = "babylonUnmuteIconBtn";
        this._muteButton.title = "Unmute";
        var css = ".babylonUnmuteIcon { position: absolute; left: 20px; top: 20px; height: 40px; width: 60px; background-color: rgba(51,51,51,0.7); background-image: url(data:image/svg+xml;charset=UTF-8,%3Csvg%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2239%22%20height%3D%2232%22%20viewBox%3D%220%200%2039%2032%22%3E%3Cpath%20fill%3D%22white%22%20d%3D%22M9.625%2018.938l-0.031%200.016h-4.953q-0.016%200-0.031-0.016v-12.453q0-0.016%200.031-0.016h4.953q0.031%200%200.031%200.016v12.453zM12.125%207.688l8.719-8.703v27.453l-8.719-8.719-0.016-0.047v-9.938zM23.359%207.875l1.406-1.406%204.219%204.203%204.203-4.203%201.422%201.406-4.219%204.219%204.219%204.203-1.484%201.359-4.141-4.156-4.219%204.219-1.406-1.422%204.219-4.203z%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E);  background-size: 80%; background-repeat:no-repeat; background-position: center; background-position-y: 4px; border: none; outline: none; transition: transform 0.125s ease-out; cursor: pointer; z-index: 9999; } .babylonUnmuteIcon:hover { transform: scale(1.05) } .babylonUnmuteIcon:active { background-color: rgba(51,51,51,1) }";
        var style = document.createElement('style');
        style.appendChild(document.createTextNode(css));
        document.getElementsByTagName('head')[0].appendChild(style);
        document.body.appendChild(this._muteButton);
        this._moveButtonToTopLeft();
        this._muteButton.addEventListener('touchend', function () {
            _this._triggerRunningState();
        }, true);
        this._muteButton.addEventListener('click', function () {
            _this._triggerRunningState();
        }, true);
        window.addEventListener("resize", this._onResize);
    };
    AudioEngine.prototype._moveButtonToTopLeft = function () {
        if (this._hostElement && this._muteButton) {
            this._muteButton.style.top = this._hostElement.offsetTop + 20 + "px";
            this._muteButton.style.left = this._hostElement.offsetLeft + 20 + "px";
        }
    };
    AudioEngine.prototype._hideMuteButton = function () {
        if (this._muteButton) {
            document.body.removeChild(this._muteButton);
            this._muteButton = null;
        }
    };
    /**
     * Destroy and release the resources associated with the audio ccontext.
     */
    AudioEngine.prototype.dispose = function () {
        if (this.canUseWebAudio && this._audioContextInitialized) {
            if (this._connectedAnalyser && this._audioContext) {
                this._connectedAnalyser.stopDebugCanvas();
                this._connectedAnalyser.dispose();
                this.masterGain.disconnect();
                this.masterGain.connect(this._audioContext.destination);
                this._connectedAnalyser = null;
            }
            this.masterGain.gain.value = 1;
        }
        this.WarnedWebAudioUnsupported = false;
        this._hideMuteButton();
        window.removeEventListener("resize", this._onResize);
        this.onAudioUnlockedObservable.clear();
        this.onAudioLockedObservable.clear();
    };
    /**
     * Gets the global volume sets on the master gain.
     * @returns the global volume if set or -1 otherwise
     */
    AudioEngine.prototype.getGlobalVolume = function () {
        if (this.canUseWebAudio && this._audioContextInitialized) {
            return this.masterGain.gain.value;
        }
        else {
            return -1;
        }
    };
    /**
     * Sets the global volume of your experience (sets on the master gain).
     * @param newVolume Defines the new global volume of the application
     */
    AudioEngine.prototype.setGlobalVolume = function (newVolume) {
        if (this.canUseWebAudio && this._audioContextInitialized) {
            this.masterGain.gain.value = newVolume;
        }
    };
    /**
     * Connect the audio engine to an audio analyser allowing some amazing
     * synchornization between the sounds/music and your visualization (VuMeter for instance).
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#using-the-analyser
     * @param analyser The analyser to connect to the engine
     */
    AudioEngine.prototype.connectToAnalyser = function (analyser) {
        if (this._connectedAnalyser) {
            this._connectedAnalyser.stopDebugCanvas();
        }
        if (this.canUseWebAudio && this._audioContextInitialized && this._audioContext) {
            this._connectedAnalyser = analyser;
            this.masterGain.disconnect();
            this._connectedAnalyser.connectAudioNodes(this.masterGain, this._audioContext.destination);
        }
    };
    return AudioEngine;
}());



/***/ }),

/***/ "./Audio/audioSceneComponent.ts":
/*!**************************************!*\
  !*** ./Audio/audioSceneComponent.ts ***!
  \**************************************/
/*! exports provided: AudioSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AudioSceneComponent", function() { return AudioSceneComponent; });
/* harmony import */ var _sound__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sound */ "./Audio/sound.ts");
/* harmony import */ var _soundTrack__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./soundTrack */ "./Audio/soundTrack.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _audioEngine__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./audioEngine */ "./Audio/audioEngine.ts");








// Adds the parser to the scene parsers.
_abstractScene__WEBPACK_IMPORTED_MODULE_6__["AbstractScene"].AddParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO, function (parsedData, scene, container, rootUrl) {
    // TODO: add sound
    var loadedSounds = [];
    var loadedSound;
    container.sounds = container.sounds || [];
    if (parsedData.sounds !== undefined && parsedData.sounds !== null) {
        for (var index = 0, cache = parsedData.sounds.length; index < cache; index++) {
            var parsedSound = parsedData.sounds[index];
            if (_Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine.canUseWebAudio) {
                if (!parsedSound.url) {
                    parsedSound.url = parsedSound.name;
                }
                if (!loadedSounds[parsedSound.url]) {
                    loadedSound = _sound__WEBPACK_IMPORTED_MODULE_0__["Sound"].Parse(parsedSound, scene, rootUrl);
                    loadedSounds[parsedSound.url] = loadedSound;
                    container.sounds.push(loadedSound);
                }
                else {
                    container.sounds.push(_sound__WEBPACK_IMPORTED_MODULE_0__["Sound"].Parse(parsedSound, scene, rootUrl, loadedSounds[parsedSound.url]));
                }
            }
            else {
                container.sounds.push(new _sound__WEBPACK_IMPORTED_MODULE_0__["Sound"](parsedSound.name, null, scene));
            }
        }
    }
    loadedSounds = [];
});
Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_5__["Scene"].prototype, "mainSoundTrack", {
    get: function () {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        if (!this._mainSoundTrack) {
            this._mainSoundTrack = new _soundTrack__WEBPACK_IMPORTED_MODULE_1__["SoundTrack"](this, { mainTrack: true });
        }
        return this._mainSoundTrack;
    },
    enumerable: true,
    configurable: true
});
_scene__WEBPACK_IMPORTED_MODULE_5__["Scene"].prototype.getSoundByName = function (name) {
    var index;
    for (index = 0; index < this.mainSoundTrack.soundCollection.length; index++) {
        if (this.mainSoundTrack.soundCollection[index].name === name) {
            return this.mainSoundTrack.soundCollection[index];
        }
    }
    if (this.soundTracks) {
        for (var sdIndex = 0; sdIndex < this.soundTracks.length; sdIndex++) {
            for (index = 0; index < this.soundTracks[sdIndex].soundCollection.length; index++) {
                if (this.soundTracks[sdIndex].soundCollection[index].name === name) {
                    return this.soundTracks[sdIndex].soundCollection[index];
                }
            }
        }
    }
    return null;
};
Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_5__["Scene"].prototype, "audioEnabled", {
    get: function () {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        return compo.audioEnabled;
    },
    set: function (value) {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        if (value) {
            compo.enableAudio();
        }
        else {
            compo.disableAudio();
        }
    },
    enumerable: true,
    configurable: true
});
Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_5__["Scene"].prototype, "headphone", {
    get: function () {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        return compo.headphone;
    },
    set: function (value) {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        if (value) {
            compo.switchAudioModeForHeadphones();
        }
        else {
            compo.switchAudioModeForNormalSpeakers();
        }
    },
    enumerable: true,
    configurable: true
});
Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_5__["Scene"].prototype, "audioListenerPositionProvider", {
    get: function () {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        return compo.audioListenerPositionProvider;
    },
    set: function (value) {
        var compo = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
        if (!compo) {
            compo = new AudioSceneComponent(this);
            this._addComponent(compo);
        }
        if (typeof value !== 'function') {
            throw new Error('The value passed to [Scene.audioListenerPositionProvider] must be a function that returns a Vector3');
        }
        else {
            compo.audioListenerPositionProvider = value;
        }
    },
    enumerable: true,
    configurable: true
});
/**
 * Defines the sound scene component responsible to manage any sounds
 * in a given scene.
 */
var AudioSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function AudioSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO;
        this._audioEnabled = true;
        this._headphone = false;
        this._audioListenerPositionProvider = null;
        this.scene = scene;
        scene.soundTracks = new Array();
        scene.sounds = new Array();
    }
    Object.defineProperty(AudioSceneComponent.prototype, "audioEnabled", {
        /**
         * Gets whether audio is enabled or not.
         * Please use related enable/disable method to switch state.
         */
        get: function () {
            return this._audioEnabled;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AudioSceneComponent.prototype, "headphone", {
        /**
         * Gets whether audio is outputing to headphone or not.
         * Please use the according Switch methods to change output.
         */
        get: function () {
            return this._headphone;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AudioSceneComponent.prototype, "audioListenerPositionProvider", {
        /**
         * Gets the current audio listener position provider
         */
        get: function () {
            return this._audioListenerPositionProvider;
        },
        /**
         * Sets a custom listener position for all sounds in the scene
         * By default, this is the position of the first active camera
         */
        set: function (value) {
            this._audioListenerPositionProvider = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Registers the component in a given scene
     */
    AudioSceneComponent.prototype.register = function () {
        this.scene._afterRenderStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].STEP_AFTERRENDER_AUDIO, this, this._afterRender);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    AudioSceneComponent.prototype.rebuild = function () {
        // Nothing to do here. (Not rendering related)
    };
    /**
     * Serializes the component data to the specified json object
     * @param serializationObject The object to serialize to
     */
    AudioSceneComponent.prototype.serialize = function (serializationObject) {
        serializationObject.sounds = [];
        if (this.scene.soundTracks) {
            for (var index = 0; index < this.scene.soundTracks.length; index++) {
                var soundtrack = this.scene.soundTracks[index];
                for (var soundId = 0; soundId < soundtrack.soundCollection.length; soundId++) {
                    serializationObject.sounds.push(soundtrack.soundCollection[soundId].serialize());
                }
            }
        }
    };
    /**
     * Adds all the elements from the container to the scene
     * @param container the container holding the elements
     */
    AudioSceneComponent.prototype.addFromContainer = function (container) {
        var _this = this;
        if (!container.sounds) {
            return;
        }
        container.sounds.forEach(function (sound) {
            sound.play();
            sound.autoplay = true;
            _this.scene.mainSoundTrack.AddSound(sound);
        });
    };
    /**
     * Removes all the elements in the container from the scene
     * @param container contains the elements to remove
     * @param dispose if the removed element should be disposed (default: false)
     */
    AudioSceneComponent.prototype.removeFromContainer = function (container, dispose) {
        var _this = this;
        if (dispose === void 0) { dispose = false; }
        if (!container.sounds) {
            return;
        }
        container.sounds.forEach(function (sound) {
            sound.stop();
            sound.autoplay = false;
            _this.scene.mainSoundTrack.RemoveSound(sound);
            if (dispose) {
                sound.dispose();
            }
        });
    };
    /**
     * Disposes the component and the associated ressources.
     */
    AudioSceneComponent.prototype.dispose = function () {
        var scene = this.scene;
        if (scene._mainSoundTrack) {
            scene.mainSoundTrack.dispose();
        }
        if (scene.soundTracks) {
            for (var scIndex = 0; scIndex < scene.soundTracks.length; scIndex++) {
                scene.soundTracks[scIndex].dispose();
            }
        }
    };
    /**
     * Disables audio in the associated scene.
     */
    AudioSceneComponent.prototype.disableAudio = function () {
        var scene = this.scene;
        this._audioEnabled = false;
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine && _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine.audioContext) {
            _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine.audioContext.suspend();
        }
        var i;
        for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {
            scene.mainSoundTrack.soundCollection[i].pause();
        }
        if (scene.soundTracks) {
            for (i = 0; i < scene.soundTracks.length; i++) {
                for (var j = 0; j < scene.soundTracks[i].soundCollection.length; j++) {
                    scene.soundTracks[i].soundCollection[j].pause();
                }
            }
        }
    };
    /**
     * Enables audio in the associated scene.
     */
    AudioSceneComponent.prototype.enableAudio = function () {
        var scene = this.scene;
        this._audioEnabled = true;
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine && _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine.audioContext) {
            _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine.audioContext.resume();
        }
        var i;
        for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {
            if (scene.mainSoundTrack.soundCollection[i].isPaused) {
                scene.mainSoundTrack.soundCollection[i].play();
            }
        }
        if (scene.soundTracks) {
            for (i = 0; i < scene.soundTracks.length; i++) {
                for (var j = 0; j < scene.soundTracks[i].soundCollection.length; j++) {
                    if (scene.soundTracks[i].soundCollection[j].isPaused) {
                        scene.soundTracks[i].soundCollection[j].play();
                    }
                }
            }
        }
    };
    /**
     * Switch audio to headphone output.
     */
    AudioSceneComponent.prototype.switchAudioModeForHeadphones = function () {
        var scene = this.scene;
        this._headphone = true;
        scene.mainSoundTrack.switchPanningModelToHRTF();
        if (scene.soundTracks) {
            for (var i = 0; i < scene.soundTracks.length; i++) {
                scene.soundTracks[i].switchPanningModelToHRTF();
            }
        }
    };
    /**
     * Switch audio to normal speakers.
     */
    AudioSceneComponent.prototype.switchAudioModeForNormalSpeakers = function () {
        var scene = this.scene;
        this._headphone = false;
        scene.mainSoundTrack.switchPanningModelToEqualPower();
        if (scene.soundTracks) {
            for (var i = 0; i < scene.soundTracks.length; i++) {
                scene.soundTracks[i].switchPanningModelToEqualPower();
            }
        }
    };
    AudioSceneComponent.prototype._afterRender = function () {
        var scene = this.scene;
        if (!this._audioEnabled || !scene._mainSoundTrack || !scene.soundTracks || (scene._mainSoundTrack.soundCollection.length === 0 && scene.soundTracks.length === 1)) {
            return;
        }
        var audioEngine = _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].audioEngine;
        if (audioEngine.audioContext) {
            // A custom listener position provider was set
            // Use the users provided position instead of camera's
            if (this._audioListenerPositionProvider) {
                var position = this._audioListenerPositionProvider();
                // Make sure all coordinates were provided
                position.x = position.x || 0;
                position.y = position.y || 0;
                position.z = position.z || 0;
                // Set the listener position
                audioEngine.audioContext.listener.setPosition(position.x, position.y, position.z);
            }
            else {
                var listeningCamera;
                if (scene.activeCameras.length > 0) {
                    listeningCamera = scene.activeCameras[0];
                }
                else {
                    listeningCamera = scene.activeCamera;
                }
                // Check if there is a listening camera
                if (listeningCamera) {
                    // Set the listener position to the listening camera global position
                    audioEngine.audioContext.listener.setPosition(listeningCamera.globalPosition.x, listeningCamera.globalPosition.y, listeningCamera.globalPosition.z);
                    // for VR cameras
                    if (listeningCamera.rigCameras && listeningCamera.rigCameras.length > 0) {
                        listeningCamera = listeningCamera.rigCameras[0];
                    }
                    var mat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Invert(listeningCamera.getViewMatrix());
                    var cameraDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, -1), mat);
                    cameraDirection.normalize();
                    // To avoid some errors on GearVR
                    if (!isNaN(cameraDirection.x) && !isNaN(cameraDirection.y) && !isNaN(cameraDirection.z)) {
                        audioEngine.audioContext.listener.setOrientation(cameraDirection.x, cameraDirection.y, cameraDirection.z, 0, 1, 0);
                    }
                }
                // Otherwise set the listener position to 0, 0 ,0
                else {
                    // Set the listener position
                    audioEngine.audioContext.listener.setPosition(0, 0, 0);
                }
            }
            var i;
            for (i = 0; i < scene.mainSoundTrack.soundCollection.length; i++) {
                var sound = scene.mainSoundTrack.soundCollection[i];
                if (sound.useCustomAttenuation) {
                    sound.updateDistanceFromListener();
                }
            }
            if (scene.soundTracks) {
                for (i = 0; i < scene.soundTracks.length; i++) {
                    for (var j = 0; j < scene.soundTracks[i].soundCollection.length; j++) {
                        sound = scene.soundTracks[i].soundCollection[j];
                        if (sound.useCustomAttenuation) {
                            sound.updateDistanceFromListener();
                        }
                    }
                }
            }
        }
    };
    return AudioSceneComponent;
}());

_sound__WEBPACK_IMPORTED_MODULE_0__["Sound"]._SceneComponentInitialization = function (scene) {
    var compo = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_AUDIO);
    if (!compo) {
        compo = new AudioSceneComponent(scene);
        scene._addComponent(compo);
    }
};


/***/ }),

/***/ "./Audio/index.ts":
/*!************************!*\
  !*** ./Audio/index.ts ***!
  \************************/
/*! exports provided: Analyser, AudioEngine, AudioSceneComponent, Sound, SoundTrack, WeightedSound */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _analyser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./analyser */ "./Audio/analyser.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Analyser", function() { return _analyser__WEBPACK_IMPORTED_MODULE_0__["Analyser"]; });

/* harmony import */ var _audioEngine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./audioEngine */ "./Audio/audioEngine.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AudioEngine", function() { return _audioEngine__WEBPACK_IMPORTED_MODULE_1__["AudioEngine"]; });

/* harmony import */ var _audioSceneComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./audioSceneComponent */ "./Audio/audioSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AudioSceneComponent", function() { return _audioSceneComponent__WEBPACK_IMPORTED_MODULE_2__["AudioSceneComponent"]; });

/* harmony import */ var _sound__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sound */ "./Audio/sound.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sound", function() { return _sound__WEBPACK_IMPORTED_MODULE_3__["Sound"]; });

/* harmony import */ var _soundTrack__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./soundTrack */ "./Audio/soundTrack.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SoundTrack", function() { return _soundTrack__WEBPACK_IMPORTED_MODULE_4__["SoundTrack"]; });

/* harmony import */ var _weightedsound__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./weightedsound */ "./Audio/weightedsound.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WeightedSound", function() { return _weightedsound__WEBPACK_IMPORTED_MODULE_5__["WeightedSound"]; });









/***/ }),

/***/ "./Audio/sound.ts":
/*!************************!*\
  !*** ./Audio/sound.ts ***!
  \************************/
/*! exports provided: Sound */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sound", function() { return Sound; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");






/**
 * Defines a sound that can be played in the application.
 * The sound can either be an ambient track or a simple sound played in reaction to a user action.
 * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music
 */
var Sound = /** @class */ (function () {
    /**
    * Create a sound and attach it to a scene
    * @param name Name of your sound
    * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer, it also works with MediaStreams
    * @param scene defines the scene the sound belongs to
    * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
    * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
    */
    function Sound(name, urlOrArrayBuffer, scene, readyToPlayCallback, options) {
        var _this = this;
        if (readyToPlayCallback === void 0) { readyToPlayCallback = null; }
        /**
         * Does the sound autoplay once loaded.
         */
        this.autoplay = false;
        /**
         * Does the sound loop after it finishes playing once.
         */
        this.loop = false;
        /**
         * Does the sound use a custom attenuation curve to simulate the falloff
         * happening when the source gets further away from the camera.
         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-your-own-custom-attenuation-function
         */
        this.useCustomAttenuation = false;
        /**
         * Is this sound currently played.
         */
        this.isPlaying = false;
        /**
         * Is this sound currently paused.
         */
        this.isPaused = false;
        /**
         * Does this sound enables spatial sound.
         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
         */
        this.spatialSound = false;
        /**
         * Define the reference distance the sound should be heard perfectly.
         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
         */
        this.refDistance = 1;
        /**
         * Define the roll off factor of spatial sounds.
         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
         */
        this.rolloffFactor = 1;
        /**
         * Define the max distance the sound should be heard (intensity just became 0 at this point).
         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
         */
        this.maxDistance = 100;
        /**
         * Define the distance attenuation model the sound will follow.
         * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
         */
        this.distanceModel = "linear";
        /**
         * Observable event when the current playing sound finishes.
         */
        this.onEndedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._panningModel = "equalpower";
        this._playbackRate = 1;
        this._streaming = false;
        this._startTime = 0;
        this._startOffset = 0;
        this._position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        /** @hidden */
        this._positionInEmitterSpace = false;
        this._localDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](1, 0, 0);
        this._volume = 1;
        this._isReadyToPlay = false;
        this._isDirectional = false;
        // Used if you'd like to create a directional sound.
        // If not set, the sound will be omnidirectional
        this._coneInnerAngle = 360;
        this._coneOuterAngle = 360;
        this._coneOuterGain = 0;
        this._isOutputConnected = false;
        this._urlType = "Unknown";
        this.name = name;
        this._scene = scene;
        Sound._SceneComponentInitialization(scene);
        this._readyToPlayCallback = readyToPlayCallback;
        // Default custom attenuation function is a linear attenuation
        this._customAttenuationFunction = function (currentVolume, currentDistance, maxDistance, refDistance, rolloffFactor) {
            if (currentDistance < maxDistance) {
                return currentVolume * (1 - currentDistance / maxDistance);
            }
            else {
                return 0;
            }
        };
        if (options) {
            this.autoplay = options.autoplay || false;
            this.loop = options.loop || false;
            // if volume === 0, we need another way to check this option
            if (options.volume !== undefined) {
                this._volume = options.volume;
            }
            this.spatialSound = options.spatialSound || false;
            this.maxDistance = options.maxDistance || 100;
            this.useCustomAttenuation = options.useCustomAttenuation || false;
            this.rolloffFactor = options.rolloffFactor || 1;
            this.refDistance = options.refDistance || 1;
            this.distanceModel = options.distanceModel || "linear";
            this._playbackRate = options.playbackRate || 1;
            this._streaming = options.streaming || false;
            this._length = options.length;
            this._offset = options.offset;
        }
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
            this._soundGain = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.createGain();
            this._soundGain.gain.value = this._volume;
            this._inputAudioNode = this._soundGain;
            this._outputAudioNode = this._soundGain;
            if (this.spatialSound) {
                this._createSpatialParameters();
            }
            this._scene.mainSoundTrack.AddSound(this);
            var validParameter = true;
            // if no parameter is passed, you need to call setAudioBuffer yourself to prepare the sound
            if (urlOrArrayBuffer) {
                try {
                    if (typeof (urlOrArrayBuffer) === "string") {
                        this._urlType = "String";
                    }
                    else if (urlOrArrayBuffer instanceof ArrayBuffer) {
                        this._urlType = "ArrayBuffer";
                    }
                    else if (urlOrArrayBuffer instanceof MediaStream) {
                        this._urlType = "MediaStream";
                    }
                    else if (Array.isArray(urlOrArrayBuffer)) {
                        this._urlType = "Array";
                    }
                    var urls = [];
                    var codecSupportedFound = false;
                    switch (this._urlType) {
                        case "MediaStream":
                            this._streaming = true;
                            this._isReadyToPlay = true;
                            this._streamingSource = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.createMediaStreamSource(urlOrArrayBuffer);
                            if (this.autoplay) {
                                this.play(0, this._offset, this._length);
                            }
                            if (this._readyToPlayCallback) {
                                this._readyToPlayCallback();
                            }
                            break;
                        case "ArrayBuffer":
                            if (urlOrArrayBuffer.byteLength > 0) {
                                codecSupportedFound = true;
                                this._soundLoaded(urlOrArrayBuffer);
                            }
                            break;
                        case "String":
                            urls.push(urlOrArrayBuffer);
                        case "Array":
                            if (urls.length === 0) {
                                urls = urlOrArrayBuffer;
                            }
                            // If we found a supported format, we load it immediately and stop the loop
                            for (var i = 0; i < urls.length; i++) {
                                var url = urls[i];
                                codecSupportedFound = (options && options.skipCodecCheck) ||
                                    (url.indexOf(".mp3", url.length - 4) !== -1 && _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.isMP3supported) ||
                                    (url.indexOf(".ogg", url.length - 4) !== -1 && _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.isOGGsupported) ||
                                    (url.indexOf(".wav", url.length - 4) !== -1) ||
                                    (url.indexOf("blob:") !== -1);
                                if (codecSupportedFound) {
                                    // Loading sound using XHR2
                                    if (!this._streaming) {
                                        this._scene._loadFile(url, function (data) {
                                            _this._soundLoaded(data);
                                        }, undefined, true, true, function (exception) {
                                            if (exception) {
                                                _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("XHR " + exception.status + " error on: " + url + ".");
                                            }
                                            _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Sound creation aborted.");
                                            _this._scene.mainSoundTrack.RemoveSound(_this);
                                        });
                                    }
                                    // Streaming sound using HTML5 Audio tag
                                    else {
                                        this._htmlAudioElement = new Audio(url);
                                        this._htmlAudioElement.controls = false;
                                        this._htmlAudioElement.loop = this.loop;
                                        _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].SetCorsBehavior(url, this._htmlAudioElement);
                                        this._htmlAudioElement.preload = "auto";
                                        this._htmlAudioElement.addEventListener("canplaythrough", function () {
                                            _this._isReadyToPlay = true;
                                            if (_this.autoplay) {
                                                _this.play(0, _this._offset, _this._length);
                                            }
                                            if (_this._readyToPlayCallback) {
                                                _this._readyToPlayCallback();
                                            }
                                        });
                                        document.body.appendChild(this._htmlAudioElement);
                                        this._htmlAudioElement.load();
                                    }
                                    break;
                                }
                            }
                            break;
                        default:
                            validParameter = false;
                            break;
                    }
                    if (!validParameter) {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Parameter must be a URL to the sound, an Array of URLs (.mp3 & .ogg) or an ArrayBuffer of the sound.");
                    }
                    else {
                        if (!codecSupportedFound) {
                            this._isReadyToPlay = true;
                            // Simulating a ready to play event to avoid breaking code path
                            if (this._readyToPlayCallback) {
                                window.setTimeout(function () {
                                    if (_this._readyToPlayCallback) {
                                        _this._readyToPlayCallback();
                                    }
                                }, 1000);
                            }
                        }
                    }
                }
                catch (ex) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Unexpected error. Sound creation aborted.");
                    this._scene.mainSoundTrack.RemoveSound(this);
                }
            }
        }
        else {
            // Adding an empty sound to avoid breaking audio calls for non Web Audio browsers
            this._scene.mainSoundTrack.AddSound(this);
            if (!_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.WarnedWebAudioUnsupported) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Web Audio is not supported by your browser.");
                _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.WarnedWebAudioUnsupported = true;
            }
            // Simulating a ready to play event to avoid breaking code for non web audio browsers
            if (this._readyToPlayCallback) {
                window.setTimeout(function () {
                    if (_this._readyToPlayCallback) {
                        _this._readyToPlayCallback();
                    }
                }, 1000);
            }
        }
    }
    /**
     * Release the sound and its associated resources
     */
    Sound.prototype.dispose = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio) {
            if (this.isPlaying) {
                this.stop();
            }
            this._isReadyToPlay = false;
            if (this.soundTrackId === -1) {
                this._scene.mainSoundTrack.RemoveSound(this);
            }
            else if (this._scene.soundTracks) {
                this._scene.soundTracks[this.soundTrackId].RemoveSound(this);
            }
            if (this._soundGain) {
                this._soundGain.disconnect();
                this._soundGain = null;
            }
            if (this._soundPanner) {
                this._soundPanner.disconnect();
                this._soundPanner = null;
            }
            if (this._soundSource) {
                this._soundSource.disconnect();
                this._soundSource = null;
            }
            this._audioBuffer = null;
            if (this._htmlAudioElement) {
                this._htmlAudioElement.pause();
                this._htmlAudioElement.src = "";
                document.body.removeChild(this._htmlAudioElement);
            }
            if (this._streamingSource) {
                this._streamingSource.disconnect();
            }
            if (this._connectedTransformNode && this._registerFunc) {
                this._connectedTransformNode.unregisterAfterWorldMatrixUpdate(this._registerFunc);
                this._connectedTransformNode = null;
            }
        }
    };
    /**
     * Gets if the sounds is ready to be played or not.
     * @returns true if ready, otherwise false
     */
    Sound.prototype.isReady = function () {
        return this._isReadyToPlay;
    };
    Sound.prototype._soundLoaded = function (audioData) {
        var _this = this;
        if (!_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
            return;
        }
        _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.decodeAudioData(audioData, function (buffer) {
            _this._audioBuffer = buffer;
            _this._isReadyToPlay = true;
            if (_this.autoplay) {
                _this.play(0, _this._offset, _this._length);
            }
            if (_this._readyToPlayCallback) {
                _this._readyToPlayCallback();
            }
        }, function (err) { _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Error while decoding audio data for: " + _this.name + " / Error: " + err); });
    };
    /**
     * Sets the data of the sound from an audiobuffer
     * @param audioBuffer The audioBuffer containing the data
     */
    Sound.prototype.setAudioBuffer = function (audioBuffer) {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio) {
            this._audioBuffer = audioBuffer;
            this._isReadyToPlay = true;
        }
    };
    /**
     * Updates the current sounds options such as maxdistance, loop...
     * @param options A JSON object containing values named as the object properties
     */
    Sound.prototype.updateOptions = function (options) {
        if (options) {
            this.loop = options.loop || this.loop;
            this.maxDistance = options.maxDistance || this.maxDistance;
            this.useCustomAttenuation = options.useCustomAttenuation || this.useCustomAttenuation;
            this.rolloffFactor = options.rolloffFactor || this.rolloffFactor;
            this.refDistance = options.refDistance || this.refDistance;
            this.distanceModel = options.distanceModel || this.distanceModel;
            this._playbackRate = options.playbackRate || this._playbackRate;
            this._length = options.length ? options.length / 1000 : undefined;
            this._offset = options.offset ? options.offset / 1000 : undefined;
            this._updateSpatialParameters();
            if (this.isPlaying) {
                if (this._streaming && this._htmlAudioElement) {
                    this._htmlAudioElement.playbackRate = this._playbackRate;
                }
                else {
                    if (this._soundSource) {
                        this._soundSource.playbackRate.value = this._playbackRate;
                    }
                }
            }
        }
    };
    Sound.prototype._createSpatialParameters = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
            if (this._scene.headphone) {
                this._panningModel = "HRTF";
            }
            this._soundPanner = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.createPanner();
            this._updateSpatialParameters();
            this._soundPanner.connect(this._outputAudioNode);
            this._inputAudioNode = this._soundPanner;
        }
    };
    Sound.prototype._updateSpatialParameters = function () {
        if (this.spatialSound && this._soundPanner) {
            if (this.useCustomAttenuation) {
                // Tricks to disable in a way embedded Web Audio attenuation
                this._soundPanner.distanceModel = "linear";
                this._soundPanner.maxDistance = Number.MAX_VALUE;
                this._soundPanner.refDistance = 1;
                this._soundPanner.rolloffFactor = 1;
                this._soundPanner.panningModel = this._panningModel;
            }
            else {
                this._soundPanner.distanceModel = this.distanceModel;
                this._soundPanner.maxDistance = this.maxDistance;
                this._soundPanner.refDistance = this.refDistance;
                this._soundPanner.rolloffFactor = this.rolloffFactor;
                this._soundPanner.panningModel = this._panningModel;
            }
        }
    };
    /**
     * Switch the panning model to HRTF:
     * Renders a stereo output of higher quality than equalpower — it uses a convolution with measured impulse responses from human subjects.
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
     */
    Sound.prototype.switchPanningModelToHRTF = function () {
        this._panningModel = "HRTF";
        this._switchPanningModel();
    };
    /**
     * Switch the panning model to Equal Power:
     * Represents the equal-power panning algorithm, generally regarded as simple and efficient. equalpower is the default value.
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
     */
    Sound.prototype.switchPanningModelToEqualPower = function () {
        this._panningModel = "equalpower";
        this._switchPanningModel();
    };
    Sound.prototype._switchPanningModel = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this.spatialSound && this._soundPanner) {
            this._soundPanner.panningModel = this._panningModel;
        }
    };
    /**
     * Connect this sound to a sound track audio node like gain...
     * @param soundTrackAudioNode the sound track audio node to connect to
     */
    Sound.prototype.connectToSoundTrackAudioNode = function (soundTrackAudioNode) {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio) {
            if (this._isOutputConnected) {
                this._outputAudioNode.disconnect();
            }
            this._outputAudioNode.connect(soundTrackAudioNode);
            this._isOutputConnected = true;
        }
    };
    /**
    * Transform this sound into a directional source
    * @param coneInnerAngle Size of the inner cone in degree
    * @param coneOuterAngle Size of the outer cone in degree
    * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
    */
    Sound.prototype.setDirectionalCone = function (coneInnerAngle, coneOuterAngle, coneOuterGain) {
        if (coneOuterAngle < coneInnerAngle) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("setDirectionalCone(): outer angle of the cone must be superior or equal to the inner angle.");
            return;
        }
        this._coneInnerAngle = coneInnerAngle;
        this._coneOuterAngle = coneOuterAngle;
        this._coneOuterGain = coneOuterGain;
        this._isDirectional = true;
        if (this.isPlaying && this.loop) {
            this.stop();
            this.play(0, this._offset, this._length);
        }
    };
    Object.defineProperty(Sound.prototype, "directionalConeInnerAngle", {
        /**
         * Gets or sets the inner angle for the directional cone.
         */
        get: function () {
            return this._coneInnerAngle;
        },
        /**
         * Gets or sets the inner angle for the directional cone.
         */
        set: function (value) {
            if (value != this._coneInnerAngle) {
                if (this._coneOuterAngle < value) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("directionalConeInnerAngle: outer angle of the cone must be superior or equal to the inner angle.");
                    return;
                }
                this._coneInnerAngle = value;
                if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this.spatialSound && this._soundPanner) {
                    this._soundPanner.coneInnerAngle = this._coneInnerAngle;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Sound.prototype, "directionalConeOuterAngle", {
        /**
         * Gets or sets the outer angle for the directional cone.
         */
        get: function () {
            return this._coneOuterAngle;
        },
        /**
         * Gets or sets the outer angle for the directional cone.
         */
        set: function (value) {
            if (value != this._coneOuterAngle) {
                if (value < this._coneInnerAngle) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("directionalConeOuterAngle: outer angle of the cone must be superior or equal to the inner angle.");
                    return;
                }
                this._coneOuterAngle = value;
                if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this.spatialSound && this._soundPanner) {
                    this._soundPanner.coneOuterAngle = this._coneOuterAngle;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets the position of the emitter if spatial sound is enabled
     * @param newPosition Defines the new posisiton
     */
    Sound.prototype.setPosition = function (newPosition) {
        this._position = newPosition;
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this.spatialSound && this._soundPanner && !isNaN(this._position.x) && !isNaN(this._position.y) && !isNaN(this._position.z)) {
            this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
        }
    };
    /**
     * Sets the local direction of the emitter if spatial sound is enabled
     * @param newLocalDirection Defines the new local direction
     */
    Sound.prototype.setLocalDirectionToMesh = function (newLocalDirection) {
        this._localDirection = newLocalDirection;
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this._connectedTransformNode && this.isPlaying) {
            this._updateDirection();
        }
    };
    Sound.prototype._updateDirection = function () {
        if (!this._connectedTransformNode || !this._soundPanner) {
            return;
        }
        var mat = this._connectedTransformNode.getWorldMatrix();
        var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformNormal(this._localDirection, mat);
        direction.normalize();
        this._soundPanner.setOrientation(direction.x, direction.y, direction.z);
    };
    /** @hidden */
    Sound.prototype.updateDistanceFromListener = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this._connectedTransformNode && this.useCustomAttenuation && this._soundGain && this._scene.activeCamera) {
            var distance = this._connectedTransformNode.getDistanceToCamera(this._scene.activeCamera);
            this._soundGain.gain.value = this._customAttenuationFunction(this._volume, distance, this.maxDistance, this.refDistance, this.rolloffFactor);
        }
    };
    /**
     * Sets a new custom attenuation function for the sound.
     * @param callback Defines the function used for the attenuation
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-your-own-custom-attenuation-function
     */
    Sound.prototype.setAttenuationFunction = function (callback) {
        this._customAttenuationFunction = callback;
    };
    /**
    * Play the sound
    * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
    * @param offset (optional) Start the sound at a specific time in seconds
    * @param length (optional) Sound duration (in seconds)
    */
    Sound.prototype.play = function (time, offset, length) {
        var _this = this;
        if (this._isReadyToPlay && this._scene.audioEnabled && _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
            try {
                if (this._startOffset < 0) {
                    time = -this._startOffset;
                    this._startOffset = 0;
                }
                var startTime = time ? _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime + time : _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime;
                if (!this._soundSource || !this._streamingSource) {
                    if (this.spatialSound && this._soundPanner) {
                        if (!isNaN(this._position.x) && !isNaN(this._position.y) && !isNaN(this._position.z)) {
                            this._soundPanner.setPosition(this._position.x, this._position.y, this._position.z);
                        }
                        if (this._isDirectional) {
                            this._soundPanner.coneInnerAngle = this._coneInnerAngle;
                            this._soundPanner.coneOuterAngle = this._coneOuterAngle;
                            this._soundPanner.coneOuterGain = this._coneOuterGain;
                            if (this._connectedTransformNode) {
                                this._updateDirection();
                            }
                            else {
                                this._soundPanner.setOrientation(this._localDirection.x, this._localDirection.y, this._localDirection.z);
                            }
                        }
                    }
                }
                if (this._streaming) {
                    if (!this._streamingSource) {
                        this._streamingSource = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.createMediaElementSource(this._htmlAudioElement);
                        this._htmlAudioElement.onended = function () { _this._onended(); };
                        this._htmlAudioElement.playbackRate = this._playbackRate;
                    }
                    this._streamingSource.disconnect();
                    this._streamingSource.connect(this._inputAudioNode);
                    if (this._htmlAudioElement) {
                        // required to manage properly the new suspended default state of Chrome
                        // When the option 'streaming: true' is used, we need first to wait for
                        // the audio engine to be unlocked by a user gesture before trying to play
                        // an HTML Audio elememt
                        var tryToPlay = function () {
                            if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.unlocked) {
                                var playPromise = _this._htmlAudioElement.play();
                                // In browsers that don’t yet support this functionality,
                                // playPromise won’t be defined.
                                if (playPromise !== undefined) {
                                    playPromise.catch(function (error) {
                                        // Automatic playback failed.
                                        // Waiting for the audio engine to be unlocked by user click on unmute
                                        _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.lock();
                                        if (_this.loop || _this.autoplay) {
                                            _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.onAudioUnlockedObservable.addOnce(function () { tryToPlay(); });
                                        }
                                    });
                                }
                            }
                            else {
                                if (_this.loop || _this.autoplay) {
                                    _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.onAudioUnlockedObservable.addOnce(function () { tryToPlay(); });
                                }
                            }
                        };
                        tryToPlay();
                    }
                }
                else {
                    var tryToPlay = function () {
                        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
                            length = length || _this._length;
                            offset = offset || _this._offset;
                            _this._soundSource = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.createBufferSource();
                            _this._soundSource.buffer = _this._audioBuffer;
                            _this._soundSource.connect(_this._inputAudioNode);
                            _this._soundSource.loop = _this.loop;
                            if (offset !== undefined) {
                                _this._soundSource.loopStart = offset;
                            }
                            if (length !== undefined) {
                                _this._soundSource.loopEnd = (offset | 0) + length;
                            }
                            _this._soundSource.playbackRate.value = _this._playbackRate;
                            _this._soundSource.onended = function () { _this._onended(); };
                            startTime = time ? _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime + time : _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime;
                            var actualOffset = _this.isPaused ? _this._startOffset % _this._soundSource.buffer.duration : offset ? offset : 0;
                            _this._soundSource.start(startTime, actualOffset, _this.loop ? undefined : length);
                        }
                    };
                    if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.state === "suspended") {
                        // Wait a bit for FF as context seems late to be ready.
                        setTimeout(function () {
                            if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.state === "suspended") {
                                // Automatic playback failed.
                                // Waiting for the audio engine to be unlocked by user click on unmute
                                _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.lock();
                                if (_this.loop || _this.autoplay) {
                                    _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.onAudioUnlockedObservable.addOnce(function () { tryToPlay(); });
                                }
                            }
                            else {
                                tryToPlay();
                            }
                        }, 500);
                    }
                    else {
                        tryToPlay();
                    }
                }
                this._startTime = startTime;
                this.isPlaying = true;
                this.isPaused = false;
            }
            catch (ex) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Error while trying to play audio: " + this.name + ", " + ex.message);
            }
        }
    };
    Sound.prototype._onended = function () {
        this.isPlaying = false;
        if (this.onended) {
            this.onended();
        }
        this.onEndedObservable.notifyObservers(this);
    };
    /**
    * Stop the sound
    * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
    */
    Sound.prototype.stop = function (time) {
        var _this = this;
        if (this.isPlaying) {
            if (this._streaming) {
                if (this._htmlAudioElement) {
                    this._htmlAudioElement.pause();
                    // Test needed for Firefox or it will generate an Invalid State Error
                    if (this._htmlAudioElement.currentTime > 0) {
                        this._htmlAudioElement.currentTime = 0;
                    }
                }
                else {
                    this._streamingSource.disconnect();
                }
                this.isPlaying = false;
            }
            else if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext && this._soundSource) {
                var stopTime = time ? _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime + time : _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime;
                this._soundSource.stop(stopTime);
                this._soundSource.onended = function () { _this.isPlaying = false; };
                if (!this.isPaused) {
                    this._startOffset = 0;
                }
            }
        }
    };
    /**
     * Put the sound in pause
     */
    Sound.prototype.pause = function () {
        if (this.isPlaying) {
            this.isPaused = true;
            if (this._streaming) {
                if (this._htmlAudioElement) {
                    this._htmlAudioElement.pause();
                }
                else {
                    this._streamingSource.disconnect();
                }
            }
            else if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
                this.stop(0);
                this._startOffset += _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime - this._startTime;
            }
        }
    };
    /**
     * Sets a dedicated volume for this sounds
     * @param newVolume Define the new volume of the sound
     * @param time Define time for gradual change to new volume
     */
    Sound.prototype.setVolume = function (newVolume, time) {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this._soundGain) {
            if (time && _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext) {
                this._soundGain.gain.cancelScheduledValues(_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime);
                this._soundGain.gain.setValueAtTime(this._soundGain.gain.value, _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime);
                this._soundGain.gain.linearRampToValueAtTime(newVolume, _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.audioContext.currentTime + time);
            }
            else {
                this._soundGain.gain.value = newVolume;
            }
        }
        this._volume = newVolume;
    };
    /**
     * Set the sound play back rate
     * @param newPlaybackRate Define the playback rate the sound should be played at
     */
    Sound.prototype.setPlaybackRate = function (newPlaybackRate) {
        this._playbackRate = newPlaybackRate;
        if (this.isPlaying) {
            if (this._streaming && this._htmlAudioElement) {
                this._htmlAudioElement.playbackRate = this._playbackRate;
            }
            else if (this._soundSource) {
                this._soundSource.playbackRate.value = this._playbackRate;
            }
        }
    };
    /**
     * Gets the volume of the sound.
     * @returns the volume of the sound
     */
    Sound.prototype.getVolume = function () {
        return this._volume;
    };
    /**
     * Attach the sound to a dedicated mesh
     * @param transformNode The transform node to connect the sound with
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#attaching-a-sound-to-a-mesh
     */
    Sound.prototype.attachToMesh = function (transformNode) {
        var _this = this;
        if (this._connectedTransformNode && this._registerFunc) {
            this._connectedTransformNode.unregisterAfterWorldMatrixUpdate(this._registerFunc);
            this._registerFunc = null;
        }
        this._connectedTransformNode = transformNode;
        if (!this.spatialSound) {
            this.spatialSound = true;
            this._createSpatialParameters();
            if (this.isPlaying && this.loop) {
                this.stop();
                this.play(0, this._offset, this._length);
            }
        }
        this._onRegisterAfterWorldMatrixUpdate(this._connectedTransformNode);
        this._registerFunc = function (transformNode) { return _this._onRegisterAfterWorldMatrixUpdate(transformNode); };
        this._connectedTransformNode.registerAfterWorldMatrixUpdate(this._registerFunc);
    };
    /**
     * Detach the sound from the previously attached mesh
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#attaching-a-sound-to-a-mesh
     */
    Sound.prototype.detachFromMesh = function () {
        if (this._connectedTransformNode && this._registerFunc) {
            this._connectedTransformNode.unregisterAfterWorldMatrixUpdate(this._registerFunc);
            this._registerFunc = null;
            this._connectedTransformNode = null;
        }
    };
    Sound.prototype._onRegisterAfterWorldMatrixUpdate = function (node) {
        if (!node.getBoundingInfo) {
            return;
        }
        var mesh = node;
        if (this._positionInEmitterSpace) {
            mesh.worldMatrixFromCache.invertToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Matrix[0]);
            this.setPosition(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Matrix[0].getTranslation());
        }
        else {
            var boundingInfo = mesh.getBoundingInfo();
            this.setPosition(boundingInfo.boundingSphere.centerWorld);
        }
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].audioEngine.canUseWebAudio && this._isDirectional && this.isPlaying) {
            this._updateDirection();
        }
    };
    /**
     * Clone the current sound in the scene.
     * @returns the new sound clone
     */
    Sound.prototype.clone = function () {
        var _this = this;
        if (!this._streaming) {
            var setBufferAndRun = function () {
                if (_this._isReadyToPlay) {
                    clonedSound._audioBuffer = _this.getAudioBuffer();
                    clonedSound._isReadyToPlay = true;
                    if (clonedSound.autoplay) {
                        clonedSound.play(0, _this._offset, _this._length);
                    }
                }
                else {
                    window.setTimeout(setBufferAndRun, 300);
                }
            };
            var currentOptions = {
                autoplay: this.autoplay, loop: this.loop,
                volume: this._volume, spatialSound: this.spatialSound, maxDistance: this.maxDistance,
                useCustomAttenuation: this.useCustomAttenuation, rolloffFactor: this.rolloffFactor,
                refDistance: this.refDistance, distanceModel: this.distanceModel
            };
            var clonedSound = new Sound(this.name + "_cloned", new ArrayBuffer(0), this._scene, null, currentOptions);
            if (this.useCustomAttenuation) {
                clonedSound.setAttenuationFunction(this._customAttenuationFunction);
            }
            clonedSound.setPosition(this._position);
            clonedSound.setPlaybackRate(this._playbackRate);
            setBufferAndRun();
            return clonedSound;
        }
        // Can't clone a streaming sound
        else {
            return null;
        }
    };
    /**
     * Gets the current underlying audio buffer containing the data
     * @returns the audio buffer
     */
    Sound.prototype.getAudioBuffer = function () {
        return this._audioBuffer;
    };
    /**
     * Serializes the Sound in a JSON representation
     * @returns the JSON representation of the sound
     */
    Sound.prototype.serialize = function () {
        var serializationObject = {
            name: this.name,
            url: this.name,
            autoplay: this.autoplay,
            loop: this.loop,
            volume: this._volume,
            spatialSound: this.spatialSound,
            maxDistance: this.maxDistance,
            rolloffFactor: this.rolloffFactor,
            refDistance: this.refDistance,
            distanceModel: this.distanceModel,
            playbackRate: this._playbackRate,
            panningModel: this._panningModel,
            soundTrackId: this.soundTrackId
        };
        if (this.spatialSound) {
            if (this._connectedTransformNode) {
                serializationObject.connectedMeshId = this._connectedTransformNode.id;
            }
            serializationObject.position = this._position.asArray();
            serializationObject.refDistance = this.refDistance;
            serializationObject.distanceModel = this.distanceModel;
            serializationObject.isDirectional = this._isDirectional;
            serializationObject.localDirectionToMesh = this._localDirection.asArray();
            serializationObject.coneInnerAngle = this._coneInnerAngle;
            serializationObject.coneOuterAngle = this._coneOuterAngle;
            serializationObject.coneOuterGain = this._coneOuterGain;
        }
        return serializationObject;
    };
    /**
     * Parse a JSON representation of a sound to innstantiate in a given scene
     * @param parsedSound Define the JSON representation of the sound (usually coming from the serialize method)
     * @param scene Define the scene the new parsed sound should be created in
     * @param rootUrl Define the rooturl of the load in case we need to fetch relative dependencies
     * @param sourceSound Define a cound place holder if do not need to instantiate a new one
     * @returns the newly parsed sound
     */
    Sound.Parse = function (parsedSound, scene, rootUrl, sourceSound) {
        var soundName = parsedSound.name;
        var soundUrl;
        if (parsedSound.url) {
            soundUrl = rootUrl + parsedSound.url;
        }
        else {
            soundUrl = rootUrl + soundName;
        }
        var options = {
            autoplay: parsedSound.autoplay, loop: parsedSound.loop, volume: parsedSound.volume,
            spatialSound: parsedSound.spatialSound, maxDistance: parsedSound.maxDistance,
            rolloffFactor: parsedSound.rolloffFactor,
            refDistance: parsedSound.refDistance,
            distanceModel: parsedSound.distanceModel,
            playbackRate: parsedSound.playbackRate
        };
        var newSound;
        if (!sourceSound) {
            newSound = new Sound(soundName, soundUrl, scene, function () { scene._removePendingData(newSound); }, options);
            scene._addPendingData(newSound);
        }
        else {
            var setBufferAndRun = function () {
                if (sourceSound._isReadyToPlay) {
                    newSound._audioBuffer = sourceSound.getAudioBuffer();
                    newSound._isReadyToPlay = true;
                    if (newSound.autoplay) {
                        newSound.play(0, newSound._offset, newSound._length);
                    }
                }
                else {
                    window.setTimeout(setBufferAndRun, 300);
                }
            };
            newSound = new Sound(soundName, new ArrayBuffer(0), scene, null, options);
            setBufferAndRun();
        }
        if (parsedSound.position) {
            var soundPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].FromArray(parsedSound.position);
            newSound.setPosition(soundPosition);
        }
        if (parsedSound.isDirectional) {
            newSound.setDirectionalCone(parsedSound.coneInnerAngle || 360, parsedSound.coneOuterAngle || 360, parsedSound.coneOuterGain || 0);
            if (parsedSound.localDirectionToMesh) {
                var localDirectionToMesh = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].FromArray(parsedSound.localDirectionToMesh);
                newSound.setLocalDirectionToMesh(localDirectionToMesh);
            }
        }
        if (parsedSound.connectedMeshId) {
            var connectedMesh = scene.getMeshByID(parsedSound.connectedMeshId);
            if (connectedMesh) {
                newSound.attachToMesh(connectedMesh);
            }
        }
        return newSound;
    };
    /** @hidden */
    Sound._SceneComponentInitialization = function (_) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_5__["_DevTools"].WarnImport("AudioSceneComponent");
    };
    return Sound;
}());



/***/ }),

/***/ "./Audio/soundTrack.ts":
/*!*****************************!*\
  !*** ./Audio/soundTrack.ts ***!
  \*****************************/
/*! exports provided: SoundTrack */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SoundTrack", function() { return SoundTrack; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");

/**
 * It could be useful to isolate your music & sounds on several tracks to better manage volume on a grouped instance of sounds.
 * It will be also used in a future release to apply effects on a specific track.
 * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#using-sound-tracks
 */
var SoundTrack = /** @class */ (function () {
    /**
     * Creates a new sound track.
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#using-sound-tracks
     * @param scene Define the scene the sound track belongs to
     * @param options
     */
    function SoundTrack(scene, options) {
        if (options === void 0) { options = {}; }
        /**
         * The unique identifier of the sound track in the scene.
         */
        this.id = -1;
        this._isMainTrack = false;
        this._isInitialized = false;
        this._scene = scene;
        this.soundCollection = new Array();
        this._options = options;
        if (!this._isMainTrack && this._scene.soundTracks) {
            this._scene.soundTracks.push(this);
            this.id = this._scene.soundTracks.length - 1;
        }
    }
    SoundTrack.prototype._initializeSoundTrackAudioGraph = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio && _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.audioContext) {
            this._outputAudioNode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.audioContext.createGain();
            this._outputAudioNode.connect(_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.masterGain);
            if (this._options) {
                if (this._options.volume) {
                    this._outputAudioNode.gain.value = this._options.volume;
                }
                if (this._options.mainTrack) {
                    this._isMainTrack = this._options.mainTrack;
                }
            }
            this._isInitialized = true;
        }
    };
    /**
     * Release the sound track and its associated resources
     */
    SoundTrack.prototype.dispose = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine && _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio) {
            if (this._connectedAnalyser) {
                this._connectedAnalyser.stopDebugCanvas();
            }
            while (this.soundCollection.length) {
                this.soundCollection[0].dispose();
            }
            if (this._outputAudioNode) {
                this._outputAudioNode.disconnect();
            }
            this._outputAudioNode = null;
        }
    };
    /**
     * Adds a sound to this sound track
     * @param sound define the cound to add
     * @ignoreNaming
     */
    SoundTrack.prototype.AddSound = function (sound) {
        if (!this._isInitialized) {
            this._initializeSoundTrackAudioGraph();
        }
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio && this._outputAudioNode) {
            sound.connectToSoundTrackAudioNode(this._outputAudioNode);
        }
        if (sound.soundTrackId) {
            if (sound.soundTrackId === -1) {
                this._scene.mainSoundTrack.RemoveSound(sound);
            }
            else if (this._scene.soundTracks) {
                this._scene.soundTracks[sound.soundTrackId].RemoveSound(sound);
            }
        }
        this.soundCollection.push(sound);
        sound.soundTrackId = this.id;
    };
    /**
     * Removes a sound to this sound track
     * @param sound define the cound to remove
     * @ignoreNaming
     */
    SoundTrack.prototype.RemoveSound = function (sound) {
        var index = this.soundCollection.indexOf(sound);
        if (index !== -1) {
            this.soundCollection.splice(index, 1);
        }
    };
    /**
     * Set a global volume for the full sound track.
     * @param newVolume Define the new volume of the sound track
     */
    SoundTrack.prototype.setVolume = function (newVolume) {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio && this._outputAudioNode) {
            this._outputAudioNode.gain.value = newVolume;
        }
    };
    /**
     * Switch the panning model to HRTF:
     * Renders a stereo output of higher quality than equalpower — it uses a convolution with measured impulse responses from human subjects.
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
     */
    SoundTrack.prototype.switchPanningModelToHRTF = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio) {
            for (var i = 0; i < this.soundCollection.length; i++) {
                this.soundCollection[i].switchPanningModelToHRTF();
            }
        }
    };
    /**
     * Switch the panning model to Equal Power:
     * Represents the equal-power panning algorithm, generally regarded as simple and efficient. equalpower is the default value.
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#creating-a-spatial-3d-sound
     */
    SoundTrack.prototype.switchPanningModelToEqualPower = function () {
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio) {
            for (var i = 0; i < this.soundCollection.length; i++) {
                this.soundCollection[i].switchPanningModelToEqualPower();
            }
        }
    };
    /**
     * Connect the sound track to an audio analyser allowing some amazing
     * synchornization between the sounds/music and your visualization (VuMeter for instance).
     * @see http://doc.babylonjs.com/how_to/playing_sounds_and_music#using-the-analyser
     * @param analyser The analyser to connect to the engine
     */
    SoundTrack.prototype.connectToAnalyser = function (analyser) {
        if (this._connectedAnalyser) {
            this._connectedAnalyser.stopDebugCanvas();
        }
        this._connectedAnalyser = analyser;
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.canUseWebAudio && this._outputAudioNode) {
            this._outputAudioNode.disconnect();
            this._connectedAnalyser.connectAudioNodes(this._outputAudioNode, _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].audioEngine.masterGain);
        }
    };
    return SoundTrack;
}());



/***/ }),

/***/ "./Audio/weightedsound.ts":
/*!********************************!*\
  !*** ./Audio/weightedsound.ts ***!
  \********************************/
/*! exports provided: WeightedSound */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WeightedSound", function() { return WeightedSound; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");

/**
 * Wraps one or more Sound objects and selects one with random weight for playback.
 */
var WeightedSound = /** @class */ (function () {
    /**
     * Creates a new WeightedSound from the list of sounds given.
     * @param loop When true a Sound will be selected and played when the current playing Sound completes.
     * @param sounds Array of Sounds that will be selected from.
     * @param weights Array of number values for selection weights; length must equal sounds, values will be normalized to 1
     */
    function WeightedSound(loop, sounds, weights) {
        var _this = this;
        /** When true a Sound will be selected and played when the current playing Sound completes. */
        this.loop = false;
        this._coneInnerAngle = 360;
        this._coneOuterAngle = 360;
        this._volume = 1;
        /** A Sound is currently playing. */
        this.isPlaying = false;
        /** A Sound is currently paused. */
        this.isPaused = false;
        this._sounds = [];
        this._weights = [];
        if (sounds.length !== weights.length) {
            throw new Error('Sounds length does not equal weights length');
        }
        this.loop = loop;
        this._weights = weights;
        // Normalize the weights
        var weightSum = 0;
        for (var _i = 0, weights_1 = weights; _i < weights_1.length; _i++) {
            var weight = weights_1[_i];
            weightSum += weight;
        }
        var invWeightSum = weightSum > 0 ? 1 / weightSum : 0;
        for (var i = 0; i < this._weights.length; i++) {
            this._weights[i] *= invWeightSum;
        }
        this._sounds = sounds;
        for (var _a = 0, _b = this._sounds; _a < _b.length; _a++) {
            var sound = _b[_a];
            sound.onEndedObservable.add(function () { _this._onended(); });
        }
    }
    Object.defineProperty(WeightedSound.prototype, "directionalConeInnerAngle", {
        /**
         * The size of cone in degrees for a directional sound in which there will be no attenuation.
         */
        get: function () {
            return this._coneInnerAngle;
        },
        /**
         * The size of cone in degress for a directional sound in which there will be no attenuation.
         */
        set: function (value) {
            if (value !== this._coneInnerAngle) {
                if (this._coneOuterAngle < value) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("directionalConeInnerAngle: outer angle of the cone must be superior or equal to the inner angle.");
                    return;
                }
                this._coneInnerAngle = value;
                for (var _i = 0, _a = this._sounds; _i < _a.length; _i++) {
                    var sound = _a[_i];
                    sound.directionalConeInnerAngle = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WeightedSound.prototype, "directionalConeOuterAngle", {
        /**
         * Size of cone in degrees for a directional sound outside of which there will be no sound.
         * Listener angles between innerAngle and outerAngle will falloff linearly.
         */
        get: function () {
            return this._coneOuterAngle;
        },
        /**
         * Size of cone in degrees for a directional sound outside of which there will be no sound.
         * Listener angles between innerAngle and outerAngle will falloff linearly.
         */
        set: function (value) {
            if (value !== this._coneOuterAngle) {
                if (value < this._coneInnerAngle) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("directionalConeOuterAngle: outer angle of the cone must be superior or equal to the inner angle.");
                    return;
                }
                this._coneOuterAngle = value;
                for (var _i = 0, _a = this._sounds; _i < _a.length; _i++) {
                    var sound = _a[_i];
                    sound.directionalConeOuterAngle = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WeightedSound.prototype, "volume", {
        /**
         * Playback volume.
         */
        get: function () {
            return this._volume;
        },
        /**
         * Playback volume.
         */
        set: function (value) {
            if (value !== this._volume) {
                for (var _i = 0, _a = this._sounds; _i < _a.length; _i++) {
                    var sound = _a[_i];
                    sound.setVolume(value);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    WeightedSound.prototype._onended = function () {
        if (this._currentIndex !== undefined) {
            this._sounds[this._currentIndex].autoplay = false;
        }
        if (this.loop && this.isPlaying) {
            this.play();
        }
        else {
            this.isPlaying = false;
        }
    };
    /**
     * Suspend playback
     */
    WeightedSound.prototype.pause = function () {
        this.isPaused = true;
        if (this._currentIndex !== undefined) {
            this._sounds[this._currentIndex].pause();
        }
    };
    /**
     * Stop playback
     */
    WeightedSound.prototype.stop = function () {
        this.isPlaying = false;
        if (this._currentIndex !== undefined) {
            this._sounds[this._currentIndex].stop();
        }
    };
    /**
     * Start playback.
     * @param startOffset Position the clip head at a specific time in seconds.
     */
    WeightedSound.prototype.play = function (startOffset) {
        if (!this.isPaused) {
            this.stop();
            var randomValue = Math.random();
            var total = 0;
            for (var i = 0; i < this._weights.length; i++) {
                total += this._weights[i];
                if (randomValue <= total) {
                    this._currentIndex = i;
                    break;
                }
            }
        }
        var sound = this._sounds[this._currentIndex];
        if (sound.isReady()) {
            sound.play(0, this.isPaused ? undefined : startOffset);
        }
        else {
            sound.autoplay = true;
        }
        this.isPlaying = true;
        this.isPaused = false;
    };
    return WeightedSound;
}());



/***/ }),

/***/ "./Behaviors/Cameras/autoRotationBehavior.ts":
/*!***************************************************!*\
  !*** ./Behaviors/Cameras/autoRotationBehavior.ts ***!
  \***************************************************/
/*! exports provided: AutoRotationBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AutoRotationBehavior", function() { return AutoRotationBehavior; });
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/precisionDate */ "./Misc/precisionDate.ts");


/**
 * The autoRotation behavior (AutoRotationBehavior) is designed to create a smooth rotation of an ArcRotateCamera when there is no user interaction.
 * @see http://doc.babylonjs.com/how_to/camera_behaviors#autorotation-behavior
 */
var AutoRotationBehavior = /** @class */ (function () {
    function AutoRotationBehavior() {
        this._zoomStopsAnimation = false;
        this._idleRotationSpeed = 0.05;
        this._idleRotationWaitTime = 2000;
        this._idleRotationSpinupTime = 2000;
        this._isPointerDown = false;
        this._lastFrameTime = null;
        this._lastInteractionTime = -Infinity;
        this._cameraRotationSpeed = 0;
        this._lastFrameRadius = 0;
    }
    Object.defineProperty(AutoRotationBehavior.prototype, "name", {
        /**
         * Gets the name of the behavior.
         */
        get: function () {
            return "AutoRotation";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AutoRotationBehavior.prototype, "zoomStopsAnimation", {
        /**
        * Gets the flag that indicates if user zooming should stop animation.
        */
        get: function () {
            return this._zoomStopsAnimation;
        },
        /**
        * Sets the flag that indicates if user zooming should stop animation.
        */
        set: function (flag) {
            this._zoomStopsAnimation = flag;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AutoRotationBehavior.prototype, "idleRotationSpeed", {
        /**
        * Gets the default speed at which the camera rotates around the model.
        */
        get: function () {
            return this._idleRotationSpeed;
        },
        /**
        * Sets the default speed at which the camera rotates around the model.
        */
        set: function (speed) {
            this._idleRotationSpeed = speed;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AutoRotationBehavior.prototype, "idleRotationWaitTime", {
        /**
        * Gets the time (milliseconds) to wait after user interaction before the camera starts rotating.
        */
        get: function () {
            return this._idleRotationWaitTime;
        },
        /**
        * Sets the time (in milliseconds) to wait after user interaction before the camera starts rotating.
        */
        set: function (time) {
            this._idleRotationWaitTime = time;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AutoRotationBehavior.prototype, "idleRotationSpinupTime", {
        /**
        * Gets the time (milliseconds) to take to spin up to the full idle rotation speed.
        */
        get: function () {
            return this._idleRotationSpinupTime;
        },
        /**
        * Sets the time (milliseconds) to take to spin up to the full idle rotation speed.
        */
        set: function (time) {
            this._idleRotationSpinupTime = time;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AutoRotationBehavior.prototype, "rotationInProgress", {
        /**
         * Gets a value indicating if the camera is currently rotating because of this behavior
         */
        get: function () {
            return Math.abs(this._cameraRotationSpeed) > 0;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Initializes the behavior.
     */
    AutoRotationBehavior.prototype.init = function () {
        // Do notihng
    };
    /**
     * Attaches the behavior to its arc rotate camera.
     * @param camera Defines the camera to attach the behavior to
     */
    AutoRotationBehavior.prototype.attach = function (camera) {
        var _this = this;
        this._attachedCamera = camera;
        var scene = this._attachedCamera.getScene();
        this._onPrePointerObservableObserver = scene.onPrePointerObservable.add(function (pointerInfoPre) {
            if (pointerInfoPre.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOWN) {
                _this._isPointerDown = true;
                return;
            }
            if (pointerInfoPre.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERUP) {
                _this._isPointerDown = false;
            }
        });
        this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(function () {
            var now = _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_1__["PrecisionDate"].Now;
            var dt = 0;
            if (_this._lastFrameTime != null) {
                dt = now - _this._lastFrameTime;
            }
            _this._lastFrameTime = now;
            // Stop the animation if there is user interaction and the animation should stop for this interaction
            _this._applyUserInteraction();
            var timeToRotation = now - _this._lastInteractionTime - _this._idleRotationWaitTime;
            var scale = Math.max(Math.min(timeToRotation / (_this._idleRotationSpinupTime), 1), 0);
            _this._cameraRotationSpeed = _this._idleRotationSpeed * scale;
            // Step camera rotation by rotation speed
            if (_this._attachedCamera) {
                _this._attachedCamera.alpha -= _this._cameraRotationSpeed * (dt / 1000);
            }
        });
    };
    /**
     * Detaches the behavior from its current arc rotate camera.
     */
    AutoRotationBehavior.prototype.detach = function () {
        if (!this._attachedCamera) {
            return;
        }
        var scene = this._attachedCamera.getScene();
        if (this._onPrePointerObservableObserver) {
            scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
        }
        this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
        this._attachedCamera = null;
    };
    /**
     * Returns true if user is scrolling.
     * @return true if user is scrolling.
     */
    AutoRotationBehavior.prototype._userIsZooming = function () {
        if (!this._attachedCamera) {
            return false;
        }
        return this._attachedCamera.inertialRadiusOffset !== 0;
    };
    AutoRotationBehavior.prototype._shouldAnimationStopForInteraction = function () {
        if (!this._attachedCamera) {
            return false;
        }
        var zoomHasHitLimit = false;
        if (this._lastFrameRadius === this._attachedCamera.radius && this._attachedCamera.inertialRadiusOffset !== 0) {
            zoomHasHitLimit = true;
        }
        // Update the record of previous radius - works as an approx. indicator of hitting radius limits
        this._lastFrameRadius = this._attachedCamera.radius;
        return this._zoomStopsAnimation ? zoomHasHitLimit : this._userIsZooming();
    };
    /**
     *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
     */
    AutoRotationBehavior.prototype._applyUserInteraction = function () {
        if (this._userIsMoving() && !this._shouldAnimationStopForInteraction()) {
            this._lastInteractionTime = _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_1__["PrecisionDate"].Now;
        }
    };
    // Tools
    AutoRotationBehavior.prototype._userIsMoving = function () {
        if (!this._attachedCamera) {
            return false;
        }
        return this._attachedCamera.inertialAlphaOffset !== 0 ||
            this._attachedCamera.inertialBetaOffset !== 0 ||
            this._attachedCamera.inertialRadiusOffset !== 0 ||
            this._attachedCamera.inertialPanningX !== 0 ||
            this._attachedCamera.inertialPanningY !== 0 ||
            this._isPointerDown;
    };
    return AutoRotationBehavior;
}());



/***/ }),

/***/ "./Behaviors/Cameras/bouncingBehavior.ts":
/*!***********************************************!*\
  !*** ./Behaviors/Cameras/bouncingBehavior.ts ***!
  \***********************************************/
/*! exports provided: BouncingBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BouncingBehavior", function() { return BouncingBehavior; });
/* harmony import */ var _Animations_easing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Animations/easing */ "./Animations/easing.ts");
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Animations/animation */ "./Animations/animation.ts");


/**
 * Add a bouncing effect to an ArcRotateCamera when reaching a specified minimum and maximum radius
 * @see http://doc.babylonjs.com/how_to/camera_behaviors#bouncing-behavior
 */
var BouncingBehavior = /** @class */ (function () {
    function BouncingBehavior() {
        /**
         * The duration of the animation, in milliseconds
         */
        this.transitionDuration = 450;
        /**
         * Length of the distance animated by the transition when lower radius is reached
         */
        this.lowerRadiusTransitionRange = 2;
        /**
         * Length of the distance animated by the transition when upper radius is reached
         */
        this.upperRadiusTransitionRange = -2;
        this._autoTransitionRange = false;
        // Animations
        this._radiusIsAnimating = false;
        this._radiusBounceTransition = null;
        this._animatables = new Array();
    }
    Object.defineProperty(BouncingBehavior.prototype, "name", {
        /**
         * Gets the name of the behavior.
         */
        get: function () {
            return "Bouncing";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BouncingBehavior.prototype, "autoTransitionRange", {
        /**
         * Gets a value indicating if the lowerRadiusTransitionRange and upperRadiusTransitionRange are defined automatically
         */
        get: function () {
            return this._autoTransitionRange;
        },
        /**
         * Sets a value indicating if the lowerRadiusTransitionRange and upperRadiusTransitionRange are defined automatically
         * Transition ranges will be set to 5% of the bounding box diagonal in world space
         */
        set: function (value) {
            var _this = this;
            if (this._autoTransitionRange === value) {
                return;
            }
            this._autoTransitionRange = value;
            var camera = this._attachedCamera;
            if (!camera) {
                return;
            }
            if (value) {
                this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add(function (mesh) {
                    if (!mesh) {
                        return;
                    }
                    mesh.computeWorldMatrix(true);
                    var diagonal = mesh.getBoundingInfo().diagonalLength;
                    _this.lowerRadiusTransitionRange = diagonal * 0.05;
                    _this.upperRadiusTransitionRange = diagonal * 0.05;
                });
            }
            else if (this._onMeshTargetChangedObserver) {
                camera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Initializes the behavior.
     */
    BouncingBehavior.prototype.init = function () {
        // Do notihng
    };
    /**
     * Attaches the behavior to its arc rotate camera.
     * @param camera Defines the camera to attach the behavior to
     */
    BouncingBehavior.prototype.attach = function (camera) {
        var _this = this;
        this._attachedCamera = camera;
        this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(function () {
            if (!_this._attachedCamera) {
                return;
            }
            // Add the bounce animation to the lower radius limit
            if (_this._isRadiusAtLimit(_this._attachedCamera.lowerRadiusLimit)) {
                _this._applyBoundRadiusAnimation(_this.lowerRadiusTransitionRange);
            }
            // Add the bounce animation to the upper radius limit
            if (_this._isRadiusAtLimit(_this._attachedCamera.upperRadiusLimit)) {
                _this._applyBoundRadiusAnimation(_this.upperRadiusTransitionRange);
            }
        });
    };
    /**
     * Detaches the behavior from its current arc rotate camera.
     */
    BouncingBehavior.prototype.detach = function () {
        if (!this._attachedCamera) {
            return;
        }
        if (this._onAfterCheckInputsObserver) {
            this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
        }
        if (this._onMeshTargetChangedObserver) {
            this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
        }
        this._attachedCamera = null;
    };
    /**
     * Checks if the camera radius is at the specified limit. Takes into account animation locks.
     * @param radiusLimit The limit to check against.
     * @return Bool to indicate if at limit.
     */
    BouncingBehavior.prototype._isRadiusAtLimit = function (radiusLimit) {
        if (!this._attachedCamera) {
            return false;
        }
        if (this._attachedCamera.radius === radiusLimit && !this._radiusIsAnimating) {
            return true;
        }
        return false;
    };
    /**
     * Applies an animation to the radius of the camera, extending by the radiusDelta.
     * @param radiusDelta The delta by which to animate to. Can be negative.
     */
    BouncingBehavior.prototype._applyBoundRadiusAnimation = function (radiusDelta) {
        var _this = this;
        if (!this._attachedCamera) {
            return;
        }
        if (!this._radiusBounceTransition) {
            BouncingBehavior.EasingFunction.setEasingMode(BouncingBehavior.EasingMode);
            this._radiusBounceTransition = _Animations_animation__WEBPACK_IMPORTED_MODULE_1__["Animation"].CreateAnimation("radius", _Animations_animation__WEBPACK_IMPORTED_MODULE_1__["Animation"].ANIMATIONTYPE_FLOAT, 60, BouncingBehavior.EasingFunction);
        }
        // Prevent zoom until bounce has completed
        this._cachedWheelPrecision = this._attachedCamera.wheelPrecision;
        this._attachedCamera.wheelPrecision = Infinity;
        this._attachedCamera.inertialRadiusOffset = 0;
        // Animate to the radius limit
        this.stopAllAnimations();
        this._radiusIsAnimating = true;
        var animatable = _Animations_animation__WEBPACK_IMPORTED_MODULE_1__["Animation"].TransitionTo("radius", this._attachedCamera.radius + radiusDelta, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusBounceTransition, this.transitionDuration, function () { return _this._clearAnimationLocks(); });
        if (animatable) {
            this._animatables.push(animatable);
        }
    };
    /**
     * Removes all animation locks. Allows new animations to be added to any of the camera properties.
     */
    BouncingBehavior.prototype._clearAnimationLocks = function () {
        this._radiusIsAnimating = false;
        if (this._attachedCamera) {
            this._attachedCamera.wheelPrecision = this._cachedWheelPrecision;
        }
    };
    /**
     * Stops and removes all animations that have been applied to the camera
     */
    BouncingBehavior.prototype.stopAllAnimations = function () {
        if (this._attachedCamera) {
            this._attachedCamera.animations = [];
        }
        while (this._animatables.length) {
            this._animatables[0].onAnimationEnd = null;
            this._animatables[0].stop();
            this._animatables.shift();
        }
    };
    /**
     * The easing function used by animations
     */
    BouncingBehavior.EasingFunction = new _Animations_easing__WEBPACK_IMPORTED_MODULE_0__["BackEase"](0.3);
    /**
     * The easing mode used by animations
     */
    BouncingBehavior.EasingMode = _Animations_easing__WEBPACK_IMPORTED_MODULE_0__["EasingFunction"].EASINGMODE_EASEOUT;
    return BouncingBehavior;
}());



/***/ }),

/***/ "./Behaviors/Cameras/framingBehavior.ts":
/*!**********************************************!*\
  !*** ./Behaviors/Cameras/framingBehavior.ts ***!
  \**********************************************/
/*! exports provided: FramingBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FramingBehavior", function() { return FramingBehavior; });
/* harmony import */ var _Animations_easing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Animations/easing */ "./Animations/easing.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/precisionDate */ "./Misc/precisionDate.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Animations/animation */ "./Animations/animation.ts");





/**
 * The framing behavior (FramingBehavior) is designed to automatically position an ArcRotateCamera when its target is set to a mesh. It is also useful if you want to prevent the camera to go under a virtual horizontal plane.
 * @see http://doc.babylonjs.com/how_to/camera_behaviors#framing-behavior
 */
var FramingBehavior = /** @class */ (function () {
    function FramingBehavior() {
        this._mode = FramingBehavior.FitFrustumSidesMode;
        this._radiusScale = 1.0;
        this._positionScale = 0.5;
        this._defaultElevation = 0.3;
        this._elevationReturnTime = 1500;
        this._elevationReturnWaitTime = 1000;
        this._zoomStopsAnimation = false;
        this._framingTime = 1500;
        /**
         * Define if the behavior should automatically change the configured
         * camera limits and sensibilities.
         */
        this.autoCorrectCameraLimitsAndSensibility = true;
        this._isPointerDown = false;
        this._lastInteractionTime = -Infinity;
        // Framing control
        this._animatables = new Array();
        this._betaIsAnimating = false;
    }
    Object.defineProperty(FramingBehavior.prototype, "name", {
        /**
         * Gets the name of the behavior.
         */
        get: function () {
            return "Framing";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "mode", {
        /**
         * Gets current mode used by the behavior.
         */
        get: function () {
            return this._mode;
        },
        /**
         * Sets the current mode used by the behavior
         */
        set: function (mode) {
            this._mode = mode;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "radiusScale", {
        /**
         * Gets the scale applied to the radius
         */
        get: function () {
            return this._radiusScale;
        },
        /**
         * Sets the scale applied to the radius (1 by default)
         */
        set: function (radius) {
            this._radiusScale = radius;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "positionScale", {
        /**
         * Gets the scale to apply on Y axis to position camera focus. 0.5 by default which means the center of the bounding box.
         */
        get: function () {
            return this._positionScale;
        },
        /**
         * Sets the scale to apply on Y axis to position camera focus. 0.5 by default which means the center of the bounding box.
         */
        set: function (scale) {
            this._positionScale = scale;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "defaultElevation", {
        /**
        * Gets the angle above/below the horizontal plane to return to when the return to default elevation idle
        * behaviour is triggered, in radians.
        */
        get: function () {
            return this._defaultElevation;
        },
        /**
        * Sets the angle above/below the horizontal plane to return to when the return to default elevation idle
        * behaviour is triggered, in radians.
        */
        set: function (elevation) {
            this._defaultElevation = elevation;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "elevationReturnTime", {
        /**
         * Gets the time (in milliseconds) taken to return to the default beta position.
         * Negative value indicates camera should not return to default.
         */
        get: function () {
            return this._elevationReturnTime;
        },
        /**
         * Sets the time (in milliseconds) taken to return to the default beta position.
         * Negative value indicates camera should not return to default.
         */
        set: function (speed) {
            this._elevationReturnTime = speed;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "elevationReturnWaitTime", {
        /**
         * Gets the delay (in milliseconds) taken before the camera returns to the default beta position.
         */
        get: function () {
            return this._elevationReturnWaitTime;
        },
        /**
         * Sets the delay (in milliseconds) taken before the camera returns to the default beta position.
         */
        set: function (time) {
            this._elevationReturnWaitTime = time;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "zoomStopsAnimation", {
        /**
        * Gets the flag that indicates if user zooming should stop animation.
        */
        get: function () {
            return this._zoomStopsAnimation;
        },
        /**
        * Sets the flag that indicates if user zooming should stop animation.
        */
        set: function (flag) {
            this._zoomStopsAnimation = flag;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FramingBehavior.prototype, "framingTime", {
        /**
         * Gets the transition time when framing the mesh, in milliseconds
        */
        get: function () {
            return this._framingTime;
        },
        /**
         * Sets the transition time when framing the mesh, in milliseconds
        */
        set: function (time) {
            this._framingTime = time;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Initializes the behavior.
     */
    FramingBehavior.prototype.init = function () {
        // Do notihng
    };
    /**
     * Attaches the behavior to its arc rotate camera.
     * @param camera Defines the camera to attach the behavior to
     */
    FramingBehavior.prototype.attach = function (camera) {
        var _this = this;
        this._attachedCamera = camera;
        var scene = this._attachedCamera.getScene();
        FramingBehavior.EasingFunction.setEasingMode(FramingBehavior.EasingMode);
        this._onPrePointerObservableObserver = scene.onPrePointerObservable.add(function (pointerInfoPre) {
            if (pointerInfoPre.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerEventTypes"].POINTERDOWN) {
                _this._isPointerDown = true;
                return;
            }
            if (pointerInfoPre.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerEventTypes"].POINTERUP) {
                _this._isPointerDown = false;
            }
        });
        this._onMeshTargetChangedObserver = camera.onMeshTargetChangedObservable.add(function (mesh) {
            if (mesh) {
                _this.zoomOnMesh(mesh);
            }
        });
        this._onAfterCheckInputsObserver = camera.onAfterCheckInputsObservable.add(function () {
            // Stop the animation if there is user interaction and the animation should stop for this interaction
            _this._applyUserInteraction();
            // Maintain the camera above the ground. If the user pulls the camera beneath the ground plane, lift it
            // back to the default position after a given timeout
            _this._maintainCameraAboveGround();
        });
    };
    /**
     * Detaches the behavior from its current arc rotate camera.
     */
    FramingBehavior.prototype.detach = function () {
        if (!this._attachedCamera) {
            return;
        }
        var scene = this._attachedCamera.getScene();
        if (this._onPrePointerObservableObserver) {
            scene.onPrePointerObservable.remove(this._onPrePointerObservableObserver);
        }
        if (this._onAfterCheckInputsObserver) {
            this._attachedCamera.onAfterCheckInputsObservable.remove(this._onAfterCheckInputsObserver);
        }
        if (this._onMeshTargetChangedObserver) {
            this._attachedCamera.onMeshTargetChangedObservable.remove(this._onMeshTargetChangedObserver);
        }
        this._attachedCamera = null;
    };
    /**
     * Targets the given mesh and updates zoom level accordingly.
     * @param mesh  The mesh to target.
     * @param radius Optional. If a cached radius position already exists, overrides default.
     * @param framingPositionY Position on mesh to center camera focus where 0 corresponds bottom of its bounding box and 1, the top
     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
     * @param onAnimationEnd Callback triggered at the end of the framing animation
     */
    FramingBehavior.prototype.zoomOnMesh = function (mesh, focusOnOriginXZ, onAnimationEnd) {
        if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
        if (onAnimationEnd === void 0) { onAnimationEnd = null; }
        mesh.computeWorldMatrix(true);
        var boundingBox = mesh.getBoundingInfo().boundingBox;
        this.zoomOnBoundingInfo(boundingBox.minimumWorld, boundingBox.maximumWorld, focusOnOriginXZ, onAnimationEnd);
    };
    /**
     * Targets the given mesh with its children and updates zoom level accordingly.
     * @param mesh  The mesh to target.
     * @param radius Optional. If a cached radius position already exists, overrides default.
     * @param framingPositionY Position on mesh to center camera focus where 0 corresponds bottom of its bounding box and 1, the top
     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
     * @param onAnimationEnd Callback triggered at the end of the framing animation
     */
    FramingBehavior.prototype.zoomOnMeshHierarchy = function (mesh, focusOnOriginXZ, onAnimationEnd) {
        if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
        if (onAnimationEnd === void 0) { onAnimationEnd = null; }
        mesh.computeWorldMatrix(true);
        var boundingBox = mesh.getHierarchyBoundingVectors(true);
        this.zoomOnBoundingInfo(boundingBox.min, boundingBox.max, focusOnOriginXZ, onAnimationEnd);
    };
    /**
     * Targets the given meshes with their children and updates zoom level accordingly.
     * @param meshes  The mesh to target.
     * @param radius Optional. If a cached radius position already exists, overrides default.
     * @param framingPositionY Position on mesh to center camera focus where 0 corresponds bottom of its bounding box and 1, the top
     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
     * @param onAnimationEnd Callback triggered at the end of the framing animation
     */
    FramingBehavior.prototype.zoomOnMeshesHierarchy = function (meshes, focusOnOriginXZ, onAnimationEnd) {
        if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
        if (onAnimationEnd === void 0) { onAnimationEnd = null; }
        var min = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        var max = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
        for (var i = 0; i < meshes.length; i++) {
            var boundingInfo = meshes[i].getHierarchyBoundingVectors(true);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].CheckExtends(boundingInfo.min, min, max);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].CheckExtends(boundingInfo.max, min, max);
        }
        this.zoomOnBoundingInfo(min, max, focusOnOriginXZ, onAnimationEnd);
    };
    /**
     * Targets the bounding box info defined by its extends and updates zoom level accordingly.
     * @param minimumWorld Determines the smaller position of the bounding box extend
     * @param maximumWorld Determines the bigger position of the bounding box extend
     * @param focusOnOriginXZ Determines if the camera should focus on 0 in the X and Z axis instead of the mesh
     * @param onAnimationEnd Callback triggered at the end of the framing animation
     */
    FramingBehavior.prototype.zoomOnBoundingInfo = function (minimumWorld, maximumWorld, focusOnOriginXZ, onAnimationEnd) {
        var _this = this;
        if (focusOnOriginXZ === void 0) { focusOnOriginXZ = false; }
        if (onAnimationEnd === void 0) { onAnimationEnd = null; }
        var zoomTarget;
        if (!this._attachedCamera) {
            return;
        }
        // Find target by interpolating from bottom of bounding box in world-space to top via framingPositionY
        var bottom = minimumWorld.y;
        var top = maximumWorld.y;
        var zoomTargetY = bottom + (top - bottom) * this._positionScale;
        var radiusWorld = maximumWorld.subtract(minimumWorld).scale(0.5);
        if (focusOnOriginXZ) {
            zoomTarget = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, zoomTargetY, 0);
        }
        else {
            var centerWorld = minimumWorld.add(radiusWorld);
            zoomTarget = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](centerWorld.x, zoomTargetY, centerWorld.z);
        }
        if (!this._vectorTransition) {
            this._vectorTransition = _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].CreateAnimation("target", _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].ANIMATIONTYPE_VECTOR3, 60, FramingBehavior.EasingFunction);
        }
        this._betaIsAnimating = true;
        var animatable = _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].TransitionTo("target", zoomTarget, this._attachedCamera, this._attachedCamera.getScene(), 60, this._vectorTransition, this._framingTime);
        if (animatable) {
            this._animatables.push(animatable);
        }
        // sets the radius and lower radius bounds
        // Small delta ensures camera is not always at lower zoom limit.
        var radius = 0;
        if (this._mode === FramingBehavior.FitFrustumSidesMode) {
            var position = this._calculateLowerRadiusFromModelBoundingSphere(minimumWorld, maximumWorld);
            if (this.autoCorrectCameraLimitsAndSensibility) {
                this._attachedCamera.lowerRadiusLimit = radiusWorld.length() + this._attachedCamera.minZ;
            }
            radius = position;
        }
        else if (this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
            radius = this._calculateLowerRadiusFromModelBoundingSphere(minimumWorld, maximumWorld);
            if (this.autoCorrectCameraLimitsAndSensibility && this._attachedCamera.lowerRadiusLimit === null) {
                this._attachedCamera.lowerRadiusLimit = this._attachedCamera.minZ;
            }
        }
        // Set sensibilities
        if (this.autoCorrectCameraLimitsAndSensibility) {
            var extend = maximumWorld.subtract(minimumWorld).length();
            this._attachedCamera.panningSensibility = 5000 / extend;
            this._attachedCamera.wheelPrecision = 100 / radius;
        }
        // transition to new radius
        if (!this._radiusTransition) {
            this._radiusTransition = _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].CreateAnimation("radius", _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
        }
        animatable = _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].TransitionTo("radius", radius, this._attachedCamera, this._attachedCamera.getScene(), 60, this._radiusTransition, this._framingTime, function () {
            _this.stopAllAnimations();
            if (onAnimationEnd) {
                onAnimationEnd();
            }
            if (_this._attachedCamera && _this._attachedCamera.useInputToRestoreState) {
                _this._attachedCamera.storeState();
            }
        });
        if (animatable) {
            this._animatables.push(animatable);
        }
    };
    /**
     * Calculates the lowest radius for the camera based on the bounding box of the mesh.
     * @param mesh The mesh on which to base the calculation. mesh boundingInfo used to estimate necessary
     *            frustum width.
     * @return The minimum distance from the primary mesh's center point at which the camera must be kept in order
     *       to fully enclose the mesh in the viewing frustum.
     */
    FramingBehavior.prototype._calculateLowerRadiusFromModelBoundingSphere = function (minimumWorld, maximumWorld) {
        var size = maximumWorld.subtract(minimumWorld);
        var boxVectorGlobalDiagonal = size.length();
        var frustumSlope = this._getFrustumSlope();
        // Formula for setting distance
        // (Good explanation: http://stackoverflow.com/questions/2866350/move-camera-to-fit-3d-scene)
        var radiusWithoutFraming = boxVectorGlobalDiagonal * 0.5;
        // Horizon distance
        var radius = radiusWithoutFraming * this._radiusScale;
        var distanceForHorizontalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.x * frustumSlope.x));
        var distanceForVerticalFrustum = radius * Math.sqrt(1.0 + 1.0 / (frustumSlope.y * frustumSlope.y));
        var distance = Math.max(distanceForHorizontalFrustum, distanceForVerticalFrustum);
        var camera = this._attachedCamera;
        if (!camera) {
            return 0;
        }
        if (camera.lowerRadiusLimit && this._mode === FramingBehavior.IgnoreBoundsSizeMode) {
            // Don't exceed the requested limit
            distance = distance < camera.lowerRadiusLimit ? camera.lowerRadiusLimit : distance;
        }
        // Don't exceed the upper radius limit
        if (camera.upperRadiusLimit) {
            distance = distance > camera.upperRadiusLimit ? camera.upperRadiusLimit : distance;
        }
        return distance;
    };
    /**
     * Keeps the camera above the ground plane. If the user pulls the camera below the ground plane, the camera
     * is automatically returned to its default position (expected to be above ground plane).
     */
    FramingBehavior.prototype._maintainCameraAboveGround = function () {
        var _this = this;
        if (this._elevationReturnTime < 0) {
            return;
        }
        var timeSinceInteraction = _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_2__["PrecisionDate"].Now - this._lastInteractionTime;
        var defaultBeta = Math.PI * 0.5 - this._defaultElevation;
        var limitBeta = Math.PI * 0.5;
        // Bring the camera back up if below the ground plane
        if (this._attachedCamera && !this._betaIsAnimating && this._attachedCamera.beta > limitBeta && timeSinceInteraction >= this._elevationReturnWaitTime) {
            this._betaIsAnimating = true;
            //Transition to new position
            this.stopAllAnimations();
            if (!this._betaTransition) {
                this._betaTransition = _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].CreateAnimation("beta", _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].ANIMATIONTYPE_FLOAT, 60, FramingBehavior.EasingFunction);
            }
            var animatabe = _Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].TransitionTo("beta", defaultBeta, this._attachedCamera, this._attachedCamera.getScene(), 60, this._betaTransition, this._elevationReturnTime, function () {
                _this._clearAnimationLocks();
                _this.stopAllAnimations();
            });
            if (animatabe) {
                this._animatables.push(animatabe);
            }
        }
    };
    /**
     * Returns the frustum slope based on the canvas ratio and camera FOV
     * @returns The frustum slope represented as a Vector2 with X and Y slopes
     */
    FramingBehavior.prototype._getFrustumSlope = function () {
        // Calculate the viewport ratio
        // Aspect Ratio is Height/Width.
        var camera = this._attachedCamera;
        if (!camera) {
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
        }
        var engine = camera.getScene().getEngine();
        var aspectRatio = engine.getAspectRatio(camera);
        // Camera FOV is the vertical field of view (top-bottom) in radians.
        // Slope of the frustum top/bottom planes in view space, relative to the forward vector.
        var frustumSlopeY = Math.tan(camera.fov / 2);
        // Slope of the frustum left/right planes in view space, relative to the forward vector.
        // Provides the amount that one side (e.g. left) of the frustum gets wider for every unit
        // along the forward vector.
        var frustumSlopeX = frustumSlopeY * aspectRatio;
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](frustumSlopeX, frustumSlopeY);
    };
    /**
     * Removes all animation locks. Allows new animations to be added to any of the arcCamera properties.
     */
    FramingBehavior.prototype._clearAnimationLocks = function () {
        this._betaIsAnimating = false;
    };
    /**
     *  Applies any current user interaction to the camera. Takes into account maximum alpha rotation.
     */
    FramingBehavior.prototype._applyUserInteraction = function () {
        if (this.isUserIsMoving) {
            this._lastInteractionTime = _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_2__["PrecisionDate"].Now;
            this.stopAllAnimations();
            this._clearAnimationLocks();
        }
    };
    /**
     * Stops and removes all animations that have been applied to the camera
     */
    FramingBehavior.prototype.stopAllAnimations = function () {
        if (this._attachedCamera) {
            this._attachedCamera.animations = [];
        }
        while (this._animatables.length) {
            if (this._animatables[0]) {
                this._animatables[0].onAnimationEnd = null;
                this._animatables[0].stop();
            }
            this._animatables.shift();
        }
    };
    Object.defineProperty(FramingBehavior.prototype, "isUserIsMoving", {
        /**
         * Gets a value indicating if the user is moving the camera
         */
        get: function () {
            if (!this._attachedCamera) {
                return false;
            }
            return this._attachedCamera.inertialAlphaOffset !== 0 ||
                this._attachedCamera.inertialBetaOffset !== 0 ||
                this._attachedCamera.inertialRadiusOffset !== 0 ||
                this._attachedCamera.inertialPanningX !== 0 ||
                this._attachedCamera.inertialPanningY !== 0 ||
                this._isPointerDown;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * The easing function used by animations
     */
    FramingBehavior.EasingFunction = new _Animations_easing__WEBPACK_IMPORTED_MODULE_0__["ExponentialEase"]();
    /**
     * The easing mode used by animations
     */
    FramingBehavior.EasingMode = _Animations_easing__WEBPACK_IMPORTED_MODULE_0__["EasingFunction"].EASINGMODE_EASEINOUT;
    // Statics
    /**
     * The camera can move all the way towards the mesh.
     */
    FramingBehavior.IgnoreBoundsSizeMode = 0;
    /**
     * The camera is not allowed to zoom closer to the mesh than the point at which the adjusted bounding sphere touches the frustum sides
     */
    FramingBehavior.FitFrustumSidesMode = 1;
    return FramingBehavior;
}());



/***/ }),

/***/ "./Behaviors/Cameras/index.ts":
/*!************************************!*\
  !*** ./Behaviors/Cameras/index.ts ***!
  \************************************/
/*! exports provided: AutoRotationBehavior, BouncingBehavior, FramingBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _autoRotationBehavior__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./autoRotationBehavior */ "./Behaviors/Cameras/autoRotationBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AutoRotationBehavior", function() { return _autoRotationBehavior__WEBPACK_IMPORTED_MODULE_0__["AutoRotationBehavior"]; });

/* harmony import */ var _bouncingBehavior__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./bouncingBehavior */ "./Behaviors/Cameras/bouncingBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BouncingBehavior", function() { return _bouncingBehavior__WEBPACK_IMPORTED_MODULE_1__["BouncingBehavior"]; });

/* harmony import */ var _framingBehavior__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./framingBehavior */ "./Behaviors/Cameras/framingBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FramingBehavior", function() { return _framingBehavior__WEBPACK_IMPORTED_MODULE_2__["FramingBehavior"]; });






/***/ }),

/***/ "./Behaviors/Meshes/attachToBoxBehavior.ts":
/*!*************************************************!*\
  !*** ./Behaviors/Meshes/attachToBoxBehavior.ts ***!
  \*************************************************/
/*! exports provided: AttachToBoxBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttachToBoxBehavior", function() { return AttachToBoxBehavior; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");

/**
 * @hidden
 */
var FaceDirectionInfo = /** @class */ (function () {
    function FaceDirectionInfo(direction, rotatedDirection, diff, ignore) {
        if (rotatedDirection === void 0) { rotatedDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](); }
        if (diff === void 0) { diff = 0; }
        if (ignore === void 0) { ignore = false; }
        this.direction = direction;
        this.rotatedDirection = rotatedDirection;
        this.diff = diff;
        this.ignore = ignore;
    }
    return FaceDirectionInfo;
}());
/**
 * A behavior that when attached to a mesh will will place a specified node on the meshes face pointing towards the camera
 */
var AttachToBoxBehavior = /** @class */ (function () {
    /**
     * Creates the AttachToBoxBehavior, used to attach UI to the closest face of the box to a camera
     * @param ui The transform node that should be attched to the mesh
     */
    function AttachToBoxBehavior(ui) {
        this.ui = ui;
        /**
         *  The name of the behavior
         */
        this.name = "AttachToBoxBehavior";
        /**
         * The distance away from the face of the mesh that the UI should be attached to (default: 0.15)
         */
        this.distanceAwayFromFace = 0.15;
        /**
         * The distance from the bottom of the face that the UI should be attached to (default: 0.15)
         */
        this.distanceAwayFromBottomOfFace = 0.15;
        this._faceVectors = [new FaceDirectionInfo(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up()), new FaceDirectionInfo(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Down()), new FaceDirectionInfo(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Left()), new FaceDirectionInfo(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Right()), new FaceDirectionInfo(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Forward()), new FaceDirectionInfo(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Forward().scaleInPlace(-1))];
        this._tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"]();
        this._tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
        this._zeroVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._lookAtTmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"]();
        /* Does nothing */
    }
    /**
     *  Initializes the behavior
     */
    AttachToBoxBehavior.prototype.init = function () {
        /* Does nothing */
    };
    AttachToBoxBehavior.prototype._closestFace = function (targetDirection) {
        var _this = this;
        // Go over each face and calculate the angle between the face's normal and targetDirection
        this._faceVectors.forEach(function (v) {
            if (!_this._target.rotationQuaternion) {
                _this._target.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(_this._target.rotation.y, _this._target.rotation.x, _this._target.rotation.z);
            }
            _this._target.rotationQuaternion.toRotationMatrix(_this._tmpMatrix);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(v.direction, _this._tmpMatrix, v.rotatedDirection);
            v.diff = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].GetAngleBetweenVectors(v.rotatedDirection, targetDirection, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(v.rotatedDirection, targetDirection));
        });
        // Return the face information of the one with the normal closeset to target direction
        return this._faceVectors.reduce(function (min, p) {
            if (min.ignore) {
                return p;
            }
            else if (p.ignore) {
                return min;
            }
            else {
                return min.diff < p.diff ? min : p;
            }
        }, this._faceVectors[0]);
    };
    AttachToBoxBehavior.prototype._lookAtToRef = function (pos, up, ref) {
        if (up === void 0) { up = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1, 0); }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].LookAtLHToRef(this._zeroVector, pos, up, this._lookAtTmpMatrix);
        this._lookAtTmpMatrix.invert();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromRotationMatrixToRef(this._lookAtTmpMatrix, ref);
    };
    /**
     * Attaches the AttachToBoxBehavior to the passed in mesh
     * @param target The mesh that the specified node will be attached to
     */
    AttachToBoxBehavior.prototype.attach = function (target) {
        var _this = this;
        this._target = target;
        this._scene = this._target.getScene();
        // Every frame, update the app bars position
        this._onRenderObserver = this._scene.onBeforeRenderObservable.add(function () {
            if (!_this._scene.activeCamera) {
                return;
            }
            // Find the face closest to the cameras position
            var cameraPos = _this._scene.activeCamera.position;
            if (_this._scene.activeCamera.devicePosition) {
                cameraPos = _this._scene.activeCamera.devicePosition;
            }
            var facing = _this._closestFace(cameraPos.subtract(target.position));
            if (_this._scene.activeCamera.leftCamera) {
                _this._scene.activeCamera.leftCamera.computeWorldMatrix().getRotationMatrixToRef(_this._tmpMatrix);
            }
            else {
                _this._scene.activeCamera.computeWorldMatrix().getRotationMatrixToRef(_this._tmpMatrix);
            }
            // Get camera up direction
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up(), _this._tmpMatrix, _this._tmpVector);
            // Ignore faces to not select a parrelel face for the up vector of the UI
            _this._faceVectors.forEach(function (v) {
                if (facing.direction.x && v.direction.x) {
                    v.ignore = true;
                }
                if (facing.direction.y && v.direction.y) {
                    v.ignore = true;
                }
                if (facing.direction.z && v.direction.z) {
                    v.ignore = true;
                }
            });
            var facingUp = _this._closestFace(_this._tmpVector);
            // Unignore faces
            _this._faceVectors.forEach(function (v) {
                v.ignore = false;
            });
            // Position the app bar on that face
            _this.ui.position.copyFrom(target.position);
            if (facing.direction.x) {
                facing.rotatedDirection.scaleToRef((target.scaling.x / 2) + _this.distanceAwayFromFace, _this._tmpVector);
                _this.ui.position.addInPlace(_this._tmpVector);
            }
            if (facing.direction.y) {
                facing.rotatedDirection.scaleToRef((target.scaling.y / 2) + _this.distanceAwayFromFace, _this._tmpVector);
                _this.ui.position.addInPlace(_this._tmpVector);
            }
            if (facing.direction.z) {
                facing.rotatedDirection.scaleToRef((target.scaling.z / 2) + _this.distanceAwayFromFace, _this._tmpVector);
                _this.ui.position.addInPlace(_this._tmpVector);
            }
            // Rotate to be oriented properly to the camera
            if (!_this.ui.rotationQuaternion) {
                _this.ui.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(_this.ui.rotation.y, _this.ui.rotation.x, _this.ui.rotation.z);
            }
            facing.rotatedDirection.scaleToRef(-1, _this._tmpVector);
            _this._lookAtToRef(_this._tmpVector, facingUp.rotatedDirection, _this.ui.rotationQuaternion);
            // Place ui the correct distance from the bottom of the mesh
            if (facingUp.direction.x) {
                _this.ui.up.scaleToRef(_this.distanceAwayFromBottomOfFace - target.scaling.x / 2, _this._tmpVector);
            }
            if (facingUp.direction.y) {
                _this.ui.up.scaleToRef(_this.distanceAwayFromBottomOfFace - target.scaling.y / 2, _this._tmpVector);
            }
            if (facingUp.direction.z) {
                _this.ui.up.scaleToRef(_this.distanceAwayFromBottomOfFace - target.scaling.z / 2, _this._tmpVector);
            }
            _this.ui.position.addInPlace(_this._tmpVector);
        });
    };
    /**
     *  Detaches the behavior from the mesh
     */
    AttachToBoxBehavior.prototype.detach = function () {
        this._scene.onBeforeRenderObservable.remove(this._onRenderObserver);
    };
    return AttachToBoxBehavior;
}());



/***/ }),

/***/ "./Behaviors/Meshes/fadeInOutBehavior.ts":
/*!***********************************************!*\
  !*** ./Behaviors/Meshes/fadeInOutBehavior.ts ***!
  \***********************************************/
/*! exports provided: FadeInOutBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FadeInOutBehavior", function() { return FadeInOutBehavior; });
/**
 * A behavior that when attached to a mesh will allow the mesh to fade in and out
 */
var FadeInOutBehavior = /** @class */ (function () {
    /**
     * Instatiates the FadeInOutBehavior
     */
    function FadeInOutBehavior() {
        var _this = this;
        /**
         * Time in milliseconds to delay before fading in (Default: 0)
         */
        this.delay = 0;
        /**
         * Time in milliseconds for the mesh to fade in (Default: 300)
         */
        this.fadeInTime = 300;
        this._millisecondsPerFrame = 1000 / 60;
        this._hovered = false;
        this._hoverValue = 0;
        this._ownerNode = null;
        this._update = function () {
            if (_this._ownerNode) {
                _this._hoverValue += _this._hovered ? _this._millisecondsPerFrame : -_this._millisecondsPerFrame;
                _this._setAllVisibility(_this._ownerNode, (_this._hoverValue - _this.delay) / _this.fadeInTime);
                if (_this._ownerNode.visibility > 1) {
                    _this._setAllVisibility(_this._ownerNode, 1);
                    _this._hoverValue = _this.fadeInTime + _this.delay;
                    return;
                }
                else if (_this._ownerNode.visibility < 0) {
                    _this._setAllVisibility(_this._ownerNode, 0);
                    if (_this._hoverValue < 0) {
                        _this._hoverValue = 0;
                        return;
                    }
                }
                setTimeout(_this._update, _this._millisecondsPerFrame);
            }
        };
    }
    Object.defineProperty(FadeInOutBehavior.prototype, "name", {
        /**
         *  The name of the behavior
         */
        get: function () {
            return "FadeInOut";
        },
        enumerable: true,
        configurable: true
    });
    /**
     *  Initializes the behavior
     */
    FadeInOutBehavior.prototype.init = function () {
    };
    /**
     * Attaches the fade behavior on the passed in mesh
     * @param ownerNode The mesh that will be faded in/out once attached
     */
    FadeInOutBehavior.prototype.attach = function (ownerNode) {
        this._ownerNode = ownerNode;
        this._setAllVisibility(this._ownerNode, 0);
    };
    /**
     *  Detaches the behavior from the mesh
     */
    FadeInOutBehavior.prototype.detach = function () {
        this._ownerNode = null;
    };
    /**
     * Triggers the mesh to begin fading in or out
     * @param value if the object should fade in or out (true to fade in)
     */
    FadeInOutBehavior.prototype.fadeIn = function (value) {
        this._hovered = value;
        this._update();
    };
    FadeInOutBehavior.prototype._setAllVisibility = function (mesh, value) {
        var _this = this;
        mesh.visibility = value;
        mesh.getChildMeshes().forEach(function (c) {
            _this._setAllVisibility(c, value);
        });
    };
    return FadeInOutBehavior;
}());



/***/ }),

/***/ "./Behaviors/Meshes/index.ts":
/*!***********************************!*\
  !*** ./Behaviors/Meshes/index.ts ***!
  \***********************************/
/*! exports provided: AttachToBoxBehavior, FadeInOutBehavior, MultiPointerScaleBehavior, PointerDragBehavior, SixDofDragBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _attachToBoxBehavior__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./attachToBoxBehavior */ "./Behaviors/Meshes/attachToBoxBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AttachToBoxBehavior", function() { return _attachToBoxBehavior__WEBPACK_IMPORTED_MODULE_0__["AttachToBoxBehavior"]; });

/* harmony import */ var _fadeInOutBehavior__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./fadeInOutBehavior */ "./Behaviors/Meshes/fadeInOutBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FadeInOutBehavior", function() { return _fadeInOutBehavior__WEBPACK_IMPORTED_MODULE_1__["FadeInOutBehavior"]; });

/* harmony import */ var _multiPointerScaleBehavior__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./multiPointerScaleBehavior */ "./Behaviors/Meshes/multiPointerScaleBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiPointerScaleBehavior", function() { return _multiPointerScaleBehavior__WEBPACK_IMPORTED_MODULE_2__["MultiPointerScaleBehavior"]; });

/* harmony import */ var _pointerDragBehavior__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerDragBehavior", function() { return _pointerDragBehavior__WEBPACK_IMPORTED_MODULE_3__["PointerDragBehavior"]; });

/* harmony import */ var _sixDofDragBehavior__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./sixDofDragBehavior */ "./Behaviors/Meshes/sixDofDragBehavior.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SixDofDragBehavior", function() { return _sixDofDragBehavior__WEBPACK_IMPORTED_MODULE_4__["SixDofDragBehavior"]; });








/***/ }),

/***/ "./Behaviors/Meshes/multiPointerScaleBehavior.ts":
/*!*******************************************************!*\
  !*** ./Behaviors/Meshes/multiPointerScaleBehavior.ts ***!
  \*******************************************************/
/*! exports provided: MultiPointerScaleBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiPointerScaleBehavior", function() { return MultiPointerScaleBehavior; });
/* harmony import */ var _pointerDragBehavior__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");


/**
 * A behavior that when attached to a mesh will allow the mesh to be scaled
 */
var MultiPointerScaleBehavior = /** @class */ (function () {
    /**
     * Instantiate a new behavior that when attached to a mesh will allow the mesh to be scaled
     */
    function MultiPointerScaleBehavior() {
        this._startDistance = 0;
        this._initialScale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, 0);
        this._targetScale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, 0);
        this._sceneRenderObserver = null;
        this._dragBehaviorA = new _pointerDragBehavior__WEBPACK_IMPORTED_MODULE_0__["PointerDragBehavior"]({});
        this._dragBehaviorA.moveAttached = false;
        this._dragBehaviorB = new _pointerDragBehavior__WEBPACK_IMPORTED_MODULE_0__["PointerDragBehavior"]({});
        this._dragBehaviorB.moveAttached = false;
    }
    Object.defineProperty(MultiPointerScaleBehavior.prototype, "name", {
        /**
         *  The name of the behavior
         */
        get: function () {
            return "MultiPointerScale";
        },
        enumerable: true,
        configurable: true
    });
    /**
     *  Initializes the behavior
     */
    MultiPointerScaleBehavior.prototype.init = function () { };
    MultiPointerScaleBehavior.prototype._getCurrentDistance = function () {
        return this._dragBehaviorA.lastDragPosition.subtract(this._dragBehaviorB.lastDragPosition).length();
    };
    /**
     * Attaches the scale behavior the passed in mesh
     * @param ownerNode The mesh that will be scaled around once attached
     */
    MultiPointerScaleBehavior.prototype.attach = function (ownerNode) {
        var _this = this;
        this._ownerNode = ownerNode;
        // Create 2 drag behaviors such that each will only be triggered by a separate pointer
        this._dragBehaviorA.onDragStartObservable.add(function (e) {
            if (_this._dragBehaviorA.dragging && _this._dragBehaviorB.dragging) {
                if (_this._dragBehaviorA.currentDraggingPointerID == _this._dragBehaviorB.currentDraggingPointerID) {
                    _this._dragBehaviorA.releaseDrag();
                }
                else {
                    _this._initialScale.copyFrom(ownerNode.scaling);
                    _this._startDistance = _this._getCurrentDistance();
                }
            }
        });
        this._dragBehaviorB.onDragStartObservable.add(function (e) {
            if (_this._dragBehaviorA.dragging && _this._dragBehaviorB.dragging) {
                if (_this._dragBehaviorA.currentDraggingPointerID == _this._dragBehaviorB.currentDraggingPointerID) {
                    _this._dragBehaviorB.releaseDrag();
                }
                else {
                    _this._initialScale.copyFrom(ownerNode.scaling);
                    _this._startDistance = _this._getCurrentDistance();
                }
            }
        });
        // Once both drag behaviors are active scale based on the distance between the two pointers
        [this._dragBehaviorA, this._dragBehaviorB].forEach(function (behavior) {
            behavior.onDragObservable.add(function () {
                if (_this._dragBehaviorA.dragging && _this._dragBehaviorB.dragging) {
                    var ratio = _this._getCurrentDistance() / _this._startDistance;
                    _this._initialScale.scaleToRef(ratio, _this._targetScale);
                }
            });
        });
        ownerNode.addBehavior(this._dragBehaviorA);
        ownerNode.addBehavior(this._dragBehaviorB);
        // On every frame move towards target scaling to avoid jitter caused by vr controllers
        this._sceneRenderObserver = ownerNode.getScene().onBeforeRenderObservable.add(function () {
            if (_this._dragBehaviorA.dragging && _this._dragBehaviorB.dragging) {
                var change = _this._targetScale.subtract(ownerNode.scaling).scaleInPlace(0.1);
                if (change.length() > 0.01) {
                    ownerNode.scaling.addInPlace(change);
                }
            }
        });
    };
    /**
     *  Detaches the behavior from the mesh
     */
    MultiPointerScaleBehavior.prototype.detach = function () {
        var _this = this;
        this._ownerNode.getScene().onBeforeRenderObservable.remove(this._sceneRenderObserver);
        [this._dragBehaviorA, this._dragBehaviorB].forEach(function (behavior) {
            behavior.onDragStartObservable.clear();
            behavior.onDragObservable.clear();
            _this._ownerNode.removeBehavior(behavior);
        });
    };
    return MultiPointerScaleBehavior;
}());



/***/ }),

/***/ "./Behaviors/Meshes/pointerDragBehavior.ts":
/*!*************************************************!*\
  !*** ./Behaviors/Meshes/pointerDragBehavior.ts ***!
  \*************************************************/
/*! exports provided: PointerDragBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointerDragBehavior", function() { return PointerDragBehavior; });
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../scene */ "./scene.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Misc/pivotTools */ "./Misc/pivotTools.ts");
/* harmony import */ var _Meshes_Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Meshes/Builders/planeBuilder */ "./Meshes/Builders/planeBuilder.ts");








/**
 * A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events
 */
var PointerDragBehavior = /** @class */ (function () {
    /**
     * Creates a pointer drag behavior that can be attached to a mesh
     * @param options The drag axis or normal of the plane that will be dragged across. If no options are specified the drag plane will always face the ray's origin (eg. camera)
     */
    function PointerDragBehavior(options) {
        this._useAlternatePickedPointAboveMaxDragAngleDragSpeed = -1.1;
        /**
         * The maximum tolerated angle between the drag plane and dragging pointer rays to trigger pointer events. Set to 0 to allow any angle (default: 0)
         */
        this.maxDragAngle = 0;
        /**
         * @hidden
         */
        this._useAlternatePickedPointAboveMaxDragAngle = false;
        /**
         * The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)
         */
        this.currentDraggingPointerID = -1;
        /**
         * If the behavior is currently in a dragging state
         */
        this.dragging = false;
        /**
         * The distance towards the target drag position to move each frame. This can be useful to avoid jitter. Set this to 1 for no delay. (Default: 0.2)
         */
        this.dragDeltaRatio = 0.2;
        /**
         * If the drag plane orientation should be updated during the dragging (Default: true)
         */
        this.updateDragPlane = true;
        // Debug mode will display drag planes to help visualize behavior
        this._debugMode = false;
        this._moving = false;
        /**
         *  Fires each time the attached mesh is dragged with the pointer
         *  * delta between last drag position and current drag position in world space
         *  * dragDistance along the drag axis
         *  * dragPlaneNormal normal of the current drag plane used during the drag
         *  * dragPlanePoint in world space where the drag intersects the drag plane
         */
        this.onDragObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         *  Fires each time a drag begins (eg. mouse down on mesh)
         */
        this.onDragStartObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         *  Fires each time a drag ends (eg. mouse release after drag)
         */
        this.onDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         *  If the attached mesh should be moved when dragged
         */
        this.moveAttached = true;
        /**
         *  If the drag behavior will react to drag events (Default: true)
         */
        this.enabled = true;
        /**
         * If pointer events should start and release the drag (Default: true)
         */
        this.startAndReleaseDragOnPointerEvents = true;
        /**
         * If camera controls should be detached during the drag
         */
        this.detachCameraControls = true;
        /**
         * If set, the drag plane/axis will be rotated based on the attached mesh's world rotation (Default: true)
         */
        this.useObjectOrienationForDragging = true;
        /**
         * Predicate to determine if it is valid to move the object to a new position when it is moved
         */
        this.validateDrag = function (targetPosition) { return true; };
        this._tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._alternatePickedPoint = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._worldDragAxis = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._targetPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._attachedElement = null;
        this._startDragRay = new _Culling_ray__WEBPACK_IMPORTED_MODULE_5__["Ray"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"]());
        this._lastPointerRay = {};
        this._dragDelta = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"]();
        // Variables to avoid instantiation in the below method
        this._pointA = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._pointB = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._pointC = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._lineA = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._lineB = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._localAxis = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._lookAt = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._options = options ? options : {};
        var optionCount = 0;
        if (this._options.dragAxis) {
            optionCount++;
        }
        if (this._options.dragPlaneNormal) {
            optionCount++;
        }
        if (optionCount > 1) {
            throw "Multiple drag modes specified in dragBehavior options. Only one expected";
        }
    }
    Object.defineProperty(PointerDragBehavior.prototype, "name", {
        /**
         *  The name of the behavior
         */
        get: function () {
            return "PointerDrag";
        },
        enumerable: true,
        configurable: true
    });
    /**
     *  Initializes the behavior
     */
    PointerDragBehavior.prototype.init = function () { };
    /**
     * Attaches the drag behavior the passed in mesh
     * @param ownerNode The mesh that will be dragged around once attached
     * @param predicate Predicate to use for pick filtering
     */
    PointerDragBehavior.prototype.attach = function (ownerNode, predicate) {
        var _this = this;
        this._scene = ownerNode.getScene();
        this.attachedNode = ownerNode;
        // Initialize drag plane to not interfere with existing scene
        if (!PointerDragBehavior._planeScene) {
            if (this._debugMode) {
                PointerDragBehavior._planeScene = this._scene;
            }
            else {
                PointerDragBehavior._planeScene = new _scene__WEBPACK_IMPORTED_MODULE_1__["Scene"](this._scene.getEngine(), { virtual: true });
                PointerDragBehavior._planeScene.detachControl();
                this._scene.onDisposeObservable.addOnce(function () {
                    PointerDragBehavior._planeScene.dispose();
                    PointerDragBehavior._planeScene = null;
                });
            }
        }
        this._dragPlane = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreatePlane("pointerDragPlane", this._debugMode ? 1 : 10000, PointerDragBehavior._planeScene, false, _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].DOUBLESIDE);
        // State of the drag
        this.lastDragPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        var pickPredicate = !!predicate ? predicate : function (m) {
            return _this.attachedNode == m || m.isDescendantOf(_this.attachedNode);
        };
        this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
            if (!_this.enabled) {
                return;
            }
            if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERDOWN) {
                if (_this.startAndReleaseDragOnPointerEvents && !_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.pickedPoint && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
                    _this._startDrag(pointerInfo.event.pointerId, pointerInfo.pickInfo.ray, pointerInfo.pickInfo.pickedPoint);
                }
            }
            else if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERUP) {
                if (_this.startAndReleaseDragOnPointerEvents && _this.currentDraggingPointerID == pointerInfo.event.pointerId) {
                    _this.releaseDrag();
                }
            }
            else if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERMOVE) {
                var pointerId = pointerInfo.event.pointerId;
                // If drag was started with anyMouseID specified, set pointerID to the next mouse that moved
                if (_this.currentDraggingPointerID === PointerDragBehavior._AnyMouseID && pointerId !== PointerDragBehavior._AnyMouseID && pointerInfo.event.pointerType == "mouse") {
                    if (_this._lastPointerRay[_this.currentDraggingPointerID]) {
                        _this._lastPointerRay[pointerId] = _this._lastPointerRay[_this.currentDraggingPointerID];
                        delete _this._lastPointerRay[_this.currentDraggingPointerID];
                    }
                    _this.currentDraggingPointerID = pointerId;
                }
                // Keep track of last pointer ray, this is used simulating the start of a drag in startDrag()
                if (!_this._lastPointerRay[pointerId]) {
                    _this._lastPointerRay[pointerId] = new _Culling_ray__WEBPACK_IMPORTED_MODULE_5__["Ray"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"]());
                }
                if (pointerInfo.pickInfo && pointerInfo.pickInfo.ray) {
                    _this._lastPointerRay[pointerId].origin.copyFrom(pointerInfo.pickInfo.ray.origin);
                    _this._lastPointerRay[pointerId].direction.copyFrom(pointerInfo.pickInfo.ray.direction);
                    if (_this.currentDraggingPointerID == pointerId && _this.dragging) {
                        _this._moveDrag(pointerInfo.pickInfo.ray);
                    }
                }
            }
        });
        this._beforeRenderObserver = this._scene.onBeforeRenderObservable.add(function () {
            if (_this._moving && _this.moveAttached) {
                _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RemoveAndStorePivotPoint(_this.attachedNode);
                // Slowly move mesh to avoid jitter
                _this._targetPosition.subtractToRef((_this.attachedNode).absolutePosition, _this._tmpVector);
                _this._tmpVector.scaleInPlace(_this.dragDeltaRatio);
                (_this.attachedNode).getAbsolutePosition().addToRef(_this._tmpVector, _this._tmpVector);
                if (_this.validateDrag(_this._tmpVector)) {
                    (_this.attachedNode).setAbsolutePosition(_this._tmpVector);
                }
                _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RestorePivotPoint(_this.attachedNode);
            }
        });
    };
    /**
     * Force relase the drag action by code.
     */
    PointerDragBehavior.prototype.releaseDrag = function () {
        this.dragging = false;
        this.onDragEndObservable.notifyObservers({ dragPlanePoint: this.lastDragPosition, pointerId: this.currentDraggingPointerID });
        this.currentDraggingPointerID = -1;
        this._moving = false;
        // Reattach camera controls
        if (this.detachCameraControls && this._attachedElement && this._scene.activeCamera && !this._scene.activeCamera.leftCamera) {
            this._scene.activeCamera.attachControl(this._attachedElement, true);
        }
    };
    /**
     * Simulates the start of a pointer drag event on the behavior
     * @param pointerId pointerID of the pointer that should be simulated (Default: Any mouse pointer ID)
     * @param fromRay initial ray of the pointer to be simulated (Default: Ray from camera to attached mesh)
     * @param startPickedPoint picked point of the pointer to be simulated (Default: attached mesh position)
     */
    PointerDragBehavior.prototype.startDrag = function (pointerId, fromRay, startPickedPoint) {
        if (pointerId === void 0) { pointerId = PointerDragBehavior._AnyMouseID; }
        this._startDrag(pointerId, fromRay, startPickedPoint);
        var lastRay = this._lastPointerRay[pointerId];
        if (pointerId === PointerDragBehavior._AnyMouseID) {
            lastRay = this._lastPointerRay[Object.keys(this._lastPointerRay)[0]];
        }
        if (lastRay) {
            // if there was a last pointer ray drag the object there
            this._moveDrag(lastRay);
        }
    };
    PointerDragBehavior.prototype._startDrag = function (pointerId, fromRay, startPickedPoint) {
        if (!this._scene.activeCamera || this.dragging || !this.attachedNode) {
            return;
        }
        _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RemoveAndStorePivotPoint(this.attachedNode);
        // Create start ray from the camera to the object
        if (fromRay) {
            this._startDragRay.direction.copyFrom(fromRay.direction);
            this._startDragRay.origin.copyFrom(fromRay.origin);
        }
        else {
            this._startDragRay.origin.copyFrom(this._scene.activeCamera.position);
            this.attachedNode.getWorldMatrix().getTranslationToRef(this._tmpVector);
            this._tmpVector.subtractToRef(this._scene.activeCamera.position, this._startDragRay.direction);
        }
        this._updateDragPlanePosition(this._startDragRay, startPickedPoint ? startPickedPoint : this._tmpVector);
        var pickedPoint = this._pickWithRayOnDragPlane(this._startDragRay);
        if (pickedPoint) {
            this.dragging = true;
            this.currentDraggingPointerID = pointerId;
            this.lastDragPosition.copyFrom(pickedPoint);
            this.onDragStartObservable.notifyObservers({ dragPlanePoint: pickedPoint, pointerId: this.currentDraggingPointerID });
            this._targetPosition.copyFrom((this.attachedNode).absolutePosition);
            // Detatch camera controls
            if (this.detachCameraControls && this._scene.activeCamera && this._scene.activeCamera.inputs && !this._scene.activeCamera.leftCamera) {
                if (this._scene.activeCamera.inputs.attachedElement) {
                    this._attachedElement = this._scene.activeCamera.inputs.attachedElement;
                    this._scene.activeCamera.detachControl(this._scene.activeCamera.inputs.attachedElement);
                }
                else {
                    this._attachedElement = null;
                }
            }
        }
        _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RestorePivotPoint(this.attachedNode);
    };
    PointerDragBehavior.prototype._moveDrag = function (ray) {
        this._moving = true;
        var pickedPoint = this._pickWithRayOnDragPlane(ray);
        if (pickedPoint) {
            if (this.updateDragPlane) {
                this._updateDragPlanePosition(ray, pickedPoint);
            }
            var dragLength = 0;
            // depending on the drag mode option drag accordingly
            if (this._options.dragAxis) {
                // Convert local drag axis to world if useObjectOrienationForDragging
                this.useObjectOrienationForDragging ? _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._options.dragAxis, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._worldDragAxis) : this._worldDragAxis.copyFrom(this._options.dragAxis);
                // Project delta drag from the drag plane onto the drag axis
                pickedPoint.subtractToRef(this.lastDragPosition, this._tmpVector);
                dragLength = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(this._tmpVector, this._worldDragAxis);
                this._worldDragAxis.scaleToRef(dragLength, this._dragDelta);
            }
            else {
                dragLength = this._dragDelta.length();
                pickedPoint.subtractToRef(this.lastDragPosition, this._dragDelta);
            }
            this._targetPosition.addInPlace(this._dragDelta);
            this.onDragObservable.notifyObservers({ dragDistance: dragLength, delta: this._dragDelta, dragPlanePoint: pickedPoint, dragPlaneNormal: this._dragPlane.forward, pointerId: this.currentDraggingPointerID });
            this.lastDragPosition.copyFrom(pickedPoint);
        }
    };
    PointerDragBehavior.prototype._pickWithRayOnDragPlane = function (ray) {
        var _this = this;
        if (!ray) {
            return null;
        }
        // Calculate angle between plane normal and ray
        var angle = Math.acos(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(this._dragPlane.forward, ray.direction));
        // Correct if ray is casted from oposite side
        if (angle > Math.PI / 2) {
            angle = Math.PI - angle;
        }
        // If the angle is too perpendicular to the plane pick another point on the plane where it is looking
        if (this.maxDragAngle > 0 && angle > this.maxDragAngle) {
            if (this._useAlternatePickedPointAboveMaxDragAngle) {
                // Invert ray direction along the towards object axis
                this._tmpVector.copyFrom(ray.direction);
                (this.attachedNode).absolutePosition.subtractToRef(ray.origin, this._alternatePickedPoint);
                this._alternatePickedPoint.normalize();
                this._alternatePickedPoint.scaleInPlace(this._useAlternatePickedPointAboveMaxDragAngleDragSpeed * _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(this._alternatePickedPoint, this._tmpVector));
                this._tmpVector.addInPlace(this._alternatePickedPoint);
                // Project resulting vector onto the drag plane and add it to the attached nodes absolute position to get a picked point
                var dot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(this._dragPlane.forward, this._tmpVector);
                this._dragPlane.forward.scaleToRef(-dot, this._alternatePickedPoint);
                this._alternatePickedPoint.addInPlace(this._tmpVector);
                this._alternatePickedPoint.addInPlace((this.attachedNode).absolutePosition);
                return this._alternatePickedPoint;
            }
            else {
                return null;
            }
        }
        var pickResult = PointerDragBehavior._planeScene.pickWithRay(ray, function (m) { return m == _this._dragPlane; });
        if (pickResult && pickResult.hit && pickResult.pickedMesh && pickResult.pickedPoint) {
            return pickResult.pickedPoint;
        }
        else {
            return null;
        }
    };
    // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
    PointerDragBehavior.prototype._updateDragPlanePosition = function (ray, dragPlanePosition) {
        this._pointA.copyFrom(dragPlanePosition);
        if (this._options.dragAxis) {
            this.useObjectOrienationForDragging ? _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._options.dragAxis, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragAxis);
            // Calculate plane normal in direction of camera but perpendicular to drag axis
            this._pointA.addToRef(this._localAxis, this._pointB); // towards drag axis
            ray.origin.subtractToRef(this._pointA, this._pointC);
            this._pointA.addToRef(this._pointC.normalize(), this._pointC); // towards camera
            // Get perpendicular line from direction to camera and drag axis
            this._pointB.subtractToRef(this._pointA, this._lineA);
            this._pointC.subtractToRef(this._pointA, this._lineB);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].CrossToRef(this._lineA, this._lineB, this._lookAt);
            // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].CrossToRef(this._lineA, this._lookAt, this._lookAt);
            this._lookAt.normalize();
            this._dragPlane.position.copyFrom(this._pointA);
            this._pointA.addToRef(this._lookAt, this._lookAt);
            this._dragPlane.lookAt(this._lookAt);
        }
        else if (this._options.dragPlaneNormal) {
            this.useObjectOrienationForDragging ? _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._options.dragPlaneNormal, this.attachedNode.getWorldMatrix().getRotationMatrix(), this._localAxis) : this._localAxis.copyFrom(this._options.dragPlaneNormal);
            this._dragPlane.position.copyFrom(this._pointA);
            this._pointA.addToRef(this._localAxis, this._lookAt);
            this._dragPlane.lookAt(this._lookAt);
        }
        else {
            this._dragPlane.position.copyFrom(this._pointA);
            this._dragPlane.lookAt(ray.origin);
        }
        // Update the position of the drag plane so it doesn't get out of sync with the node (eg. when moving back and forth quickly)
        this._dragPlane.position.copyFrom(this.attachedNode.absolutePosition);
        this._dragPlane.computeWorldMatrix(true);
    };
    /**
     *  Detaches the behavior from the mesh
     */
    PointerDragBehavior.prototype.detach = function () {
        if (this._pointerObserver) {
            this._scene.onPointerObservable.remove(this._pointerObserver);
        }
        if (this._beforeRenderObserver) {
            this._scene.onBeforeRenderObservable.remove(this._beforeRenderObserver);
        }
        this.releaseDrag();
    };
    PointerDragBehavior._AnyMouseID = -2;
    return PointerDragBehavior;
}());



/***/ }),

/***/ "./Behaviors/Meshes/sixDofDragBehavior.ts":
/*!************************************************!*\
  !*** ./Behaviors/Meshes/sixDofDragBehavior.ts ***!
  \************************************************/
/*! exports provided: SixDofDragBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SixDofDragBehavior", function() { return SixDofDragBehavior; });
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../scene */ "./scene.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Misc/pivotTools */ "./Misc/pivotTools.ts");







/**
 * A behavior that when attached to a mesh will allow the mesh to be dragged around based on directions and origin of the pointer's ray
 */
var SixDofDragBehavior = /** @class */ (function () {
    /**
     * Instantiates a behavior that when attached to a mesh will allow the mesh to be dragged around based on directions and origin of the pointer's ray
     */
    function SixDofDragBehavior() {
        this._sceneRenderObserver = null;
        this._targetPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        this._moving = false;
        this._startingOrientation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        /**
         * How much faster the object should move when the controller is moving towards it. This is useful to bring objects that are far away from the user to them faster. Set this to 0 to avoid any speed increase. (Default: 3)
         */
        this.zDragFactor = 3;
        /**
         * If the object should rotate to face the drag origin
         */
        this.rotateDraggedObject = true;
        /**
         * If the behavior is currently in a dragging state
         */
        this.dragging = false;
        /**
         * The distance towards the target drag position to move each frame. This can be useful to avoid jitter. Set this to 1 for no delay. (Default: 0.2)
         */
        this.dragDeltaRatio = 0.2;
        /**
         * The id of the pointer that is currently interacting with the behavior (-1 when no pointer is active)
         */
        this.currentDraggingPointerID = -1;
        /**
         * If camera controls should be detached during the drag
         */
        this.detachCameraControls = true;
        /**
         * Fires each time a drag starts
         */
        this.onDragStartObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
        /**
         *  Fires each time a drag ends (eg. mouse release after drag)
         */
        this.onDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
    }
    Object.defineProperty(SixDofDragBehavior.prototype, "name", {
        /**
         *  The name of the behavior
         */
        get: function () {
            return "SixDofDrag";
        },
        enumerable: true,
        configurable: true
    });
    /**
     *  Initializes the behavior
     */
    SixDofDragBehavior.prototype.init = function () { };
    Object.defineProperty(SixDofDragBehavior.prototype, "_pointerCamera", {
        /**
         * In the case of multiplea active cameras, the cameraToUseForPointers should be used if set instead of active camera
         */
        get: function () {
            if (this._scene.cameraToUseForPointers) {
                return this._scene.cameraToUseForPointers;
            }
            else {
                return this._scene.activeCamera;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attaches the scale behavior the passed in mesh
     * @param ownerNode The mesh that will be scaled around once attached
     */
    SixDofDragBehavior.prototype.attach = function (ownerNode) {
        var _this = this;
        this._ownerNode = ownerNode;
        this._scene = this._ownerNode.getScene();
        if (!SixDofDragBehavior._virtualScene) {
            SixDofDragBehavior._virtualScene = new _scene__WEBPACK_IMPORTED_MODULE_1__["Scene"](this._scene.getEngine());
            SixDofDragBehavior._virtualScene.detachControl();
            this._scene.getEngine().scenes.pop();
        }
        var pickedMesh = null;
        var lastSixDofOriginPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        // Setup virtual meshes to be used for dragging without dirtying the existing scene
        this._virtualOriginMesh = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_0__["AbstractMesh"]("", SixDofDragBehavior._virtualScene);
        this._virtualOriginMesh.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        this._virtualDragMesh = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_0__["AbstractMesh"]("", SixDofDragBehavior._virtualScene);
        this._virtualDragMesh.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        var pickPredicate = function (m) {
            return _this._ownerNode == m || m.isDescendantOf(_this._ownerNode);
        };
        var attachedElement = null;
        this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
            if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERDOWN) {
                if (!_this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
                    if (_this._pointerCamera && _this._pointerCamera.cameraRigMode == _Cameras_camera__WEBPACK_IMPORTED_MODULE_5__["Camera"].RIG_MODE_NONE) {
                        pointerInfo.pickInfo.ray.origin.copyFrom(_this._pointerCamera.globalPosition);
                    }
                    pickedMesh = _this._ownerNode;
                    _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RemoveAndStorePivotPoint(pickedMesh);
                    lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
                    // Set position and orientation of the controller
                    _this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
                    _this._virtualOriginMesh.lookAt(pointerInfo.pickInfo.ray.origin.add(pointerInfo.pickInfo.ray.direction));
                    // Attach the virtual drag mesh to the virtual origin mesh so it can be dragged
                    _this._virtualOriginMesh.removeChild(_this._virtualDragMesh);
                    pickedMesh.computeWorldMatrix();
                    _this._virtualDragMesh.position.copyFrom(pickedMesh.absolutePosition);
                    if (!pickedMesh.rotationQuaternion) {
                        pickedMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(pickedMesh.rotation.y, pickedMesh.rotation.x, pickedMesh.rotation.z);
                    }
                    var oldParent = pickedMesh.parent;
                    pickedMesh.setParent(null);
                    _this._virtualDragMesh.rotationQuaternion.copyFrom(pickedMesh.rotationQuaternion);
                    pickedMesh.setParent(oldParent);
                    _this._virtualOriginMesh.addChild(_this._virtualDragMesh);
                    // Update state
                    _this._targetPosition.copyFrom(_this._virtualDragMesh.absolutePosition);
                    _this.dragging = true;
                    _this.currentDraggingPointerID = pointerInfo.event.pointerId;
                    // Detatch camera controls
                    if (_this.detachCameraControls && _this._pointerCamera && !_this._pointerCamera.leftCamera) {
                        if (_this._pointerCamera.inputs.attachedElement) {
                            attachedElement = _this._pointerCamera.inputs.attachedElement;
                            _this._pointerCamera.detachControl(_this._pointerCamera.inputs.attachedElement);
                        }
                        else {
                            attachedElement = null;
                        }
                    }
                    _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RestorePivotPoint(pickedMesh);
                    _this.onDragStartObservable.notifyObservers({});
                }
            }
            else if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERUP) {
                if (_this.currentDraggingPointerID == pointerInfo.event.pointerId) {
                    _this.dragging = false;
                    _this._moving = false;
                    _this.currentDraggingPointerID = -1;
                    pickedMesh = null;
                    _this._virtualOriginMesh.removeChild(_this._virtualDragMesh);
                    // Reattach camera controls
                    if (_this.detachCameraControls && attachedElement && _this._pointerCamera && !_this._pointerCamera.leftCamera) {
                        _this._pointerCamera.attachControl(attachedElement, true);
                    }
                    _this.onDragEndObservable.notifyObservers({});
                }
            }
            else if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERMOVE) {
                if (_this.currentDraggingPointerID == pointerInfo.event.pointerId && _this.dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray && pickedMesh) {
                    var zDragFactor = _this.zDragFactor;
                    if (_this._pointerCamera && _this._pointerCamera.cameraRigMode == _Cameras_camera__WEBPACK_IMPORTED_MODULE_5__["Camera"].RIG_MODE_NONE) {
                        pointerInfo.pickInfo.ray.origin.copyFrom(_this._pointerCamera.globalPosition);
                        zDragFactor = 0;
                    }
                    // Calculate controller drag distance in controller space
                    var originDragDifference = pointerInfo.pickInfo.ray.origin.subtract(lastSixDofOriginPosition);
                    lastSixDofOriginPosition.copyFrom(pointerInfo.pickInfo.ray.origin);
                    var localOriginDragDifference = -_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(originDragDifference, pointerInfo.pickInfo.ray.direction);
                    _this._virtualOriginMesh.addChild(_this._virtualDragMesh);
                    // Determine how much the controller moved to/away towards the dragged object and use this to move the object further when its further away
                    _this._virtualDragMesh.position.z -= _this._virtualDragMesh.position.z < 1 ? localOriginDragDifference * _this.zDragFactor : localOriginDragDifference * zDragFactor * _this._virtualDragMesh.position.z;
                    if (_this._virtualDragMesh.position.z < 0) {
                        _this._virtualDragMesh.position.z = 0;
                    }
                    // Update the controller position
                    _this._virtualOriginMesh.position.copyFrom(pointerInfo.pickInfo.ray.origin);
                    _this._virtualOriginMesh.lookAt(pointerInfo.pickInfo.ray.origin.add(pointerInfo.pickInfo.ray.direction));
                    _this._virtualOriginMesh.removeChild(_this._virtualDragMesh);
                    // Move the virtualObjectsPosition into the picked mesh's space if needed
                    _this._targetPosition.copyFrom(_this._virtualDragMesh.absolutePosition);
                    if (pickedMesh.parent) {
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(_this._targetPosition, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Invert(pickedMesh.parent.getWorldMatrix()), _this._targetPosition);
                    }
                    if (!_this._moving) {
                        _this._startingOrientation.copyFrom(_this._virtualDragMesh.rotationQuaternion);
                    }
                    _this._moving = true;
                }
            }
        });
        var tmpQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        // On every frame move towards target scaling to avoid jitter caused by vr controllers
        this._sceneRenderObserver = ownerNode.getScene().onBeforeRenderObservable.add(function () {
            if (_this.dragging && _this._moving && pickedMesh) {
                _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RemoveAndStorePivotPoint(pickedMesh);
                // Slowly move mesh to avoid jitter
                pickedMesh.position.addInPlace(_this._targetPosition.subtract(pickedMesh.position).scale(_this.dragDeltaRatio));
                if (_this.rotateDraggedObject) {
                    // Get change in rotation
                    tmpQuaternion.copyFrom(_this._startingOrientation);
                    tmpQuaternion.x = -tmpQuaternion.x;
                    tmpQuaternion.y = -tmpQuaternion.y;
                    tmpQuaternion.z = -tmpQuaternion.z;
                    _this._virtualDragMesh.rotationQuaternion.multiplyToRef(tmpQuaternion, tmpQuaternion);
                    // Convert change in rotation to only y axis rotation
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(tmpQuaternion.toEulerAngles("xyz").y, 0, 0, tmpQuaternion);
                    tmpQuaternion.multiplyToRef(_this._startingOrientation, tmpQuaternion);
                    // Slowly move mesh to avoid jitter
                    var oldParent = pickedMesh.parent;
                    // Only rotate the mesh if it's parent has uniform scaling
                    if (!oldParent || (oldParent.scaling && !oldParent.scaling.isNonUniformWithinEpsilon(0.001))) {
                        pickedMesh.setParent(null);
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].SlerpToRef(pickedMesh.rotationQuaternion, tmpQuaternion, _this.dragDeltaRatio, pickedMesh.rotationQuaternion);
                        pickedMesh.setParent(oldParent);
                    }
                }
                _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_6__["PivotTools"]._RestorePivotPoint(pickedMesh);
            }
        });
    };
    /**
     *  Detaches the behavior from the mesh
     */
    SixDofDragBehavior.prototype.detach = function () {
        if (this._scene) {
            this._scene.onPointerObservable.remove(this._pointerObserver);
        }
        if (this._ownerNode) {
            this._ownerNode.getScene().onBeforeRenderObservable.remove(this._sceneRenderObserver);
        }
        if (this._virtualOriginMesh) {
            this._virtualOriginMesh.dispose();
        }
        if (this._virtualDragMesh) {
            this._virtualDragMesh.dispose();
        }
        this.onDragEndObservable.clear();
        this.onDragStartObservable.clear();
    };
    return SixDofDragBehavior;
}());



/***/ }),

/***/ "./Behaviors/index.ts":
/*!****************************!*\
  !*** ./Behaviors/index.ts ***!
  \****************************/
/*! exports provided: AutoRotationBehavior, BouncingBehavior, FramingBehavior, AttachToBoxBehavior, FadeInOutBehavior, MultiPointerScaleBehavior, PointerDragBehavior, SixDofDragBehavior */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Cameras_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Cameras/index */ "./Behaviors/Cameras/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AutoRotationBehavior", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_0__["AutoRotationBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BouncingBehavior", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_0__["BouncingBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FramingBehavior", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_0__["FramingBehavior"]; });

/* harmony import */ var _Meshes_index__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Meshes/index */ "./Behaviors/Meshes/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AttachToBoxBehavior", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_1__["AttachToBoxBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FadeInOutBehavior", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_1__["FadeInOutBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiPointerScaleBehavior", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_1__["MultiPointerScaleBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerDragBehavior", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_1__["PointerDragBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SixDofDragBehavior", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_1__["SixDofDragBehavior"]; });





/***/ }),

/***/ "./Bones/bone.ts":
/*!***********************!*\
  !*** ./Bones/bone.ts ***!
  \***********************/
/*! exports provided: Bone */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Bone", function() { return Bone; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");





/**
 * Class used to store bone information
 * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons
 */
var Bone = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Bone, _super);
    /**
     * Create a new bone
     * @param name defines the bone name
     * @param skeleton defines the parent skeleton
     * @param parentBone defines the parent (can be null if the bone is the root)
     * @param localMatrix defines the local matrix
     * @param restPose defines the rest pose matrix
     * @param baseMatrix defines the base matrix
     * @param index defines index of the bone in the hiearchy
     */
    function Bone(
    /**
     * defines the bone name
     */
    name, skeleton, parentBone, localMatrix, restPose, baseMatrix, index) {
        if (parentBone === void 0) { parentBone = null; }
        if (localMatrix === void 0) { localMatrix = null; }
        if (restPose === void 0) { restPose = null; }
        if (baseMatrix === void 0) { baseMatrix = null; }
        if (index === void 0) { index = null; }
        var _this = _super.call(this, name, skeleton.getScene(), false) || this;
        _this.name = name;
        /**
         * Gets the list of child bones
         */
        _this.children = new Array();
        /** Gets the animations associated with this bone */
        _this.animations = new Array();
        /**
         * @hidden Internal only
         * Set this value to map this bone to a different index in the transform matrices
         * Set this value to -1 to exclude the bone from the transform matrices
         */
        _this._index = null;
        _this._absoluteTransform = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
        _this._invertedAbsoluteTransform = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
        _this._scalingDeterminant = 1;
        _this._worldTransform = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
        _this._needToDecompose = true;
        _this._needToCompose = false;
        /** @hidden */
        _this._linkedTransformNode = null;
        /** @hidden */
        _this._waitingTransformNodeId = null;
        _this._skeleton = skeleton;
        _this._localMatrix = localMatrix ? localMatrix.clone() : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        _this._restPose = restPose ? restPose : _this._localMatrix.clone();
        _this._baseMatrix = baseMatrix ? baseMatrix : _this._localMatrix.clone();
        _this._index = index;
        skeleton.bones.push(_this);
        _this.setParent(parentBone, false);
        if (baseMatrix || localMatrix) {
            _this._updateDifferenceMatrix();
        }
        return _this;
    }
    Object.defineProperty(Bone.prototype, "_matrix", {
        /** @hidden */
        get: function () {
            this._compose();
            return this._localMatrix;
        },
        /** @hidden */
        set: function (value) {
            this._localMatrix.copyFrom(value);
            this._needToDecompose = true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current object class name.
     * @return the class name
     */
    Bone.prototype.getClassName = function () {
        return "Bone";
    };
    // Members
    /**
     * Gets the parent skeleton
     * @returns a skeleton
     */
    Bone.prototype.getSkeleton = function () {
        return this._skeleton;
    };
    /**
     * Gets parent bone
     * @returns a bone or null if the bone is the root of the bone hierarchy
     */
    Bone.prototype.getParent = function () {
        return this._parent;
    };
    /**
     * Returns an array containing the root bones
     * @returns an array containing the root bones
     */
    Bone.prototype.getChildren = function () {
        return this.children;
    };
    /**
     * Sets the parent bone
     * @param parent defines the parent (can be null if the bone is the root)
     * @param updateDifferenceMatrix defines if the difference matrix must be updated
     */
    Bone.prototype.setParent = function (parent, updateDifferenceMatrix) {
        if (updateDifferenceMatrix === void 0) { updateDifferenceMatrix = true; }
        if (this._parent === parent) {
            return;
        }
        if (this._parent) {
            var index = this._parent.children.indexOf(this);
            if (index !== -1) {
                this._parent.children.splice(index, 1);
            }
        }
        this._parent = parent;
        if (this._parent) {
            this._parent.children.push(this);
        }
        if (updateDifferenceMatrix) {
            this._updateDifferenceMatrix();
        }
        this.markAsDirty();
    };
    /**
     * Gets the local matrix
     * @returns a matrix
     */
    Bone.prototype.getLocalMatrix = function () {
        this._compose();
        return this._localMatrix;
    };
    /**
     * Gets the base matrix (initial matrix which remains unchanged)
     * @returns a matrix
     */
    Bone.prototype.getBaseMatrix = function () {
        return this._baseMatrix;
    };
    /**
     * Gets the rest pose matrix
     * @returns a matrix
     */
    Bone.prototype.getRestPose = function () {
        return this._restPose;
    };
    /**
     * Gets a matrix used to store world matrix (ie. the matrix sent to shaders)
     */
    Bone.prototype.getWorldMatrix = function () {
        return this._worldTransform;
    };
    /**
     * Sets the local matrix to rest pose matrix
     */
    Bone.prototype.returnToRest = function () {
        this.updateMatrix(this._restPose.clone());
    };
    /**
     * Gets the inverse of the absolute transform matrix.
     * This matrix will be multiplied by local matrix to get the difference matrix (ie. the difference between original state and current state)
     * @returns a matrix
     */
    Bone.prototype.getInvertedAbsoluteTransform = function () {
        return this._invertedAbsoluteTransform;
    };
    /**
     * Gets the absolute transform matrix (ie base matrix * parent world matrix)
     * @returns a matrix
     */
    Bone.prototype.getAbsoluteTransform = function () {
        return this._absoluteTransform;
    };
    /**
     * Links with the given transform node.
     * The local matrix of this bone is copied from the transform node every frame.
     * @param transformNode defines the transform node to link to
     */
    Bone.prototype.linkTransformNode = function (transformNode) {
        if (this._linkedTransformNode) {
            this._skeleton._numBonesWithLinkedTransformNode--;
        }
        this._linkedTransformNode = transformNode;
        if (this._linkedTransformNode) {
            this._skeleton._numBonesWithLinkedTransformNode++;
        }
    };
    // Properties (matches AbstractMesh properties)
    /**
     * Gets the node used to drive the bone's transformation
     * @returns a transform node or null
     */
    Bone.prototype.getTransformNode = function () {
        return this._linkedTransformNode;
    };
    Object.defineProperty(Bone.prototype, "position", {
        /** Gets or sets current position (in local space) */
        get: function () {
            this._decompose();
            return this._localPosition;
        },
        set: function (newPosition) {
            this._decompose();
            this._localPosition.copyFrom(newPosition);
            this._markAsDirtyAndCompose();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Bone.prototype, "rotation", {
        /** Gets or sets current rotation (in local space) */
        get: function () {
            return this.getRotation();
        },
        set: function (newRotation) {
            this.setRotation(newRotation);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Bone.prototype, "rotationQuaternion", {
        /** Gets or sets current rotation quaternion (in local space) */
        get: function () {
            this._decompose();
            return this._localRotation;
        },
        set: function (newRotation) {
            this.setRotationQuaternion(newRotation);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Bone.prototype, "scaling", {
        /** Gets or sets current scaling (in local space) */
        get: function () {
            return this.getScale();
        },
        set: function (newScaling) {
            this.setScale(newScaling);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Bone.prototype, "animationPropertiesOverride", {
        /**
         * Gets the animation properties override
         */
        get: function () {
            return this._skeleton.animationPropertiesOverride;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    Bone.prototype._decompose = function () {
        if (!this._needToDecompose) {
            return;
        }
        this._needToDecompose = false;
        if (!this._localScaling) {
            this._localScaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
            this._localRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Zero();
            this._localPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        }
        this._localMatrix.decompose(this._localScaling, this._localRotation, this._localPosition);
    };
    Bone.prototype._compose = function () {
        if (!this._needToCompose) {
            return;
        }
        if (!this._localScaling) {
            this._needToCompose = false;
            return;
        }
        this._needToCompose = false;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].ComposeToRef(this._localScaling, this._localRotation, this._localPosition, this._localMatrix);
    };
    /**
     * Update the base and local matrices
     * @param matrix defines the new base or local matrix
     * @param updateDifferenceMatrix defines if the difference matrix must be updated
     * @param updateLocalMatrix defines if the local matrix should be updated
     */
    Bone.prototype.updateMatrix = function (matrix, updateDifferenceMatrix, updateLocalMatrix) {
        if (updateDifferenceMatrix === void 0) { updateDifferenceMatrix = true; }
        if (updateLocalMatrix === void 0) { updateLocalMatrix = true; }
        this._baseMatrix.copyFrom(matrix);
        if (updateDifferenceMatrix) {
            this._updateDifferenceMatrix();
        }
        if (updateLocalMatrix) {
            this._localMatrix.copyFrom(matrix);
            this._markAsDirtyAndDecompose();
        }
        else {
            this.markAsDirty();
        }
    };
    /** @hidden */
    Bone.prototype._updateDifferenceMatrix = function (rootMatrix, updateChildren) {
        if (updateChildren === void 0) { updateChildren = true; }
        if (!rootMatrix) {
            rootMatrix = this._baseMatrix;
        }
        if (this._parent) {
            rootMatrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
        }
        else {
            this._absoluteTransform.copyFrom(rootMatrix);
        }
        this._absoluteTransform.invertToRef(this._invertedAbsoluteTransform);
        if (updateChildren) {
            for (var index = 0; index < this.children.length; index++) {
                this.children[index]._updateDifferenceMatrix();
            }
        }
        this._scalingDeterminant = (this._absoluteTransform.determinant() < 0 ? -1 : 1);
    };
    /**
     * Flag the bone as dirty (Forcing it to update everything)
     */
    Bone.prototype.markAsDirty = function () {
        this._currentRenderId++;
        this._childUpdateId++;
        this._skeleton._markAsDirty();
    };
    /** @hidden */
    Bone.prototype._markAsDirtyAndCompose = function () {
        this.markAsDirty();
        this._needToCompose = true;
    };
    Bone.prototype._markAsDirtyAndDecompose = function () {
        this.markAsDirty();
        this._needToDecompose = true;
    };
    /**
     * Translate the bone in local or world space
     * @param vec The amount to translate the bone
     * @param space The space that the translation is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     */
    Bone.prototype.translate = function (vec, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        var lm = this.getLocalMatrix();
        if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            lm.addAtIndex(12, vec.x);
            lm.addAtIndex(13, vec.y);
            lm.addAtIndex(14, vec.z);
        }
        else {
            var wm = null;
            //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
            if (mesh) {
                wm = mesh.getWorldMatrix();
            }
            this._skeleton.computeAbsoluteTransforms();
            var tmat = Bone._tmpMats[0];
            var tvec = Bone._tmpVecs[0];
            if (this._parent) {
                if (mesh && wm) {
                    tmat.copyFrom(this._parent.getAbsoluteTransform());
                    tmat.multiplyToRef(wm, tmat);
                }
                else {
                    tmat.copyFrom(this._parent.getAbsoluteTransform());
                }
            }
            tmat.setTranslationFromFloats(0, 0, 0);
            tmat.invert();
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(vec, tmat, tvec);
            lm.addAtIndex(12, tvec.x);
            lm.addAtIndex(13, tvec.y);
            lm.addAtIndex(14, tvec.z);
        }
        this._markAsDirtyAndDecompose();
    };
    /**
     * Set the postion of the bone in local or world space
     * @param position The position to set the bone
     * @param space The space that the position is in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     */
    Bone.prototype.setPosition = function (position, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        var lm = this.getLocalMatrix();
        if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            lm.setTranslationFromFloats(position.x, position.y, position.z);
        }
        else {
            var wm = null;
            //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
            if (mesh) {
                wm = mesh.getWorldMatrix();
            }
            this._skeleton.computeAbsoluteTransforms();
            var tmat = Bone._tmpMats[0];
            var vec = Bone._tmpVecs[0];
            if (this._parent) {
                if (mesh && wm) {
                    tmat.copyFrom(this._parent.getAbsoluteTransform());
                    tmat.multiplyToRef(wm, tmat);
                }
                else {
                    tmat.copyFrom(this._parent.getAbsoluteTransform());
                }
            }
            tmat.invert();
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(position, tmat, vec);
            lm.setTranslationFromFloats(vec.x, vec.y, vec.z);
        }
        this._markAsDirtyAndDecompose();
    };
    /**
     * Set the absolute position of the bone (world space)
     * @param position The position to set the bone
     * @param mesh The mesh that this bone is attached to
     */
    Bone.prototype.setAbsolutePosition = function (position, mesh) {
        this.setPosition(position, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].WORLD, mesh);
    };
    /**
     * Scale the bone on the x, y and z axes (in local space)
     * @param x The amount to scale the bone on the x axis
     * @param y The amount to scale the bone on the y axis
     * @param z The amount to scale the bone on the z axis
     * @param scaleChildren sets this to true if children of the bone should be scaled as well (false by default)
     */
    Bone.prototype.scale = function (x, y, z, scaleChildren) {
        if (scaleChildren === void 0) { scaleChildren = false; }
        var locMat = this.getLocalMatrix();
        // Apply new scaling on top of current local matrix
        var scaleMat = Bone._tmpMats[0];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].ScalingToRef(x, y, z, scaleMat);
        scaleMat.multiplyToRef(locMat, locMat);
        // Invert scaling matrix and apply the inverse to all children
        scaleMat.invert();
        for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
            var child = _a[_i];
            var cm = child.getLocalMatrix();
            cm.multiplyToRef(scaleMat, cm);
            cm.multiplyAtIndex(12, x);
            cm.multiplyAtIndex(13, y);
            cm.multiplyAtIndex(14, z);
            child._markAsDirtyAndDecompose();
        }
        this._markAsDirtyAndDecompose();
        if (scaleChildren) {
            for (var _b = 0, _c = this.children; _b < _c.length; _b++) {
                var child = _c[_b];
                child.scale(x, y, z, scaleChildren);
            }
        }
    };
    /**
     * Set the bone scaling in local space
     * @param scale defines the scaling vector
     */
    Bone.prototype.setScale = function (scale) {
        this._decompose();
        this._localScaling.copyFrom(scale);
        this._markAsDirtyAndCompose();
    };
    /**
     * Gets the current scaling in local space
     * @returns the current scaling vector
     */
    Bone.prototype.getScale = function () {
        this._decompose();
        return this._localScaling;
    };
    /**
     * Gets the current scaling in local space and stores it in a target vector
     * @param result defines the target vector
     */
    Bone.prototype.getScaleToRef = function (result) {
        this._decompose();
        result.copyFrom(this._localScaling);
    };
    /**
     * Set the yaw, pitch, and roll of the bone in local or world space
     * @param yaw The rotation of the bone on the y axis
     * @param pitch The rotation of the bone on the x axis
     * @param roll The rotation of the bone on the z axis
     * @param space The space that the axes of rotation are in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     */
    Bone.prototype.setYawPitchRoll = function (yaw, pitch, roll, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            var quat = Bone._tmpQuat;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].RotationYawPitchRollToRef(yaw, pitch, roll, quat);
            this.setRotationQuaternion(quat, space, mesh);
            return;
        }
        var rotMatInv = Bone._tmpMats[0];
        if (!this._getNegativeRotationToRef(rotMatInv, mesh)) {
            return;
        }
        var rotMat = Bone._tmpMats[1];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].RotationYawPitchRollToRef(yaw, pitch, roll, rotMat);
        rotMatInv.multiplyToRef(rotMat, rotMat);
        this._rotateWithMatrix(rotMat, space, mesh);
    };
    /**
     * Add a rotation to the bone on an axis in local or world space
     * @param axis The axis to rotate the bone on
     * @param amount The amount to rotate the bone
     * @param space The space that the axis is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     */
    Bone.prototype.rotate = function (axis, amount, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        var rmat = Bone._tmpMats[0];
        rmat.setTranslationFromFloats(0, 0, 0);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].RotationAxisToRef(axis, amount, rmat);
        this._rotateWithMatrix(rmat, space, mesh);
    };
    /**
     * Set the rotation of the bone to a particular axis angle in local or world space
     * @param axis The axis to rotate the bone on
     * @param angle The angle that the bone should be rotated to
     * @param space The space that the axis is in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     */
    Bone.prototype.setAxisAngle = function (axis, angle, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            var quat = Bone._tmpQuat;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].RotationAxisToRef(axis, angle, quat);
            this.setRotationQuaternion(quat, space, mesh);
            return;
        }
        var rotMatInv = Bone._tmpMats[0];
        if (!this._getNegativeRotationToRef(rotMatInv, mesh)) {
            return;
        }
        var rotMat = Bone._tmpMats[1];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].RotationAxisToRef(axis, angle, rotMat);
        rotMatInv.multiplyToRef(rotMat, rotMat);
        this._rotateWithMatrix(rotMat, space, mesh);
    };
    /**
     * Set the euler rotation of the bone in local of world space
     * @param rotation The euler rotation that the bone should be set to
     * @param space The space that the rotation is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     */
    Bone.prototype.setRotation = function (rotation, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        this.setYawPitchRoll(rotation.y, rotation.x, rotation.z, space, mesh);
    };
    /**
     * Set the quaternion rotation of the bone in local of world space
     * @param quat The quaternion rotation that the bone should be set to
     * @param space The space that the rotation is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     */
    Bone.prototype.setRotationQuaternion = function (quat, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            this._decompose();
            this._localRotation.copyFrom(quat);
            this._markAsDirtyAndCompose();
            return;
        }
        var rotMatInv = Bone._tmpMats[0];
        if (!this._getNegativeRotationToRef(rotMatInv, mesh)) {
            return;
        }
        var rotMat = Bone._tmpMats[1];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromQuaternionToRef(quat, rotMat);
        rotMatInv.multiplyToRef(rotMat, rotMat);
        this._rotateWithMatrix(rotMat, space, mesh);
    };
    /**
     * Set the rotation matrix of the bone in local of world space
     * @param rotMat The rotation matrix that the bone should be set to
     * @param space The space that the rotation is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     */
    Bone.prototype.setRotationMatrix = function (rotMat, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            var quat = Bone._tmpQuat;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].FromRotationMatrixToRef(rotMat, quat);
            this.setRotationQuaternion(quat, space, mesh);
            return;
        }
        var rotMatInv = Bone._tmpMats[0];
        if (!this._getNegativeRotationToRef(rotMatInv, mesh)) {
            return;
        }
        var rotMat2 = Bone._tmpMats[1];
        rotMat2.copyFrom(rotMat);
        rotMatInv.multiplyToRef(rotMat, rotMat2);
        this._rotateWithMatrix(rotMat2, space, mesh);
    };
    Bone.prototype._rotateWithMatrix = function (rmat, space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        var lmat = this.getLocalMatrix();
        var lx = lmat.m[12];
        var ly = lmat.m[13];
        var lz = lmat.m[14];
        var parent = this.getParent();
        var parentScale = Bone._tmpMats[3];
        var parentScaleInv = Bone._tmpMats[4];
        if (parent && space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].WORLD) {
            if (mesh) {
                parentScale.copyFrom(mesh.getWorldMatrix());
                parent.getAbsoluteTransform().multiplyToRef(parentScale, parentScale);
            }
            else {
                parentScale.copyFrom(parent.getAbsoluteTransform());
            }
            parentScaleInv.copyFrom(parentScale);
            parentScaleInv.invert();
            lmat.multiplyToRef(parentScale, lmat);
            lmat.multiplyToRef(rmat, lmat);
            lmat.multiplyToRef(parentScaleInv, lmat);
        }
        else {
            if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].WORLD && mesh) {
                parentScale.copyFrom(mesh.getWorldMatrix());
                parentScaleInv.copyFrom(parentScale);
                parentScaleInv.invert();
                lmat.multiplyToRef(parentScale, lmat);
                lmat.multiplyToRef(rmat, lmat);
                lmat.multiplyToRef(parentScaleInv, lmat);
            }
            else {
                lmat.multiplyToRef(rmat, lmat);
            }
        }
        lmat.setTranslationFromFloats(lx, ly, lz);
        this.computeAbsoluteTransforms();
        this._markAsDirtyAndDecompose();
    };
    Bone.prototype._getNegativeRotationToRef = function (rotMatInv, mesh) {
        var scaleMatrix = Bone._tmpMats[2];
        rotMatInv.copyFrom(this.getAbsoluteTransform());
        if (mesh) {
            rotMatInv.multiplyToRef(mesh.getWorldMatrix(), rotMatInv);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].ScalingToRef(mesh.scaling.x, mesh.scaling.y, mesh.scaling.z, scaleMatrix);
        }
        rotMatInv.invert();
        if (isNaN(rotMatInv.m[0])) {
            // Matrix failed to invert.
            // This can happen if scale is zero for example.
            return false;
        }
        scaleMatrix.multiplyAtIndex(0, this._scalingDeterminant);
        rotMatInv.multiplyToRef(scaleMatrix, rotMatInv);
        return true;
    };
    /**
     * Get the position of the bone in local or world space
     * @param space The space that the returned position is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     * @returns The position of the bone
     */
    Bone.prototype.getPosition = function (space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (mesh === void 0) { mesh = null; }
        var pos = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.getPositionToRef(space, mesh, pos);
        return pos;
    };
    /**
     * Copy the position of the bone to a vector3 in local or world space
     * @param space The space that the returned position is in
     * @param mesh The mesh that this bone is attached to. This is only used in world space
     * @param result The vector3 to copy the position to
     */
    Bone.prototype.getPositionToRef = function (space, mesh, result) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            var lm = this.getLocalMatrix();
            result.x = lm.m[12];
            result.y = lm.m[13];
            result.z = lm.m[14];
        }
        else {
            var wm = null;
            //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
            if (mesh) {
                wm = mesh.getWorldMatrix();
            }
            this._skeleton.computeAbsoluteTransforms();
            var tmat = Bone._tmpMats[0];
            if (mesh && wm) {
                tmat.copyFrom(this.getAbsoluteTransform());
                tmat.multiplyToRef(wm, tmat);
            }
            else {
                tmat = this.getAbsoluteTransform();
            }
            result.x = tmat.m[12];
            result.y = tmat.m[13];
            result.z = tmat.m[14];
        }
    };
    /**
     * Get the absolute position of the bone (world space)
     * @param mesh The mesh that this bone is attached to
     * @returns The absolute position of the bone
     */
    Bone.prototype.getAbsolutePosition = function (mesh) {
        if (mesh === void 0) { mesh = null; }
        var pos = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.getPositionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].WORLD, mesh, pos);
        return pos;
    };
    /**
     * Copy the absolute position of the bone (world space) to the result param
     * @param mesh The mesh that this bone is attached to
     * @param result The vector3 to copy the absolute position to
     */
    Bone.prototype.getAbsolutePositionToRef = function (mesh, result) {
        this.getPositionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].WORLD, mesh, result);
    };
    /**
     * Compute the absolute transforms of this bone and its children
     */
    Bone.prototype.computeAbsoluteTransforms = function () {
        this._compose();
        if (this._parent) {
            this._localMatrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
        }
        else {
            this._absoluteTransform.copyFrom(this._localMatrix);
            var poseMatrix = this._skeleton.getPoseMatrix();
            if (poseMatrix) {
                this._absoluteTransform.multiplyToRef(poseMatrix, this._absoluteTransform);
            }
        }
        var children = this.children;
        var len = children.length;
        for (var i = 0; i < len; i++) {
            children[i].computeAbsoluteTransforms();
        }
    };
    /**
     * Get the world direction from an axis that is in the local space of the bone
     * @param localAxis The local direction that is used to compute the world direction
     * @param mesh The mesh that this bone is attached to
     * @returns The world direction
     */
    Bone.prototype.getDirection = function (localAxis, mesh) {
        if (mesh === void 0) { mesh = null; }
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.getDirectionToRef(localAxis, mesh, result);
        return result;
    };
    /**
     * Copy the world direction to a vector3 from an axis that is in the local space of the bone
     * @param localAxis The local direction that is used to compute the world direction
     * @param mesh The mesh that this bone is attached to
     * @param result The vector3 that the world direction will be copied to
     */
    Bone.prototype.getDirectionToRef = function (localAxis, mesh, result) {
        if (mesh === void 0) { mesh = null; }
        var wm = null;
        //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
        if (mesh) {
            wm = mesh.getWorldMatrix();
        }
        this._skeleton.computeAbsoluteTransforms();
        var mat = Bone._tmpMats[0];
        mat.copyFrom(this.getAbsoluteTransform());
        if (mesh && wm) {
            mat.multiplyToRef(wm, mat);
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalToRef(localAxis, mat, result);
        result.normalize();
    };
    /**
     * Get the euler rotation of the bone in local or world space
     * @param space The space that the rotation should be in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     * @returns The euler rotation
     */
    Bone.prototype.getRotation = function (space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (mesh === void 0) { mesh = null; }
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.getRotationToRef(space, mesh, result);
        return result;
    };
    /**
     * Copy the euler rotation of the bone to a vector3.  The rotation can be in either local or world space
     * @param space The space that the rotation should be in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     * @param result The vector3 that the rotation should be copied to
     */
    Bone.prototype.getRotationToRef = function (space, mesh, result) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (mesh === void 0) { mesh = null; }
        var quat = Bone._tmpQuat;
        this.getRotationQuaternionToRef(space, mesh, quat);
        quat.toEulerAnglesToRef(result);
    };
    /**
     * Get the quaternion rotation of the bone in either local or world space
     * @param space The space that the rotation should be in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     * @returns The quaternion rotation
     */
    Bone.prototype.getRotationQuaternion = function (space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (mesh === void 0) { mesh = null; }
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity();
        this.getRotationQuaternionToRef(space, mesh, result);
        return result;
    };
    /**
     * Copy the quaternion rotation of the bone to a quaternion.  The rotation can be in either local or world space
     * @param space The space that the rotation should be in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     * @param result The quaternion that the rotation should be copied to
     */
    Bone.prototype.getRotationQuaternionToRef = function (space, mesh, result) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (mesh === void 0) { mesh = null; }
        if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            this._decompose();
            result.copyFrom(this._localRotation);
        }
        else {
            var mat = Bone._tmpMats[0];
            var amat = this.getAbsoluteTransform();
            if (mesh) {
                amat.multiplyToRef(mesh.getWorldMatrix(), mat);
            }
            else {
                mat.copyFrom(amat);
            }
            mat.multiplyAtIndex(0, this._scalingDeterminant);
            mat.multiplyAtIndex(1, this._scalingDeterminant);
            mat.multiplyAtIndex(2, this._scalingDeterminant);
            mat.decompose(undefined, result, undefined);
        }
    };
    /**
     * Get the rotation matrix of the bone in local or world space
     * @param space The space that the rotation should be in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     * @returns The rotation matrix
     */
    Bone.prototype.getRotationMatrix = function (space, mesh) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        this.getRotationMatrixToRef(space, mesh, result);
        return result;
    };
    /**
     * Copy the rotation matrix of the bone to a matrix.  The rotation can be in either local or world space
     * @param space The space that the rotation should be in
     * @param mesh The mesh that this bone is attached to.  This is only used in world space
     * @param result The quaternion that the rotation should be copied to
     */
    Bone.prototype.getRotationMatrixToRef = function (space, mesh, result) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL; }
        if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Space"].LOCAL) {
            this.getLocalMatrix().getRotationMatrixToRef(result);
        }
        else {
            var mat = Bone._tmpMats[0];
            var amat = this.getAbsoluteTransform();
            if (mesh) {
                amat.multiplyToRef(mesh.getWorldMatrix(), mat);
            }
            else {
                mat.copyFrom(amat);
            }
            mat.multiplyAtIndex(0, this._scalingDeterminant);
            mat.multiplyAtIndex(1, this._scalingDeterminant);
            mat.multiplyAtIndex(2, this._scalingDeterminant);
            mat.getRotationMatrixToRef(result);
        }
    };
    /**
     * Get the world position of a point that is in the local space of the bone
     * @param position The local position
     * @param mesh The mesh that this bone is attached to
     * @returns The world position
     */
    Bone.prototype.getAbsolutePositionFromLocal = function (position, mesh) {
        if (mesh === void 0) { mesh = null; }
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.getAbsolutePositionFromLocalToRef(position, mesh, result);
        return result;
    };
    /**
     * Get the world position of a point that is in the local space of the bone and copy it to the result param
     * @param position The local position
     * @param mesh The mesh that this bone is attached to
     * @param result The vector3 that the world position should be copied to
     */
    Bone.prototype.getAbsolutePositionFromLocalToRef = function (position, mesh, result) {
        if (mesh === void 0) { mesh = null; }
        var wm = null;
        //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
        if (mesh) {
            wm = mesh.getWorldMatrix();
        }
        this._skeleton.computeAbsoluteTransforms();
        var tmat = Bone._tmpMats[0];
        if (mesh && wm) {
            tmat.copyFrom(this.getAbsoluteTransform());
            tmat.multiplyToRef(wm, tmat);
        }
        else {
            tmat = this.getAbsoluteTransform();
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(position, tmat, result);
    };
    /**
     * Get the local position of a point that is in world space
     * @param position The world position
     * @param mesh The mesh that this bone is attached to
     * @returns The local position
     */
    Bone.prototype.getLocalPositionFromAbsolute = function (position, mesh) {
        if (mesh === void 0) { mesh = null; }
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.getLocalPositionFromAbsoluteToRef(position, mesh, result);
        return result;
    };
    /**
     * Get the local position of a point that is in world space and copy it to the result param
     * @param position The world position
     * @param mesh The mesh that this bone is attached to
     * @param result The vector3 that the local position should be copied to
     */
    Bone.prototype.getLocalPositionFromAbsoluteToRef = function (position, mesh, result) {
        if (mesh === void 0) { mesh = null; }
        var wm = null;
        //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
        if (mesh) {
            wm = mesh.getWorldMatrix();
        }
        this._skeleton.computeAbsoluteTransforms();
        var tmat = Bone._tmpMats[0];
        tmat.copyFrom(this.getAbsoluteTransform());
        if (mesh && wm) {
            tmat.multiplyToRef(wm, tmat);
        }
        tmat.invert();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(position, tmat, result);
    };
    Bone._tmpVecs = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(2, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
    Bone._tmpQuat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity();
    Bone._tmpMats = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(5, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity);
    return Bone;
}(_node__WEBPACK_IMPORTED_MODULE_3__["Node"]));



/***/ }),

/***/ "./Bones/boneIKController.ts":
/*!***********************************!*\
  !*** ./Bones/boneIKController.ts ***!
  \***********************************/
/*! exports provided: BoneIKController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoneIKController", function() { return BoneIKController; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");


/**
 * Class used to apply inverse kinematics to bones
 * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons#boneikcontroller
 */
var BoneIKController = /** @class */ (function () {
    /**
     * Creates a new BoneIKController
     * @param mesh defines the mesh to control
     * @param bone defines the bone to control
     * @param options defines options to set up the controller
     */
    function BoneIKController(mesh, bone, options) {
        /**
         * Gets or sets the target position
         */
        this.targetPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * Gets or sets the pole target position
         */
        this.poleTargetPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * Gets or sets the pole target local offset
         */
        this.poleTargetLocalOffset = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * Gets or sets the pole angle
         */
        this.poleAngle = 0;
        /**
         * The amount to slerp (spherical linear interpolation) to the target.  Set this to a value between 0 and 1 (a value of 1 disables slerp)
         */
        this.slerpAmount = 1;
        this._bone1Quat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity();
        this._bone1Mat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Identity();
        this._bone2Ang = Math.PI;
        this._maxAngle = Math.PI;
        this._rightHandedSystem = false;
        this._bendAxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Right();
        this._slerping = false;
        this._adjustRoll = 0;
        this._bone2 = bone;
        this._bone1 = bone.getParent();
        if (!this._bone1) {
            return;
        }
        this.mesh = mesh;
        var bonePos = bone.getPosition();
        if (bone.getAbsoluteTransform().determinant() > 0) {
            this._rightHandedSystem = true;
            this._bendAxis.x = 0;
            this._bendAxis.y = 0;
            this._bendAxis.z = -1;
            if (bonePos.x > bonePos.y && bonePos.x > bonePos.z) {
                this._adjustRoll = Math.PI * .5;
                this._bendAxis.z = 1;
            }
        }
        if (this._bone1.length) {
            var boneScale1 = this._bone1.getScale();
            var boneScale2 = this._bone2.getScale();
            this._bone1Length = this._bone1.length * boneScale1.y * this.mesh.scaling.y;
            this._bone2Length = this._bone2.length * boneScale2.y * this.mesh.scaling.y;
        }
        else if (this._bone1.children[0]) {
            mesh.computeWorldMatrix(true);
            var pos1 = this._bone2.children[0].getAbsolutePosition(mesh);
            var pos2 = this._bone2.getAbsolutePosition(mesh);
            var pos3 = this._bone1.getAbsolutePosition(mesh);
            this._bone1Length = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Distance(pos1, pos2);
            this._bone2Length = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Distance(pos2, pos3);
        }
        this._bone1.getRotationMatrixToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_1__["Space"].WORLD, mesh, this._bone1Mat);
        this.maxAngle = Math.PI;
        if (options) {
            if (options.targetMesh) {
                this.targetMesh = options.targetMesh;
                this.targetMesh.computeWorldMatrix(true);
            }
            if (options.poleTargetMesh) {
                this.poleTargetMesh = options.poleTargetMesh;
                this.poleTargetMesh.computeWorldMatrix(true);
            }
            else if (options.poleTargetBone) {
                this.poleTargetBone = options.poleTargetBone;
            }
            else if (this._bone1.getParent()) {
                this.poleTargetBone = this._bone1.getParent();
            }
            if (options.poleTargetLocalOffset) {
                this.poleTargetLocalOffset.copyFrom(options.poleTargetLocalOffset);
            }
            if (options.poleAngle) {
                this.poleAngle = options.poleAngle;
            }
            if (options.bendAxis) {
                this._bendAxis.copyFrom(options.bendAxis);
            }
            if (options.maxAngle) {
                this.maxAngle = options.maxAngle;
            }
            if (options.slerpAmount) {
                this.slerpAmount = options.slerpAmount;
            }
        }
    }
    Object.defineProperty(BoneIKController.prototype, "maxAngle", {
        /**
         * Gets or sets maximum allowed angle
         */
        get: function () {
            return this._maxAngle;
        },
        set: function (value) {
            this._setMaxAngle(value);
        },
        enumerable: true,
        configurable: true
    });
    BoneIKController.prototype._setMaxAngle = function (ang) {
        if (ang < 0) {
            ang = 0;
        }
        if (ang > Math.PI || ang == undefined) {
            ang = Math.PI;
        }
        this._maxAngle = ang;
        var a = this._bone1Length;
        var b = this._bone2Length;
        this._maxReach = Math.sqrt(a * a + b * b - 2 * a * b * Math.cos(ang));
    };
    /**
     * Force the controller to update the bones
     */
    BoneIKController.prototype.update = function () {
        var bone1 = this._bone1;
        if (!bone1) {
            return;
        }
        var target = this.targetPosition;
        var poleTarget = this.poleTargetPosition;
        var mat1 = BoneIKController._tmpMats[0];
        var mat2 = BoneIKController._tmpMats[1];
        if (this.targetMesh) {
            target.copyFrom(this.targetMesh.getAbsolutePosition());
        }
        if (this.poleTargetBone) {
            this.poleTargetBone.getAbsolutePositionFromLocalToRef(this.poleTargetLocalOffset, this.mesh, poleTarget);
        }
        else if (this.poleTargetMesh) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this.poleTargetLocalOffset, this.poleTargetMesh.getWorldMatrix(), poleTarget);
        }
        var bonePos = BoneIKController._tmpVecs[0];
        var zaxis = BoneIKController._tmpVecs[1];
        var xaxis = BoneIKController._tmpVecs[2];
        var yaxis = BoneIKController._tmpVecs[3];
        var upAxis = BoneIKController._tmpVecs[4];
        var _tmpQuat = BoneIKController._tmpQuat;
        bone1.getAbsolutePositionToRef(this.mesh, bonePos);
        poleTarget.subtractToRef(bonePos, upAxis);
        if (upAxis.x == 0 && upAxis.y == 0 && upAxis.z == 0) {
            upAxis.y = 1;
        }
        else {
            upAxis.normalize();
        }
        target.subtractToRef(bonePos, yaxis);
        yaxis.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(yaxis, upAxis, zaxis);
        zaxis.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(yaxis, zaxis, xaxis);
        xaxis.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].FromXYZAxesToRef(xaxis, yaxis, zaxis, mat1);
        var a = this._bone1Length;
        var b = this._bone2Length;
        var c = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Distance(bonePos, target);
        if (this._maxReach > 0) {
            c = Math.min(this._maxReach, c);
        }
        var acosa = (b * b + c * c - a * a) / (2 * b * c);
        var acosb = (c * c + a * a - b * b) / (2 * c * a);
        if (acosa > 1) {
            acosa = 1;
        }
        if (acosb > 1) {
            acosb = 1;
        }
        if (acosa < -1) {
            acosa = -1;
        }
        if (acosb < -1) {
            acosb = -1;
        }
        var angA = Math.acos(acosa);
        var angB = Math.acos(acosb);
        var angC = -angA - angB;
        if (this._rightHandedSystem) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationYawPitchRollToRef(0, 0, this._adjustRoll, mat2);
            mat2.multiplyToRef(mat1, mat1);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationAxisToRef(this._bendAxis, angB, mat2);
            mat2.multiplyToRef(mat1, mat1);
        }
        else {
            var _tmpVec = BoneIKController._tmpVecs[5];
            _tmpVec.copyFrom(this._bendAxis);
            _tmpVec.x *= -1;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationAxisToRef(_tmpVec, -angB, mat2);
            mat2.multiplyToRef(mat1, mat1);
        }
        if (this.poleAngle) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationAxisToRef(yaxis, this.poleAngle, mat2);
            mat1.multiplyToRef(mat2, mat1);
        }
        if (this._bone1) {
            if (this.slerpAmount < 1) {
                if (!this._slerping) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromRotationMatrixToRef(this._bone1Mat, this._bone1Quat);
                }
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromRotationMatrixToRef(mat1, _tmpQuat);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].SlerpToRef(this._bone1Quat, _tmpQuat, this.slerpAmount, this._bone1Quat);
                angC = this._bone2Ang * (1.0 - this.slerpAmount) + angC * this.slerpAmount;
                this._bone1.setRotationQuaternion(this._bone1Quat, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_1__["Space"].WORLD, this.mesh);
                this._slerping = true;
            }
            else {
                this._bone1.setRotationMatrix(mat1, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_1__["Space"].WORLD, this.mesh);
                this._bone1Mat.copyFrom(mat1);
                this._slerping = false;
            }
        }
        this._bone2.setAxisAngle(this._bendAxis, angC, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_1__["Space"].LOCAL);
        this._bone2Ang = angC;
    };
    BoneIKController._tmpVecs = [_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero()];
    BoneIKController._tmpQuat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity();
    BoneIKController._tmpMats = [_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Identity(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Identity()];
    return BoneIKController;
}());



/***/ }),

/***/ "./Bones/boneLookController.ts":
/*!*************************************!*\
  !*** ./Bones/boneLookController.ts ***!
  \*************************************/
/*! exports provided: BoneLookController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoneLookController", function() { return BoneLookController; });
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");



/**
 * Class used to make a bone look toward a point in space
 * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons#bonelookcontroller
 */
var BoneLookController = /** @class */ (function () {
    /**
     * Create a BoneLookController
     * @param mesh the mesh that the bone belongs to
     * @param bone the bone that will be looking to the target
     * @param target the target Vector3 to look at
     * @param options optional settings:
     * * maxYaw: the maximum angle the bone will yaw to
     * * minYaw: the minimum angle the bone will yaw to
     * * maxPitch: the maximum angle the bone will pitch to
     * * minPitch: the minimum angle the bone will yaw to
     * * slerpAmount: set the between 0 and 1 to make the bone slerp to the target.
     * * upAxis: the up axis of the coordinate system
     * * upAxisSpace: the space that the up axis is in - Space.BONE, Space.LOCAL (default), or Space.WORLD.
     * * yawAxis: set yawAxis if the bone does not yaw on the y axis
     * * pitchAxis: set pitchAxis if the bone does not pitch on the x axis
     * * adjustYaw: used to make an adjustment to the yaw of the bone
     * * adjustPitch: used to make an adjustment to the pitch of the bone
     * * adjustRoll: used to make an adjustment to the roll of the bone
     **/
    function BoneLookController(mesh, bone, target, options) {
        /**
         * The up axis of the coordinate system that is used when the bone is rotated
         */
        this.upAxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Up();
        /**
         * The space that the up axis is in - Space.BONE, Space.LOCAL (default), or Space.WORLD
         */
        this.upAxisSpace = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].LOCAL;
        /**
         * Used to make an adjustment to the yaw of the bone
         */
        this.adjustYaw = 0;
        /**
         * Used to make an adjustment to the pitch of the bone
         */
        this.adjustPitch = 0;
        /**
         * Used to make an adjustment to the roll of the bone
         */
        this.adjustRoll = 0;
        /**
         * The amount to slerp (spherical linear interpolation) to the target.  Set this to a value between 0 and 1 (a value of 1 disables slerp)
         */
        this.slerpAmount = 1;
        this._boneQuat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity();
        this._slerping = false;
        this._firstFrameSkipped = false;
        this._fowardAxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Forward();
        this.mesh = mesh;
        this.bone = bone;
        this.target = target;
        if (options) {
            if (options.adjustYaw) {
                this.adjustYaw = options.adjustYaw;
            }
            if (options.adjustPitch) {
                this.adjustPitch = options.adjustPitch;
            }
            if (options.adjustRoll) {
                this.adjustRoll = options.adjustRoll;
            }
            if (options.maxYaw != null) {
                this.maxYaw = options.maxYaw;
            }
            else {
                this.maxYaw = Math.PI;
            }
            if (options.minYaw != null) {
                this.minYaw = options.minYaw;
            }
            else {
                this.minYaw = -Math.PI;
            }
            if (options.maxPitch != null) {
                this.maxPitch = options.maxPitch;
            }
            else {
                this.maxPitch = Math.PI;
            }
            if (options.minPitch != null) {
                this.minPitch = options.minPitch;
            }
            else {
                this.minPitch = -Math.PI;
            }
            if (options.slerpAmount != null) {
                this.slerpAmount = options.slerpAmount;
            }
            if (options.upAxis != null) {
                this.upAxis = options.upAxis;
            }
            if (options.upAxisSpace != null) {
                this.upAxisSpace = options.upAxisSpace;
            }
            if (options.yawAxis != null || options.pitchAxis != null) {
                var newYawAxis = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Axis"].Y;
                var newPitchAxis = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Axis"].X;
                if (options.yawAxis != null) {
                    newYawAxis = options.yawAxis.clone();
                    newYawAxis.normalize();
                }
                if (options.pitchAxis != null) {
                    newPitchAxis = options.pitchAxis.clone();
                    newPitchAxis.normalize();
                }
                var newRollAxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(newPitchAxis, newYawAxis);
                this._transformYawPitch = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromXYZAxesToRef(newPitchAxis, newYawAxis, newRollAxis, this._transformYawPitch);
                this._transformYawPitchInv = this._transformYawPitch.clone();
                this._transformYawPitch.invert();
            }
        }
        if (!bone.getParent() && this.upAxisSpace == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].BONE) {
            this.upAxisSpace = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].LOCAL;
        }
    }
    Object.defineProperty(BoneLookController.prototype, "minYaw", {
        /**
         * Gets or sets the minimum yaw angle that the bone can look to
         */
        get: function () {
            return this._minYaw;
        },
        set: function (value) {
            this._minYaw = value;
            this._minYawSin = Math.sin(value);
            this._minYawCos = Math.cos(value);
            if (this._maxYaw != null) {
                this._midYawConstraint = this._getAngleDiff(this._minYaw, this._maxYaw) * .5 + this._minYaw;
                this._yawRange = this._maxYaw - this._minYaw;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BoneLookController.prototype, "maxYaw", {
        /**
         * Gets or sets the maximum yaw angle that the bone can look to
         */
        get: function () {
            return this._maxYaw;
        },
        set: function (value) {
            this._maxYaw = value;
            this._maxYawSin = Math.sin(value);
            this._maxYawCos = Math.cos(value);
            if (this._minYaw != null) {
                this._midYawConstraint = this._getAngleDiff(this._minYaw, this._maxYaw) * .5 + this._minYaw;
                this._yawRange = this._maxYaw - this._minYaw;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BoneLookController.prototype, "minPitch", {
        /**
         * Gets or sets the minimum pitch angle that the bone can look to
         */
        get: function () {
            return this._minPitch;
        },
        set: function (value) {
            this._minPitch = value;
            this._minPitchTan = Math.tan(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BoneLookController.prototype, "maxPitch", {
        /**
         * Gets or sets the maximum pitch angle that the bone can look to
         */
        get: function () {
            return this._maxPitch;
        },
        set: function (value) {
            this._maxPitch = value;
            this._maxPitchTan = Math.tan(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Update the bone to look at the target.  This should be called before the scene is rendered (use scene.registerBeforeRender())
     */
    BoneLookController.prototype.update = function () {
        //skip the first frame when slerping so that the mesh rotation is correct
        if (this.slerpAmount < 1 && !this._firstFrameSkipped) {
            this._firstFrameSkipped = true;
            return;
        }
        var bone = this.bone;
        var bonePos = BoneLookController._tmpVecs[0];
        bone.getAbsolutePositionToRef(this.mesh, bonePos);
        var target = this.target;
        var _tmpMat1 = BoneLookController._tmpMats[0];
        var _tmpMat2 = BoneLookController._tmpMats[1];
        var mesh = this.mesh;
        var parentBone = bone.getParent();
        var upAxis = BoneLookController._tmpVecs[1];
        upAxis.copyFrom(this.upAxis);
        if (this.upAxisSpace == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].BONE && parentBone) {
            if (this._transformYawPitch) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(upAxis, this._transformYawPitchInv, upAxis);
            }
            parentBone.getDirectionToRef(upAxis, this.mesh, upAxis);
        }
        else if (this.upAxisSpace == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].LOCAL) {
            mesh.getDirectionToRef(upAxis, upAxis);
            if (mesh.scaling.x != 1 || mesh.scaling.y != 1 || mesh.scaling.z != 1) {
                upAxis.normalize();
            }
        }
        var checkYaw = false;
        var checkPitch = false;
        if (this._maxYaw != Math.PI || this._minYaw != -Math.PI) {
            checkYaw = true;
        }
        if (this._maxPitch != Math.PI || this._minPitch != -Math.PI) {
            checkPitch = true;
        }
        if (checkYaw || checkPitch) {
            var spaceMat = BoneLookController._tmpMats[2];
            var spaceMatInv = BoneLookController._tmpMats[3];
            if (this.upAxisSpace == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].BONE && upAxis.y == 1 && parentBone) {
                parentBone.getRotationMatrixToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].WORLD, this.mesh, spaceMat);
            }
            else if (this.upAxisSpace == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].LOCAL && upAxis.y == 1 && !parentBone) {
                spaceMat.copyFrom(mesh.getWorldMatrix());
            }
            else {
                var forwardAxis = BoneLookController._tmpVecs[2];
                forwardAxis.copyFrom(this._fowardAxis);
                if (this._transformYawPitch) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(forwardAxis, this._transformYawPitchInv, forwardAxis);
                }
                if (parentBone) {
                    parentBone.getDirectionToRef(forwardAxis, this.mesh, forwardAxis);
                }
                else {
                    mesh.getDirectionToRef(forwardAxis, forwardAxis);
                }
                var rightAxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(upAxis, forwardAxis);
                rightAxis.normalize();
                var forwardAxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(rightAxis, upAxis);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromXYZAxesToRef(rightAxis, upAxis, forwardAxis, spaceMat);
            }
            spaceMat.invertToRef(spaceMatInv);
            var xzlen = null;
            if (checkPitch) {
                var localTarget = BoneLookController._tmpVecs[3];
                target.subtractToRef(bonePos, localTarget);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(localTarget, spaceMatInv, localTarget);
                xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
                var pitch = Math.atan2(localTarget.y, xzlen);
                var newPitch = pitch;
                if (pitch > this._maxPitch) {
                    localTarget.y = this._maxPitchTan * xzlen;
                    newPitch = this._maxPitch;
                }
                else if (pitch < this._minPitch) {
                    localTarget.y = this._minPitchTan * xzlen;
                    newPitch = this._minPitch;
                }
                if (pitch != newPitch) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(localTarget, spaceMat, localTarget);
                    localTarget.addInPlace(bonePos);
                    target = localTarget;
                }
            }
            if (checkYaw) {
                var localTarget = BoneLookController._tmpVecs[4];
                target.subtractToRef(bonePos, localTarget);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(localTarget, spaceMatInv, localTarget);
                var yaw = Math.atan2(localTarget.x, localTarget.z);
                var newYaw = yaw;
                if (yaw > this._maxYaw || yaw < this._minYaw) {
                    if (xzlen == null) {
                        xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
                    }
                    if (this._yawRange > Math.PI) {
                        if (this._isAngleBetween(yaw, this._maxYaw, this._midYawConstraint)) {
                            localTarget.z = this._maxYawCos * xzlen;
                            localTarget.x = this._maxYawSin * xzlen;
                            newYaw = this._maxYaw;
                        }
                        else if (this._isAngleBetween(yaw, this._midYawConstraint, this._minYaw)) {
                            localTarget.z = this._minYawCos * xzlen;
                            localTarget.x = this._minYawSin * xzlen;
                            newYaw = this._minYaw;
                        }
                    }
                    else {
                        if (yaw > this._maxYaw) {
                            localTarget.z = this._maxYawCos * xzlen;
                            localTarget.x = this._maxYawSin * xzlen;
                            newYaw = this._maxYaw;
                        }
                        else if (yaw < this._minYaw) {
                            localTarget.z = this._minYawCos * xzlen;
                            localTarget.x = this._minYawSin * xzlen;
                            newYaw = this._minYaw;
                        }
                    }
                }
                if (this._slerping && this._yawRange > Math.PI) {
                    //are we going to be crossing into the min/max region?
                    var boneFwd = BoneLookController._tmpVecs[8];
                    boneFwd.copyFrom(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Axis"].Z);
                    if (this._transformYawPitch) {
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(boneFwd, this._transformYawPitchInv, boneFwd);
                    }
                    var boneRotMat = BoneLookController._tmpMats[4];
                    this._boneQuat.toRotationMatrix(boneRotMat);
                    this.mesh.getWorldMatrix().multiplyToRef(boneRotMat, boneRotMat);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(boneFwd, boneRotMat, boneFwd);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(boneFwd, spaceMatInv, boneFwd);
                    var boneYaw = Math.atan2(boneFwd.x, boneFwd.z);
                    var angBtwTar = this._getAngleBetween(boneYaw, yaw);
                    var angBtwMidYaw = this._getAngleBetween(boneYaw, this._midYawConstraint);
                    if (angBtwTar > angBtwMidYaw) {
                        if (xzlen == null) {
                            xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
                        }
                        var angBtwMax = this._getAngleBetween(boneYaw, this._maxYaw);
                        var angBtwMin = this._getAngleBetween(boneYaw, this._minYaw);
                        if (angBtwMin < angBtwMax) {
                            newYaw = boneYaw + Math.PI * .75;
                            localTarget.z = Math.cos(newYaw) * xzlen;
                            localTarget.x = Math.sin(newYaw) * xzlen;
                        }
                        else {
                            newYaw = boneYaw - Math.PI * .75;
                            localTarget.z = Math.cos(newYaw) * xzlen;
                            localTarget.x = Math.sin(newYaw) * xzlen;
                        }
                    }
                }
                if (yaw != newYaw) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(localTarget, spaceMat, localTarget);
                    localTarget.addInPlace(bonePos);
                    target = localTarget;
                }
            }
        }
        var zaxis = BoneLookController._tmpVecs[5];
        var xaxis = BoneLookController._tmpVecs[6];
        var yaxis = BoneLookController._tmpVecs[7];
        var _tmpQuat = BoneLookController._tmpQuat;
        target.subtractToRef(bonePos, zaxis);
        zaxis.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(upAxis, zaxis, xaxis);
        xaxis.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(zaxis, xaxis, yaxis);
        yaxis.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromXYZAxesToRef(xaxis, yaxis, zaxis, _tmpMat1);
        if (xaxis.x === 0 && xaxis.y === 0 && xaxis.z === 0) {
            return;
        }
        if (yaxis.x === 0 && yaxis.y === 0 && yaxis.z === 0) {
            return;
        }
        if (zaxis.x === 0 && zaxis.y === 0 && zaxis.z === 0) {
            return;
        }
        if (this.adjustYaw || this.adjustPitch || this.adjustRoll) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].RotationYawPitchRollToRef(this.adjustYaw, this.adjustPitch, this.adjustRoll, _tmpMat2);
            _tmpMat2.multiplyToRef(_tmpMat1, _tmpMat1);
        }
        if (this.slerpAmount < 1) {
            if (!this._slerping) {
                this.bone.getRotationQuaternionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].WORLD, this.mesh, this._boneQuat);
            }
            if (this._transformYawPitch) {
                this._transformYawPitch.multiplyToRef(_tmpMat1, _tmpMat1);
            }
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].FromRotationMatrixToRef(_tmpMat1, _tmpQuat);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].SlerpToRef(this._boneQuat, _tmpQuat, this.slerpAmount, this._boneQuat);
            this.bone.setRotationQuaternion(this._boneQuat, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].WORLD, this.mesh);
            this._slerping = true;
        }
        else {
            if (this._transformYawPitch) {
                this._transformYawPitch.multiplyToRef(_tmpMat1, _tmpMat1);
            }
            this.bone.setRotationMatrix(_tmpMat1, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_2__["Space"].WORLD, this.mesh);
            this._slerping = false;
        }
    };
    BoneLookController.prototype._getAngleDiff = function (ang1, ang2) {
        var angDiff = ang2 - ang1;
        angDiff %= Math.PI * 2;
        if (angDiff > Math.PI) {
            angDiff -= Math.PI * 2;
        }
        else if (angDiff < -Math.PI) {
            angDiff += Math.PI * 2;
        }
        return angDiff;
    };
    BoneLookController.prototype._getAngleBetween = function (ang1, ang2) {
        ang1 %= (2 * Math.PI);
        ang1 = (ang1 < 0) ? ang1 + (2 * Math.PI) : ang1;
        ang2 %= (2 * Math.PI);
        ang2 = (ang2 < 0) ? ang2 + (2 * Math.PI) : ang2;
        var ab = 0;
        if (ang1 < ang2) {
            ab = ang2 - ang1;
        }
        else {
            ab = ang1 - ang2;
        }
        if (ab > Math.PI) {
            ab = Math.PI * 2 - ab;
        }
        return ab;
    };
    BoneLookController.prototype._isAngleBetween = function (ang, ang1, ang2) {
        ang %= (2 * Math.PI);
        ang = (ang < 0) ? ang + (2 * Math.PI) : ang;
        ang1 %= (2 * Math.PI);
        ang1 = (ang1 < 0) ? ang1 + (2 * Math.PI) : ang1;
        ang2 %= (2 * Math.PI);
        ang2 = (ang2 < 0) ? ang2 + (2 * Math.PI) : ang2;
        if (ang1 < ang2) {
            if (ang > ang1 && ang < ang2) {
                return true;
            }
        }
        else {
            if (ang > ang2 && ang < ang1) {
                return true;
            }
        }
        return false;
    };
    BoneLookController._tmpVecs = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(10, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
    BoneLookController._tmpQuat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Identity();
    BoneLookController._tmpMats = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(5, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity);
    return BoneLookController;
}());



/***/ }),

/***/ "./Bones/index.ts":
/*!************************!*\
  !*** ./Bones/index.ts ***!
  \************************/
/*! exports provided: Bone, BoneIKController, BoneLookController, Skeleton */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _bone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bone */ "./Bones/bone.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Bone", function() { return _bone__WEBPACK_IMPORTED_MODULE_0__["Bone"]; });

/* harmony import */ var _boneIKController__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./boneIKController */ "./Bones/boneIKController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneIKController", function() { return _boneIKController__WEBPACK_IMPORTED_MODULE_1__["BoneIKController"]; });

/* harmony import */ var _boneLookController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./boneLookController */ "./Bones/boneLookController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneLookController", function() { return _boneLookController__WEBPACK_IMPORTED_MODULE_2__["BoneLookController"]; });

/* harmony import */ var _skeleton__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./skeleton */ "./Bones/skeleton.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Skeleton", function() { return _skeleton__WEBPACK_IMPORTED_MODULE_3__["Skeleton"]; });







/***/ }),

/***/ "./Bones/skeleton.ts":
/*!***************************!*\
  !*** ./Bones/skeleton.ts ***!
  \***************************/
/*! exports provided: Skeleton */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Skeleton", function() { return Skeleton; });
/* harmony import */ var _bone__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./bone */ "./Bones/bone.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Materials/Textures/rawTexture */ "./Materials/Textures/rawTexture.ts");
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Animations/animation */ "./Animations/animation.ts");
/* harmony import */ var _Animations_animationRange__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Animations/animationRange */ "./Animations/animationRange.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");










/**
 * Class used to handle skinning animations
 * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons
 */
var Skeleton = /** @class */ (function () {
    /**
     * Creates a new skeleton
     * @param name defines the skeleton name
     * @param id defines the skeleton Id
     * @param scene defines the hosting scene
     */
    function Skeleton(
    /** defines the skeleton name */
    name,
    /** defines the skeleton Id */
    id, scene) {
        this.name = name;
        this.id = id;
        /**
         * Defines the list of child bones
         */
        this.bones = new Array();
        /**
         * Defines a boolean indicating if the root matrix is provided by meshes or by the current skeleton (this is the default value)
         */
        this.needInitialSkinMatrix = false;
        /**
         * Defines a mesh that override the matrix used to get the world matrix (null by default).
         */
        this.overrideMesh = null;
        this._isDirty = true;
        this._meshesWithPoseMatrix = new Array();
        this._identity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Identity();
        this._ranges = {};
        this._lastAbsoluteTransformsUpdateId = -1;
        this._canUseTextureForBones = false;
        this._uniqueId = 0;
        /** @hidden */
        this._numBonesWithLinkedTransformNode = 0;
        /** @hidden */
        this._hasWaitingData = null;
        /**
         * Specifies if the skeleton should be serialized
         */
        this.doNotSerialize = false;
        this._useTextureToStoreBoneMatrices = true;
        this._animationPropertiesOverride = null;
        // Events
        /**
         * An observable triggered before computing the skeleton's matrices
         */
        this.onBeforeComputeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this.bones = [];
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__["EngineStore"].LastCreatedScene;
        this._uniqueId = this._scene.getUniqueId();
        this._scene.addSkeleton(this);
        //make sure it will recalculate the matrix next time prepare is called.
        this._isDirty = true;
        var engineCaps = this._scene.getEngine().getCaps();
        this._canUseTextureForBones = engineCaps.textureFloat && engineCaps.maxVertexTextureImageUnits > 0;
    }
    Object.defineProperty(Skeleton.prototype, "useTextureToStoreBoneMatrices", {
        /**
         * Gets or sets a boolean indicating that bone matrices should be stored as a texture instead of using shader uniforms (default is true).
         * Please note that this option is not available if the hardware does not support it
         */
        get: function () {
            return this._useTextureToStoreBoneMatrices;
        },
        set: function (value) {
            this._useTextureToStoreBoneMatrices = value;
            this._markAsDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Skeleton.prototype, "animationPropertiesOverride", {
        /**
         * Gets or sets the animation properties override
         */
        get: function () {
            if (!this._animationPropertiesOverride) {
                return this._scene.animationPropertiesOverride;
            }
            return this._animationPropertiesOverride;
        },
        set: function (value) {
            this._animationPropertiesOverride = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Skeleton.prototype, "isUsingTextureForMatrices", {
        /**
         * Gets a boolean indicating that the skeleton effectively stores matrices into a texture
         */
        get: function () {
            return this.useTextureToStoreBoneMatrices && this._canUseTextureForBones;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Skeleton.prototype, "uniqueId", {
        /**
         * Gets the unique ID of this skeleton
         */
        get: function () {
            return this._uniqueId;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current object class name.
     * @return the class name
     */
    Skeleton.prototype.getClassName = function () {
        return "Skeleton";
    };
    /**
     * Returns an array containing the root bones
     * @returns an array containing the root bones
     */
    Skeleton.prototype.getChildren = function () {
        return this.bones.filter(function (b) { return !b.getParent(); });
    };
    // Members
    /**
     * Gets the list of transform matrices to send to shaders (one matrix per bone)
     * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)
     * @returns a Float32Array containing matrices data
     */
    Skeleton.prototype.getTransformMatrices = function (mesh) {
        if (this.needInitialSkinMatrix && mesh._bonesTransformMatrices) {
            return mesh._bonesTransformMatrices;
        }
        if (!this._transformMatrices) {
            this.prepare();
        }
        return this._transformMatrices;
    };
    /**
     * Gets the list of transform matrices to send to shaders inside a texture (one matrix per bone)
     * @param mesh defines the mesh to use to get the root matrix (if needInitialSkinMatrix === true)
     * @returns a raw texture containing the data
     */
    Skeleton.prototype.getTransformMatrixTexture = function (mesh) {
        if (this.needInitialSkinMatrix && mesh._transformMatrixTexture) {
            return mesh._transformMatrixTexture;
        }
        return this._transformMatrixTexture;
    };
    /**
     * Gets the current hosting scene
     * @returns a scene object
     */
    Skeleton.prototype.getScene = function () {
        return this._scene;
    };
    // Methods
    /**
     * Gets a string representing the current skeleton data
     * @param fullDetails defines a boolean indicating if we want a verbose version
     * @returns a string representing the current skeleton data
     */
    Skeleton.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name + ", nBones: " + this.bones.length;
        ret += ", nAnimationRanges: " + (this._ranges ? Object.keys(this._ranges).length : "none");
        if (fullDetails) {
            ret += ", Ranges: {";
            var first = true;
            for (var name_1 in this._ranges) {
                if (first) {
                    ret += ", ";
                    first = false;
                }
                ret += name_1;
            }
            ret += "}";
        }
        return ret;
    };
    /**
    * Get bone's index searching by name
    * @param name defines bone's name to search for
    * @return the indice of the bone. Returns -1 if not found
    */
    Skeleton.prototype.getBoneIndexByName = function (name) {
        for (var boneIndex = 0, cache = this.bones.length; boneIndex < cache; boneIndex++) {
            if (this.bones[boneIndex].name === name) {
                return boneIndex;
            }
        }
        return -1;
    };
    /**
     * Creater a new animation range
     * @param name defines the name of the range
     * @param from defines the start key
     * @param to defines the end key
     */
    Skeleton.prototype.createAnimationRange = function (name, from, to) {
        // check name not already in use
        if (!this._ranges[name]) {
            this._ranges[name] = new _Animations_animationRange__WEBPACK_IMPORTED_MODULE_5__["AnimationRange"](name, from, to);
            for (var i = 0, nBones = this.bones.length; i < nBones; i++) {
                if (this.bones[i].animations[0]) {
                    this.bones[i].animations[0].createRange(name, from, to);
                }
            }
        }
    };
    /**
     * Delete a specific animation range
     * @param name defines the name of the range
     * @param deleteFrames defines if frames must be removed as well
     */
    Skeleton.prototype.deleteAnimationRange = function (name, deleteFrames) {
        if (deleteFrames === void 0) { deleteFrames = true; }
        for (var i = 0, nBones = this.bones.length; i < nBones; i++) {
            if (this.bones[i].animations[0]) {
                this.bones[i].animations[0].deleteRange(name, deleteFrames);
            }
        }
        this._ranges[name] = null; // said much faster than 'delete this._range[name]'
    };
    /**
     * Gets a specific animation range
     * @param name defines the name of the range to look for
     * @returns the requested animation range or null if not found
     */
    Skeleton.prototype.getAnimationRange = function (name) {
        return this._ranges[name];
    };
    /**
     * Gets the list of all animation ranges defined on this skeleton
     * @returns an array
     */
    Skeleton.prototype.getAnimationRanges = function () {
        var animationRanges = [];
        var name;
        for (name in this._ranges) {
            animationRanges.push(this._ranges[name]);
        }
        return animationRanges;
    };
    /**
     * Copy animation range from a source skeleton.
     * This is not for a complete retargeting, only between very similar skeleton's with only possible bone length differences
     * @param source defines the source skeleton
     * @param name defines the name of the range to copy
     * @param rescaleAsRequired defines if rescaling must be applied if required
     * @returns true if operation was successful
     */
    Skeleton.prototype.copyAnimationRange = function (source, name, rescaleAsRequired) {
        if (rescaleAsRequired === void 0) { rescaleAsRequired = false; }
        if (this._ranges[name] || !source.getAnimationRange(name)) {
            return false;
        }
        var ret = true;
        var frameOffset = this._getHighestAnimationFrame() + 1;
        // make a dictionary of source skeleton's bones, so exact same order or doublely nested loop is not required
        var boneDict = {};
        var sourceBones = source.bones;
        var nBones;
        var i;
        for (i = 0, nBones = sourceBones.length; i < nBones; i++) {
            boneDict[sourceBones[i].name] = sourceBones[i];
        }
        if (this.bones.length !== sourceBones.length) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_8__["Logger"].Warn("copyAnimationRange: this rig has " + this.bones.length + " bones, while source as " + sourceBones.length);
            ret = false;
        }
        var skelDimensionsRatio = (rescaleAsRequired && this.dimensionsAtRest && source.dimensionsAtRest) ? this.dimensionsAtRest.divide(source.dimensionsAtRest) : null;
        for (i = 0, nBones = this.bones.length; i < nBones; i++) {
            var boneName = this.bones[i].name;
            var sourceBone = boneDict[boneName];
            if (sourceBone) {
                ret = ret && this.bones[i].copyAnimationRange(sourceBone, name, frameOffset, rescaleAsRequired, skelDimensionsRatio);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_8__["Logger"].Warn("copyAnimationRange: not same rig, missing source bone " + boneName);
                ret = false;
            }
        }
        // do not call createAnimationRange(), since it also is done to bones, which was already done
        var range = source.getAnimationRange(name);
        if (range) {
            this._ranges[name] = new _Animations_animationRange__WEBPACK_IMPORTED_MODULE_5__["AnimationRange"](name, range.from + frameOffset, range.to + frameOffset);
        }
        return ret;
    };
    /**
     * Forces the skeleton to go to rest pose
     */
    Skeleton.prototype.returnToRest = function () {
        for (var index = 0; index < this.bones.length; index++) {
            this.bones[index].returnToRest();
        }
    };
    Skeleton.prototype._getHighestAnimationFrame = function () {
        var ret = 0;
        for (var i = 0, nBones = this.bones.length; i < nBones; i++) {
            if (this.bones[i].animations[0]) {
                var highest = this.bones[i].animations[0].getHighestFrame();
                if (ret < highest) {
                    ret = highest;
                }
            }
        }
        return ret;
    };
    /**
     * Begin a specific animation range
     * @param name defines the name of the range to start
     * @param loop defines if looping must be turned on (false by default)
     * @param speedRatio defines the speed ratio to apply (1 by default)
     * @param onAnimationEnd defines a callback which will be called when animation will end
     * @returns a new animatable
     */
    Skeleton.prototype.beginAnimation = function (name, loop, speedRatio, onAnimationEnd) {
        var range = this.getAnimationRange(name);
        if (!range) {
            return null;
        }
        return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);
    };
    /** @hidden */
    Skeleton.prototype._markAsDirty = function () {
        this._isDirty = true;
    };
    /** @hidden */
    Skeleton.prototype._registerMeshWithPoseMatrix = function (mesh) {
        this._meshesWithPoseMatrix.push(mesh);
    };
    /** @hidden */
    Skeleton.prototype._unregisterMeshWithPoseMatrix = function (mesh) {
        var index = this._meshesWithPoseMatrix.indexOf(mesh);
        if (index > -1) {
            this._meshesWithPoseMatrix.splice(index, 1);
        }
    };
    Skeleton.prototype._computeTransformMatrices = function (targetMatrix, initialSkinMatrix) {
        this.onBeforeComputeObservable.notifyObservers(this);
        for (var index = 0; index < this.bones.length; index++) {
            var bone = this.bones[index];
            bone._childUpdateId++;
            var parentBone = bone.getParent();
            if (parentBone) {
                bone.getLocalMatrix().multiplyToRef(parentBone.getWorldMatrix(), bone.getWorldMatrix());
            }
            else {
                if (initialSkinMatrix) {
                    bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getWorldMatrix());
                }
                else {
                    bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
                }
            }
            if (bone._index !== -1) {
                var mappedIndex = bone._index === null ? index : bone._index;
                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), targetMatrix, mappedIndex * 16);
            }
        }
        this._identity.copyToArray(targetMatrix, this.bones.length * 16);
    };
    /**
     * Build all resources required to render a skeleton
     */
    Skeleton.prototype.prepare = function () {
        // Update the local matrix of bones with linked transform nodes.
        if (this._numBonesWithLinkedTransformNode > 0) {
            for (var _i = 0, _a = this.bones; _i < _a.length; _i++) {
                var bone_1 = _a[_i];
                if (bone_1._linkedTransformNode) {
                    // Computing the world matrix also computes the local matrix.
                    bone_1._linkedTransformNode.computeWorldMatrix();
                    bone_1._matrix = bone_1._linkedTransformNode._localMatrix;
                    bone_1.markAsDirty();
                }
            }
        }
        if (!this._isDirty) {
            return;
        }
        if (this.needInitialSkinMatrix) {
            for (var index = 0; index < this._meshesWithPoseMatrix.length; index++) {
                var mesh = this._meshesWithPoseMatrix[index];
                var poseMatrix = mesh.getPoseMatrix();
                if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {
                    mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));
                }
                if (this._synchronizedWithMesh !== mesh) {
                    this._synchronizedWithMesh = mesh;
                    // Prepare bones
                    for (var boneIndex = 0; boneIndex < this.bones.length; boneIndex++) {
                        var bone = this.bones[boneIndex];
                        if (!bone.getParent()) {
                            var matrix = bone.getBaseMatrix();
                            matrix.multiplyToRef(poseMatrix, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Matrix[1]);
                            bone._updateDifferenceMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Matrix[1]);
                        }
                    }
                    if (this.isUsingTextureForMatrices) {
                        var textureWidth = (this.bones.length + 1) * 4;
                        if (!mesh._transformMatrixTexture || mesh._transformMatrixTexture.getSize().width !== textureWidth) {
                            if (mesh._transformMatrixTexture) {
                                mesh._transformMatrixTexture.dispose();
                            }
                            mesh._transformMatrixTexture = _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_3__["RawTexture"].CreateRGBATexture(mesh._bonesTransformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_FLOAT);
                        }
                    }
                }
                this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);
                if (this.isUsingTextureForMatrices && mesh._transformMatrixTexture) {
                    mesh._transformMatrixTexture.update(mesh._bonesTransformMatrices);
                }
            }
        }
        else {
            if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
                this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
                if (this.isUsingTextureForMatrices) {
                    if (this._transformMatrixTexture) {
                        this._transformMatrixTexture.dispose();
                    }
                    this._transformMatrixTexture = _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_3__["RawTexture"].CreateRGBATexture(this._transformMatrices, (this.bones.length + 1) * 4, 1, this._scene, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_FLOAT);
                }
            }
            this._computeTransformMatrices(this._transformMatrices, null);
            if (this.isUsingTextureForMatrices && this._transformMatrixTexture) {
                this._transformMatrixTexture.update(this._transformMatrices);
            }
        }
        this._isDirty = false;
        this._scene._activeBones.addCount(this.bones.length, false);
    };
    /**
     * Gets the list of animatables currently running for this skeleton
     * @returns an array of animatables
     */
    Skeleton.prototype.getAnimatables = function () {
        if (!this._animatables || this._animatables.length !== this.bones.length) {
            this._animatables = [];
            for (var index = 0; index < this.bones.length; index++) {
                this._animatables.push(this.bones[index]);
            }
        }
        return this._animatables;
    };
    /**
     * Clone the current skeleton
     * @param name defines the name of the new skeleton
     * @param id defines the id of the new skeleton
     * @returns the new skeleton
     */
    Skeleton.prototype.clone = function (name, id) {
        var result = new Skeleton(name, id || name, this._scene);
        result.needInitialSkinMatrix = this.needInitialSkinMatrix;
        for (var index = 0; index < this.bones.length; index++) {
            var source = this.bones[index];
            var parentBone = null;
            var parent_1 = source.getParent();
            if (parent_1) {
                var parentIndex = this.bones.indexOf(parent_1);
                parentBone = result.bones[parentIndex];
            }
            var bone = new _bone__WEBPACK_IMPORTED_MODULE_0__["Bone"](source.name, result, parentBone, source.getBaseMatrix().clone(), source.getRestPose().clone());
            _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_9__["DeepCopier"].DeepCopy(source.animations, bone.animations);
        }
        if (this._ranges) {
            result._ranges = {};
            for (var rangeName in this._ranges) {
                var range = this._ranges[rangeName];
                if (range) {
                    result._ranges[rangeName] = range.clone();
                }
            }
        }
        this._isDirty = true;
        return result;
    };
    /**
     * Enable animation blending for this skeleton
     * @param blendingSpeed defines the blending speed to apply
     * @see http://doc.babylonjs.com/babylon101/animations#animation-blending
     */
    Skeleton.prototype.enableBlending = function (blendingSpeed) {
        if (blendingSpeed === void 0) { blendingSpeed = 0.01; }
        this.bones.forEach(function (bone) {
            bone.animations.forEach(function (animation) {
                animation.enableBlending = true;
                animation.blendingSpeed = blendingSpeed;
            });
        });
    };
    /**
     * Releases all resources associated with the current skeleton
     */
    Skeleton.prototype.dispose = function () {
        this._meshesWithPoseMatrix = [];
        // Animations
        this.getScene().stopAnimation(this);
        // Remove from scene
        this.getScene().removeSkeleton(this);
        if (this._transformMatrixTexture) {
            this._transformMatrixTexture.dispose();
            this._transformMatrixTexture = null;
        }
    };
    /**
     * Serialize the skeleton in a JSON object
     * @returns a JSON object
     */
    Skeleton.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.id = this.id;
        if (this.dimensionsAtRest) {
            serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();
        }
        serializationObject.bones = [];
        serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;
        for (var index = 0; index < this.bones.length; index++) {
            var bone = this.bones[index];
            var parent_2 = bone.getParent();
            var serializedBone = {
                parentBoneIndex: parent_2 ? this.bones.indexOf(parent_2) : -1,
                name: bone.name,
                matrix: bone.getBaseMatrix().toArray(),
                rest: bone.getRestPose().toArray()
            };
            serializationObject.bones.push(serializedBone);
            if (bone.length) {
                serializedBone.length = bone.length;
            }
            if (bone.metadata) {
                serializedBone.metadata = bone.metadata;
            }
            if (bone.animations && bone.animations.length > 0) {
                serializedBone.animation = bone.animations[0].serialize();
            }
            serializationObject.ranges = [];
            for (var name in this._ranges) {
                var source = this._ranges[name];
                if (!source) {
                    continue;
                }
                var range = {};
                range.name = name;
                range.from = source.from;
                range.to = source.to;
                serializationObject.ranges.push(range);
            }
        }
        return serializationObject;
    };
    /**
     * Creates a new skeleton from serialized data
     * @param parsedSkeleton defines the serialized data
     * @param scene defines the hosting scene
     * @returns a new skeleton
     */
    Skeleton.Parse = function (parsedSkeleton, scene) {
        var skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);
        if (parsedSkeleton.dimensionsAtRest) {
            skeleton.dimensionsAtRest = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].FromArray(parsedSkeleton.dimensionsAtRest);
        }
        skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;
        var index;
        for (index = 0; index < parsedSkeleton.bones.length; index++) {
            var parsedBone = parsedSkeleton.bones[index];
            var parentBone = null;
            if (parsedBone.parentBoneIndex > -1) {
                parentBone = skeleton.bones[parsedBone.parentBoneIndex];
            }
            var rest = parsedBone.rest ? _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromArray(parsedBone.rest) : null;
            var bone = new _bone__WEBPACK_IMPORTED_MODULE_0__["Bone"](parsedBone.name, skeleton, parentBone, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromArray(parsedBone.matrix), rest);
            if (parsedBone.id !== undefined && parsedBone.id !== null) {
                bone.id = parsedBone.id;
            }
            if (parsedBone.length) {
                bone.length = parsedBone.length;
            }
            if (parsedBone.metadata) {
                bone.metadata = parsedBone.metadata;
            }
            if (parsedBone.animation) {
                bone.animations.push(_Animations_animation__WEBPACK_IMPORTED_MODULE_4__["Animation"].Parse(parsedBone.animation));
            }
            if (parsedBone.linkedTransformNodeId !== undefined && parsedBone.linkedTransformNodeId !== null) {
                skeleton._hasWaitingData = true;
                bone._waitingTransformNodeId = parsedBone.linkedTransformNodeId;
            }
        }
        // placed after bones, so createAnimationRange can cascade down
        if (parsedSkeleton.ranges) {
            for (index = 0; index < parsedSkeleton.ranges.length; index++) {
                var data = parsedSkeleton.ranges[index];
                skeleton.createAnimationRange(data.name, data.from, data.to);
            }
        }
        return skeleton;
    };
    /**
     * Compute all node absolute transforms
     * @param forceUpdate defines if computation must be done even if cache is up to date
     */
    Skeleton.prototype.computeAbsoluteTransforms = function (forceUpdate) {
        if (forceUpdate === void 0) { forceUpdate = false; }
        var renderId = this._scene.getRenderId();
        if (this._lastAbsoluteTransformsUpdateId != renderId || forceUpdate) {
            this.bones[0].computeAbsoluteTransforms();
            this._lastAbsoluteTransformsUpdateId = renderId;
        }
    };
    /**
     * Gets the root pose matrix
     * @returns a matrix
     */
    Skeleton.prototype.getPoseMatrix = function () {
        var poseMatrix = null;
        if (this._meshesWithPoseMatrix.length > 0) {
            poseMatrix = this._meshesWithPoseMatrix[0].getPoseMatrix();
        }
        return poseMatrix;
    };
    /**
     * Sorts bones per internal index
     */
    Skeleton.prototype.sortBones = function () {
        var bones = new Array();
        var visited = new Array(this.bones.length);
        for (var index = 0; index < this.bones.length; index++) {
            this._sortBones(index, bones, visited);
        }
        this.bones = bones;
    };
    Skeleton.prototype._sortBones = function (index, bones, visited) {
        if (visited[index]) {
            return;
        }
        visited[index] = true;
        var bone = this.bones[index];
        if (bone._index === undefined) {
            bone._index = index;
        }
        var parentBone = bone.getParent();
        if (parentBone) {
            this._sortBones(this.bones.indexOf(parentBone), bones, visited);
        }
        bones.push(bone);
    };
    return Skeleton;
}());



/***/ }),

/***/ "./Cameras/Inputs/BaseCameraPointersInput.ts":
/*!***************************************************!*\
  !*** ./Cameras/Inputs/BaseCameraPointersInput.ts ***!
  \***************************************************/
/*! exports provided: BaseCameraPointersInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseCameraPointersInput", function() { return BaseCameraPointersInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");




/**
 * Base class for Camera Pointer Inputs.
 * See FollowCameraPointersInput in src/Cameras/Inputs/followCameraPointersInput.ts
 * for example usage.
 */
var BaseCameraPointersInput = /** @class */ (function () {
    function BaseCameraPointersInput() {
        /**
         * Defines the buttons associated with the input to handle camera move.
         */
        this.buttons = [0, 1, 2];
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    BaseCameraPointersInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        var engine = this.camera.getEngine();
        var previousPinchSquaredDistance = 0;
        var previousMultiTouchPanPosition = null;
        this.pointA = null;
        this.pointB = null;
        this._altKey = false;
        this._ctrlKey = false;
        this._metaKey = false;
        this._shiftKey = false;
        this._buttonsPressed = 0;
        this._pointerInput = function (p, s) {
            var evt = p.event;
            var isTouch = evt.pointerType === "touch";
            if (engine.isInVRExclusivePointerMode) {
                return;
            }
            if (p.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE &&
                _this.buttons.indexOf(evt.button) === -1) {
                return;
            }
            var srcElement = (evt.srcElement || evt.target);
            _this._altKey = evt.altKey;
            _this._ctrlKey = evt.ctrlKey;
            _this._metaKey = evt.metaKey;
            _this._shiftKey = evt.shiftKey;
            _this._buttonsPressed = evt.buttons;
            if (engine.isPointerLock) {
                var offsetX = evt.movementX ||
                    evt.mozMovementX ||
                    evt.webkitMovementX ||
                    evt.msMovementX ||
                    0;
                var offsetY = evt.movementY ||
                    evt.mozMovementY ||
                    evt.webkitMovementY ||
                    evt.msMovementY ||
                    0;
                _this.onTouch(null, offsetX, offsetY);
                _this.pointA = null;
                _this.pointB = null;
            }
            else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOWN && srcElement) {
                try {
                    srcElement.setPointerCapture(evt.pointerId);
                }
                catch (e) {
                    //Nothing to do with the error. Execution will continue.
                }
                if (_this.pointA === null) {
                    _this.pointA = { x: evt.clientX,
                        y: evt.clientY,
                        pointerId: evt.pointerId,
                        type: evt.pointerType };
                }
                else if (_this.pointB === null) {
                    _this.pointB = { x: evt.clientX,
                        y: evt.clientY,
                        pointerId: evt.pointerId,
                        type: evt.pointerType };
                }
                _this.onButtonDown(evt);
                if (!noPreventDefault) {
                    evt.preventDefault();
                    element.focus();
                }
            }
            else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOUBLETAP) {
                _this.onDoubleTap(evt.pointerType);
            }
            else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERUP && srcElement) {
                try {
                    srcElement.releasePointerCapture(evt.pointerId);
                }
                catch (e) {
                    //Nothing to do with the error.
                }
                if (!isTouch) {
                    _this.pointB = null; // Mouse and pen are mono pointer
                }
                //would be better to use pointers.remove(evt.pointerId) for multitouch gestures,
                //but emptying completely pointers collection is required to fix a bug on iPhone :
                //when changing orientation while pinching camera,
                //one pointer stay pressed forever if we don't release all pointers
                //will be ok to put back pointers.remove(evt.pointerId); when iPhone bug corrected
                if (engine._badOS) {
                    _this.pointA = _this.pointB = null;
                }
                else {
                    //only remove the impacted pointer in case of multitouch allowing on most
                    //platforms switching from rotate to zoom and pan seamlessly.
                    if (_this.pointB && _this.pointA && _this.pointA.pointerId == evt.pointerId) {
                        _this.pointA = _this.pointB;
                        _this.pointB = null;
                    }
                    else if (_this.pointA && _this.pointB &&
                        _this.pointB.pointerId == evt.pointerId) {
                        _this.pointB = null;
                    }
                    else {
                        _this.pointA = _this.pointB = null;
                    }
                }
                if (previousPinchSquaredDistance !== 0 || previousMultiTouchPanPosition) {
                    // Previous pinch data is populated but a button has been lifted
                    // so pinch has ended.
                    _this.onMultiTouch(_this.pointA, _this.pointB, previousPinchSquaredDistance, 0, // pinchSquaredDistance
                    previousMultiTouchPanPosition, null // multiTouchPanPosition
                    );
                    previousPinchSquaredDistance = 0;
                    previousMultiTouchPanPosition = null;
                }
                _this.onButtonUp(evt);
                if (!noPreventDefault) {
                    evt.preventDefault();
                }
            }
            else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE) {
                if (!noPreventDefault) {
                    evt.preventDefault();
                }
                // One button down
                if (_this.pointA && _this.pointB === null) {
                    var offsetX = evt.clientX - _this.pointA.x;
                    var offsetY = evt.clientY - _this.pointA.y;
                    _this.onTouch(_this.pointA, offsetX, offsetY);
                    _this.pointA.x = evt.clientX;
                    _this.pointA.y = evt.clientY;
                }
                // Two buttons down: pinch
                else if (_this.pointA && _this.pointB) {
                    var ed = (_this.pointA.pointerId === evt.pointerId) ?
                        _this.pointA : _this.pointB;
                    ed.x = evt.clientX;
                    ed.y = evt.clientY;
                    var distX = _this.pointA.x - _this.pointB.x;
                    var distY = _this.pointA.y - _this.pointB.y;
                    var pinchSquaredDistance = (distX * distX) + (distY * distY);
                    var multiTouchPanPosition = { x: (_this.pointA.x + _this.pointB.x) / 2,
                        y: (_this.pointA.y + _this.pointB.y) / 2,
                        pointerId: evt.pointerId,
                        type: p.type };
                    _this.onMultiTouch(_this.pointA, _this.pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition);
                    previousMultiTouchPanPosition = multiTouchPanPosition;
                    previousPinchSquaredDistance = pinchSquaredDistance;
                }
            }
        };
        this._observer = this.camera.getScene().onPointerObservable.add(this._pointerInput, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOWN | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERUP |
            _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE);
        this._onLostFocus = function () {
            _this.pointA = _this.pointB = null;
            previousPinchSquaredDistance = 0;
            previousMultiTouchPanPosition = null;
            _this.onLostFocus();
        };
        element.addEventListener("contextmenu", this.onContextMenu.bind(this), false);
        _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].RegisterTopRootEvents(this.camera.getScene().getEngine().getHostWindow(), [
            { name: "blur", handler: this._onLostFocus }
        ]);
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    BaseCameraPointersInput.prototype.detachControl = function (element) {
        if (this._onLostFocus) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].UnregisterTopRootEvents(this.camera.getScene().getEngine().getHostWindow(), [
                { name: "blur", handler: this._onLostFocus }
            ]);
        }
        if (element && this._observer) {
            this.camera.getScene().onPointerObservable.remove(this._observer);
            this._observer = null;
            if (this.onContextMenu) {
                element.removeEventListener("contextmenu", this.onContextMenu);
            }
            this._onLostFocus = null;
        }
        this._altKey = false;
        this._ctrlKey = false;
        this._metaKey = false;
        this._shiftKey = false;
        this._buttonsPressed = 0;
    };
    /**
     * Gets the class name of the current input.
     * @returns the class name
     */
    BaseCameraPointersInput.prototype.getClassName = function () {
        return "BaseCameraPointersInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    BaseCameraPointersInput.prototype.getSimpleName = function () {
        return "pointers";
    };
    /**
     * Called on pointer POINTERDOUBLETAP event.
     * Override this method to provide functionality on POINTERDOUBLETAP event.
     */
    BaseCameraPointersInput.prototype.onDoubleTap = function (type) {
    };
    /**
     * Called on pointer POINTERMOVE event if only a single touch is active.
     * Override this method to provide functionality.
     */
    BaseCameraPointersInput.prototype.onTouch = function (point, offsetX, offsetY) {
    };
    /**
     * Called on pointer POINTERMOVE event if multiple touches are active.
     * Override this method to provide functionality.
     */
    BaseCameraPointersInput.prototype.onMultiTouch = function (pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition) {
    };
    /**
     * Called on JS contextmenu event.
     * Override this method to provide functionality.
     */
    BaseCameraPointersInput.prototype.onContextMenu = function (evt) {
        evt.preventDefault();
    };
    /**
     * Called each time a new POINTERDOWN event occurs. Ie, for each button
     * press.
     * Override this method to provide functionality.
     */
    BaseCameraPointersInput.prototype.onButtonDown = function (evt) {
    };
    /**
     * Called each time a new POINTERUP event occurs. Ie, for each button
     * release.
     * Override this method to provide functionality.
     */
    BaseCameraPointersInput.prototype.onButtonUp = function (evt) {
    };
    /**
     * Called when window becomes inactive.
     * Override this method to provide functionality.
     */
    BaseCameraPointersInput.prototype.onLostFocus = function () {
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseCameraPointersInput.prototype, "buttons", void 0);
    return BaseCameraPointersInput;
}());



/***/ }),

/***/ "./Cameras/Inputs/arcRotateCameraGamepadInput.ts":
/*!*******************************************************!*\
  !*** ./Cameras/Inputs/arcRotateCameraGamepadInput.ts ***!
  \*******************************************************/
/*! exports provided: ArcRotateCameraGamepadInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraGamepadInput", function() { return ArcRotateCameraGamepadInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Gamepads/gamepad */ "./Gamepads/gamepad.ts");




/**
 * Manage the gamepad inputs to control an arc rotate camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var ArcRotateCameraGamepadInput = /** @class */ (function () {
    function ArcRotateCameraGamepadInput() {
        /**
         * Defines the gamepad rotation sensiblity.
         * This is the threshold from when rotation starts to be accounted for to prevent jittering.
         */
        this.gamepadRotationSensibility = 80;
        /**
         * Defines the gamepad move sensiblity.
         * This is the threshold from when moving starts to be accounted for for to prevent jittering.
         */
        this.gamepadMoveSensibility = 40;
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    ArcRotateCameraGamepadInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        var manager = this.camera.getScene().gamepadManager;
        this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
            if (gamepad.type !== _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_3__["Gamepad"].POSE_ENABLED) {
                // prioritize XBOX gamepads.
                if (!_this.gamepad || gamepad.type === _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_3__["Gamepad"].XBOX) {
                    _this.gamepad = gamepad;
                }
            }
        });
        this._onGamepadDisconnectedObserver = manager.onGamepadDisconnectedObservable.add(function (gamepad) {
            if (_this.gamepad === gamepad) {
                _this.gamepad = null;
            }
        });
        this.gamepad = manager.getGamepadByType(_Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_3__["Gamepad"].XBOX);
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    ArcRotateCameraGamepadInput.prototype.detachControl = function (element) {
        this.camera.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);
        this.camera.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);
        this.gamepad = null;
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    ArcRotateCameraGamepadInput.prototype.checkInputs = function () {
        if (this.gamepad) {
            var camera = this.camera;
            var RSValues = this.gamepad.rightStick;
            if (RSValues) {
                if (RSValues.x != 0) {
                    var normalizedRX = RSValues.x / this.gamepadRotationSensibility;
                    if (normalizedRX != 0 && Math.abs(normalizedRX) > 0.005) {
                        camera.inertialAlphaOffset += normalizedRX;
                    }
                }
                if (RSValues.y != 0) {
                    var normalizedRY = RSValues.y / this.gamepadRotationSensibility;
                    if (normalizedRY != 0 && Math.abs(normalizedRY) > 0.005) {
                        camera.inertialBetaOffset += normalizedRY;
                    }
                }
            }
            var LSValues = this.gamepad.leftStick;
            if (LSValues && LSValues.y != 0) {
                var normalizedLY = LSValues.y / this.gamepadMoveSensibility;
                if (normalizedLY != 0 && Math.abs(normalizedLY) > 0.005) {
                    this.camera.inertialRadiusOffset -= normalizedLY;
                }
            }
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    ArcRotateCameraGamepadInput.prototype.getClassName = function () {
        return "ArcRotateCameraGamepadInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    ArcRotateCameraGamepadInput.prototype.getSimpleName = function () {
        return "gamepad";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraGamepadInput.prototype, "gamepadRotationSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraGamepadInput.prototype, "gamepadMoveSensibility", void 0);
    return ArcRotateCameraGamepadInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["ArcRotateCameraGamepadInput"] = ArcRotateCameraGamepadInput;


/***/ }),

/***/ "./Cameras/Inputs/arcRotateCameraKeyboardMoveInput.ts":
/*!************************************************************!*\
  !*** ./Cameras/Inputs/arcRotateCameraKeyboardMoveInput.ts ***!
  \************************************************************/
/*! exports provided: ArcRotateCameraKeyboardMoveInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraKeyboardMoveInput", function() { return ArcRotateCameraKeyboardMoveInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/keyboardEvents */ "./Events/keyboardEvents.ts");




/**
 * Manage the keyboard inputs to control the movement of an arc rotate camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var ArcRotateCameraKeyboardMoveInput = /** @class */ (function () {
    function ArcRotateCameraKeyboardMoveInput() {
        /**
         * Defines the list of key codes associated with the up action (increase alpha)
         */
        this.keysUp = [38];
        /**
         * Defines the list of key codes associated with the down action (decrease alpha)
         */
        this.keysDown = [40];
        /**
         * Defines the list of key codes associated with the left action (increase beta)
         */
        this.keysLeft = [37];
        /**
         * Defines the list of key codes associated with the right action (decrease beta)
         */
        this.keysRight = [39];
        /**
         * Defines the list of key codes associated with the reset action.
         * Those keys reset the camera to its last stored state (with the method camera.storeState())
         */
        this.keysReset = [220];
        /**
         * Defines the panning sensibility of the inputs.
         * (How fast is the camera paning)
         */
        this.panningSensibility = 50.0;
        /**
         * Defines the zooming sensibility of the inputs.
         * (How fast is the camera zooming)
         */
        this.zoomingSensibility = 25.0;
        /**
         * Defines wether maintaining the alt key down switch the movement mode from
         * orientation to zoom.
         */
        this.useAltToZoom = true;
        /**
         * Rotation speed of the camera
         */
        this.angularSpeed = 0.01;
        this._keys = new Array();
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    ArcRotateCameraKeyboardMoveInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        if (this._onCanvasBlurObserver) {
            return;
        }
        this._scene = this.camera.getScene();
        this._engine = this._scene.getEngine();
        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(function () {
            _this._keys = [];
        });
        this._onKeyboardObserver = this._scene.onKeyboardObservable.add(function (info) {
            var evt = info.event;
            if (!evt.metaKey) {
                if (info.type === _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__["KeyboardEventTypes"].KEYDOWN) {
                    _this._ctrlPressed = evt.ctrlKey;
                    _this._altPressed = evt.altKey;
                    if (_this.keysUp.indexOf(evt.keyCode) !== -1 ||
                        _this.keysDown.indexOf(evt.keyCode) !== -1 ||
                        _this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRight.indexOf(evt.keyCode) !== -1 ||
                        _this.keysReset.indexOf(evt.keyCode) !== -1) {
                        var index = _this._keys.indexOf(evt.keyCode);
                        if (index === -1) {
                            _this._keys.push(evt.keyCode);
                        }
                        if (evt.preventDefault) {
                            if (!noPreventDefault) {
                                evt.preventDefault();
                            }
                        }
                    }
                }
                else {
                    if (_this.keysUp.indexOf(evt.keyCode) !== -1 ||
                        _this.keysDown.indexOf(evt.keyCode) !== -1 ||
                        _this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRight.indexOf(evt.keyCode) !== -1 ||
                        _this.keysReset.indexOf(evt.keyCode) !== -1) {
                        var index = _this._keys.indexOf(evt.keyCode);
                        if (index >= 0) {
                            _this._keys.splice(index, 1);
                        }
                        if (evt.preventDefault) {
                            if (!noPreventDefault) {
                                evt.preventDefault();
                            }
                        }
                    }
                }
            }
        });
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    ArcRotateCameraKeyboardMoveInput.prototype.detachControl = function (element) {
        if (this._scene) {
            if (this._onKeyboardObserver) {
                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
            }
            if (this._onCanvasBlurObserver) {
                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
            }
            this._onKeyboardObserver = null;
            this._onCanvasBlurObserver = null;
        }
        this._keys = [];
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    ArcRotateCameraKeyboardMoveInput.prototype.checkInputs = function () {
        if (this._onKeyboardObserver) {
            var camera = this.camera;
            for (var index = 0; index < this._keys.length; index++) {
                var keyCode = this._keys[index];
                if (this.keysLeft.indexOf(keyCode) !== -1) {
                    if (this._ctrlPressed && this.camera._useCtrlForPanning) {
                        camera.inertialPanningX -= 1 / this.panningSensibility;
                    }
                    else {
                        camera.inertialAlphaOffset -= this.angularSpeed;
                    }
                }
                else if (this.keysUp.indexOf(keyCode) !== -1) {
                    if (this._ctrlPressed && this.camera._useCtrlForPanning) {
                        camera.inertialPanningY += 1 / this.panningSensibility;
                    }
                    else if (this._altPressed && this.useAltToZoom) {
                        camera.inertialRadiusOffset += 1 / this.zoomingSensibility;
                    }
                    else {
                        camera.inertialBetaOffset -= this.angularSpeed;
                    }
                }
                else if (this.keysRight.indexOf(keyCode) !== -1) {
                    if (this._ctrlPressed && this.camera._useCtrlForPanning) {
                        camera.inertialPanningX += 1 / this.panningSensibility;
                    }
                    else {
                        camera.inertialAlphaOffset += this.angularSpeed;
                    }
                }
                else if (this.keysDown.indexOf(keyCode) !== -1) {
                    if (this._ctrlPressed && this.camera._useCtrlForPanning) {
                        camera.inertialPanningY -= 1 / this.panningSensibility;
                    }
                    else if (this._altPressed && this.useAltToZoom) {
                        camera.inertialRadiusOffset -= 1 / this.zoomingSensibility;
                    }
                    else {
                        camera.inertialBetaOffset += this.angularSpeed;
                    }
                }
                else if (this.keysReset.indexOf(keyCode) !== -1) {
                    if (camera.useInputToRestoreState) {
                        camera.restoreState();
                    }
                }
            }
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    ArcRotateCameraKeyboardMoveInput.prototype.getClassName = function () {
        return "ArcRotateCameraKeyboardMoveInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    ArcRotateCameraKeyboardMoveInput.prototype.getSimpleName = function () {
        return "keyboard";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "keysUp", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "keysDown", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "keysLeft", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "keysRight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "keysReset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "panningSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "zoomingSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "useAltToZoom", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraKeyboardMoveInput.prototype, "angularSpeed", void 0);
    return ArcRotateCameraKeyboardMoveInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["ArcRotateCameraKeyboardMoveInput"] = ArcRotateCameraKeyboardMoveInput;


/***/ }),

/***/ "./Cameras/Inputs/arcRotateCameraMouseWheelInput.ts":
/*!**********************************************************!*\
  !*** ./Cameras/Inputs/arcRotateCameraMouseWheelInput.ts ***!
  \**********************************************************/
/*! exports provided: ArcRotateCameraMouseWheelInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraMouseWheelInput", function() { return ArcRotateCameraMouseWheelInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");





/**
 * Manage the mouse wheel inputs to control an arc rotate camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var ArcRotateCameraMouseWheelInput = /** @class */ (function () {
    function ArcRotateCameraMouseWheelInput() {
        /**
         * Gets or Set the mouse wheel precision or how fast is the camera zooming.
         */
        this.wheelPrecision = 3.0;
        /**
         * wheelDeltaPercentage will be used instead of wheelPrecision if different from 0.
         * It defines the percentage of current camera.radius to use as delta when wheel is used.
         */
        this.wheelDeltaPercentage = 0;
    }
    ArcRotateCameraMouseWheelInput.prototype.computeDeltaFromMouseWheelLegacyEvent = function (mouseWheelLegacyEvent, radius) {
        var delta = 0;
        var wheelDelta = (mouseWheelLegacyEvent.wheelDelta * 0.01 * this.wheelDeltaPercentage) * radius;
        if (mouseWheelLegacyEvent.wheelDelta > 0) {
            delta = wheelDelta / (1.0 + this.wheelDeltaPercentage);
        }
        else {
            delta = wheelDelta * (1.0 + this.wheelDeltaPercentage);
        }
        return delta;
    };
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    ArcRotateCameraMouseWheelInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        this._wheel = function (p, s) {
            //sanity check - this should be a PointerWheel event.
            if (p.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERWHEEL) {
                return;
            }
            var event = p.event;
            var delta = 0;
            var mouseWheelLegacyEvent = event;
            if (mouseWheelLegacyEvent.wheelDelta) {
                if (_this.wheelDeltaPercentage) {
                    delta = _this.computeDeltaFromMouseWheelLegacyEvent(mouseWheelLegacyEvent, _this.camera.radius);
                    // If zooming in, estimate the target radius and use that to compute the delta for inertia
                    // this will stop multiple scroll events zooming in from adding too much inertia
                    if (delta > 0) {
                        var estimatedTargetRadius = _this.camera.radius;
                        var targetInertia = _this.camera.inertialRadiusOffset + delta;
                        for (var i = 0; i < 20 && Math.abs(targetInertia) > 0.001; i++) {
                            estimatedTargetRadius -= targetInertia;
                            targetInertia *= _this.camera.inertia;
                        }
                        estimatedTargetRadius = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Clamp(estimatedTargetRadius, 0, Number.MAX_VALUE);
                        delta = _this.computeDeltaFromMouseWheelLegacyEvent(mouseWheelLegacyEvent, estimatedTargetRadius);
                    }
                }
                else {
                    delta = mouseWheelLegacyEvent.wheelDelta / (_this.wheelPrecision * 40);
                }
            }
            else {
                var deltaValue = event.deltaY || event.detail;
                delta = -deltaValue / _this.wheelPrecision;
            }
            if (delta) {
                _this.camera.inertialRadiusOffset += delta;
            }
            if (event.preventDefault) {
                if (!noPreventDefault) {
                    event.preventDefault();
                }
            }
        };
        this._observer = this.camera.getScene().onPointerObservable.add(this._wheel, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERWHEEL);
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    ArcRotateCameraMouseWheelInput.prototype.detachControl = function (element) {
        if (this._observer && element) {
            this.camera.getScene().onPointerObservable.remove(this._observer);
            this._observer = null;
            this._wheel = null;
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    ArcRotateCameraMouseWheelInput.prototype.getClassName = function () {
        return "ArcRotateCameraMouseWheelInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    ArcRotateCameraMouseWheelInput.prototype.getSimpleName = function () {
        return "mousewheel";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraMouseWheelInput.prototype, "wheelPrecision", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraMouseWheelInput.prototype, "wheelDeltaPercentage", void 0);
    return ArcRotateCameraMouseWheelInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["ArcRotateCameraMouseWheelInput"] = ArcRotateCameraMouseWheelInput;


/***/ }),

/***/ "./Cameras/Inputs/arcRotateCameraPointersInput.ts":
/*!********************************************************!*\
  !*** ./Cameras/Inputs/arcRotateCameraPointersInput.ts ***!
  \********************************************************/
/*! exports provided: ArcRotateCameraPointersInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraPointersInput", function() { return ArcRotateCameraPointersInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Cameras_Inputs_BaseCameraPointersInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/Inputs/BaseCameraPointersInput */ "./Cameras/Inputs/BaseCameraPointersInput.ts");




/**
 * Manage the pointers inputs to control an arc rotate camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var ArcRotateCameraPointersInput = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ArcRotateCameraPointersInput, _super);
    function ArcRotateCameraPointersInput() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        /**
         * Defines the buttons associated with the input to handle camera move.
         */
        _this.buttons = [0, 1, 2];
        /**
         * Defines the pointer angular sensibility  along the X axis or how fast is
         * the camera rotating.
         */
        _this.angularSensibilityX = 1000.0;
        /**
         * Defines the pointer angular sensibility along the Y axis or how fast is
         * the camera rotating.
         */
        _this.angularSensibilityY = 1000.0;
        /**
         * Defines the pointer pinch precision or how fast is the camera zooming.
         */
        _this.pinchPrecision = 12.0;
        /**
         * pinchDeltaPercentage will be used instead of pinchPrecision if different
         * from 0.
         * It defines the percentage of current camera.radius to use as delta when
         * pinch zoom is used.
         */
        _this.pinchDeltaPercentage = 0;
        /**
         * Defines the pointer panning sensibility or how fast is the camera moving.
         */
        _this.panningSensibility = 1000.0;
        /**
         * Defines whether panning (2 fingers swipe) is enabled through multitouch.
         */
        _this.multiTouchPanning = true;
        /**
         * Defines whether panning is enabled for both pan (2 fingers swipe) and
         * zoom (pinch) through multitouch.
         */
        _this.multiTouchPanAndZoom = true;
        /**
         * Revers pinch action direction.
         */
        _this.pinchInwards = true;
        _this._isPanClick = false;
        _this._twoFingerActivityCount = 0;
        _this._isPinching = false;
        return _this;
    }
    /**
     * Gets the class name of the current input.
     * @returns the class name
     */
    ArcRotateCameraPointersInput.prototype.getClassName = function () {
        return "ArcRotateCameraPointersInput";
    };
    /**
     * Called on pointer POINTERMOVE event if only a single touch is active.
     */
    ArcRotateCameraPointersInput.prototype.onTouch = function (point, offsetX, offsetY) {
        if (this.panningSensibility !== 0 &&
            ((this._ctrlKey && this.camera._useCtrlForPanning) || this._isPanClick)) {
            this.camera.inertialPanningX += -offsetX / this.panningSensibility;
            this.camera.inertialPanningY += offsetY / this.panningSensibility;
        }
        else {
            this.camera.inertialAlphaOffset -= offsetX / this.angularSensibilityX;
            this.camera.inertialBetaOffset -= offsetY / this.angularSensibilityY;
        }
    };
    /**
     * Called on pointer POINTERDOUBLETAP event.
     */
    ArcRotateCameraPointersInput.prototype.onDoubleTap = function (type) {
        if (this.camera.useInputToRestoreState) {
            this.camera.restoreState();
        }
    };
    /**
     * Called on pointer POINTERMOVE event if multiple touches are active.
     */
    ArcRotateCameraPointersInput.prototype.onMultiTouch = function (pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition) {
        if (previousPinchSquaredDistance === 0 && previousMultiTouchPanPosition === null) {
            // First time this method is called for new pinch.
            // Next time this is called there will be a
            // previousPinchSquaredDistance and pinchSquaredDistance to compare.
            return;
        }
        if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {
            // Last time this method is called at the end of a pinch.
            return;
        }
        var direction = this.pinchInwards ? 1 : -1;
        if (this.multiTouchPanAndZoom) {
            if (this.pinchDeltaPercentage) {
                this.camera.inertialRadiusOffset +=
                    (pinchSquaredDistance - previousPinchSquaredDistance) * 0.001 *
                        this.camera.radius * this.pinchDeltaPercentage;
            }
            else {
                this.camera.inertialRadiusOffset +=
                    (pinchSquaredDistance - previousPinchSquaredDistance) /
                        (this.pinchPrecision * direction *
                            (this.angularSensibilityX + this.angularSensibilityY) / 2);
            }
            if (this.panningSensibility !== 0 &&
                previousMultiTouchPanPosition && multiTouchPanPosition) {
                var moveDeltaX = multiTouchPanPosition.x - previousMultiTouchPanPosition.x;
                var moveDeltaY = multiTouchPanPosition.y - previousMultiTouchPanPosition.y;
                this.camera.inertialPanningX += -moveDeltaX / this.panningSensibility;
                this.camera.inertialPanningY += moveDeltaY / this.panningSensibility;
            }
        }
        else {
            this._twoFingerActivityCount++;
            var previousPinchDistance = Math.sqrt(previousPinchSquaredDistance);
            var pinchDistance = Math.sqrt(pinchSquaredDistance);
            if (this._isPinching ||
                (this._twoFingerActivityCount < 20 &&
                    Math.abs(pinchDistance - previousPinchDistance) >
                        this.camera.pinchToPanMaxDistance)) {
                // Since pinch has not been active long, assume we intend to zoom.
                if (this.pinchDeltaPercentage) {
                    this.camera.inertialRadiusOffset +=
                        (pinchSquaredDistance - previousPinchSquaredDistance) * 0.001 *
                            this.camera.radius * this.pinchDeltaPercentage;
                }
                else {
                    this.camera.inertialRadiusOffset +=
                        (pinchSquaredDistance - previousPinchSquaredDistance) /
                            (this.pinchPrecision * direction *
                                (this.angularSensibilityX + this.angularSensibilityY) / 2);
                }
                // Since we are pinching, remain pinching on next iteration.
                this._isPinching = true;
            }
            else {
                // Pause between pinch starting and moving implies not a zoom event.
                // Pan instead.
                if (this.panningSensibility !== 0 && this.multiTouchPanning &&
                    multiTouchPanPosition && previousMultiTouchPanPosition) {
                    var moveDeltaX = multiTouchPanPosition.x - previousMultiTouchPanPosition.x;
                    var moveDeltaY = multiTouchPanPosition.y - previousMultiTouchPanPosition.y;
                    this.camera.inertialPanningX += -moveDeltaX / this.panningSensibility;
                    this.camera.inertialPanningY += moveDeltaY / this.panningSensibility;
                }
            }
        }
    };
    /**
     * Called each time a new POINTERDOWN event occurs. Ie, for each button
     * press.
     */
    ArcRotateCameraPointersInput.prototype.onButtonDown = function (evt) {
        this._isPanClick = evt.button === this.camera._panningMouseButton;
    };
    /**
     * Called each time a new POINTERUP event occurs. Ie, for each button
     * release.
     */
    ArcRotateCameraPointersInput.prototype.onButtonUp = function (evt) {
        this._twoFingerActivityCount = 0;
        this._isPinching = false;
    };
    /**
     * Called when window becomes inactive.
     */
    ArcRotateCameraPointersInput.prototype.onLostFocus = function () {
        this._isPanClick = false;
        this._twoFingerActivityCount = 0;
        this._isPinching = false;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "buttons", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "angularSensibilityX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "angularSensibilityY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "pinchPrecision", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "pinchDeltaPercentage", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "panningSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "multiTouchPanning", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCameraPointersInput.prototype, "multiTouchPanAndZoom", void 0);
    return ArcRotateCameraPointersInput;
}(_Cameras_Inputs_BaseCameraPointersInput__WEBPACK_IMPORTED_MODULE_3__["BaseCameraPointersInput"]));

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["ArcRotateCameraPointersInput"] =
    ArcRotateCameraPointersInput;


/***/ }),

/***/ "./Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.ts":
/*!*******************************************************************!*\
  !*** ./Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.ts ***!
  \*******************************************************************/
/*! exports provided: ArcRotateCameraVRDeviceOrientationInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraVRDeviceOrientationInput", function() { return ArcRotateCameraVRDeviceOrientationInput; });
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Cameras_arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/arcRotateCameraInputsManager */ "./Cameras/arcRotateCameraInputsManager.ts");


/**
 * Add orientation input support to the input manager.
 * @returns the current input manager
 */
_Cameras_arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["ArcRotateCameraInputsManager"].prototype.addVRDeviceOrientation = function () {
    this.add(new ArcRotateCameraVRDeviceOrientationInput());
    return this;
};
/**
 * Manage the device orientation inputs (gyroscope) to control an arc rotate camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var ArcRotateCameraVRDeviceOrientationInput = /** @class */ (function () {
    /**
     * Instantiate a new ArcRotateCameraVRDeviceOrientationInput.
     */
    function ArcRotateCameraVRDeviceOrientationInput() {
        /**
         * Defines a correction factor applied on the alpha value retrieved from the orientation events.
         */
        this.alphaCorrection = 1;
        /**
         * Defines a correction factor applied on the gamma value retrieved from the orientation events.
         */
        this.gammaCorrection = 1;
        this._alpha = 0;
        this._gamma = 0;
        this._dirty = false;
        this._deviceOrientationHandler = this._onOrientationEvent.bind(this);
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    ArcRotateCameraVRDeviceOrientationInput.prototype.attachControl = function (element, noPreventDefault) {
        this.camera.attachControl(element, noPreventDefault);
        var hostWindow = this.camera.getScene().getEngine().getHostWindow();
        hostWindow.addEventListener("deviceorientation", this._deviceOrientationHandler);
    };
    /** @hidden */
    ArcRotateCameraVRDeviceOrientationInput.prototype._onOrientationEvent = function (evt) {
        if (evt.alpha !== null) {
            this._alpha = (+evt.alpha | 0) * this.alphaCorrection;
        }
        if (evt.gamma !== null) {
            this._gamma = (+evt.gamma | 0) * this.gammaCorrection;
        }
        this._dirty = true;
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    ArcRotateCameraVRDeviceOrientationInput.prototype.checkInputs = function () {
        if (this._dirty) {
            this._dirty = false;
            if (this._gamma < 0) {
                this._gamma = 180 + this._gamma;
            }
            this.camera.alpha = (-this._alpha / 180.0 * Math.PI) % Math.PI * 2;
            this.camera.beta = (this._gamma / 180.0 * Math.PI);
        }
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    ArcRotateCameraVRDeviceOrientationInput.prototype.detachControl = function (element) {
        window.removeEventListener("deviceorientation", this._deviceOrientationHandler);
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    ArcRotateCameraVRDeviceOrientationInput.prototype.getClassName = function () {
        return "ArcRotateCameraVRDeviceOrientationInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    ArcRotateCameraVRDeviceOrientationInput.prototype.getSimpleName = function () {
        return "VRDeviceOrientation";
    };
    return ArcRotateCameraVRDeviceOrientationInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_0__["CameraInputTypes"]["ArcRotateCameraVRDeviceOrientationInput"] = ArcRotateCameraVRDeviceOrientationInput;


/***/ }),

/***/ "./Cameras/Inputs/flyCameraKeyboardInput.ts":
/*!**************************************************!*\
  !*** ./Cameras/Inputs/flyCameraKeyboardInput.ts ***!
  \**************************************************/
/*! exports provided: FlyCameraKeyboardInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FlyCameraKeyboardInput", function() { return FlyCameraKeyboardInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/keyboardEvents */ "./Events/keyboardEvents.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");





/**
 * Listen to keyboard events to control the camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FlyCameraKeyboardInput = /** @class */ (function () {
    function FlyCameraKeyboardInput() {
        /**
         * The list of keyboard keys used to control the forward move of the camera.
         */
        this.keysForward = [87];
        /**
         * The list of keyboard keys used to control the backward move of the camera.
         */
        this.keysBackward = [83];
        /**
         * The list of keyboard keys used to control the forward move of the camera.
         */
        this.keysUp = [69];
        /**
         * The list of keyboard keys used to control the backward move of the camera.
         */
        this.keysDown = [81];
        /**
         * The list of keyboard keys used to control the right strafe move of the camera.
         */
        this.keysRight = [68];
        /**
         * The list of keyboard keys used to control the left strafe move of the camera.
         */
        this.keysLeft = [65];
        this._keys = new Array();
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FlyCameraKeyboardInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        if (this._onCanvasBlurObserver) {
            return;
        }
        this._scene = this.camera.getScene();
        this._engine = this._scene.getEngine();
        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(function () {
            _this._keys = [];
        });
        this._onKeyboardObserver = this._scene.onKeyboardObservable.add(function (info) {
            var evt = info.event;
            if (info.type === _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__["KeyboardEventTypes"].KEYDOWN) {
                if (_this.keysForward.indexOf(evt.keyCode) !== -1 ||
                    _this.keysBackward.indexOf(evt.keyCode) !== -1 ||
                    _this.keysUp.indexOf(evt.keyCode) !== -1 ||
                    _this.keysDown.indexOf(evt.keyCode) !== -1 ||
                    _this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                    _this.keysRight.indexOf(evt.keyCode) !== -1) {
                    var index = _this._keys.indexOf(evt.keyCode);
                    if (index === -1) {
                        _this._keys.push(evt.keyCode);
                    }
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                }
            }
            else {
                if (_this.keysForward.indexOf(evt.keyCode) !== -1 ||
                    _this.keysBackward.indexOf(evt.keyCode) !== -1 ||
                    _this.keysUp.indexOf(evt.keyCode) !== -1 ||
                    _this.keysDown.indexOf(evt.keyCode) !== -1 ||
                    _this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                    _this.keysRight.indexOf(evt.keyCode) !== -1) {
                    var index = _this._keys.indexOf(evt.keyCode);
                    if (index >= 0) {
                        _this._keys.splice(index, 1);
                    }
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                }
            }
        });
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FlyCameraKeyboardInput.prototype.detachControl = function (element) {
        if (this._scene) {
            if (this._onKeyboardObserver) {
                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
            }
            if (this._onCanvasBlurObserver) {
                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
            }
            this._onKeyboardObserver = null;
            this._onCanvasBlurObserver = null;
        }
        this._keys = [];
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FlyCameraKeyboardInput.prototype.getClassName = function () {
        return "FlyCameraKeyboardInput";
    };
    /** @hidden */
    FlyCameraKeyboardInput.prototype._onLostFocus = function (e) {
        this._keys = [];
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FlyCameraKeyboardInput.prototype.getSimpleName = function () {
        return "keyboard";
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FlyCameraKeyboardInput.prototype.checkInputs = function () {
        if (this._onKeyboardObserver) {
            var camera = this.camera;
            // Keyboard
            for (var index = 0; index < this._keys.length; index++) {
                var keyCode = this._keys[index];
                var speed = camera._computeLocalCameraSpeed();
                if (this.keysForward.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(0, 0, speed);
                }
                else if (this.keysBackward.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(0, 0, -speed);
                }
                else if (this.keysUp.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(0, speed, 0);
                }
                else if (this.keysDown.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(0, -speed, 0);
                }
                else if (this.keysRight.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(speed, 0, 0);
                }
                else if (this.keysLeft.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(-speed, 0, 0);
                }
                if (camera.getScene().useRightHandedSystem) {
                    camera._localDirection.z *= -1;
                }
                camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection);
                camera.cameraDirection.addInPlace(camera._transformedDirection);
            }
        }
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraKeyboardInput.prototype, "keysForward", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraKeyboardInput.prototype, "keysBackward", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraKeyboardInput.prototype, "keysUp", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraKeyboardInput.prototype, "keysDown", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraKeyboardInput.prototype, "keysRight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraKeyboardInput.prototype, "keysLeft", void 0);
    return FlyCameraKeyboardInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FlyCameraKeyboardInput"] = FlyCameraKeyboardInput;


/***/ }),

/***/ "./Cameras/Inputs/flyCameraMouseInput.ts":
/*!***********************************************!*\
  !*** ./Cameras/Inputs/flyCameraMouseInput.ts ***!
  \***********************************************/
/*! exports provided: FlyCameraMouseInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FlyCameraMouseInput", function() { return FlyCameraMouseInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Maths/math.axis */ "./Maths/math.axis.ts");






/**
 * Listen to mouse events to control the camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FlyCameraMouseInput = /** @class */ (function () {
    /**
     * Listen to mouse events to control the camera.
     * @param touchEnabled Define if touch is enabled. (Default is true.)
     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
     */
    function FlyCameraMouseInput(touchEnabled) {
        if (touchEnabled === void 0) { touchEnabled = true; }
        /**
         * Defines the buttons associated with the input to handle camera rotation.
         */
        this.buttons = [0, 1, 2];
        /**
         * Assign buttons for Yaw control.
         */
        this.buttonsYaw = [-1, 0, 1];
        /**
        * Assign buttons for Pitch control.
        */
        this.buttonsPitch = [-1, 0, 1];
        /**
        * Assign buttons for Roll control.
        */
        this.buttonsRoll = [2];
        /**
         * Detect if any button is being pressed while mouse is moved.
         * -1 = Mouse locked.
         * 0 = Left button.
         * 1 = Middle Button.
         * 2 = Right Button.
         */
        this.activeButton = -1;
        /**
         * Defines the pointer's angular sensibility, to control the camera rotation speed.
         * Higher values reduce its sensitivity.
         */
        this.angularSensibility = 1000.0;
        this.previousPosition = null;
    }
    /**
     * Attach the mouse control to the HTML DOM element.
     * @param element Defines the element that listens to the input events.
     * @param noPreventDefault Defines whether events caught by the controls should call preventdefault().
     */
    FlyCameraMouseInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        this.element = element;
        this.noPreventDefault = noPreventDefault;
        this._observer = this.camera.getScene().onPointerObservable.add(function (p, s) {
            _this._pointerInput(p, s);
        }, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOWN | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERUP | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE);
        // Correct Roll by rate, if enabled.
        this._rollObserver = this.camera.getScene().onBeforeRenderObservable.add(function () {
            if (_this.camera.rollCorrect) {
                _this.camera.restoreRoll(_this.camera.rollCorrect);
            }
        });
        // Helper function to keep 'this'.
        this._mousemoveCallback = function (e) {
            _this._onMouseMove(e);
        };
        element.addEventListener("mousemove", this._mousemoveCallback, false);
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FlyCameraMouseInput.prototype.detachControl = function (element) {
        if (this._observer && element) {
            this.camera.getScene().onPointerObservable.remove(this._observer);
            this.camera.getScene().onBeforeRenderObservable.remove(this._rollObserver);
            if (this._mousemoveCallback) {
                element.removeEventListener("mousemove", this._mousemoveCallback);
            }
            this._observer = null;
            this._rollObserver = null;
            this.previousPosition = null;
            this.noPreventDefault = undefined;
        }
    };
    /**
     * Gets the class name of the current input.
     * @returns the class name.
     */
    FlyCameraMouseInput.prototype.getClassName = function () {
        return "FlyCameraMouseInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input's friendly name.
     */
    FlyCameraMouseInput.prototype.getSimpleName = function () {
        return "mouse";
    };
    // Track mouse movement, when the pointer is not locked.
    FlyCameraMouseInput.prototype._pointerInput = function (p, s) {
        var e = p.event;
        var camera = this.camera;
        var engine = camera.getEngine();
        if (engine.isInVRExclusivePointerMode) {
            return;
        }
        if (!this.touchEnabled && e.pointerType === "touch") {
            return;
        }
        // Mouse is moved but an unknown mouse button is pressed.
        if (p.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE && this.buttons.indexOf(e.button) === -1) {
            return;
        }
        var srcElement = (e.srcElement || e.target);
        // Mouse down.
        if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOWN && srcElement) {
            try {
                srcElement.setPointerCapture(e.pointerId);
            }
            catch (e) {
                // Nothing to do with the error. Execution continues.
            }
            this.previousPosition = {
                x: e.clientX,
                y: e.clientY
            };
            this.activeButton = e.button;
            if (!this.noPreventDefault) {
                e.preventDefault();
                this.element.focus();
            }
        }
        else
        // Mouse up.
        if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERUP && srcElement) {
            try {
                srcElement.releasePointerCapture(e.pointerId);
            }
            catch (e) {
                // Nothing to do with the error. Execution continues.
            }
            this.activeButton = -1;
            this.previousPosition = null;
            if (!this.noPreventDefault) {
                e.preventDefault();
            }
        }
        else
        // Mouse move.
        if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE) {
            if (!this.previousPosition || engine.isPointerLock) {
                return;
            }
            var offsetX = e.clientX - this.previousPosition.x;
            var offsetY = e.clientY - this.previousPosition.y;
            this.rotateCamera(offsetX, offsetY);
            this.previousPosition = {
                x: e.clientX,
                y: e.clientY
            };
            if (!this.noPreventDefault) {
                e.preventDefault();
            }
        }
    };
    // Track mouse movement, when pointer is locked.
    FlyCameraMouseInput.prototype._onMouseMove = function (e) {
        var camera = this.camera;
        var engine = camera.getEngine();
        if (!engine.isPointerLock || engine.isInVRExclusivePointerMode) {
            return;
        }
        var offsetX = e.movementX || e.mozMovementX || e.webkitMovementX || e.msMovementX || 0;
        var offsetY = e.movementY || e.mozMovementY || e.webkitMovementY || e.msMovementY || 0;
        this.rotateCamera(offsetX, offsetY);
        this.previousPosition = null;
        if (!this.noPreventDefault) {
            e.preventDefault();
        }
    };
    /**
     * Rotate camera by mouse offset.
     */
    FlyCameraMouseInput.prototype.rotateCamera = function (offsetX, offsetY) {
        var _this = this;
        var camera = this.camera;
        var scene = this.camera.getScene();
        if (scene.useRightHandedSystem) {
            offsetX *= -1;
        }
        if (camera.parent && camera.parent._getWorldMatrixDeterminant() < 0) {
            offsetX *= -1;
        }
        var x = offsetX / this.angularSensibility;
        var y = offsetY / this.angularSensibility;
        // Initialize to current rotation.
        var currentRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].RotationYawPitchRoll(camera.rotation.y, camera.rotation.x, camera.rotation.z);
        var rotationChange;
        // Pitch.
        if (this.buttonsPitch.some(function (v) { return v === _this.activeButton; })) {
            // Apply change in Radians to vector Angle.
            rotationChange = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].RotationAxis(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].X, y);
            // Apply Pitch to quaternion.
            currentRotation.multiplyInPlace(rotationChange);
        }
        // Yaw.
        if (this.buttonsYaw.some(function (v) { return v === _this.activeButton; })) {
            // Apply change in Radians to vector Angle.
            rotationChange = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].RotationAxis(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Y, x);
            // Apply Yaw to quaternion.
            currentRotation.multiplyInPlace(rotationChange);
            // Add Roll, if banked turning is enabled, within Roll limit.
            var limit = (camera.bankedTurnLimit) + camera._trackRoll; // Defaults to 90° plus manual roll.
            if (camera.bankedTurn && -limit < camera.rotation.z && camera.rotation.z < limit) {
                var bankingDelta = camera.bankedTurnMultiplier * -x;
                // Apply change in Radians to vector Angle.
                rotationChange = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].RotationAxis(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Z, bankingDelta);
                // Apply Yaw to quaternion.
                currentRotation.multiplyInPlace(rotationChange);
            }
        }
        // Roll.
        if (this.buttonsRoll.some(function (v) { return v === _this.activeButton; })) {
            // Apply change in Radians to vector Angle.
            rotationChange = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].RotationAxis(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Z, -x);
            // Track Rolling.
            camera._trackRoll -= x;
            // Apply Pitch to quaternion.
            currentRotation.multiplyInPlace(rotationChange);
        }
        // Apply rotationQuaternion to Euler camera.rotation.
        currentRotation.toEulerAnglesToRef(camera.rotation);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraMouseInput.prototype, "buttons", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCameraMouseInput.prototype, "angularSensibility", void 0);
    return FlyCameraMouseInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FlyCameraMouseInput"] = FlyCameraMouseInput;


/***/ }),

/***/ "./Cameras/Inputs/followCameraKeyboardMoveInput.ts":
/*!*********************************************************!*\
  !*** ./Cameras/Inputs/followCameraKeyboardMoveInput.ts ***!
  \*********************************************************/
/*! exports provided: FollowCameraKeyboardMoveInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FollowCameraKeyboardMoveInput", function() { return FollowCameraKeyboardMoveInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/keyboardEvents */ "./Events/keyboardEvents.ts");




/**
 * Manage the keyboard inputs to control the movement of a follow camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FollowCameraKeyboardMoveInput = /** @class */ (function () {
    function FollowCameraKeyboardMoveInput() {
        /**
         * Defines the list of key codes associated with the up action (increase heightOffset)
         */
        this.keysHeightOffsetIncr = [38];
        /**
         * Defines the list of key codes associated with the down action (decrease heightOffset)
         */
        this.keysHeightOffsetDecr = [40];
        /**
         * Defines whether the Alt modifier key is required to move up/down (alter heightOffset)
         */
        this.keysHeightOffsetModifierAlt = false;
        /**
         * Defines whether the Ctrl modifier key is required to move up/down (alter heightOffset)
         */
        this.keysHeightOffsetModifierCtrl = false;
        /**
         * Defines whether the Shift modifier key is required to move up/down (alter heightOffset)
         */
        this.keysHeightOffsetModifierShift = false;
        /**
         * Defines the list of key codes associated with the left action (increase rotationOffset)
         */
        this.keysRotationOffsetIncr = [37];
        /**
         * Defines the list of key codes associated with the right action (decrease rotationOffset)
         */
        this.keysRotationOffsetDecr = [39];
        /**
         * Defines whether the Alt modifier key is required to move left/right (alter rotationOffset)
         */
        this.keysRotationOffsetModifierAlt = false;
        /**
         * Defines whether the Ctrl modifier key is required to move left/right (alter rotationOffset)
         */
        this.keysRotationOffsetModifierCtrl = false;
        /**
         * Defines whether the Shift modifier key is required to move left/right (alter rotationOffset)
         */
        this.keysRotationOffsetModifierShift = false;
        /**
         * Defines the list of key codes associated with the zoom-in action (decrease radius)
         */
        this.keysRadiusIncr = [40];
        /**
         * Defines the list of key codes associated with the zoom-out action (increase radius)
         */
        this.keysRadiusDecr = [38];
        /**
         * Defines whether the Alt modifier key is required to zoom in/out (alter radius value)
         */
        this.keysRadiusModifierAlt = true;
        /**
         * Defines whether the Ctrl modifier key is required to zoom in/out (alter radius value)
         */
        this.keysRadiusModifierCtrl = false;
        /**
         * Defines whether the Shift modifier key is required to zoom in/out (alter radius value)
         */
        this.keysRadiusModifierShift = false;
        /**
         * Defines the rate of change of heightOffset.
         */
        this.heightSensibility = 1;
        /**
         * Defines the rate of change of rotationOffset.
         */
        this.rotationSensibility = 1;
        /**
         * Defines the rate of change of radius.
         */
        this.radiusSensibility = 1;
        this._keys = new Array();
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FollowCameraKeyboardMoveInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        if (this._onCanvasBlurObserver) {
            return;
        }
        this._scene = this.camera.getScene();
        this._engine = this._scene.getEngine();
        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(function () {
            _this._keys = [];
        });
        this._onKeyboardObserver = this._scene.onKeyboardObservable.add(function (info) {
            var evt = info.event;
            if (!evt.metaKey) {
                if (info.type === _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__["KeyboardEventTypes"].KEYDOWN) {
                    _this._ctrlPressed = evt.ctrlKey;
                    _this._altPressed = evt.altKey;
                    _this._shiftPressed = evt.shiftKey;
                    if (_this.keysHeightOffsetIncr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysHeightOffsetDecr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRotationOffsetIncr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRotationOffsetDecr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRadiusIncr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRadiusDecr.indexOf(evt.keyCode) !== -1) {
                        var index = _this._keys.indexOf(evt.keyCode);
                        if (index === -1) {
                            _this._keys.push(evt.keyCode);
                        }
                        if (evt.preventDefault) {
                            if (!noPreventDefault) {
                                evt.preventDefault();
                            }
                        }
                    }
                }
                else {
                    if (_this.keysHeightOffsetIncr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysHeightOffsetDecr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRotationOffsetIncr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRotationOffsetDecr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRadiusIncr.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRadiusDecr.indexOf(evt.keyCode) !== -1) {
                        var index = _this._keys.indexOf(evt.keyCode);
                        if (index >= 0) {
                            _this._keys.splice(index, 1);
                        }
                        if (evt.preventDefault) {
                            if (!noPreventDefault) {
                                evt.preventDefault();
                            }
                        }
                    }
                }
            }
        });
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FollowCameraKeyboardMoveInput.prototype.detachControl = function (element) {
        if (this._scene) {
            if (this._onKeyboardObserver) {
                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
            }
            if (this._onCanvasBlurObserver) {
                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
            }
            this._onKeyboardObserver = null;
            this._onCanvasBlurObserver = null;
        }
        this._keys = [];
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FollowCameraKeyboardMoveInput.prototype.checkInputs = function () {
        var _this = this;
        if (this._onKeyboardObserver) {
            this._keys.forEach(function (keyCode) {
                if (_this.keysHeightOffsetIncr.indexOf(keyCode) !== -1 &&
                    _this._modifierHeightOffset()) {
                    _this.camera.heightOffset += _this.heightSensibility;
                }
                else if (_this.keysHeightOffsetDecr.indexOf(keyCode) !== -1 &&
                    _this._modifierHeightOffset()) {
                    _this.camera.heightOffset -= _this.heightSensibility;
                }
                else if (_this.keysRotationOffsetIncr.indexOf(keyCode) !== -1 &&
                    _this._modifierRotationOffset()) {
                    _this.camera.rotationOffset += _this.rotationSensibility;
                    _this.camera.rotationOffset %= 360;
                }
                else if (_this.keysRotationOffsetDecr.indexOf(keyCode) !== -1 &&
                    _this._modifierRotationOffset()) {
                    _this.camera.rotationOffset -= _this.rotationSensibility;
                    _this.camera.rotationOffset %= 360;
                }
                else if (_this.keysRadiusIncr.indexOf(keyCode) !== -1 &&
                    _this._modifierRadius()) {
                    _this.camera.radius += _this.radiusSensibility;
                }
                else if (_this.keysRadiusDecr.indexOf(keyCode) !== -1 &&
                    _this._modifierRadius()) {
                    _this.camera.radius -= _this.radiusSensibility;
                }
            });
        }
    };
    /**
     * Gets the class name of the current input.
     * @returns the class name
     */
    FollowCameraKeyboardMoveInput.prototype.getClassName = function () {
        return "FollowCameraKeyboardMoveInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FollowCameraKeyboardMoveInput.prototype.getSimpleName = function () {
        return "keyboard";
    };
    /**
     * Check if the pressed modifier keys (Alt/Ctrl/Shift) match those configured to
     * allow modification of the heightOffset value.
     */
    FollowCameraKeyboardMoveInput.prototype._modifierHeightOffset = function () {
        return (this.keysHeightOffsetModifierAlt === this._altPressed &&
            this.keysHeightOffsetModifierCtrl === this._ctrlPressed &&
            this.keysHeightOffsetModifierShift === this._shiftPressed);
    };
    /**
     * Check if the pressed modifier keys (Alt/Ctrl/Shift) match those configured to
     * allow modification of the rotationOffset value.
     */
    FollowCameraKeyboardMoveInput.prototype._modifierRotationOffset = function () {
        return (this.keysRotationOffsetModifierAlt === this._altPressed &&
            this.keysRotationOffsetModifierCtrl === this._ctrlPressed &&
            this.keysRotationOffsetModifierShift === this._shiftPressed);
    };
    /**
     * Check if the pressed modifier keys (Alt/Ctrl/Shift) match those configured to
     * allow modification of the radius value.
     */
    FollowCameraKeyboardMoveInput.prototype._modifierRadius = function () {
        return (this.keysRadiusModifierAlt === this._altPressed &&
            this.keysRadiusModifierCtrl === this._ctrlPressed &&
            this.keysRadiusModifierShift === this._shiftPressed);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysHeightOffsetIncr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysHeightOffsetDecr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysHeightOffsetModifierAlt", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysHeightOffsetModifierCtrl", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysHeightOffsetModifierShift", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRotationOffsetIncr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRotationOffsetDecr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRotationOffsetModifierAlt", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRotationOffsetModifierCtrl", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRotationOffsetModifierShift", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRadiusIncr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRadiusDecr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRadiusModifierAlt", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRadiusModifierCtrl", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "keysRadiusModifierShift", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "heightSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "rotationSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FollowCameraKeyboardMoveInput.prototype, "radiusSensibility", void 0);
    return FollowCameraKeyboardMoveInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputTypes"]["FollowCameraKeyboardMoveInput"] = FollowCameraKeyboardMoveInput;


/***/ }),

/***/ "./Cameras/Inputs/followCameraMouseWheelInput.ts":
/*!*******************************************************!*\
  !*** ./Cameras/Inputs/followCameraMouseWheelInput.ts ***!
  \*******************************************************/
/*! exports provided: FollowCameraMouseWheelInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FollowCameraMouseWheelInput", function() { return FollowCameraMouseWheelInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");




/**
 * Manage the mouse wheel inputs to control a follow camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FollowCameraMouseWheelInput = /** @class */ (function () {
    function FollowCameraMouseWheelInput() {
        /**
         * Moue wheel controls zoom. (Mouse wheel modifies camera.radius value.)
         */
        this.axisControlRadius = true;
        /**
         * Moue wheel controls height. (Mouse wheel modifies camera.heightOffset value.)
         */
        this.axisControlHeight = false;
        /**
         * Moue wheel controls angle. (Mouse wheel modifies camera.rotationOffset value.)
         */
        this.axisControlRotation = false;
        /**
         * Gets or Set the mouse wheel precision or how fast is the camera moves in
         * relation to mouseWheel events.
         */
        this.wheelPrecision = 3.0;
        /**
         * wheelDeltaPercentage will be used instead of wheelPrecision if different from 0.
         * It defines the percentage of current camera.radius to use as delta when wheel is used.
         */
        this.wheelDeltaPercentage = 0;
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FollowCameraMouseWheelInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        this._wheel = function (p, s) {
            // sanity check - this should be a PointerWheel event.
            if (p.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERWHEEL) {
                return;
            }
            var event = p.event;
            var delta = 0;
            // Chrome, Safari: event.deltaY
            // IE: event.wheelDelta
            // Firefox: event.detail (inverted)
            var wheelDelta = Math.max(-1, Math.min(1, (event.deltaY || event.wheelDelta || -event.detail)));
            if (_this.wheelDeltaPercentage) {
                console.assert((_this.axisControlRadius +
                    _this.axisControlHeight +
                    _this.axisControlRotation) <= 1, "wheelDeltaPercentage only usable when mouse wheel " +
                    "controlls ONE axis. " +
                    "Currently enabled: " +
                    "axisControlRadius: " + _this.axisControlRadius +
                    ", axisControlHeightOffset: " + _this.axisControlHeight +
                    ", axisControlRotationOffset: " + _this.axisControlRotation);
                if (_this.axisControlRadius) {
                    delta =
                        wheelDelta * 0.01 * _this.wheelDeltaPercentage *
                            _this.camera.radius;
                }
                else if (_this.axisControlHeight) {
                    delta =
                        wheelDelta * 0.01 * _this.wheelDeltaPercentage *
                            _this.camera.heightOffset;
                }
                else if (_this.axisControlRotation) {
                    delta =
                        wheelDelta * 0.01 * _this.wheelDeltaPercentage *
                            _this.camera.rotationOffset;
                }
            }
            else {
                delta = wheelDelta * _this.wheelPrecision;
            }
            if (delta) {
                if (_this.axisControlRadius) {
                    _this.camera.radius += delta;
                }
                else if (_this.axisControlHeight) {
                    _this.camera.heightOffset -= delta;
                }
                else if (_this.axisControlRotation) {
                    _this.camera.rotationOffset -= delta;
                }
            }
            if (event.preventDefault) {
                if (!noPreventDefault) {
                    event.preventDefault();
                }
            }
        };
        this._observer = this.camera.getScene().onPointerObservable.add(this._wheel, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERWHEEL);
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FollowCameraMouseWheelInput.prototype.detachControl = function (element) {
        if (this._observer && element) {
            this.camera.getScene().onPointerObservable.remove(this._observer);
            this._observer = null;
            this._wheel = null;
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FollowCameraMouseWheelInput.prototype.getClassName = function () {
        return "ArcRotateCameraMouseWheelInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FollowCameraMouseWheelInput.prototype.getSimpleName = function () {
        return "mousewheel";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraMouseWheelInput.prototype, "axisControlRadius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraMouseWheelInput.prototype, "axisControlHeight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraMouseWheelInput.prototype, "axisControlRotation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraMouseWheelInput.prototype, "wheelPrecision", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraMouseWheelInput.prototype, "wheelDeltaPercentage", void 0);
    return FollowCameraMouseWheelInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FollowCameraMouseWheelInput"] = FollowCameraMouseWheelInput;


/***/ }),

/***/ "./Cameras/Inputs/followCameraPointersInput.ts":
/*!*****************************************************!*\
  !*** ./Cameras/Inputs/followCameraPointersInput.ts ***!
  \*****************************************************/
/*! exports provided: FollowCameraPointersInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FollowCameraPointersInput", function() { return FollowCameraPointersInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Cameras_Inputs_BaseCameraPointersInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/Inputs/BaseCameraPointersInput */ "./Cameras/Inputs/BaseCameraPointersInput.ts");




/**
 * Manage the pointers inputs to control an follow camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FollowCameraPointersInput = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FollowCameraPointersInput, _super);
    function FollowCameraPointersInput() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        /**
         * Defines the pointer angular sensibility along the X axis or how fast is
         * the camera rotating.
         * A negative number will reverse the axis direction.
         */
        _this.angularSensibilityX = 1;
        /**
         * Defines the pointer angular sensibility along the Y axis or how fast is
         * the camera rotating.
         * A negative number will reverse the axis direction.
         */
        _this.angularSensibilityY = 1;
        /**
         * Defines the pointer pinch precision or how fast is the camera zooming.
         * A negative number will reverse the axis direction.
         */
        _this.pinchPrecision = 10000.0;
        /**
         * pinchDeltaPercentage will be used instead of pinchPrecision if different
         * from 0.
         * It defines the percentage of current camera.radius to use as delta when
         * pinch zoom is used.
         */
        _this.pinchDeltaPercentage = 0;
        /**
         * Pointer X axis controls zoom. (X axis modifies camera.radius value.)
         */
        _this.axisXControlRadius = false;
        /**
         * Pointer X axis controls height. (X axis modifies camera.heightOffset value.)
         */
        _this.axisXControlHeight = false;
        /**
         * Pointer X axis controls angle. (X axis modifies camera.rotationOffset value.)
         */
        _this.axisXControlRotation = true;
        /**
         * Pointer Y axis controls zoom. (Y axis modifies camera.radius value.)
         */
        _this.axisYControlRadius = false;
        /**
         * Pointer Y axis controls height. (Y axis modifies camera.heightOffset value.)
         */
        _this.axisYControlHeight = true;
        /**
         * Pointer Y axis controls angle. (Y axis modifies camera.rotationOffset value.)
         */
        _this.axisYControlRotation = false;
        /**
         * Pinch controls zoom. (Pinch modifies camera.radius value.)
         */
        _this.axisPinchControlRadius = true;
        /**
         * Pinch controls height. (Pinch modifies camera.heightOffset value.)
         */
        _this.axisPinchControlHeight = false;
        /**
         * Pinch controls angle. (Pinch modifies camera.rotationOffset value.)
         */
        _this.axisPinchControlRotation = false;
        /**
         * Log error messages if basic misconfiguration has occurred.
         */
        _this.warningEnable = true;
        /* Check for obvious misconfiguration. */
        _this._warningCounter = 0;
        return _this;
    }
    /**
     * Gets the class name of the current input.
     * @returns the class name
     */
    FollowCameraPointersInput.prototype.getClassName = function () {
        return "FollowCameraPointersInput";
    };
    FollowCameraPointersInput.prototype.onTouch = function (pointA, offsetX, offsetY) {
        this._warning();
        if (this.axisXControlRotation) {
            this.camera.rotationOffset += offsetX / this.angularSensibilityX;
        }
        else if (this.axisYControlRotation) {
            this.camera.rotationOffset += offsetY / this.angularSensibilityX;
        }
        if (this.axisXControlHeight) {
            this.camera.heightOffset += offsetX / this.angularSensibilityY;
        }
        else if (this.axisYControlHeight) {
            this.camera.heightOffset += offsetY / this.angularSensibilityY;
        }
        if (this.axisXControlRadius) {
            this.camera.radius -= offsetX / this.angularSensibilityY;
        }
        else if (this.axisYControlRadius) {
            this.camera.radius -= offsetY / this.angularSensibilityY;
        }
    };
    FollowCameraPointersInput.prototype.onMultiTouch = function (pointA, pointB, previousPinchSquaredDistance, pinchSquaredDistance, previousMultiTouchPanPosition, multiTouchPanPosition) {
        if (previousPinchSquaredDistance === 0 && previousMultiTouchPanPosition === null) {
            // First time this method is called for new pinch.
            // Next time this is called there will be a
            // previousPinchSquaredDistance and pinchSquaredDistance to compare.
            return;
        }
        if (pinchSquaredDistance === 0 && multiTouchPanPosition === null) {
            // Last time this method is called at the end of a pinch.
            return;
        }
        var pinchDelta = (pinchSquaredDistance - previousPinchSquaredDistance) /
            (this.pinchPrecision * (this.angularSensibilityX + this.angularSensibilityY) / 2);
        if (this.pinchDeltaPercentage) {
            pinchDelta *= 0.01 * this.pinchDeltaPercentage;
            if (this.axisPinchControlRotation) {
                this.camera.rotationOffset += pinchDelta * this.camera.rotationOffset;
            }
            if (this.axisPinchControlHeight) {
                this.camera.heightOffset += pinchDelta * this.camera.heightOffset;
            }
            if (this.axisPinchControlRadius) {
                this.camera.radius -= pinchDelta * this.camera.radius;
            }
        }
        else {
            if (this.axisPinchControlRotation) {
                this.camera.rotationOffset += pinchDelta;
            }
            if (this.axisPinchControlHeight) {
                this.camera.heightOffset += pinchDelta;
            }
            if (this.axisPinchControlRadius) {
                this.camera.radius -= pinchDelta;
            }
        }
    };
    FollowCameraPointersInput.prototype._warning = function () {
        if (!this.warningEnable || this._warningCounter++ % 100 !== 0) {
            return;
        }
        var warn = "It probably only makes sense to control ONE camera " +
            "property with each pointer axis. Set 'warningEnable = false' " +
            "if you are sure. Currently enabled: ";
        console.assert((this.axisXControlRotation +
            this.axisXControlHeight +
            this.axisXControlRadius) <= 1, warn +
            "axisXControlRotation: " + this.axisXControlRotation +
            ", axisXControlHeight: " + this.axisXControlHeight +
            ", axisXControlRadius: " + this.axisXControlRadius);
        console.assert((this.axisYControlRotation +
            this.axisYControlHeight +
            this.axisYControlRadius) <= 1, warn +
            "axisYControlRotation: " + this.axisYControlRotation +
            ", axisYControlHeight: " + this.axisYControlHeight +
            ", axisYControlRadius: " + this.axisYControlRadius);
        console.assert((this.axisPinchControlRotation +
            this.axisPinchControlHeight +
            this.axisPinchControlRadius) <= 1, warn +
            "axisPinchControlRotation: " + this.axisPinchControlRotation +
            ", axisPinchControlHeight: " + this.axisPinchControlHeight +
            ", axisPinchControlRadius: " + this.axisPinchControlRadius);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "angularSensibilityX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "angularSensibilityY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "pinchPrecision", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "pinchDeltaPercentage", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisXControlRadius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisXControlHeight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisXControlRotation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisYControlRadius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisYControlHeight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisYControlRotation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisPinchControlRadius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisPinchControlHeight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCameraPointersInput.prototype, "axisPinchControlRotation", void 0);
    return FollowCameraPointersInput;
}(_Cameras_Inputs_BaseCameraPointersInput__WEBPACK_IMPORTED_MODULE_3__["BaseCameraPointersInput"]));

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FollowCameraPointersInput"] = FollowCameraPointersInput;


/***/ }),

/***/ "./Cameras/Inputs/freeCameraDeviceOrientationInput.ts":
/*!************************************************************!*\
  !*** ./Cameras/Inputs/freeCameraDeviceOrientationInput.ts ***!
  \************************************************************/
/*! exports provided: FreeCameraDeviceOrientationInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraDeviceOrientationInput", function() { return FreeCameraDeviceOrientationInput; });
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Cameras_freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/freeCameraInputsManager */ "./Cameras/freeCameraInputsManager.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");





/**
 * Add orientation input support to the input manager.
 * @returns the current input manager
 */
_Cameras_freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_3__["FreeCameraInputsManager"].prototype.addDeviceOrientation = function () {
    if (!this._deviceOrientationInput) {
        this._deviceOrientationInput = new FreeCameraDeviceOrientationInput();
        this.add(this._deviceOrientationInput);
    }
    return this;
};
/**
 * Takes information about the orientation of the device as reported by the deviceorientation event to orient the camera.
 * Screen rotation is taken into account.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraDeviceOrientationInput = /** @class */ (function () {
    /**
     * Instantiates a new input
     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
     */
    function FreeCameraDeviceOrientationInput() {
        var _this = this;
        this._screenOrientationAngle = 0;
        this._screenQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]();
        this._alpha = 0;
        this._beta = 0;
        this._gamma = 0;
        /**
         * @hidden
         */
        this._onDeviceOrientationChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
        this._orientationChanged = function () {
            _this._screenOrientationAngle = (window.orientation !== undefined ? +window.orientation : (window.screen.orientation && (window.screen.orientation)['angle'] ? (window.screen.orientation).angle : 0));
            _this._screenOrientationAngle = -_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].ToRadians(_this._screenOrientationAngle / 2);
            _this._screenQuaternion.copyFromFloats(0, Math.sin(_this._screenOrientationAngle), 0, Math.cos(_this._screenOrientationAngle));
        };
        this._deviceOrientation = function (evt) {
            _this._alpha = evt.alpha !== null ? evt.alpha : 0;
            _this._beta = evt.beta !== null ? evt.beta : 0;
            _this._gamma = evt.gamma !== null ? evt.gamma : 0;
            if (evt.alpha !== null) {
                _this._onDeviceOrientationChangedObservable.notifyObservers();
            }
        };
        this._constantTranform = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"](-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
        this._orientationChanged();
    }
    /**
     * Can be used to detect if a device orientation sensor is availible on a device
     * @param timeout amount of time in milliseconds to wait for a response from the sensor (default: infinite)
     * @returns a promise that will resolve on orientation change
     */
    FreeCameraDeviceOrientationInput.WaitForOrientationChangeAsync = function (timeout) {
        return new Promise(function (res, rej) {
            var gotValue = false;
            var eventHandler = function () {
                window.removeEventListener("deviceorientation", eventHandler);
                gotValue = true;
                res();
            };
            // If timeout is pupulated reject the promise
            if (timeout) {
                setTimeout(function () {
                    if (!gotValue) {
                        window.removeEventListener("deviceorientation", eventHandler);
                        rej("WaitForOrientationChangeAsync timed out");
                    }
                }, timeout);
            }
            window.addEventListener("deviceorientation", eventHandler);
        });
    };
    Object.defineProperty(FreeCameraDeviceOrientationInput.prototype, "camera", {
        /**
         * Define the camera controlled by the input.
         */
        get: function () {
            return this._camera;
        },
        set: function (camera) {
            var _this = this;
            this._camera = camera;
            if (this._camera != null && !this._camera.rotationQuaternion) {
                this._camera.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]();
            }
            if (this._camera) {
                this._camera.onDisposeObservable.add(function () {
                    _this._onDeviceOrientationChangedObservable.clear();
                });
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCameraDeviceOrientationInput.prototype.attachControl = function (element, noPreventDefault) {
        var hostWindow = this.camera.getScene().getEngine().getHostWindow();
        hostWindow.addEventListener("orientationchange", this._orientationChanged);
        hostWindow.addEventListener("deviceorientation", this._deviceOrientation);
        //In certain cases, the attach control is called AFTER orientation was changed,
        //So this is needed.
        this._orientationChanged();
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCameraDeviceOrientationInput.prototype.detachControl = function (element) {
        window.removeEventListener("orientationchange", this._orientationChanged);
        window.removeEventListener("deviceorientation", this._deviceOrientation);
        this._alpha = 0;
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FreeCameraDeviceOrientationInput.prototype.checkInputs = function () {
        //if no device orientation provided, don't update the rotation.
        //Only testing against alpha under the assumption thatnorientation will never be so exact when set.
        if (!this._alpha) {
            return;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].RotationYawPitchRollToRef(_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].ToRadians(this._alpha), _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].ToRadians(this._beta), -_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].ToRadians(this._gamma), this.camera.rotationQuaternion);
        this._camera.rotationQuaternion.multiplyInPlace(this._screenQuaternion);
        this._camera.rotationQuaternion.multiplyInPlace(this._constantTranform);
        //Mirror on XY Plane
        this._camera.rotationQuaternion.z *= -1;
        this._camera.rotationQuaternion.w *= -1;
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FreeCameraDeviceOrientationInput.prototype.getClassName = function () {
        return "FreeCameraDeviceOrientationInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FreeCameraDeviceOrientationInput.prototype.getSimpleName = function () {
        return "deviceOrientation";
    };
    return FreeCameraDeviceOrientationInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_0__["CameraInputTypes"]["FreeCameraDeviceOrientationInput"] = FreeCameraDeviceOrientationInput;


/***/ }),

/***/ "./Cameras/Inputs/freeCameraGamepadInput.ts":
/*!**************************************************!*\
  !*** ./Cameras/Inputs/freeCameraGamepadInput.ts ***!
  \**************************************************/
/*! exports provided: FreeCameraGamepadInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraGamepadInput", function() { return FreeCameraGamepadInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Gamepads/gamepad */ "./Gamepads/gamepad.ts");





/**
 * Manage the gamepad inputs to control a free camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraGamepadInput = /** @class */ (function () {
    function FreeCameraGamepadInput() {
        /**
         * Defines the gamepad rotation sensiblity.
         * This is the threshold from when rotation starts to be accounted for to prevent jittering.
         */
        this.gamepadAngularSensibility = 200;
        /**
         * Defines the gamepad move sensiblity.
         * This is the threshold from when moving starts to be accounted for for to prevent jittering.
         */
        this.gamepadMoveSensibility = 40;
        this._cameraTransform = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
        this._deltaTransform = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this._vector3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this._vector2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCameraGamepadInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        var manager = this.camera.getScene().gamepadManager;
        this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
            if (gamepad.type !== _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_4__["Gamepad"].POSE_ENABLED) {
                // prioritize XBOX gamepads.
                if (!_this.gamepad || gamepad.type === _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_4__["Gamepad"].XBOX) {
                    _this.gamepad = gamepad;
                }
            }
        });
        this._onGamepadDisconnectedObserver = manager.onGamepadDisconnectedObservable.add(function (gamepad) {
            if (_this.gamepad === gamepad) {
                _this.gamepad = null;
            }
        });
        this.gamepad = manager.getGamepadByType(_Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_4__["Gamepad"].XBOX);
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCameraGamepadInput.prototype.detachControl = function (element) {
        this.camera.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);
        this.camera.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);
        this.gamepad = null;
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FreeCameraGamepadInput.prototype.checkInputs = function () {
        if (this.gamepad && this.gamepad.leftStick) {
            var camera = this.camera;
            var LSValues = this.gamepad.leftStick;
            var normalizedLX = LSValues.x / this.gamepadMoveSensibility;
            var normalizedLY = LSValues.y / this.gamepadMoveSensibility;
            LSValues.x = Math.abs(normalizedLX) > 0.005 ? 0 + normalizedLX : 0;
            LSValues.y = Math.abs(normalizedLY) > 0.005 ? 0 + normalizedLY : 0;
            var RSValues = this.gamepad.rightStick;
            if (RSValues) {
                var normalizedRX = RSValues.x / this.gamepadAngularSensibility;
                var normalizedRY = RSValues.y / this.gamepadAngularSensibility;
                RSValues.x = Math.abs(normalizedRX) > 0.001 ? 0 + normalizedRX : 0;
                RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;
            }
            else {
                RSValues = { x: 0, y: 0 };
            }
            if (!camera.rotationQuaternion) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationYawPitchRollToRef(camera.rotation.y, camera.rotation.x, 0, this._cameraTransform);
            }
            else {
                camera.rotationQuaternion.toRotationMatrix(this._cameraTransform);
            }
            var speed = camera._computeLocalCameraSpeed() * 50.0;
            this._vector3.copyFromFloats(LSValues.x * speed, 0, -LSValues.y * speed);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._vector3, this._cameraTransform, this._deltaTransform);
            camera.cameraDirection.addInPlace(this._deltaTransform);
            this._vector2.copyFromFloats(RSValues.y, RSValues.x);
            camera.cameraRotation.addInPlace(this._vector2);
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FreeCameraGamepadInput.prototype.getClassName = function () {
        return "FreeCameraGamepadInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FreeCameraGamepadInput.prototype.getSimpleName = function () {
        return "gamepad";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraGamepadInput.prototype, "gamepadAngularSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraGamepadInput.prototype, "gamepadMoveSensibility", void 0);
    return FreeCameraGamepadInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FreeCameraGamepadInput"] = FreeCameraGamepadInput;


/***/ }),

/***/ "./Cameras/Inputs/freeCameraKeyboardMoveInput.ts":
/*!*******************************************************!*\
  !*** ./Cameras/Inputs/freeCameraKeyboardMoveInput.ts ***!
  \*******************************************************/
/*! exports provided: FreeCameraKeyboardMoveInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraKeyboardMoveInput", function() { return FreeCameraKeyboardMoveInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/keyboardEvents */ "./Events/keyboardEvents.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");





/**
 * Manage the keyboard inputs to control the movement of a free camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraKeyboardMoveInput = /** @class */ (function () {
    function FreeCameraKeyboardMoveInput() {
        /**
         * Gets or Set the list of keyboard keys used to control the forward move of the camera.
         */
        this.keysUp = [38];
        /**
         * Gets or Set the list of keyboard keys used to control the backward move of the camera.
         */
        this.keysDown = [40];
        /**
         * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
         */
        this.keysLeft = [37];
        /**
         * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.
         */
        this.keysRight = [39];
        this._keys = new Array();
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCameraKeyboardMoveInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        if (this._onCanvasBlurObserver) {
            return;
        }
        this._scene = this.camera.getScene();
        this._engine = this._scene.getEngine();
        this._onCanvasBlurObserver = this._engine.onCanvasBlurObservable.add(function () {
            _this._keys = [];
        });
        this._onKeyboardObserver = this._scene.onKeyboardObservable.add(function (info) {
            var evt = info.event;
            if (!evt.metaKey) {
                if (info.type === _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_3__["KeyboardEventTypes"].KEYDOWN) {
                    if (_this.keysUp.indexOf(evt.keyCode) !== -1 ||
                        _this.keysDown.indexOf(evt.keyCode) !== -1 ||
                        _this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRight.indexOf(evt.keyCode) !== -1) {
                        var index = _this._keys.indexOf(evt.keyCode);
                        if (index === -1) {
                            _this._keys.push(evt.keyCode);
                        }
                        if (!noPreventDefault) {
                            evt.preventDefault();
                        }
                    }
                }
                else {
                    if (_this.keysUp.indexOf(evt.keyCode) !== -1 ||
                        _this.keysDown.indexOf(evt.keyCode) !== -1 ||
                        _this.keysLeft.indexOf(evt.keyCode) !== -1 ||
                        _this.keysRight.indexOf(evt.keyCode) !== -1) {
                        var index = _this._keys.indexOf(evt.keyCode);
                        if (index >= 0) {
                            _this._keys.splice(index, 1);
                        }
                        if (!noPreventDefault) {
                            evt.preventDefault();
                        }
                    }
                }
            }
        });
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCameraKeyboardMoveInput.prototype.detachControl = function (element) {
        if (this._scene) {
            if (this._onKeyboardObserver) {
                this._scene.onKeyboardObservable.remove(this._onKeyboardObserver);
            }
            if (this._onCanvasBlurObserver) {
                this._engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
            }
            this._onKeyboardObserver = null;
            this._onCanvasBlurObserver = null;
        }
        this._keys = [];
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FreeCameraKeyboardMoveInput.prototype.checkInputs = function () {
        if (this._onKeyboardObserver) {
            var camera = this.camera;
            // Keyboard
            for (var index = 0; index < this._keys.length; index++) {
                var keyCode = this._keys[index];
                var speed = camera._computeLocalCameraSpeed();
                if (this.keysLeft.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(-speed, 0, 0);
                }
                else if (this.keysUp.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(0, 0, speed);
                }
                else if (this.keysRight.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(speed, 0, 0);
                }
                else if (this.keysDown.indexOf(keyCode) !== -1) {
                    camera._localDirection.copyFromFloats(0, 0, -speed);
                }
                if (camera.getScene().useRightHandedSystem) {
                    camera._localDirection.z *= -1;
                }
                camera.getViewMatrix().invertToRef(camera._cameraTransformMatrix);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].TransformNormalToRef(camera._localDirection, camera._cameraTransformMatrix, camera._transformedDirection);
                camera.cameraDirection.addInPlace(camera._transformedDirection);
            }
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FreeCameraKeyboardMoveInput.prototype.getClassName = function () {
        return "FreeCameraKeyboardMoveInput";
    };
    /** @hidden */
    FreeCameraKeyboardMoveInput.prototype._onLostFocus = function () {
        this._keys = [];
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FreeCameraKeyboardMoveInput.prototype.getSimpleName = function () {
        return "keyboard";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraKeyboardMoveInput.prototype, "keysUp", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraKeyboardMoveInput.prototype, "keysDown", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraKeyboardMoveInput.prototype, "keysLeft", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraKeyboardMoveInput.prototype, "keysRight", void 0);
    return FreeCameraKeyboardMoveInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FreeCameraKeyboardMoveInput"] = FreeCameraKeyboardMoveInput;


/***/ }),

/***/ "./Cameras/Inputs/freeCameraMouseInput.ts":
/*!************************************************!*\
  !*** ./Cameras/Inputs/freeCameraMouseInput.ts ***!
  \************************************************/
/*! exports provided: FreeCameraMouseInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraMouseInput", function() { return FreeCameraMouseInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");





/**
 * Manage the mouse inputs to control the movement of a free camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraMouseInput = /** @class */ (function () {
    /**
     * Manage the mouse inputs to control the movement of a free camera.
     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
     * @param touchEnabled Defines if touch is enabled or not
     */
    function FreeCameraMouseInput(
    /**
     * Define if touch is enabled in the mouse input
     */
    touchEnabled) {
        if (touchEnabled === void 0) { touchEnabled = true; }
        this.touchEnabled = touchEnabled;
        /**
         * Defines the buttons associated with the input to handle camera move.
         */
        this.buttons = [0, 1, 2];
        /**
         * Defines the pointer angular sensibility  along the X and Y axis or how fast is the camera rotating.
         */
        this.angularSensibility = 2000.0;
        this.previousPosition = null;
        /**
         * Observable for when a pointer move event occurs containing the move offset
         */
        this.onPointerMovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * @hidden
         * If the camera should be rotated automatically based on pointer movement
         */
        this._allowCameraRotation = true;
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCameraMouseInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        var engine = this.camera.getEngine();
        if (!this._pointerInput) {
            this._pointerInput = function (p) {
                var evt = p.event;
                if (engine.isInVRExclusivePointerMode) {
                    return;
                }
                if (!_this.touchEnabled && evt.pointerType === "touch") {
                    return;
                }
                if (p.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERMOVE && _this.buttons.indexOf(evt.button) === -1) {
                    return;
                }
                var srcElement = (evt.srcElement || evt.target);
                if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERDOWN && srcElement) {
                    try {
                        srcElement.setPointerCapture(evt.pointerId);
                    }
                    catch (e) {
                        //Nothing to do with the error. Execution will continue.
                    }
                    _this.previousPosition = {
                        x: evt.clientX,
                        y: evt.clientY
                    };
                    if (!noPreventDefault) {
                        evt.preventDefault();
                        element.focus();
                    }
                }
                else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERUP && srcElement) {
                    try {
                        srcElement.releasePointerCapture(evt.pointerId);
                    }
                    catch (e) {
                        //Nothing to do with the error.
                    }
                    _this.previousPosition = null;
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                }
                else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERMOVE) {
                    if (!_this.previousPosition || engine.isPointerLock) {
                        return;
                    }
                    var offsetX = evt.clientX - _this.previousPosition.x;
                    var offsetY = evt.clientY - _this.previousPosition.y;
                    if (_this.camera.getScene().useRightHandedSystem) {
                        offsetX *= -1;
                    }
                    if (_this.camera.parent && _this.camera.parent._getWorldMatrixDeterminant() < 0) {
                        offsetX *= -1;
                    }
                    if (_this._allowCameraRotation) {
                        _this.camera.cameraRotation.y += offsetX / _this.angularSensibility;
                        _this.camera.cameraRotation.x += offsetY / _this.angularSensibility;
                    }
                    _this.onPointerMovedObservable.notifyObservers({ offsetX: offsetX, offsetY: offsetY });
                    _this.previousPosition = {
                        x: evt.clientX,
                        y: evt.clientY
                    };
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                }
            };
        }
        this._onMouseMove = function (evt) {
            if (!engine.isPointerLock) {
                return;
            }
            if (engine.isInVRExclusivePointerMode) {
                return;
            }
            var offsetX = evt.movementX || evt.mozMovementX || evt.webkitMovementX || evt.msMovementX || 0;
            if (_this.camera.getScene().useRightHandedSystem) {
                offsetX *= -1;
            }
            if (_this.camera.parent && _this.camera.parent._getWorldMatrixDeterminant() < 0) {
                offsetX *= -1;
            }
            _this.camera.cameraRotation.y += offsetX / _this.angularSensibility;
            var offsetY = evt.movementY || evt.mozMovementY || evt.webkitMovementY || evt.msMovementY || 0;
            _this.camera.cameraRotation.x += offsetY / _this.angularSensibility;
            _this.previousPosition = null;
            if (!noPreventDefault) {
                evt.preventDefault();
            }
        };
        this._observer = this.camera.getScene().onPointerObservable.add(this._pointerInput, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERDOWN | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERUP | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_4__["PointerEventTypes"].POINTERMOVE);
        element.addEventListener("mousemove", this._onMouseMove, false);
        element.addEventListener("contextmenu", this.onContextMenu.bind(this), false);
    };
    /**
     * Called on JS contextmenu event.
     * Override this method to provide functionality.
     */
    FreeCameraMouseInput.prototype.onContextMenu = function (evt) {
        evt.preventDefault();
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCameraMouseInput.prototype.detachControl = function (element) {
        if (this._observer && element) {
            this.camera.getScene().onPointerObservable.remove(this._observer);
            if (this._onMouseMove) {
                element.removeEventListener("mousemove", this._onMouseMove);
            }
            if (this.onContextMenu) {
                element.removeEventListener("contextmenu", this.onContextMenu);
            }
            if (this.onPointerMovedObservable) {
                this.onPointerMovedObservable.clear();
            }
            this._observer = null;
            this._onMouseMove = null;
            this.previousPosition = null;
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FreeCameraMouseInput.prototype.getClassName = function () {
        return "FreeCameraMouseInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FreeCameraMouseInput.prototype.getSimpleName = function () {
        return "mouse";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FreeCameraMouseInput.prototype, "buttons", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], FreeCameraMouseInput.prototype, "angularSensibility", void 0);
    return FreeCameraMouseInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_3__["CameraInputTypes"]["FreeCameraMouseInput"] = FreeCameraMouseInput;


/***/ }),

/***/ "./Cameras/Inputs/freeCameraTouchInput.ts":
/*!************************************************!*\
  !*** ./Cameras/Inputs/freeCameraTouchInput.ts ***!
  \************************************************/
/*! exports provided: FreeCameraTouchInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraTouchInput", function() { return FreeCameraTouchInput; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");





/**
 * Manage the touch inputs to control the movement of a free camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraTouchInput = /** @class */ (function () {
    function FreeCameraTouchInput() {
        /**
         * Defines the touch sensibility for rotation.
         * The higher the faster.
         */
        this.touchAngularSensibility = 200000.0;
        /**
         * Defines the touch sensibility for move.
         * The higher the faster.
         */
        this.touchMoveSensibility = 250.0;
        this._offsetX = null;
        this._offsetY = null;
        this._pointerPressed = new Array();
    }
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCameraTouchInput.prototype.attachControl = function (element, noPreventDefault) {
        var _this = this;
        var previousPosition = null;
        if (this._pointerInput === undefined) {
            this._onLostFocus = function () {
                _this._offsetX = null;
                _this._offsetY = null;
            };
            this._pointerInput = function (p) {
                var evt = p.event;
                if (evt.pointerType === "mouse") {
                    return;
                }
                if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOWN) {
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                    _this._pointerPressed.push(evt.pointerId);
                    if (_this._pointerPressed.length !== 1) {
                        return;
                    }
                    previousPosition = {
                        x: evt.clientX,
                        y: evt.clientY
                    };
                }
                else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERUP) {
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                    var index = _this._pointerPressed.indexOf(evt.pointerId);
                    if (index === -1) {
                        return;
                    }
                    _this._pointerPressed.splice(index, 1);
                    if (index != 0) {
                        return;
                    }
                    previousPosition = null;
                    _this._offsetX = null;
                    _this._offsetY = null;
                }
                else if (p.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE) {
                    if (!noPreventDefault) {
                        evt.preventDefault();
                    }
                    if (!previousPosition) {
                        return;
                    }
                    var index = _this._pointerPressed.indexOf(evt.pointerId);
                    if (index != 0) {
                        return;
                    }
                    _this._offsetX = evt.clientX - previousPosition.x;
                    _this._offsetY = -(evt.clientY - previousPosition.y);
                }
            };
        }
        this._observer = this.camera.getScene().onPointerObservable.add(this._pointerInput, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERDOWN | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERUP | _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_3__["PointerEventTypes"].POINTERMOVE);
        if (this._onLostFocus) {
            element.addEventListener("blur", this._onLostFocus);
        }
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCameraTouchInput.prototype.detachControl = function (element) {
        if (this._pointerInput && element) {
            if (this._observer) {
                this.camera.getScene().onPointerObservable.remove(this._observer);
                this._observer = null;
            }
            if (this._onLostFocus) {
                element.removeEventListener("blur", this._onLostFocus);
                this._onLostFocus = null;
            }
            this._pointerPressed = [];
            this._offsetX = null;
            this._offsetY = null;
        }
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FreeCameraTouchInput.prototype.checkInputs = function () {
        if (this._offsetX && this._offsetY) {
            var camera = this.camera;
            camera.cameraRotation.y += this._offsetX / this.touchAngularSensibility;
            if (this._pointerPressed.length > 1) {
                camera.cameraRotation.x += -this._offsetY / this.touchAngularSensibility;
            }
            else {
                var speed = camera._computeLocalCameraSpeed();
                var direction = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](0, 0, speed * this._offsetY / this.touchMoveSensibility);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].RotationYawPitchRollToRef(camera.rotation.y, camera.rotation.x, 0, camera._cameraRotationMatrix);
                camera.cameraDirection.addInPlace(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].TransformCoordinates(direction, camera._cameraRotationMatrix));
            }
        }
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FreeCameraTouchInput.prototype.getClassName = function () {
        return "FreeCameraTouchInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FreeCameraTouchInput.prototype.getSimpleName = function () {
        return "touch";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraTouchInput.prototype, "touchAngularSensibility", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCameraTouchInput.prototype, "touchMoveSensibility", void 0);
    return FreeCameraTouchInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_2__["CameraInputTypes"]["FreeCameraTouchInput"] = FreeCameraTouchInput;


/***/ }),

/***/ "./Cameras/Inputs/freeCameraVirtualJoystickInput.ts":
/*!**********************************************************!*\
  !*** ./Cameras/Inputs/freeCameraVirtualJoystickInput.ts ***!
  \**********************************************************/
/*! exports provided: FreeCameraVirtualJoystickInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraVirtualJoystickInput", function() { return FreeCameraVirtualJoystickInput; });
/* harmony import */ var _Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/virtualJoystick */ "./Misc/virtualJoystick.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Cameras_freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/freeCameraInputsManager */ "./Cameras/freeCameraInputsManager.ts");




/**
* Add virtual joystick input support to the input manager.
* @returns the current input manager
*/
_Cameras_freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_3__["FreeCameraInputsManager"].prototype.addVirtualJoystick = function () {
    this.add(new FreeCameraVirtualJoystickInput());
    return this;
};
/**
 * Manage the Virtual Joystick inputs to control the movement of a free camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraVirtualJoystickInput = /** @class */ (function () {
    function FreeCameraVirtualJoystickInput() {
    }
    /**
     * Gets the left stick of the virtual joystick.
     * @returns The virtual Joystick
     */
    FreeCameraVirtualJoystickInput.prototype.getLeftJoystick = function () {
        return this._leftjoystick;
    };
    /**
     * Gets the right stick of the virtual joystick.
     * @returns The virtual Joystick
     */
    FreeCameraVirtualJoystickInput.prototype.getRightJoystick = function () {
        return this._rightjoystick;
    };
    /**
     * Update the current camera state depending on the inputs that have been used this frame.
     * This is a dynamically created lambda to avoid the performance penalty of looping for inputs in the render loop.
     */
    FreeCameraVirtualJoystickInput.prototype.checkInputs = function () {
        if (this._leftjoystick) {
            var camera = this.camera;
            var speed = camera._computeLocalCameraSpeed() * 50;
            var cameraTransform = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].RotationYawPitchRoll(camera.rotation.y, camera.rotation.x, 0);
            var deltaTransform = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinates(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](this._leftjoystick.deltaPosition.x * speed, this._leftjoystick.deltaPosition.y * speed, this._leftjoystick.deltaPosition.z * speed), cameraTransform);
            camera.cameraDirection = camera.cameraDirection.add(deltaTransform);
            camera.cameraRotation = camera.cameraRotation.addVector3(this._rightjoystick.deltaPosition);
            if (!this._leftjoystick.pressed) {
                this._leftjoystick.deltaPosition = this._leftjoystick.deltaPosition.scale(0.9);
            }
            if (!this._rightjoystick.pressed) {
                this._rightjoystick.deltaPosition = this._rightjoystick.deltaPosition.scale(0.9);
            }
        }
    };
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCameraVirtualJoystickInput.prototype.attachControl = function (element, noPreventDefault) {
        this._leftjoystick = new _Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__["VirtualJoystick"](true);
        this._leftjoystick.setAxisForUpDown(_Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__["JoystickAxis"].Z);
        this._leftjoystick.setAxisForLeftRight(_Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__["JoystickAxis"].X);
        this._leftjoystick.setJoystickSensibility(0.15);
        this._rightjoystick = new _Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__["VirtualJoystick"](false);
        this._rightjoystick.setAxisForUpDown(_Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__["JoystickAxis"].X);
        this._rightjoystick.setAxisForLeftRight(_Misc_virtualJoystick__WEBPACK_IMPORTED_MODULE_0__["JoystickAxis"].Y);
        this._rightjoystick.reverseUpDown = true;
        this._rightjoystick.setJoystickSensibility(0.05);
        this._rightjoystick.setJoystickColor("yellow");
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCameraVirtualJoystickInput.prototype.detachControl = function (element) {
        this._leftjoystick.releaseCanvas();
        this._rightjoystick.releaseCanvas();
    };
    /**
     * Gets the class name of the current intput.
     * @returns the class name
     */
    FreeCameraVirtualJoystickInput.prototype.getClassName = function () {
        return "FreeCameraVirtualJoystickInput";
    };
    /**
     * Get the friendly name associated with the input class.
     * @returns the input friendly name
     */
    FreeCameraVirtualJoystickInput.prototype.getSimpleName = function () {
        return "virtualJoystick";
    };
    return FreeCameraVirtualJoystickInput;
}());

_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputTypes"]["FreeCameraVirtualJoystickInput"] = FreeCameraVirtualJoystickInput;


/***/ }),

/***/ "./Cameras/Inputs/index.ts":
/*!*********************************!*\
  !*** ./Cameras/Inputs/index.ts ***!
  \*********************************/
/*! exports provided: ArcRotateCameraGamepadInput, ArcRotateCameraKeyboardMoveInput, ArcRotateCameraMouseWheelInput, ArcRotateCameraPointersInput, ArcRotateCameraVRDeviceOrientationInput, FlyCameraKeyboardInput, FlyCameraMouseInput, FollowCameraKeyboardMoveInput, FollowCameraMouseWheelInput, FollowCameraPointersInput, FreeCameraDeviceOrientationInput, FreeCameraGamepadInput, FreeCameraKeyboardMoveInput, FreeCameraMouseInput, FreeCameraTouchInput, FreeCameraVirtualJoystickInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _arcRotateCameraGamepadInput__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./arcRotateCameraGamepadInput */ "./Cameras/Inputs/arcRotateCameraGamepadInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraGamepadInput", function() { return _arcRotateCameraGamepadInput__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraGamepadInput"]; });

/* harmony import */ var _arcRotateCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./arcRotateCameraKeyboardMoveInput */ "./Cameras/Inputs/arcRotateCameraKeyboardMoveInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraKeyboardMoveInput", function() { return _arcRotateCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_1__["ArcRotateCameraKeyboardMoveInput"]; });

/* harmony import */ var _arcRotateCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./arcRotateCameraMouseWheelInput */ "./Cameras/Inputs/arcRotateCameraMouseWheelInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraMouseWheelInput", function() { return _arcRotateCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_2__["ArcRotateCameraMouseWheelInput"]; });

/* harmony import */ var _arcRotateCameraPointersInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./arcRotateCameraPointersInput */ "./Cameras/Inputs/arcRotateCameraPointersInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraPointersInput", function() { return _arcRotateCameraPointersInput__WEBPACK_IMPORTED_MODULE_3__["ArcRotateCameraPointersInput"]; });

/* harmony import */ var _arcRotateCameraVRDeviceOrientationInput__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./arcRotateCameraVRDeviceOrientationInput */ "./Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraVRDeviceOrientationInput", function() { return _arcRotateCameraVRDeviceOrientationInput__WEBPACK_IMPORTED_MODULE_4__["ArcRotateCameraVRDeviceOrientationInput"]; });

/* harmony import */ var _flyCameraKeyboardInput__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./flyCameraKeyboardInput */ "./Cameras/Inputs/flyCameraKeyboardInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraKeyboardInput", function() { return _flyCameraKeyboardInput__WEBPACK_IMPORTED_MODULE_5__["FlyCameraKeyboardInput"]; });

/* harmony import */ var _flyCameraMouseInput__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./flyCameraMouseInput */ "./Cameras/Inputs/flyCameraMouseInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraMouseInput", function() { return _flyCameraMouseInput__WEBPACK_IMPORTED_MODULE_6__["FlyCameraMouseInput"]; });

/* harmony import */ var _followCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./followCameraKeyboardMoveInput */ "./Cameras/Inputs/followCameraKeyboardMoveInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraKeyboardMoveInput", function() { return _followCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_7__["FollowCameraKeyboardMoveInput"]; });

/* harmony import */ var _followCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./followCameraMouseWheelInput */ "./Cameras/Inputs/followCameraMouseWheelInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraMouseWheelInput", function() { return _followCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_8__["FollowCameraMouseWheelInput"]; });

/* harmony import */ var _followCameraPointersInput__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./followCameraPointersInput */ "./Cameras/Inputs/followCameraPointersInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraPointersInput", function() { return _followCameraPointersInput__WEBPACK_IMPORTED_MODULE_9__["FollowCameraPointersInput"]; });

/* harmony import */ var _freeCameraDeviceOrientationInput__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./freeCameraDeviceOrientationInput */ "./Cameras/Inputs/freeCameraDeviceOrientationInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraDeviceOrientationInput", function() { return _freeCameraDeviceOrientationInput__WEBPACK_IMPORTED_MODULE_10__["FreeCameraDeviceOrientationInput"]; });

/* harmony import */ var _freeCameraGamepadInput__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./freeCameraGamepadInput */ "./Cameras/Inputs/freeCameraGamepadInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraGamepadInput", function() { return _freeCameraGamepadInput__WEBPACK_IMPORTED_MODULE_11__["FreeCameraGamepadInput"]; });

/* harmony import */ var _freeCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./freeCameraKeyboardMoveInput */ "./Cameras/Inputs/freeCameraKeyboardMoveInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraKeyboardMoveInput", function() { return _freeCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_12__["FreeCameraKeyboardMoveInput"]; });

/* harmony import */ var _freeCameraMouseInput__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./freeCameraMouseInput */ "./Cameras/Inputs/freeCameraMouseInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraMouseInput", function() { return _freeCameraMouseInput__WEBPACK_IMPORTED_MODULE_13__["FreeCameraMouseInput"]; });

/* harmony import */ var _freeCameraTouchInput__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./freeCameraTouchInput */ "./Cameras/Inputs/freeCameraTouchInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraTouchInput", function() { return _freeCameraTouchInput__WEBPACK_IMPORTED_MODULE_14__["FreeCameraTouchInput"]; });

/* harmony import */ var _freeCameraVirtualJoystickInput__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./freeCameraVirtualJoystickInput */ "./Cameras/Inputs/freeCameraVirtualJoystickInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraVirtualJoystickInput", function() { return _freeCameraVirtualJoystickInput__WEBPACK_IMPORTED_MODULE_15__["FreeCameraVirtualJoystickInput"]; });



















/***/ }),

/***/ "./Cameras/RigModes/stereoscopicAnaglyphRigMode.ts":
/*!*********************************************************!*\
  !*** ./Cameras/RigModes/stereoscopicAnaglyphRigMode.ts ***!
  \*********************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../camera */ "./Cameras/camera.ts");
/* harmony import */ var _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../PostProcesses/passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony import */ var _PostProcesses_anaglyphPostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../PostProcesses/anaglyphPostProcess */ "./PostProcesses/anaglyphPostProcess.ts");



_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"]._setStereoscopicAnaglyphRigMode = function (camera) {
    camera._rigCameras[0]._rigPostProcess = new _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_1__["PassPostProcess"](camera.name + "_passthru", 1.0, camera._rigCameras[0]);
    camera._rigCameras[1]._rigPostProcess = new _PostProcesses_anaglyphPostProcess__WEBPACK_IMPORTED_MODULE_2__["AnaglyphPostProcess"](camera.name + "_anaglyph", 1.0, camera._rigCameras);
};


/***/ }),

/***/ "./Cameras/RigModes/stereoscopicRigMode.ts":
/*!*************************************************!*\
  !*** ./Cameras/RigModes/stereoscopicRigMode.ts ***!
  \*************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../camera */ "./Cameras/camera.ts");
/* harmony import */ var _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../PostProcesses/passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony import */ var _PostProcesses_stereoscopicInterlacePostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../PostProcesses/stereoscopicInterlacePostProcess */ "./PostProcesses/stereoscopicInterlacePostProcess.ts");



_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"]._setStereoscopicRigMode = function (camera) {
    var isStereoscopicHoriz = camera.cameraRigMode === _camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL || camera.cameraRigMode === _camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED;
    camera._rigCameras[0]._rigPostProcess = new _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_1__["PassPostProcess"](camera.name + "_passthru", 1.0, camera._rigCameras[0]);
    camera._rigCameras[1]._rigPostProcess = new _PostProcesses_stereoscopicInterlacePostProcess__WEBPACK_IMPORTED_MODULE_2__["StereoscopicInterlacePostProcess"](camera.name + "_stereoInterlace", camera._rigCameras, isStereoscopicHoriz);
};


/***/ }),

/***/ "./Cameras/RigModes/vrRigMode.ts":
/*!***************************************!*\
  !*** ./Cameras/RigModes/vrRigMode.ts ***!
  \***************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../camera */ "./Cameras/camera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _PostProcesses_vrDistortionCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../PostProcesses/vrDistortionCorrectionPostProcess */ "./PostProcesses/vrDistortionCorrectionPostProcess.ts");
/* harmony import */ var _PostProcesses_vrMultiviewToSingleviewPostProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../PostProcesses/vrMultiviewToSingleviewPostProcess */ "./PostProcesses/vrMultiviewToSingleviewPostProcess.ts");
/* harmony import */ var _VR_vrCameraMetrics__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../VR/vrCameraMetrics */ "./Cameras/VR/vrCameraMetrics.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Maths/math.viewport */ "./Maths/math.viewport.ts");







_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"]._setVRRigMode = function (camera, rigParams) {
    var metrics = rigParams.vrCameraMetrics || _VR_vrCameraMetrics__WEBPACK_IMPORTED_MODULE_4__["VRCameraMetrics"].GetDefault();
    camera._rigCameras[0]._cameraRigParams.vrMetrics = metrics;
    camera._rigCameras[0].viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_6__["Viewport"](0, 0, 0.5, 1.0);
    camera._rigCameras[0]._cameraRigParams.vrWorkMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
    camera._rigCameras[0]._cameraRigParams.vrHMatrix = metrics.leftHMatrix;
    camera._rigCameras[0]._cameraRigParams.vrPreViewMatrix = metrics.leftPreViewMatrix;
    camera._rigCameras[0].getProjectionMatrix = camera._rigCameras[0]._getVRProjectionMatrix;
    camera._rigCameras[1]._cameraRigParams.vrMetrics = metrics;
    camera._rigCameras[1].viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_6__["Viewport"](0.5, 0, 0.5, 1.0);
    camera._rigCameras[1]._cameraRigParams.vrWorkMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
    camera._rigCameras[1]._cameraRigParams.vrHMatrix = metrics.rightHMatrix;
    camera._rigCameras[1]._cameraRigParams.vrPreViewMatrix = metrics.rightPreViewMatrix;
    camera._rigCameras[1].getProjectionMatrix = camera._rigCameras[1]._getVRProjectionMatrix;
    // For multiview on a webVR camera
    // First multiview will be rendered to camera._multiviewTexture
    // Then this postprocess will run on each eye to copy the right texture to each eye
    if (metrics.multiviewEnabled) {
        if (!camera.getScene().getEngine().getCaps().multiview) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_5__["Logger"].Warn("Multiview is not supported, falling back to standard rendering");
            metrics.multiviewEnabled = false;
        }
        else {
            camera._useMultiviewToSingleView = true;
            camera._rigPostProcess = new _PostProcesses_vrMultiviewToSingleviewPostProcess__WEBPACK_IMPORTED_MODULE_3__["VRMultiviewToSingleviewPostProcess"]("VRMultiviewToSingleview", camera, metrics.postProcessScaleFactor);
        }
    }
    if (metrics.compensateDistortion) {
        camera._rigCameras[0]._rigPostProcess = new _PostProcesses_vrDistortionCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_2__["VRDistortionCorrectionPostProcess"]("VR_Distort_Compensation_Left", camera._rigCameras[0], false, metrics);
        camera._rigCameras[1]._rigPostProcess = new _PostProcesses_vrDistortionCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_2__["VRDistortionCorrectionPostProcess"]("VR_Distort_Compensation_Right", camera._rigCameras[1], true, metrics);
    }
};


/***/ }),

/***/ "./Cameras/RigModes/webVRRigMode.ts":
/*!******************************************!*\
  !*** ./Cameras/RigModes/webVRRigMode.ts ***!
  \******************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../camera */ "./Cameras/camera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.viewport */ "./Maths/math.viewport.ts");



_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"]._setWebVRRigMode = function (camera, rigParams) {
    if (rigParams.vrDisplay) {
        var leftEye = rigParams.vrDisplay.getEyeParameters('left');
        var rightEye = rigParams.vrDisplay.getEyeParameters('right');
        //Left eye
        camera._rigCameras[0].viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_2__["Viewport"](0, 0, 0.5, 1.0);
        camera._rigCameras[0].setCameraRigParameter("left", true);
        //leaving this for future reference
        camera._rigCameras[0].setCameraRigParameter("specs", rigParams.specs);
        camera._rigCameras[0].setCameraRigParameter("eyeParameters", leftEye);
        camera._rigCameras[0].setCameraRigParameter("frameData", rigParams.frameData);
        camera._rigCameras[0].setCameraRigParameter("parentCamera", rigParams.parentCamera);
        camera._rigCameras[0]._cameraRigParams.vrWorkMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
        camera._rigCameras[0].getProjectionMatrix = camera._getWebVRProjectionMatrix;
        camera._rigCameras[0].parent = camera;
        camera._rigCameras[0]._getViewMatrix = camera._getWebVRViewMatrix;
        //Right eye
        camera._rigCameras[1].viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_2__["Viewport"](0.5, 0, 0.5, 1.0);
        camera._rigCameras[1].setCameraRigParameter('eyeParameters', rightEye);
        camera._rigCameras[1].setCameraRigParameter("specs", rigParams.specs);
        camera._rigCameras[1].setCameraRigParameter("frameData", rigParams.frameData);
        camera._rigCameras[1].setCameraRigParameter("parentCamera", rigParams.parentCamera);
        camera._rigCameras[1]._cameraRigParams.vrWorkMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
        camera._rigCameras[1].getProjectionMatrix = camera._getWebVRProjectionMatrix;
        camera._rigCameras[1].parent = camera;
        camera._rigCameras[1]._getViewMatrix = camera._getWebVRViewMatrix;
    }
};


/***/ }),

/***/ "./Cameras/Stereoscopic/anaglyphArcRotateCamera.ts":
/*!*********************************************************!*\
  !*** ./Cameras/Stereoscopic/anaglyphArcRotateCamera.ts ***!
  \*********************************************************/
/*! exports provided: AnaglyphArcRotateCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnaglyphArcRotateCamera", function() { return AnaglyphArcRotateCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/arcRotateCamera */ "./Cameras/arcRotateCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicAnaglyphRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicAnaglyphRigMode */ "./Cameras/RigModes/stereoscopicAnaglyphRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("AnaglyphArcRotateCamera", function (name, scene, options) {
    return function () { return new AnaglyphArcRotateCamera(name, 0, 0, 1.0, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, scene); };
});
/**
 * Camera used to simulate anaglyphic rendering (based on ArcRotateCamera)
 * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
 */
var AnaglyphArcRotateCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnaglyphArcRotateCamera, _super);
    /**
     * Creates a new AnaglyphArcRotateCamera
     * @param name defines camera name
     * @param alpha defines alpha angle (in radians)
     * @param beta defines beta angle (in radians)
     * @param radius defines radius
     * @param target defines camera target
     * @param interaxialDistance defines distance between each color axis
     * @param scene defines the hosting scene
     */
    function AnaglyphArcRotateCamera(name, alpha, beta, radius, target, interaxialDistance, scene) {
        var _this = _super.call(this, name, alpha, beta, radius, target, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns AnaglyphArcRotateCamera
     */
    AnaglyphArcRotateCamera.prototype.getClassName = function () {
        return "AnaglyphArcRotateCamera";
    };
    return AnaglyphArcRotateCamera;
}(_Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__["ArcRotateCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/anaglyphFreeCamera.ts":
/*!****************************************************!*\
  !*** ./Cameras/Stereoscopic/anaglyphFreeCamera.ts ***!
  \****************************************************/
/*! exports provided: AnaglyphFreeCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnaglyphFreeCamera", function() { return AnaglyphFreeCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicAnaglyphRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicAnaglyphRigMode */ "./Cameras/RigModes/stereoscopicAnaglyphRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("AnaglyphFreeCamera", function (name, scene, options) {
    return function () { return new AnaglyphFreeCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, scene); };
});
/**
 * Camera used to simulate anaglyphic rendering (based on FreeCamera)
 * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
 */
var AnaglyphFreeCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnaglyphFreeCamera, _super);
    /**
     * Creates a new AnaglyphFreeCamera
     * @param name defines camera name
     * @param position defines initial position
     * @param interaxialDistance defines distance between each color axis
     * @param scene defines the hosting scene
     */
    function AnaglyphFreeCamera(name, position, interaxialDistance, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns AnaglyphFreeCamera
     */
    AnaglyphFreeCamera.prototype.getClassName = function () {
        return "AnaglyphFreeCamera";
    };
    return AnaglyphFreeCamera;
}(_Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_2__["FreeCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/anaglyphGamepadCamera.ts":
/*!*******************************************************!*\
  !*** ./Cameras/Stereoscopic/anaglyphGamepadCamera.ts ***!
  \*******************************************************/
/*! exports provided: AnaglyphGamepadCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnaglyphGamepadCamera", function() { return AnaglyphGamepadCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_gamepadCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/gamepadCamera */ "./Cameras/gamepadCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicAnaglyphRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicAnaglyphRigMode */ "./Cameras/RigModes/stereoscopicAnaglyphRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("AnaglyphGamepadCamera", function (name, scene, options) {
    return function () { return new AnaglyphGamepadCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, scene); };
});
/**
 * Camera used to simulate anaglyphic rendering (based on GamepadCamera)
 * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
 */
var AnaglyphGamepadCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnaglyphGamepadCamera, _super);
    /**
     * Creates a new AnaglyphGamepadCamera
     * @param name defines camera name
     * @param position defines initial position
     * @param interaxialDistance defines distance between each color axis
     * @param scene defines the hosting scene
     */
    function AnaglyphGamepadCamera(name, position, interaxialDistance, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns AnaglyphGamepadCamera
     */
    AnaglyphGamepadCamera.prototype.getClassName = function () {
        return "AnaglyphGamepadCamera";
    };
    return AnaglyphGamepadCamera;
}(_Cameras_gamepadCamera__WEBPACK_IMPORTED_MODULE_2__["GamepadCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/anaglyphUniversalCamera.ts":
/*!*********************************************************!*\
  !*** ./Cameras/Stereoscopic/anaglyphUniversalCamera.ts ***!
  \*********************************************************/
/*! exports provided: AnaglyphUniversalCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnaglyphUniversalCamera", function() { return AnaglyphUniversalCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_universalCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/universalCamera */ "./Cameras/universalCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicAnaglyphRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicAnaglyphRigMode */ "./Cameras/RigModes/stereoscopicAnaglyphRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("AnaglyphUniversalCamera", function (name, scene, options) {
    return function () { return new AnaglyphUniversalCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, scene); };
});
/**
 * Camera used to simulate anaglyphic rendering (based on UniversalCamera)
 * @see http://doc.babylonjs.com/features/cameras#anaglyph-cameras
 */
var AnaglyphUniversalCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnaglyphUniversalCamera, _super);
    /**
     * Creates a new AnaglyphUniversalCamera
     * @param name defines camera name
     * @param position defines initial position
     * @param interaxialDistance defines distance between each color axis
     * @param scene defines the hosting scene
     */
    function AnaglyphUniversalCamera(name, position, interaxialDistance, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns AnaglyphUniversalCamera
     */
    AnaglyphUniversalCamera.prototype.getClassName = function () {
        return "AnaglyphUniversalCamera";
    };
    return AnaglyphUniversalCamera;
}(_Cameras_universalCamera__WEBPACK_IMPORTED_MODULE_2__["UniversalCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/index.ts":
/*!***************************************!*\
  !*** ./Cameras/Stereoscopic/index.ts ***!
  \***************************************/
/*! exports provided: AnaglyphArcRotateCamera, AnaglyphFreeCamera, AnaglyphGamepadCamera, AnaglyphUniversalCamera, StereoscopicArcRotateCamera, StereoscopicFreeCamera, StereoscopicGamepadCamera, StereoscopicUniversalCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _anaglyphArcRotateCamera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./anaglyphArcRotateCamera */ "./Cameras/Stereoscopic/anaglyphArcRotateCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphArcRotateCamera", function() { return _anaglyphArcRotateCamera__WEBPACK_IMPORTED_MODULE_0__["AnaglyphArcRotateCamera"]; });

/* harmony import */ var _anaglyphFreeCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./anaglyphFreeCamera */ "./Cameras/Stereoscopic/anaglyphFreeCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphFreeCamera", function() { return _anaglyphFreeCamera__WEBPACK_IMPORTED_MODULE_1__["AnaglyphFreeCamera"]; });

/* harmony import */ var _anaglyphGamepadCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./anaglyphGamepadCamera */ "./Cameras/Stereoscopic/anaglyphGamepadCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphGamepadCamera", function() { return _anaglyphGamepadCamera__WEBPACK_IMPORTED_MODULE_2__["AnaglyphGamepadCamera"]; });

/* harmony import */ var _anaglyphUniversalCamera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./anaglyphUniversalCamera */ "./Cameras/Stereoscopic/anaglyphUniversalCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphUniversalCamera", function() { return _anaglyphUniversalCamera__WEBPACK_IMPORTED_MODULE_3__["AnaglyphUniversalCamera"]; });

/* harmony import */ var _stereoscopicArcRotateCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./stereoscopicArcRotateCamera */ "./Cameras/Stereoscopic/stereoscopicArcRotateCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicArcRotateCamera", function() { return _stereoscopicArcRotateCamera__WEBPACK_IMPORTED_MODULE_4__["StereoscopicArcRotateCamera"]; });

/* harmony import */ var _stereoscopicFreeCamera__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./stereoscopicFreeCamera */ "./Cameras/Stereoscopic/stereoscopicFreeCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicFreeCamera", function() { return _stereoscopicFreeCamera__WEBPACK_IMPORTED_MODULE_5__["StereoscopicFreeCamera"]; });

/* harmony import */ var _stereoscopicGamepadCamera__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./stereoscopicGamepadCamera */ "./Cameras/Stereoscopic/stereoscopicGamepadCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicGamepadCamera", function() { return _stereoscopicGamepadCamera__WEBPACK_IMPORTED_MODULE_6__["StereoscopicGamepadCamera"]; });

/* harmony import */ var _stereoscopicUniversalCamera__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./stereoscopicUniversalCamera */ "./Cameras/Stereoscopic/stereoscopicUniversalCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicUniversalCamera", function() { return _stereoscopicUniversalCamera__WEBPACK_IMPORTED_MODULE_7__["StereoscopicUniversalCamera"]; });











/***/ }),

/***/ "./Cameras/Stereoscopic/stereoscopicArcRotateCamera.ts":
/*!*************************************************************!*\
  !*** ./Cameras/Stereoscopic/stereoscopicArcRotateCamera.ts ***!
  \*************************************************************/
/*! exports provided: StereoscopicArcRotateCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StereoscopicArcRotateCamera", function() { return StereoscopicArcRotateCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/arcRotateCamera */ "./Cameras/arcRotateCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicRigMode */ "./Cameras/RigModes/stereoscopicRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("StereoscopicArcRotateCamera", function (name, scene, options) {
    return function () { return new StereoscopicArcRotateCamera(name, 0, 0, 1.0, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene); };
});
/**
 * Camera used to simulate stereoscopic rendering (based on ArcRotateCamera)
 * @see http://doc.babylonjs.com/features/cameras
 */
var StereoscopicArcRotateCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StereoscopicArcRotateCamera, _super);
    /**
     * Creates a new StereoscopicArcRotateCamera
     * @param name defines camera name
     * @param alpha defines alpha angle (in radians)
     * @param beta defines beta angle (in radians)
     * @param radius defines radius
     * @param target defines camera target
     * @param interaxialDistance defines distance between each color axis
     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under
     * @param scene defines the hosting scene
     */
    function StereoscopicArcRotateCamera(name, alpha, beta, radius, target, interaxialDistance, isStereoscopicSideBySide, scene) {
        var _this = _super.call(this, name, alpha, beta, radius, target, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.isStereoscopicSideBySide = isStereoscopicSideBySide;
        _this.setCameraRigMode(isStereoscopicSideBySide ? _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns StereoscopicArcRotateCamera
     */
    StereoscopicArcRotateCamera.prototype.getClassName = function () {
        return "StereoscopicArcRotateCamera";
    };
    return StereoscopicArcRotateCamera;
}(_Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__["ArcRotateCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/stereoscopicFreeCamera.ts":
/*!********************************************************!*\
  !*** ./Cameras/Stereoscopic/stereoscopicFreeCamera.ts ***!
  \********************************************************/
/*! exports provided: StereoscopicFreeCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StereoscopicFreeCamera", function() { return StereoscopicFreeCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicRigMode */ "./Cameras/RigModes/stereoscopicRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("StereoscopicFreeCamera", function (name, scene, options) {
    return function () { return new StereoscopicFreeCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene); };
});
/**
 * Camera used to simulate stereoscopic rendering (based on FreeCamera)
 * @see http://doc.babylonjs.com/features/cameras
 */
var StereoscopicFreeCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StereoscopicFreeCamera, _super);
    /**
     * Creates a new StereoscopicFreeCamera
     * @param name defines camera name
     * @param position defines initial position
     * @param interaxialDistance defines distance between each color axis
     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under
     * @param scene defines the hosting scene
     */
    function StereoscopicFreeCamera(name, position, interaxialDistance, isStereoscopicSideBySide, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.isStereoscopicSideBySide = isStereoscopicSideBySide;
        _this.setCameraRigMode(isStereoscopicSideBySide ? _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns StereoscopicFreeCamera
     */
    StereoscopicFreeCamera.prototype.getClassName = function () {
        return "StereoscopicFreeCamera";
    };
    return StereoscopicFreeCamera;
}(_Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_2__["FreeCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/stereoscopicGamepadCamera.ts":
/*!***********************************************************!*\
  !*** ./Cameras/Stereoscopic/stereoscopicGamepadCamera.ts ***!
  \***********************************************************/
/*! exports provided: StereoscopicGamepadCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StereoscopicGamepadCamera", function() { return StereoscopicGamepadCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_gamepadCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/gamepadCamera */ "./Cameras/gamepadCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicRigMode */ "./Cameras/RigModes/stereoscopicRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("StereoscopicGamepadCamera", function (name, scene, options) {
    return function () { return new StereoscopicGamepadCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene); };
});
/**
 * Camera used to simulate stereoscopic rendering (based on GamepadCamera)
 * @see http://doc.babylonjs.com/features/cameras
 */
var StereoscopicGamepadCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StereoscopicGamepadCamera, _super);
    /**
     * Creates a new StereoscopicGamepadCamera
     * @param name defines camera name
     * @param position defines initial position
     * @param interaxialDistance defines distance between each color axis
     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under
     * @param scene defines the hosting scene
     */
    function StereoscopicGamepadCamera(name, position, interaxialDistance, isStereoscopicSideBySide, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.isStereoscopicSideBySide = isStereoscopicSideBySide;
        _this.setCameraRigMode(isStereoscopicSideBySide ? _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns StereoscopicGamepadCamera
     */
    StereoscopicGamepadCamera.prototype.getClassName = function () {
        return "StereoscopicGamepadCamera";
    };
    return StereoscopicGamepadCamera;
}(_Cameras_gamepadCamera__WEBPACK_IMPORTED_MODULE_2__["GamepadCamera"]));



/***/ }),

/***/ "./Cameras/Stereoscopic/stereoscopicUniversalCamera.ts":
/*!*************************************************************!*\
  !*** ./Cameras/Stereoscopic/stereoscopicUniversalCamera.ts ***!
  \*************************************************************/
/*! exports provided: StereoscopicUniversalCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StereoscopicUniversalCamera", function() { return StereoscopicUniversalCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_universalCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/universalCamera */ "./Cameras/universalCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_stereoscopicRigMode__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../RigModes/stereoscopicRigMode */ "./Cameras/RigModes/stereoscopicRigMode.ts");





// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("StereoscopicFreeCamera", function (name, scene, options) {
    return function () { return new StereoscopicUniversalCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), options.interaxial_distance, options.isStereoscopicSideBySide, scene); };
});
/**
 * Camera used to simulate stereoscopic rendering (based on UniversalCamera)
 * @see http://doc.babylonjs.com/features/cameras
 */
var StereoscopicUniversalCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StereoscopicUniversalCamera, _super);
    /**
     * Creates a new StereoscopicUniversalCamera
     * @param name defines camera name
     * @param position defines initial position
     * @param interaxialDistance defines distance between each color axis
     * @param isStereoscopicSideBySide defines is stereoscopic is done side by side or over under
     * @param scene defines the hosting scene
     */
    function StereoscopicUniversalCamera(name, position, interaxialDistance, isStereoscopicSideBySide, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.interaxialDistance = interaxialDistance;
        _this.isStereoscopicSideBySide = isStereoscopicSideBySide;
        _this.setCameraRigMode(isStereoscopicSideBySide ? _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL : _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER, { interaxialDistance: interaxialDistance });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns StereoscopicUniversalCamera
     */
    StereoscopicUniversalCamera.prototype.getClassName = function () {
        return "StereoscopicUniversalCamera";
    };
    return StereoscopicUniversalCamera;
}(_Cameras_universalCamera__WEBPACK_IMPORTED_MODULE_2__["UniversalCamera"]));



/***/ }),

/***/ "./Cameras/VR/index.ts":
/*!*****************************!*\
  !*** ./Cameras/VR/index.ts ***!
  \*****************************/
/*! exports provided: VRCameraMetrics, VRDeviceOrientationArcRotateCamera, VRDeviceOrientationFreeCamera, VRDeviceOrientationGamepadCamera, OnAfterEnteringVRObservableEvent, VRExperienceHelper, WebVRFreeCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vrCameraMetrics */ "./Cameras/VR/vrCameraMetrics.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRCameraMetrics", function() { return _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_0__["VRCameraMetrics"]; });

/* harmony import */ var _vrDeviceOrientationArcRotateCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vrDeviceOrientationArcRotateCamera */ "./Cameras/VR/vrDeviceOrientationArcRotateCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationArcRotateCamera", function() { return _vrDeviceOrientationArcRotateCamera__WEBPACK_IMPORTED_MODULE_1__["VRDeviceOrientationArcRotateCamera"]; });

/* harmony import */ var _vrDeviceOrientationFreeCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./vrDeviceOrientationFreeCamera */ "./Cameras/VR/vrDeviceOrientationFreeCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationFreeCamera", function() { return _vrDeviceOrientationFreeCamera__WEBPACK_IMPORTED_MODULE_2__["VRDeviceOrientationFreeCamera"]; });

/* harmony import */ var _vrDeviceOrientationGamepadCamera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./vrDeviceOrientationGamepadCamera */ "./Cameras/VR/vrDeviceOrientationGamepadCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationGamepadCamera", function() { return _vrDeviceOrientationGamepadCamera__WEBPACK_IMPORTED_MODULE_3__["VRDeviceOrientationGamepadCamera"]; });

/* harmony import */ var _vrExperienceHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./vrExperienceHelper */ "./Cameras/VR/vrExperienceHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OnAfterEnteringVRObservableEvent", function() { return _vrExperienceHelper__WEBPACK_IMPORTED_MODULE_4__["OnAfterEnteringVRObservableEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRExperienceHelper", function() { return _vrExperienceHelper__WEBPACK_IMPORTED_MODULE_4__["VRExperienceHelper"]; });

/* harmony import */ var _webVRCamera__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./webVRCamera */ "./Cameras/VR/webVRCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRFreeCamera", function() { return _webVRCamera__WEBPACK_IMPORTED_MODULE_5__["WebVRFreeCamera"]; });









/***/ }),

/***/ "./Cameras/VR/vrCameraMetrics.ts":
/*!***************************************!*\
  !*** ./Cameras/VR/vrCameraMetrics.ts ***!
  \***************************************/
/*! exports provided: VRCameraMetrics */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRCameraMetrics", function() { return VRCameraMetrics; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");

/**
 * This represents all the required metrics to create a VR camera.
 * @see http://doc.babylonjs.com/babylon101/cameras#device-orientation-camera
 */
var VRCameraMetrics = /** @class */ (function () {
    function VRCameraMetrics() {
        /**
         * Define if the current vr camera should compensate the distortion of the lense or not.
         */
        this.compensateDistortion = true;
        /**
         * Defines if multiview should be enabled when rendering (Default: false)
         */
        this.multiviewEnabled = false;
    }
    Object.defineProperty(VRCameraMetrics.prototype, "aspectRatio", {
        /**
         * Gets the rendering aspect ratio based on the provided resolutions.
         */
        get: function () {
            return this.hResolution / (2 * this.vResolution);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRCameraMetrics.prototype, "aspectRatioFov", {
        /**
         * Gets the aspect ratio based on the FOV, scale factors, and real screen sizes.
         */
        get: function () {
            return (2 * Math.atan((this.postProcessScaleFactor * this.vScreenSize) / (2 * this.eyeToScreenDistance)));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRCameraMetrics.prototype, "leftHMatrix", {
        /**
         * @hidden
         */
        get: function () {
            var meters = (this.hScreenSize / 4) - (this.lensSeparationDistance / 2);
            var h = (4 * meters) / this.hScreenSize;
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Translation(h, 0, 0);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRCameraMetrics.prototype, "rightHMatrix", {
        /**
         * @hidden
         */
        get: function () {
            var meters = (this.hScreenSize / 4) - (this.lensSeparationDistance / 2);
            var h = (4 * meters) / this.hScreenSize;
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Translation(-h, 0, 0);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRCameraMetrics.prototype, "leftPreViewMatrix", {
        /**
         * @hidden
         */
        get: function () {
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Translation(0.5 * this.interpupillaryDistance, 0, 0);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRCameraMetrics.prototype, "rightPreViewMatrix", {
        /**
         * @hidden
         */
        get: function () {
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Translation(-0.5 * this.interpupillaryDistance, 0, 0);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the default VRMetrics based on the most generic setup.
     * @returns the default vr metrics
     */
    VRCameraMetrics.GetDefault = function () {
        var result = new VRCameraMetrics();
        result.hResolution = 1280;
        result.vResolution = 800;
        result.hScreenSize = 0.149759993;
        result.vScreenSize = 0.0935999975;
        result.vScreenCenter = 0.0467999987;
        result.eyeToScreenDistance = 0.0410000011;
        result.lensSeparationDistance = 0.0635000020;
        result.interpupillaryDistance = 0.0640000030;
        result.distortionK = [1.0, 0.219999999, 0.239999995, 0.0];
        result.chromaAbCorrection = [0.995999992, -0.00400000019, 1.01400006, 0.0];
        result.postProcessScaleFactor = 1.714605507808412;
        result.lensCenterOffset = 0.151976421;
        return result;
    };
    return VRCameraMetrics;
}());



/***/ }),

/***/ "./Cameras/VR/vrDeviceOrientationArcRotateCamera.ts":
/*!**********************************************************!*\
  !*** ./Cameras/VR/vrDeviceOrientationArcRotateCamera.ts ***!
  \**********************************************************/
/*! exports provided: VRDeviceOrientationArcRotateCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationArcRotateCamera", function() { return VRDeviceOrientationArcRotateCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/arcRotateCamera */ "./Cameras/arcRotateCamera.ts");
/* harmony import */ var _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./vrCameraMetrics */ "./Cameras/VR/vrCameraMetrics.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _Inputs_arcRotateCameraVRDeviceOrientationInput__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Inputs/arcRotateCameraVRDeviceOrientationInput */ "./Cameras/Inputs/arcRotateCameraVRDeviceOrientationInput.ts");
/* harmony import */ var _RigModes_vrRigMode__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../RigModes/vrRigMode */ "./Cameras/RigModes/vrRigMode.ts");







// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_5__["Node"].AddNodeConstructor("VRDeviceOrientationFreeCamera", function (name, scene) {
    return function () { return new VRDeviceOrientationArcRotateCamera(name, 0, 0, 1.0, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero(), scene); };
});
/**
 * Camera used to simulate VR rendering (based on ArcRotateCamera)
 * @see http://doc.babylonjs.com/babylon101/cameras#vr-device-orientation-cameras
 */
var VRDeviceOrientationArcRotateCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRDeviceOrientationArcRotateCamera, _super);
    /**
     * Creates a new VRDeviceOrientationArcRotateCamera
     * @param name defines camera name
     * @param alpha defines the camera rotation along the logitudinal axis
     * @param beta defines the camera rotation along the latitudinal axis
     * @param radius defines the camera distance from its target
     * @param target defines the camera target
     * @param scene defines the scene the camera belongs to
     * @param compensateDistortion defines if the camera needs to compensate the lens distorsion
     * @param vrCameraMetrics defines the vr metrics associated to the camera
     */
    function VRDeviceOrientationArcRotateCamera(name, alpha, beta, radius, target, scene, compensateDistortion, vrCameraMetrics) {
        if (compensateDistortion === void 0) { compensateDistortion = true; }
        if (vrCameraMetrics === void 0) { vrCameraMetrics = _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_3__["VRCameraMetrics"].GetDefault(); }
        var _this = _super.call(this, name, alpha, beta, radius, target, scene) || this;
        vrCameraMetrics.compensateDistortion = compensateDistortion;
        _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_VR, { vrCameraMetrics: vrCameraMetrics });
        _this.inputs.addVRDeviceOrientation();
        return _this;
    }
    /**
     * Gets camera class name
     * @returns VRDeviceOrientationArcRotateCamera
     */
    VRDeviceOrientationArcRotateCamera.prototype.getClassName = function () {
        return "VRDeviceOrientationArcRotateCamera";
    };
    return VRDeviceOrientationArcRotateCamera;
}(_Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__["ArcRotateCamera"]));



/***/ }),

/***/ "./Cameras/VR/vrDeviceOrientationFreeCamera.ts":
/*!*****************************************************!*\
  !*** ./Cameras/VR/vrDeviceOrientationFreeCamera.ts ***!
  \*****************************************************/
/*! exports provided: VRDeviceOrientationFreeCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationFreeCamera", function() { return VRDeviceOrientationFreeCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_deviceOrientationCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/deviceOrientationCamera */ "./Cameras/deviceOrientationCamera.ts");
/* harmony import */ var _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./vrCameraMetrics */ "./Cameras/VR/vrCameraMetrics.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _RigModes_vrRigMode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../RigModes/vrRigMode */ "./Cameras/RigModes/vrRigMode.ts");






// Side effect import to define the stereoscopic mode.

_node__WEBPACK_IMPORTED_MODULE_5__["Node"].AddNodeConstructor("VRDeviceOrientationFreeCamera", function (name, scene) {
    return function () { return new VRDeviceOrientationFreeCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero(), scene); };
});
/**
 * Camera used to simulate VR rendering (based on FreeCamera)
 * @see http://doc.babylonjs.com/babylon101/cameras#vr-device-orientation-cameras
 */
var VRDeviceOrientationFreeCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRDeviceOrientationFreeCamera, _super);
    /**
     * Creates a new VRDeviceOrientationFreeCamera
     * @param name defines camera name
     * @param position defines the start position of the camera
     * @param scene defines the scene the camera belongs to
     * @param compensateDistortion defines if the camera needs to compensate the lens distorsion
     * @param vrCameraMetrics defines the vr metrics associated to the camera
     */
    function VRDeviceOrientationFreeCamera(name, position, scene, compensateDistortion, vrCameraMetrics) {
        if (compensateDistortion === void 0) { compensateDistortion = true; }
        if (vrCameraMetrics === void 0) { vrCameraMetrics = _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_3__["VRCameraMetrics"].GetDefault(); }
        var _this = _super.call(this, name, position, scene) || this;
        vrCameraMetrics.compensateDistortion = compensateDistortion;
        _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].RIG_MODE_VR, { vrCameraMetrics: vrCameraMetrics });
        return _this;
    }
    /**
     * Gets camera class name
     * @returns VRDeviceOrientationFreeCamera
     */
    VRDeviceOrientationFreeCamera.prototype.getClassName = function () {
        return "VRDeviceOrientationFreeCamera";
    };
    return VRDeviceOrientationFreeCamera;
}(_Cameras_deviceOrientationCamera__WEBPACK_IMPORTED_MODULE_2__["DeviceOrientationCamera"]));



/***/ }),

/***/ "./Cameras/VR/vrDeviceOrientationGamepadCamera.ts":
/*!********************************************************!*\
  !*** ./Cameras/VR/vrDeviceOrientationGamepadCamera.ts ***!
  \********************************************************/
/*! exports provided: VRDeviceOrientationGamepadCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationGamepadCamera", function() { return VRDeviceOrientationGamepadCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _vrDeviceOrientationFreeCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vrDeviceOrientationFreeCamera */ "./Cameras/VR/vrDeviceOrientationFreeCamera.ts");
/* harmony import */ var _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./vrCameraMetrics */ "./Cameras/VR/vrCameraMetrics.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _Gamepads_gamepadSceneComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Gamepads/gamepadSceneComponent */ "./Gamepads/gamepadSceneComponent.ts");






_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("VRDeviceOrientationGamepadCamera", function (name, scene) {
    return function () { return new VRDeviceOrientationGamepadCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), scene); };
});
/**
 * Camera used to simulate VR rendering (based on VRDeviceOrientationFreeCamera)
 * @see http://doc.babylonjs.com/babylon101/cameras#vr-device-orientation-cameras
 */
var VRDeviceOrientationGamepadCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRDeviceOrientationGamepadCamera, _super);
    /**
     * Creates a new VRDeviceOrientationGamepadCamera
     * @param name defines camera name
     * @param position defines the start position of the camera
     * @param scene defines the scene the camera belongs to
     * @param compensateDistortion defines if the camera needs to compensate the lens distorsion
     * @param vrCameraMetrics defines the vr metrics associated to the camera
     */
    function VRDeviceOrientationGamepadCamera(name, position, scene, compensateDistortion, vrCameraMetrics) {
        if (compensateDistortion === void 0) { compensateDistortion = true; }
        if (vrCameraMetrics === void 0) { vrCameraMetrics = _vrCameraMetrics__WEBPACK_IMPORTED_MODULE_2__["VRCameraMetrics"].GetDefault(); }
        var _this = _super.call(this, name, position, scene, compensateDistortion, vrCameraMetrics) || this;
        _this.inputs.addGamepad();
        return _this;
    }
    /**
     * Gets camera class name
     * @returns VRDeviceOrientationGamepadCamera
     */
    VRDeviceOrientationGamepadCamera.prototype.getClassName = function () {
        return "VRDeviceOrientationGamepadCamera";
    };
    return VRDeviceOrientationGamepadCamera;
}(_vrDeviceOrientationFreeCamera__WEBPACK_IMPORTED_MODULE_1__["VRDeviceOrientationFreeCamera"]));



/***/ }),

/***/ "./Cameras/VR/vrExperienceHelper.ts":
/*!******************************************!*\
  !*** ./Cameras/VR/vrExperienceHelper.ts ***!
  \******************************************/
/*! exports provided: OnAfterEnteringVRObservableEvent, VRExperienceHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OnAfterEnteringVRObservableEvent", function() { return OnAfterEnteringVRObservableEvent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRExperienceHelper", function() { return VRExperienceHelper; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Cameras_targetCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Cameras/targetCamera */ "./Cameras/targetCamera.ts");
/* harmony import */ var _Cameras_deviceOrientationCamera__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Cameras/deviceOrientationCamera */ "./Cameras/deviceOrientationCamera.ts");
/* harmony import */ var _Cameras_VR_vrDeviceOrientationFreeCamera__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Cameras/VR/vrDeviceOrientationFreeCamera */ "./Cameras/VR/vrDeviceOrientationFreeCamera.ts");
/* harmony import */ var _Cameras_VR_webVRCamera__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Cameras/VR/webVRCamera */ "./Cameras/VR/webVRCamera.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../Gamepads/gamepad */ "./Gamepads/gamepad.ts");
/* harmony import */ var _Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../Gamepads/Controllers/poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");
/* harmony import */ var _Gamepads_Controllers_webVRController__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../Gamepads/Controllers/webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _Gamepads_xboxGamepad__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../Gamepads/xboxGamepad */ "./Gamepads/xboxGamepad.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../../Materials/Textures/dynamicTexture */ "./Materials/Textures/dynamicTexture.ts");
/* harmony import */ var _PostProcesses_imageProcessingPostProcess__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../../PostProcesses/imageProcessingPostProcess */ "./PostProcesses/imageProcessingPostProcess.ts");
/* harmony import */ var _Animations_easing__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../../Animations/easing */ "./Animations/easing.ts");
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../../Animations/animation */ "./Animations/animation.ts");
/* harmony import */ var _Cameras_VR_vrCameraMetrics__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../../Cameras/VR/vrCameraMetrics */ "./Cameras/VR/vrCameraMetrics.ts");
/* harmony import */ var _Meshes_Builders_groundBuilder__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../../Meshes/Builders/groundBuilder */ "./Meshes/Builders/groundBuilder.ts");
/* harmony import */ var _Meshes_Builders_torusBuilder__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../../Meshes/Builders/torusBuilder */ "./Meshes/Builders/torusBuilder.ts");
/* harmony import */ var _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../../Meshes/Builders/cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");
/* harmony import */ var _Gamepads_gamepadSceneComponent__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ../../Gamepads/gamepadSceneComponent */ "./Gamepads/gamepadSceneComponent.ts");
/* harmony import */ var _Animations_animatable__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ../../Animations/animatable */ "./Animations/animatable.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ../../Maths/math.axis */ "./Maths/math.axis.ts");






























var VRExperienceHelperGazer = /** @class */ (function () {
    function VRExperienceHelperGazer(scene, gazeTrackerToClone) {
        if (gazeTrackerToClone === void 0) { gazeTrackerToClone = null; }
        this.scene = scene;
        /** @hidden */
        this._pointerDownOnMeshAsked = false;
        /** @hidden */
        this._isActionableMesh = false;
        /** @hidden */
        this._teleportationRequestInitiated = false;
        /** @hidden */
        this._teleportationBackRequestInitiated = false;
        /** @hidden */
        this._rotationRightAsked = false;
        /** @hidden */
        this._rotationLeftAsked = false;
        /** @hidden */
        this._dpadPressed = true;
        /** @hidden */
        this._activePointer = false;
        this._id = VRExperienceHelperGazer._idCounter++;
        // Gaze tracker
        if (!gazeTrackerToClone) {
            this._gazeTracker = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__["Mesh"].CreateTorus("gazeTracker", 0.0035, 0.0025, 20, scene, false);
            this._gazeTracker.bakeCurrentTransformIntoVertices();
            this._gazeTracker.isPickable = false;
            this._gazeTracker.isVisible = false;
            var targetMat = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_18__["StandardMaterial"]("targetMat", scene);
            targetMat.specularColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"].Black();
            targetMat.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7);
            targetMat.backFaceCulling = false;
            this._gazeTracker.material = targetMat;
        }
        else {
            this._gazeTracker = gazeTrackerToClone.clone("gazeTracker");
        }
    }
    /** @hidden */
    VRExperienceHelperGazer.prototype._getForwardRay = function (length) {
        return new _Culling_ray__WEBPACK_IMPORTED_MODULE_16__["Ray"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Zero(), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"](0, 0, length));
    };
    /** @hidden */
    VRExperienceHelperGazer.prototype._selectionPointerDown = function () {
        this._pointerDownOnMeshAsked = true;
        if (this._currentHit) {
            this.scene.simulatePointerDown(this._currentHit, { pointerId: this._id });
        }
    };
    /** @hidden */
    VRExperienceHelperGazer.prototype._selectionPointerUp = function () {
        if (this._currentHit) {
            this.scene.simulatePointerUp(this._currentHit, { pointerId: this._id });
        }
        this._pointerDownOnMeshAsked = false;
    };
    /** @hidden */
    VRExperienceHelperGazer.prototype._activatePointer = function () {
        this._activePointer = true;
    };
    /** @hidden */
    VRExperienceHelperGazer.prototype._deactivatePointer = function () {
        this._activePointer = false;
    };
    /** @hidden */
    VRExperienceHelperGazer.prototype._updatePointerDistance = function (distance) {
        if (distance === void 0) { distance = 100; }
    };
    VRExperienceHelperGazer.prototype.dispose = function () {
        this._interactionsEnabled = false;
        this._teleportationEnabled = false;
        if (this._gazeTracker) {
            this._gazeTracker.dispose();
        }
    };
    VRExperienceHelperGazer._idCounter = 0;
    return VRExperienceHelperGazer;
}());
var VRExperienceHelperControllerGazer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRExperienceHelperControllerGazer, _super);
    function VRExperienceHelperControllerGazer(webVRController, scene, gazeTrackerToClone) {
        var _this = _super.call(this, scene, gazeTrackerToClone) || this;
        _this.webVRController = webVRController;
        // Laser pointer
        _this._laserPointer = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__["Mesh"].CreateCylinder("laserPointer", 1, 0.004, 0.0002, 20, 1, scene, false);
        var laserPointerMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_18__["StandardMaterial"]("laserPointerMat", scene);
        laserPointerMaterial.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7);
        laserPointerMaterial.alpha = 0.6;
        _this._laserPointer.material = laserPointerMaterial;
        _this._laserPointer.rotation.x = Math.PI / 2;
        _this._laserPointer.position.z = -0.5;
        _this._laserPointer.isVisible = false;
        _this._laserPointer.isPickable = false;
        if (!webVRController.mesh) {
            // Create an empty mesh that is used prior to loading the high quality model
            var preloadMesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__["Mesh"]("preloadControllerMesh", scene);
            var preloadPointerPose = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__["Mesh"](_Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_12__["PoseEnabledController"].POINTING_POSE, scene);
            preloadPointerPose.rotation.x = -0.7;
            preloadMesh.addChild(preloadPointerPose);
            webVRController.attachToMesh(preloadMesh);
        }
        _this._setLaserPointerParent(webVRController.mesh);
        _this._meshAttachedObserver = webVRController._meshAttachedObservable.add(function (mesh) {
            _this._setLaserPointerParent(mesh);
        });
        return _this;
    }
    VRExperienceHelperControllerGazer.prototype._getForwardRay = function (length) {
        return this.webVRController.getForwardRay(length);
    };
    /** @hidden */
    VRExperienceHelperControllerGazer.prototype._activatePointer = function () {
        _super.prototype._activatePointer.call(this);
        this._laserPointer.isVisible = true;
    };
    /** @hidden */
    VRExperienceHelperControllerGazer.prototype._deactivatePointer = function () {
        _super.prototype._deactivatePointer.call(this);
        this._laserPointer.isVisible = false;
    };
    /** @hidden */
    VRExperienceHelperControllerGazer.prototype._setLaserPointerColor = function (color) {
        this._laserPointer.material.emissiveColor = color;
    };
    /** @hidden */
    VRExperienceHelperControllerGazer.prototype._setLaserPointerParent = function (mesh) {
        var makeNotPick = function (root) {
            root.isPickable = false;
            root.getChildMeshes().forEach(function (c) {
                makeNotPick(c);
            });
        };
        makeNotPick(mesh);
        var meshChildren = mesh.getChildren(undefined, false);
        var laserParent = mesh;
        this.webVRController._pointingPoseNode = null;
        for (var i = 0; i < meshChildren.length; i++) {
            if (meshChildren[i].name && meshChildren[i].name.indexOf(_Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_12__["PoseEnabledController"].POINTING_POSE) >= 0) {
                laserParent = meshChildren[i];
                this.webVRController._pointingPoseNode = laserParent;
                break;
            }
        }
        this._laserPointer.parent = laserParent;
    };
    VRExperienceHelperControllerGazer.prototype._updatePointerDistance = function (distance) {
        if (distance === void 0) { distance = 100; }
        this._laserPointer.scaling.y = distance;
        this._laserPointer.position.z = -distance / 2;
    };
    VRExperienceHelperControllerGazer.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this._laserPointer.dispose();
        if (this._meshAttachedObserver) {
            this.webVRController._meshAttachedObservable.remove(this._meshAttachedObserver);
        }
    };
    return VRExperienceHelperControllerGazer;
}(VRExperienceHelperGazer));
var VRExperienceHelperCameraGazer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRExperienceHelperCameraGazer, _super);
    function VRExperienceHelperCameraGazer(getCamera, scene) {
        var _this = _super.call(this, scene) || this;
        _this.getCamera = getCamera;
        return _this;
    }
    VRExperienceHelperCameraGazer.prototype._getForwardRay = function (length) {
        var camera = this.getCamera();
        if (camera) {
            return camera.getForwardRay(length);
        }
        else {
            return new _Culling_ray__WEBPACK_IMPORTED_MODULE_16__["Ray"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Forward());
        }
    };
    return VRExperienceHelperCameraGazer;
}(VRExperienceHelperGazer));
/**
 * Event containing information after VR has been entered
 */
var OnAfterEnteringVRObservableEvent = /** @class */ (function () {
    function OnAfterEnteringVRObservableEvent() {
    }
    return OnAfterEnteringVRObservableEvent;
}());

/**
 * Helps to quickly add VR support to an existing scene.
 * See http://doc.babylonjs.com/how_to/webvr_helper
 */
var VRExperienceHelper = /** @class */ (function () {
    /**
     * Instantiates a VRExperienceHelper.
     * Helps to quickly add VR support to an existing scene.
     * @param scene The scene the VRExperienceHelper belongs to.
     * @param webVROptions Options to modify the vr experience helper's behavior.
     */
    function VRExperienceHelper(scene,
    /** Options to modify the vr experience helper's behavior. */
    webVROptions) {
        var _this = this;
        if (webVROptions === void 0) { webVROptions = {}; }
        this.webVROptions = webVROptions;
        // Can the system support WebVR, even if a headset isn't plugged in?
        this._webVRsupported = false;
        // If WebVR is supported, is a headset plugged in and are we ready to present?
        this._webVRready = false;
        // Are we waiting for the requestPresent callback to complete?
        this._webVRrequesting = false;
        // Are we presenting to the headset right now? (this is the vrDevice state)
        this._webVRpresenting = false;
        // Are we presenting in the fullscreen fallback?
        this._fullscreenVRpresenting = false;
        /**
         * Gets or sets a boolean indicating that gaze can be enabled even if pointer lock is not engage (useful on iOS where fullscreen mode and pointer lock are not supported)
         */
        this.enableGazeEvenWhenNoPointerLock = false;
        /**
         * Gets or sets a boolean indicating that the VREXperienceHelper will exit VR if double tap is detected
         */
        this.exitVROnDoubleTap = true;
        /**
         * Observable raised right before entering VR.
         */
        this.onEnteringVRObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observable raised when entering VR has completed.
         */
        this.onAfterEnteringVRObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observable raised when exiting VR.
         */
        this.onExitingVRObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observable raised when controller mesh is loaded.
         */
        this.onControllerMeshLoadedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        this._useCustomVRButton = false;
        this._teleportationRequested = false;
        this._teleportActive = false;
        this._floorMeshesCollection = [];
        this._rotationAllowed = true;
        this._teleportBackwardsVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"](0, -1, -1);
        this._isDefaultTeleportationTarget = true;
        this._teleportationFillColor = "#444444";
        this._teleportationBorderColor = "#FFFFFF";
        this._rotationAngle = 0;
        this._haloCenter = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"](0, 0, 0);
        this._padSensibilityUp = 0.65;
        this._padSensibilityDown = 0.35;
        this._leftController = null;
        this._rightController = null;
        /**
         * Observable raised when a new mesh is selected based on meshSelectionPredicate
         */
        this.onNewMeshSelected = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observable raised when a new mesh is selected based on meshSelectionPredicate.
         * This observable will provide the mesh and the controller used to select the mesh
         */
        this.onMeshSelectedWithController = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observable raised when a new mesh is picked based on meshSelectionPredicate
         */
        this.onNewMeshPicked = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Observable raised before camera teleportation
        */
        this.onBeforeCameraTeleport = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         *  Observable raised after camera teleportation
        */
        this.onAfterCameraTeleport = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
        * Observable raised when current selected mesh gets unselected
        */
        this.onSelectedMeshUnselected = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Set teleportation enabled. If set to false camera teleportation will be disabled but camera rotation will be kept.
         */
        this.teleportationEnabled = true;
        this._teleportationInitialized = false;
        this._interactionsEnabled = false;
        this._interactionsRequested = false;
        this._displayGaze = true;
        this._displayLaserPointer = true;
        /**
         * If the gaze trackers scale should be updated to be constant size when pointing at near/far meshes
         */
        this.updateGazeTrackerScale = true;
        /**
         * If the gaze trackers color should be updated when selecting meshes
         */
        this.updateGazeTrackerColor = true;
        /**
         * Defines wether or not Pointer lock should be requested when switching to
         * full screen.
         */
        this.requestPointerLockOnFullScreen = true;
        this._onResize = function () {
            _this.moveButtonToBottomRight();
            if (_this._fullscreenVRpresenting && _this._webVRready) {
                _this.exitVR();
            }
        };
        this._onFullscreenChange = function () {
            var anyDoc = document;
            if (anyDoc.fullscreen !== undefined) {
                _this._fullscreenVRpresenting = document.fullscreen;
            }
            else if (anyDoc.mozFullScreen !== undefined) {
                _this._fullscreenVRpresenting = anyDoc.mozFullScreen;
            }
            else if (anyDoc.webkitIsFullScreen !== undefined) {
                _this._fullscreenVRpresenting = anyDoc.webkitIsFullScreen;
            }
            else if (anyDoc.msIsFullScreen !== undefined) {
                _this._fullscreenVRpresenting = anyDoc.msIsFullScreen;
            }
            else if (document.msFullscreenElement !== undefined) {
                _this._fullscreenVRpresenting = document.msFullscreenElement;
            }
            if (!_this._fullscreenVRpresenting && _this._canvas) {
                _this.exitVR();
                if (!_this._useCustomVRButton && _this._btnVR) {
                    _this._btnVR.style.top = _this._canvas.offsetTop + _this._canvas.offsetHeight - 70 + "px";
                    _this._btnVR.style.left = _this._canvas.offsetLeft + _this._canvas.offsetWidth - 100 + "px";
                }
            }
        };
        this._cachedAngularSensibility = { angularSensibilityX: null, angularSensibilityY: null, angularSensibility: null };
        this.beforeRender = function () {
            if (_this._leftController && _this._leftController._activePointer) {
                _this._castRayAndSelectObject(_this._leftController);
            }
            if (_this._rightController && _this._rightController._activePointer) {
                _this._castRayAndSelectObject(_this._rightController);
            }
            if (_this._noControllerIsActive && (_this._scene.getEngine().isPointerLock || _this.enableGazeEvenWhenNoPointerLock)) {
                _this._castRayAndSelectObject(_this._cameraGazer);
            }
            else {
                _this._cameraGazer._gazeTracker.isVisible = false;
            }
        };
        this._onNewGamepadConnected = function (gamepad) {
            if (gamepad.type !== _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_11__["Gamepad"].POSE_ENABLED) {
                if (gamepad.leftStick) {
                    gamepad.onleftstickchanged(function (stickValues) {
                        if (_this._teleportationInitialized && _this.teleportationEnabled) {
                            // Listening to classic/xbox gamepad only if no VR controller is active
                            if ((!_this._leftController && !_this._rightController) ||
                                ((_this._leftController && !_this._leftController._activePointer) &&
                                    (_this._rightController && !_this._rightController._activePointer))) {
                                _this._checkTeleportWithRay(stickValues, _this._cameraGazer);
                                _this._checkTeleportBackwards(stickValues, _this._cameraGazer);
                            }
                        }
                    });
                }
                if (gamepad.rightStick) {
                    gamepad.onrightstickchanged(function (stickValues) {
                        if (_this._teleportationInitialized) {
                            _this._checkRotate(stickValues, _this._cameraGazer);
                        }
                    });
                }
                if (gamepad.type === _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_11__["Gamepad"].XBOX) {
                    gamepad.onbuttondown(function (buttonPressed) {
                        if (_this._interactionsEnabled && buttonPressed === _Gamepads_xboxGamepad__WEBPACK_IMPORTED_MODULE_14__["Xbox360Button"].A) {
                            _this._cameraGazer._selectionPointerDown();
                        }
                    });
                    gamepad.onbuttonup(function (buttonPressed) {
                        if (_this._interactionsEnabled && buttonPressed === _Gamepads_xboxGamepad__WEBPACK_IMPORTED_MODULE_14__["Xbox360Button"].A) {
                            _this._cameraGazer._selectionPointerUp();
                        }
                    });
                }
            }
            else {
                var webVRController = gamepad;
                var controller = new VRExperienceHelperControllerGazer(webVRController, _this._scene, _this._cameraGazer._gazeTracker);
                if (webVRController.hand === "right" || (_this._leftController && _this._leftController.webVRController != webVRController)) {
                    _this._rightController = controller;
                }
                else {
                    _this._leftController = controller;
                }
                _this._tryEnableInteractionOnController(controller);
            }
        };
        // This only succeeds if the controller's mesh exists for the controller so this must be called whenever new controller is connected or when mesh is loaded
        this._tryEnableInteractionOnController = function (controller) {
            if (_this._interactionsRequested && !controller._interactionsEnabled) {
                _this._enableInteractionOnController(controller);
            }
            if (_this._teleportationRequested && !controller._teleportationEnabled) {
                _this._enableTeleportationOnController(controller);
            }
        };
        this._onNewGamepadDisconnected = function (gamepad) {
            if (gamepad instanceof _Gamepads_Controllers_webVRController__WEBPACK_IMPORTED_MODULE_13__["WebVRController"]) {
                if (gamepad.hand === "left" && _this._leftController != null) {
                    _this._leftController.dispose();
                    _this._leftController = null;
                }
                if (gamepad.hand === "right" && _this._rightController != null) {
                    _this._rightController.dispose();
                    _this._rightController = null;
                }
            }
        };
        this._workingVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Zero();
        this._workingQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].Identity();
        this._workingMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Matrix"].Identity();
        this._scene = scene;
        this._canvas = scene.getEngine().getRenderingCanvas();
        // Parse options
        if (webVROptions.createFallbackVRDeviceOrientationFreeCamera === undefined) {
            webVROptions.createFallbackVRDeviceOrientationFreeCamera = true;
        }
        if (webVROptions.createDeviceOrientationCamera === undefined) {
            webVROptions.createDeviceOrientationCamera = true;
        }
        if (webVROptions.laserToggle === undefined) {
            webVROptions.laserToggle = true;
        }
        if (webVROptions.defaultHeight === undefined) {
            webVROptions.defaultHeight = 1.7;
        }
        if (webVROptions.useCustomVRButton) {
            this._useCustomVRButton = true;
            if (webVROptions.customVRButton) {
                this._btnVR = webVROptions.customVRButton;
            }
        }
        if (webVROptions.rayLength) {
            this._rayLength = webVROptions.rayLength;
        }
        this._defaultHeight = webVROptions.defaultHeight;
        if (webVROptions.positionScale) {
            this._rayLength *= webVROptions.positionScale;
            this._defaultHeight *= webVROptions.positionScale;
        }
        this._hasEnteredVR = false;
        // Set position
        if (this._scene.activeCamera) {
            this._position = this._scene.activeCamera.position.clone();
        }
        else {
            this._position = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"](0, this._defaultHeight, 0);
        }
        // Set non-vr camera
        if (webVROptions.createDeviceOrientationCamera || !this._scene.activeCamera) {
            this._deviceOrientationCamera = new _Cameras_deviceOrientationCamera__WEBPACK_IMPORTED_MODULE_5__["DeviceOrientationCamera"]("deviceOrientationVRHelper", this._position.clone(), scene);
            // Copy data from existing camera
            if (this._scene.activeCamera) {
                this._deviceOrientationCamera.minZ = this._scene.activeCamera.minZ;
                this._deviceOrientationCamera.maxZ = this._scene.activeCamera.maxZ;
                // Set rotation from previous camera
                if (this._scene.activeCamera instanceof _Cameras_targetCamera__WEBPACK_IMPORTED_MODULE_4__["TargetCamera"] && this._scene.activeCamera.rotation) {
                    var targetCamera = this._scene.activeCamera;
                    if (targetCamera.rotationQuaternion) {
                        this._deviceOrientationCamera.rotationQuaternion.copyFrom(targetCamera.rotationQuaternion);
                    }
                    else {
                        this._deviceOrientationCamera.rotationQuaternion.copyFrom(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].RotationYawPitchRoll(targetCamera.rotation.y, targetCamera.rotation.x, targetCamera.rotation.z));
                    }
                    this._deviceOrientationCamera.rotation = targetCamera.rotation.clone();
                }
            }
            this._scene.activeCamera = this._deviceOrientationCamera;
            if (this._canvas) {
                this._scene.activeCamera.attachControl(this._canvas);
            }
        }
        else {
            this._existingCamera = this._scene.activeCamera;
        }
        // Create VR cameras
        if (webVROptions.createFallbackVRDeviceOrientationFreeCamera) {
            if (webVROptions.useMultiview) {
                if (!webVROptions.vrDeviceOrientationCameraMetrics) {
                    webVROptions.vrDeviceOrientationCameraMetrics = _Cameras_VR_vrCameraMetrics__WEBPACK_IMPORTED_MODULE_23__["VRCameraMetrics"].GetDefault();
                }
                webVROptions.vrDeviceOrientationCameraMetrics.multiviewEnabled = true;
            }
            this._vrDeviceOrientationCamera = new _Cameras_VR_vrDeviceOrientationFreeCamera__WEBPACK_IMPORTED_MODULE_6__["VRDeviceOrientationFreeCamera"]("VRDeviceOrientationVRHelper", this._position, this._scene, true, webVROptions.vrDeviceOrientationCameraMetrics);
            this._vrDeviceOrientationCamera.angularSensibility = Number.MAX_VALUE;
        }
        this._webVRCamera = new _Cameras_VR_webVRCamera__WEBPACK_IMPORTED_MODULE_7__["WebVRFreeCamera"]("WebVRHelper", this._position, this._scene, webVROptions);
        this._webVRCamera.useStandingMatrix();
        this._cameraGazer = new VRExperienceHelperCameraGazer(function () { return _this.currentVRCamera; }, scene);
        // Create default button
        if (!this._useCustomVRButton) {
            this._btnVR = document.createElement("BUTTON");
            this._btnVR.className = "babylonVRicon";
            this._btnVR.id = "babylonVRiconbtn";
            this._btnVR.title = "Click to switch to VR";
            var css = ".babylonVRicon { position: absolute; right: 20px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-image: url(data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%222048%22%20height%3D%221152%22%20viewBox%3D%220%200%202048%201152%22%20version%3D%221.1%22%3E%3Cpath%20transform%3D%22rotate%28180%201024%2C576.0000000000001%29%22%20d%3D%22m1109%2C896q17%2C0%2030%2C-12t13%2C-30t-12.5%2C-30.5t-30.5%2C-12.5l-170%2C0q-18%2C0%20-30.5%2C12.5t-12.5%2C30.5t13%2C30t30%2C12l170%2C0zm-85%2C256q59%2C0%20132.5%2C-1.5t154.5%2C-5.5t164.5%2C-11.5t163%2C-20t150%2C-30t124.5%2C-41.5q23%2C-11%2042%2C-24t38%2C-30q27%2C-25%2041%2C-61.5t14%2C-72.5l0%2C-257q0%2C-123%20-47%2C-232t-128%2C-190t-190%2C-128t-232%2C-47l-81%2C0q-37%2C0%20-68.5%2C14t-60.5%2C34.5t-55.5%2C45t-53%2C45t-53%2C34.5t-55.5%2C14t-55.5%2C-14t-53%2C-34.5t-53%2C-45t-55.5%2C-45t-60.5%2C-34.5t-68.5%2C-14l-81%2C0q-123%2C0%20-232%2C47t-190%2C128t-128%2C190t-47%2C232l0%2C257q0%2C68%2038%2C115t97%2C73q54%2C24%20124.5%2C41.5t150%2C30t163%2C20t164.5%2C11.5t154.5%2C5.5t132.5%2C1.5zm939%2C-298q0%2C39%20-24.5%2C67t-58.5%2C42q-54%2C23%20-122%2C39.5t-143.5%2C28t-155.5%2C19t-157%2C11t-148.5%2C5t-129.5%2C1.5q-59%2C0%20-130%2C-1.5t-148%2C-5t-157%2C-11t-155.5%2C-19t-143.5%2C-28t-122%2C-39.5q-34%2C-14%20-58.5%2C-42t-24.5%2C-67l0%2C-257q0%2C-106%2040.5%2C-199t110%2C-162.5t162.5%2C-109.5t199%2C-40l81%2C0q27%2C0%2052%2C14t50%2C34.5t51%2C44.5t55.5%2C44.5t63.5%2C34.5t74%2C14t74%2C-14t63.5%2C-34.5t55.5%2C-44.5t51%2C-44.5t50%2C-34.5t52%2C-14l14%2C0q37%2C0%2070%2C0.5t64.5%2C4.5t63.5%2C12t68%2C23q71%2C30%20128.5%2C78.5t98.5%2C110t63.5%2C133.5t22.5%2C149l0%2C257z%22%20fill%3D%22white%22%20/%3E%3C/svg%3E%0A); background-size: 80%; background-repeat:no-repeat; background-position: center; border: none; outline: none; transition: transform 0.125s ease-out } .babylonVRicon:hover { transform: scale(1.05) } .babylonVRicon:active {background-color: rgba(51,51,51,1) } .babylonVRicon:focus {background-color: rgba(51,51,51,1) }";
            css += ".babylonVRicon.vrdisplaypresenting { display: none; }";
            // TODO: Add user feedback so that they know what state the VRDisplay is in (disconnected, connected, entering-VR)
            // css += ".babylonVRicon.vrdisplaysupported { }";
            // css += ".babylonVRicon.vrdisplayready { }";
            // css += ".babylonVRicon.vrdisplayrequesting { }";
            var style = document.createElement('style');
            style.appendChild(document.createTextNode(css));
            document.getElementsByTagName('head')[0].appendChild(style);
            this.moveButtonToBottomRight();
        }
        // VR button click event
        if (this._btnVR) {
            this._btnVR.addEventListener("click", function () {
                if (!_this.isInVRMode) {
                    _this.enterVR();
                }
                else {
                    _this.exitVR();
                }
            });
        }
        // Window events
        var hostWindow = this._scene.getEngine().getHostWindow();
        hostWindow.addEventListener("resize", this._onResize);
        document.addEventListener("fullscreenchange", this._onFullscreenChange, false);
        document.addEventListener("mozfullscreenchange", this._onFullscreenChange, false);
        document.addEventListener("webkitfullscreenchange", this._onFullscreenChange, false);
        document.addEventListener("msfullscreenchange", this._onFullscreenChange, false);
        document.onmsfullscreenchange = this._onFullscreenChange;
        // Display vr button when headset is connected
        if (webVROptions.createFallbackVRDeviceOrientationFreeCamera) {
            this.displayVRButton();
        }
        else {
            this._scene.getEngine().onVRDisplayChangedObservable.add(function (e) {
                if (e.vrDisplay) {
                    _this.displayVRButton();
                }
            });
        }
        // Exiting VR mode using 'ESC' key on desktop
        this._onKeyDown = function (event) {
            if (event.keyCode === 27 && _this.isInVRMode) {
                _this.exitVR();
            }
        };
        document.addEventListener("keydown", this._onKeyDown);
        // Exiting VR mode double tapping the touch screen
        this._scene.onPrePointerObservable.add(function () {
            if (_this.isInVRMode && _this.exitVROnDoubleTap) {
                _this.exitVR();
                if (_this._fullscreenVRpresenting) {
                    _this._scene.getEngine().exitFullscreen();
                }
            }
        }, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_8__["PointerEventTypes"].POINTERDOUBLETAP, false);
        // Listen for WebVR display changes
        this._onVRDisplayChanged = function (eventArgs) { return _this.onVRDisplayChanged(eventArgs); };
        this._onVrDisplayPresentChange = function () { return _this.onVrDisplayPresentChange(); };
        this._onVRRequestPresentStart = function () {
            _this._webVRrequesting = true;
            _this.updateButtonVisibility();
        };
        this._onVRRequestPresentComplete = function () {
            _this._webVRrequesting = false;
            _this.updateButtonVisibility();
        };
        scene.getEngine().onVRDisplayChangedObservable.add(this._onVRDisplayChanged);
        scene.getEngine().onVRRequestPresentStart.add(this._onVRRequestPresentStart);
        scene.getEngine().onVRRequestPresentComplete.add(this._onVRRequestPresentComplete);
        hostWindow.addEventListener('vrdisplaypresentchange', this._onVrDisplayPresentChange);
        scene.onDisposeObservable.add(function () {
            _this.dispose();
        });
        // Gamepad connection events
        this._webVRCamera.onControllerMeshLoadedObservable.add(function (webVRController) { return _this._onDefaultMeshLoaded(webVRController); });
        this._scene.gamepadManager.onGamepadConnectedObservable.add(this._onNewGamepadConnected);
        this._scene.gamepadManager.onGamepadDisconnectedObservable.add(this._onNewGamepadDisconnected);
        this.updateButtonVisibility();
        //create easing functions
        this._circleEase = new _Animations_easing__WEBPACK_IMPORTED_MODULE_21__["CircleEase"]();
        this._circleEase.setEasingMode(_Animations_easing__WEBPACK_IMPORTED_MODULE_21__["EasingFunction"].EASINGMODE_EASEINOUT);
        // Allow clicking in the vrDeviceOrientationCamera
        scene.onPointerObservable.add(function (e) {
            if (_this._interactionsEnabled) {
                if (scene.activeCamera === _this.vrDeviceOrientationCamera && e.event.pointerType === "mouse") {
                    if (e.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_8__["PointerEventTypes"].POINTERDOWN) {
                        _this._cameraGazer._selectionPointerDown();
                    }
                    else if (e.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_8__["PointerEventTypes"].POINTERUP) {
                        _this._cameraGazer._selectionPointerUp();
                    }
                }
            }
        });
        if (this.webVROptions.floorMeshes) {
            this.enableTeleportation({ floorMeshes: this.webVROptions.floorMeshes });
        }
    }
    Object.defineProperty(VRExperienceHelper.prototype, "onEnteringVR", {
        /** Return this.onEnteringVRObservable
         * Note: This one is for backward compatibility. Please use onEnteringVRObservable directly
         */
        get: function () {
            return this.onEnteringVRObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "onExitingVR", {
        /** Return this.onExitingVRObservable
         * Note: This one is for backward compatibility. Please use onExitingVRObservable directly
         */
        get: function () {
            return this.onExitingVRObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "onControllerMeshLoaded", {
        /** Return this.onControllerMeshLoadedObservable
         * Note: This one is for backward compatibility. Please use onControllerMeshLoadedObservable directly
         */
        get: function () {
            return this.onControllerMeshLoadedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "teleportationTarget", {
        /**
         * The mesh used to display where the user is going to teleport.
         */
        get: function () {
            return this._teleportationTarget;
        },
        /**
         * Sets the mesh to be used to display where the user is going to teleport.
         */
        set: function (value) {
            if (value) {
                value.name = "teleportationTarget";
                this._isDefaultTeleportationTarget = false;
                this._teleportationTarget = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "gazeTrackerMesh", {
        /**
         * The mesh used to display where the user is selecting, this mesh will be cloned and set as the gazeTracker for the left and right controller
         * when set bakeCurrentTransformIntoVertices will be called on the mesh.
         * See http://doc.babylonjs.com/resources/baking_transformations
         */
        get: function () {
            return this._cameraGazer._gazeTracker;
        },
        set: function (value) {
            if (value) {
                // Dispose of existing meshes
                if (this._cameraGazer._gazeTracker) {
                    this._cameraGazer._gazeTracker.dispose();
                }
                if (this._leftController && this._leftController._gazeTracker) {
                    this._leftController._gazeTracker.dispose();
                }
                if (this._rightController && this._rightController._gazeTracker) {
                    this._rightController._gazeTracker.dispose();
                }
                // Set and create gaze trackers on head and controllers
                this._cameraGazer._gazeTracker = value;
                this._cameraGazer._gazeTracker.bakeCurrentTransformIntoVertices();
                this._cameraGazer._gazeTracker.isPickable = false;
                this._cameraGazer._gazeTracker.isVisible = false;
                this._cameraGazer._gazeTracker.name = "gazeTracker";
                if (this._leftController) {
                    this._leftController._gazeTracker = this._cameraGazer._gazeTracker.clone("gazeTracker");
                }
                if (this._rightController) {
                    this._rightController._gazeTracker = this._cameraGazer._gazeTracker.clone("gazeTracker");
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "leftControllerGazeTrackerMesh", {
        /**
         * The gaze tracking mesh corresponding to the left controller
         */
        get: function () {
            if (this._leftController) {
                return this._leftController._gazeTracker;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "rightControllerGazeTrackerMesh", {
        /**
         * The gaze tracking mesh corresponding to the right controller
         */
        get: function () {
            if (this._rightController) {
                return this._rightController._gazeTracker;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "displayGaze", {
        /**
         * If the ray of the gaze should be displayed.
         */
        get: function () {
            return this._displayGaze;
        },
        /**
         * Sets if the ray of the gaze should be displayed.
         */
        set: function (value) {
            this._displayGaze = value;
            if (!value) {
                this._cameraGazer._gazeTracker.isVisible = false;
                if (this._leftController) {
                    this._leftController._gazeTracker.isVisible = false;
                }
                if (this._rightController) {
                    this._rightController._gazeTracker.isVisible = false;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "displayLaserPointer", {
        /**
         * If the ray of the LaserPointer should be displayed.
         */
        get: function () {
            return this._displayLaserPointer;
        },
        /**
         * Sets if the ray of the LaserPointer should be displayed.
         */
        set: function (value) {
            this._displayLaserPointer = value;
            if (!value) {
                if (this._rightController) {
                    this._rightController._deactivatePointer();
                    this._rightController._gazeTracker.isVisible = false;
                }
                if (this._leftController) {
                    this._leftController._deactivatePointer();
                    this._leftController._gazeTracker.isVisible = false;
                }
            }
            else {
                if (this._rightController) {
                    this._rightController._activatePointer();
                }
                if (this._leftController) {
                    this._leftController._activatePointer();
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "deviceOrientationCamera", {
        /**
         * The deviceOrientationCamera used as the camera when not in VR.
         */
        get: function () {
            return this._deviceOrientationCamera;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "currentVRCamera", {
        /**
         * Based on the current WebVR support, returns the current VR camera used.
         */
        get: function () {
            if (this._webVRready) {
                return this._webVRCamera;
            }
            else {
                return this._scene.activeCamera;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "webVRCamera", {
        /**
         * The webVRCamera which is used when in VR.
         */
        get: function () {
            return this._webVRCamera;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "vrDeviceOrientationCamera", {
        /**
         * The deviceOrientationCamera that is used as a fallback when vr device is not connected.
         */
        get: function () {
            return this._vrDeviceOrientationCamera;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "vrButton", {
        /**
         * The html button that is used to trigger entering into VR.
         */
        get: function () {
            return this._btnVR;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VRExperienceHelper.prototype, "_teleportationRequestInitiated", {
        get: function () {
            var result = this._cameraGazer._teleportationRequestInitiated
                || (this._leftController !== null && this._leftController._teleportationRequestInitiated)
                || (this._rightController !== null && this._rightController._teleportationRequestInitiated);
            return result;
        },
        enumerable: true,
        configurable: true
    });
    // Raised when one of the controller has loaded successfully its associated default mesh
    VRExperienceHelper.prototype._onDefaultMeshLoaded = function (webVRController) {
        if (this._leftController && this._leftController.webVRController == webVRController) {
            if (webVRController.mesh) {
                this._leftController._setLaserPointerParent(webVRController.mesh);
            }
        }
        if (this._rightController && this._rightController.webVRController == webVRController) {
            if (webVRController.mesh) {
                this._rightController._setLaserPointerParent(webVRController.mesh);
            }
        }
        try {
            this.onControllerMeshLoadedObservable.notifyObservers(webVRController);
        }
        catch (err) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Error in your custom logic onControllerMeshLoaded: " + err);
        }
    };
    Object.defineProperty(VRExperienceHelper.prototype, "isInVRMode", {
        /**
         * Gets a value indicating if we are currently in VR mode.
         */
        get: function () {
            return this._webVRpresenting || this._fullscreenVRpresenting;
        },
        enumerable: true,
        configurable: true
    });
    VRExperienceHelper.prototype.onVrDisplayPresentChange = function () {
        var vrDisplay = this._scene.getEngine().getVRDevice();
        if (vrDisplay) {
            var wasPresenting = this._webVRpresenting;
            this._webVRpresenting = vrDisplay.isPresenting;
            if (wasPresenting && !this._webVRpresenting) {
                this.exitVR();
            }
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Detected VRDisplayPresentChange on an unknown VRDisplay. Did you can enterVR on the vrExperienceHelper?');
        }
        this.updateButtonVisibility();
    };
    VRExperienceHelper.prototype.onVRDisplayChanged = function (eventArgs) {
        this._webVRsupported = eventArgs.vrSupported;
        this._webVRready = !!eventArgs.vrDisplay;
        this._webVRpresenting = eventArgs.vrDisplay && eventArgs.vrDisplay.isPresenting;
        this.updateButtonVisibility();
    };
    VRExperienceHelper.prototype.moveButtonToBottomRight = function () {
        if (this._canvas && !this._useCustomVRButton && this._btnVR) {
            var rect = this._canvas.getBoundingClientRect();
            this._btnVR.style.top = rect.top + rect.height - 70 + "px";
            this._btnVR.style.left = rect.left + rect.width - 100 + "px";
        }
    };
    VRExperienceHelper.prototype.displayVRButton = function () {
        if (!this._useCustomVRButton && !this._btnVRDisplayed && this._btnVR) {
            document.body.appendChild(this._btnVR);
            this._btnVRDisplayed = true;
        }
    };
    VRExperienceHelper.prototype.updateButtonVisibility = function () {
        if (!this._btnVR || this._useCustomVRButton) {
            return;
        }
        this._btnVR.className = "babylonVRicon";
        if (this.isInVRMode) {
            this._btnVR.className += " vrdisplaypresenting";
        }
        else {
            if (this._webVRready) {
                this._btnVR.className += " vrdisplayready";
            }
            if (this._webVRsupported) {
                this._btnVR.className += " vrdisplaysupported";
            }
            if (this._webVRrequesting) {
                this._btnVR.className += " vrdisplayrequesting";
            }
        }
    };
    /**
     * Attempt to enter VR. If a headset is connected and ready, will request present on that.
     * Otherwise, will use the fullscreen API.
     */
    VRExperienceHelper.prototype.enterVR = function () {
        var _this = this;
        if (this.onEnteringVRObservable) {
            try {
                this.onEnteringVRObservable.notifyObservers(this);
            }
            catch (err) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Error in your custom logic onEnteringVR: " + err);
            }
        }
        if (this._scene.activeCamera) {
            this._position = this._scene.activeCamera.position.clone();
            if (this.vrDeviceOrientationCamera) {
                this.vrDeviceOrientationCamera.rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].FromRotationMatrix(this._scene.activeCamera.getWorldMatrix().getRotationMatrix()).toEulerAngles();
                this.vrDeviceOrientationCamera.angularSensibility = 2000;
            }
            if (this.webVRCamera) {
                var currentYRotation = this.webVRCamera.deviceRotationQuaternion.toEulerAngles().y;
                var desiredYRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].FromRotationMatrix(this._scene.activeCamera.getWorldMatrix().getRotationMatrix()).toEulerAngles().y;
                var delta = desiredYRotation - currentYRotation;
                var currentGlobalRotation = this.webVRCamera.rotationQuaternion.toEulerAngles().y;
                this.webVRCamera.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].FromEulerAngles(0, currentGlobalRotation + delta, 0);
            }
            // make sure that we return to the last active camera
            this._existingCamera = this._scene.activeCamera;
            // Remove and cache angular sensability to avoid camera rotation when in VR
            if (this._existingCamera.angularSensibilityX) {
                this._cachedAngularSensibility.angularSensibilityX = this._existingCamera.angularSensibilityX;
                this._existingCamera.angularSensibilityX = Number.MAX_VALUE;
            }
            if (this._existingCamera.angularSensibilityY) {
                this._cachedAngularSensibility.angularSensibilityY = this._existingCamera.angularSensibilityY;
                this._existingCamera.angularSensibilityY = Number.MAX_VALUE;
            }
            if (this._existingCamera.angularSensibility) {
                this._cachedAngularSensibility.angularSensibility = this._existingCamera.angularSensibility;
                this._existingCamera.angularSensibility = Number.MAX_VALUE;
            }
        }
        if (this._webVRrequesting) {
            return;
        }
        // If WebVR is supported and a headset is connected
        if (this._webVRready) {
            if (!this._webVRpresenting) {
                this._scene.getEngine().onVRRequestPresentComplete.addOnce(function (result) {
                    _this.onAfterEnteringVRObservable.notifyObservers({ success: result });
                });
                this._webVRCamera.position = this._position;
                this._scene.activeCamera = this._webVRCamera;
            }
        }
        else if (this._vrDeviceOrientationCamera) {
            this._vrDeviceOrientationCamera.position = this._position;
            if (this._scene.activeCamera) {
                this._vrDeviceOrientationCamera.minZ = this._scene.activeCamera.minZ;
            }
            this._scene.activeCamera = this._vrDeviceOrientationCamera;
            this._scene.getEngine().enterFullscreen(this.requestPointerLockOnFullScreen);
            this.updateButtonVisibility();
            this._vrDeviceOrientationCamera.onViewMatrixChangedObservable.addOnce(function () {
                _this.onAfterEnteringVRObservable.notifyObservers({ success: true });
            });
        }
        if (this._scene.activeCamera && this._canvas) {
            this._scene.activeCamera.attachControl(this._canvas);
        }
        if (this._interactionsEnabled) {
            this._scene.registerBeforeRender(this.beforeRender);
        }
        if (this._displayLaserPointer) {
            [this._leftController, this._rightController].forEach(function (controller) {
                if (controller) {
                    controller._activatePointer();
                }
            });
        }
        this._hasEnteredVR = true;
    };
    /**
     * Attempt to exit VR, or fullscreen.
     */
    VRExperienceHelper.prototype.exitVR = function () {
        if (this._hasEnteredVR) {
            if (this.onExitingVRObservable) {
                try {
                    this.onExitingVRObservable.notifyObservers(this);
                }
                catch (err) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Error in your custom logic onExitingVR: " + err);
                }
            }
            if (this._webVRpresenting) {
                this._scene.getEngine().disableVR();
            }
            if (this._scene.activeCamera) {
                this._position = this._scene.activeCamera.position.clone();
            }
            if (this.vrDeviceOrientationCamera) {
                this.vrDeviceOrientationCamera.angularSensibility = Number.MAX_VALUE;
            }
            if (this._deviceOrientationCamera) {
                this._deviceOrientationCamera.position = this._position;
                this._scene.activeCamera = this._deviceOrientationCamera;
                if (this._canvas) {
                    this._scene.activeCamera.attachControl(this._canvas);
                }
                // Restore angular sensibility
                if (this._cachedAngularSensibility.angularSensibilityX) {
                    this._deviceOrientationCamera.angularSensibilityX = this._cachedAngularSensibility.angularSensibilityX;
                    this._cachedAngularSensibility.angularSensibilityX = null;
                }
                if (this._cachedAngularSensibility.angularSensibilityY) {
                    this._deviceOrientationCamera.angularSensibilityY = this._cachedAngularSensibility.angularSensibilityY;
                    this._cachedAngularSensibility.angularSensibilityY = null;
                }
                if (this._cachedAngularSensibility.angularSensibility) {
                    this._deviceOrientationCamera.angularSensibility = this._cachedAngularSensibility.angularSensibility;
                    this._cachedAngularSensibility.angularSensibility = null;
                }
            }
            else if (this._existingCamera) {
                this._existingCamera.position = this._position;
                this._scene.activeCamera = this._existingCamera;
                // Restore angular sensibility
                if (this._cachedAngularSensibility.angularSensibilityX) {
                    this._existingCamera.angularSensibilityX = this._cachedAngularSensibility.angularSensibilityX;
                    this._cachedAngularSensibility.angularSensibilityX = null;
                }
                if (this._cachedAngularSensibility.angularSensibilityY) {
                    this._existingCamera.angularSensibilityY = this._cachedAngularSensibility.angularSensibilityY;
                    this._cachedAngularSensibility.angularSensibilityY = null;
                }
                if (this._cachedAngularSensibility.angularSensibility) {
                    this._existingCamera.angularSensibility = this._cachedAngularSensibility.angularSensibility;
                    this._cachedAngularSensibility.angularSensibility = null;
                }
            }
            this.updateButtonVisibility();
            if (this._interactionsEnabled) {
                this._scene.unregisterBeforeRender(this.beforeRender);
                this._cameraGazer._gazeTracker.isVisible = false;
                if (this._leftController) {
                    this._leftController._gazeTracker.isVisible = false;
                }
                if (this._rightController) {
                    this._rightController._gazeTracker.isVisible = false;
                }
            }
            // resize to update width and height when exiting vr exits fullscreen
            this._scene.getEngine().resize();
            [this._leftController, this._rightController].forEach(function (controller) {
                if (controller) {
                    controller._deactivatePointer();
                }
            });
            this._hasEnteredVR = false;
            // Update engine state to re enable non-vr camera input
            var engine = this._scene.getEngine();
            if (engine._onVrDisplayPresentChange) {
                engine._onVrDisplayPresentChange();
            }
        }
    };
    Object.defineProperty(VRExperienceHelper.prototype, "position", {
        /**
         * The position of the vr experience helper.
         */
        get: function () {
            return this._position;
        },
        /**
         * Sets the position of the vr experience helper.
         */
        set: function (value) {
            this._position = value;
            if (this._scene.activeCamera) {
                this._scene.activeCamera.position = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Enables controllers and user interactions such as selecting and object or clicking on an object.
     */
    VRExperienceHelper.prototype.enableInteractions = function () {
        var _this = this;
        if (!this._interactionsEnabled) {
            this._interactionsRequested = true;
            if (this._leftController) {
                this._enableInteractionOnController(this._leftController);
            }
            if (this._rightController) {
                this._enableInteractionOnController(this._rightController);
            }
            this.raySelectionPredicate = function (mesh) {
                return mesh.isVisible && (mesh.isPickable || mesh.name === _this._floorMeshName);
            };
            this.meshSelectionPredicate = function () {
                return true;
            };
            this._raySelectionPredicate = function (mesh) {
                if (_this._isTeleportationFloor(mesh) || (mesh.name.indexOf("gazeTracker") === -1
                    && mesh.name.indexOf("teleportationTarget") === -1
                    && mesh.name.indexOf("torusTeleportation") === -1)) {
                    return _this.raySelectionPredicate(mesh);
                }
                return false;
            };
            this._interactionsEnabled = true;
        }
    };
    Object.defineProperty(VRExperienceHelper.prototype, "_noControllerIsActive", {
        get: function () {
            return !(this._leftController && this._leftController._activePointer) && !(this._rightController && this._rightController._activePointer);
        },
        enumerable: true,
        configurable: true
    });
    VRExperienceHelper.prototype._isTeleportationFloor = function (mesh) {
        for (var i = 0; i < this._floorMeshesCollection.length; i++) {
            if (this._floorMeshesCollection[i].id === mesh.id) {
                return true;
            }
        }
        if (this._floorMeshName && mesh.name === this._floorMeshName) {
            return true;
        }
        return false;
    };
    /**
     * Adds a floor mesh to be used for teleportation.
     * @param floorMesh the mesh to be used for teleportation.
     */
    VRExperienceHelper.prototype.addFloorMesh = function (floorMesh) {
        if (!this._floorMeshesCollection) {
            return;
        }
        if (this._floorMeshesCollection.indexOf(floorMesh) > -1) {
            return;
        }
        this._floorMeshesCollection.push(floorMesh);
    };
    /**
     * Removes a floor mesh from being used for teleportation.
     * @param floorMesh the mesh to be removed.
     */
    VRExperienceHelper.prototype.removeFloorMesh = function (floorMesh) {
        if (!this._floorMeshesCollection) {
            return;
        }
        var meshIndex = this._floorMeshesCollection.indexOf(floorMesh);
        if (meshIndex !== -1) {
            this._floorMeshesCollection.splice(meshIndex, 1);
        }
    };
    /**
     * Enables interactions and teleportation using the VR controllers and gaze.
     * @param vrTeleportationOptions options to modify teleportation behavior.
     */
    VRExperienceHelper.prototype.enableTeleportation = function (vrTeleportationOptions) {
        if (vrTeleportationOptions === void 0) { vrTeleportationOptions = {}; }
        if (!this._teleportationInitialized) {
            this._teleportationRequested = true;
            this.enableInteractions();
            if (vrTeleportationOptions.floorMeshName) {
                this._floorMeshName = vrTeleportationOptions.floorMeshName;
            }
            if (vrTeleportationOptions.floorMeshes) {
                this._floorMeshesCollection = vrTeleportationOptions.floorMeshes;
            }
            if (this._leftController != null) {
                this._enableTeleportationOnController(this._leftController);
            }
            if (this._rightController != null) {
                this._enableTeleportationOnController(this._rightController);
            }
            // Creates an image processing post process for the vignette not relying
            // on the main scene configuration for image processing to reduce setup and spaces
            // (gamma/linear) conflicts.
            var imageProcessingConfiguration = new _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_17__["ImageProcessingConfiguration"]();
            imageProcessingConfiguration.vignetteColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color4"](0, 0, 0, 0);
            imageProcessingConfiguration.vignetteEnabled = true;
            this._postProcessMove = new _PostProcesses_imageProcessingPostProcess__WEBPACK_IMPORTED_MODULE_20__["ImageProcessingPostProcess"]("postProcessMove", 1.0, this._webVRCamera, undefined, undefined, undefined, undefined, imageProcessingConfiguration);
            this._webVRCamera.detachPostProcess(this._postProcessMove);
            this._teleportationInitialized = true;
            if (this._isDefaultTeleportationTarget) {
                this._createTeleportationCircles();
                this._teleportationTarget.scaling.scaleInPlace(this._webVRCamera.deviceScaleFactor);
            }
        }
    };
    VRExperienceHelper.prototype._enableInteractionOnController = function (controller) {
        var _this = this;
        var controllerMesh = controller.webVRController.mesh;
        if (controllerMesh) {
            controller._interactionsEnabled = true;
            if (this.isInVRMode && this._displayLaserPointer) {
                controller._activatePointer();
            }
            if (this.webVROptions.laserToggle) {
                controller.webVRController.onMainButtonStateChangedObservable.add(function (stateObject) {
                    // Enabling / disabling laserPointer
                    if (_this._displayLaserPointer && stateObject.value === 1) {
                        if (controller._activePointer) {
                            controller._deactivatePointer();
                        }
                        else {
                            controller._activatePointer();
                        }
                        if (_this.displayGaze) {
                            controller._gazeTracker.isVisible = controller._activePointer;
                        }
                    }
                });
            }
            controller.webVRController.onTriggerStateChangedObservable.add(function (stateObject) {
                var gazer = controller;
                if (_this._noControllerIsActive) {
                    gazer = _this._cameraGazer;
                }
                if (!gazer._pointerDownOnMeshAsked) {
                    if (stateObject.value > _this._padSensibilityUp) {
                        gazer._selectionPointerDown();
                    }
                }
                else if (stateObject.value < _this._padSensibilityDown) {
                    gazer._selectionPointerUp();
                }
            });
        }
    };
    VRExperienceHelper.prototype._checkTeleportWithRay = function (stateObject, gazer) {
        // Dont teleport if another gaze already requested teleportation
        if (this._teleportationRequestInitiated && !gazer._teleportationRequestInitiated) {
            return;
        }
        if (!gazer._teleportationRequestInitiated) {
            if (stateObject.y < -this._padSensibilityUp && gazer._dpadPressed) {
                gazer._activatePointer();
                gazer._teleportationRequestInitiated = true;
            }
        }
        else {
            // Listening to the proper controller values changes to confirm teleportation
            if (Math.sqrt(stateObject.y * stateObject.y + stateObject.x * stateObject.x) < this._padSensibilityDown) {
                if (this._teleportActive) {
                    this.teleportCamera(this._haloCenter);
                }
                gazer._teleportationRequestInitiated = false;
            }
        }
    };
    VRExperienceHelper.prototype._checkRotate = function (stateObject, gazer) {
        // Only rotate when user is not currently selecting a teleportation location
        if (gazer._teleportationRequestInitiated) {
            return;
        }
        if (!gazer._rotationLeftAsked) {
            if (stateObject.x < -this._padSensibilityUp && gazer._dpadPressed) {
                gazer._rotationLeftAsked = true;
                if (this._rotationAllowed) {
                    this._rotateCamera(false);
                }
            }
        }
        else {
            if (stateObject.x > -this._padSensibilityDown) {
                gazer._rotationLeftAsked = false;
            }
        }
        if (!gazer._rotationRightAsked) {
            if (stateObject.x > this._padSensibilityUp && gazer._dpadPressed) {
                gazer._rotationRightAsked = true;
                if (this._rotationAllowed) {
                    this._rotateCamera(true);
                }
            }
        }
        else {
            if (stateObject.x < this._padSensibilityDown) {
                gazer._rotationRightAsked = false;
            }
        }
    };
    VRExperienceHelper.prototype._checkTeleportBackwards = function (stateObject, gazer) {
        // Only teleport backwards when user is not currently selecting a teleportation location
        if (gazer._teleportationRequestInitiated) {
            return;
        }
        // Teleport backwards
        if (stateObject.y > this._padSensibilityUp && gazer._dpadPressed) {
            if (!gazer._teleportationBackRequestInitiated) {
                if (!this.currentVRCamera) {
                    return;
                }
                // Get rotation and position of the current camera
                var rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].FromRotationMatrix(this.currentVRCamera.getWorldMatrix().getRotationMatrix());
                var position = this.currentVRCamera.position;
                // If the camera has device position, use that instead
                if (this.currentVRCamera.devicePosition && this.currentVRCamera.deviceRotationQuaternion) {
                    rotation = this.currentVRCamera.deviceRotationQuaternion;
                    position = this.currentVRCamera.devicePosition;
                }
                // Get matrix with only the y rotation of the device rotation
                rotation.toEulerAnglesToRef(this._workingVector);
                this._workingVector.z = 0;
                this._workingVector.x = 0;
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].RotationYawPitchRollToRef(this._workingVector.y, this._workingVector.x, this._workingVector.z, this._workingQuaternion);
                this._workingQuaternion.toRotationMatrix(this._workingMatrix);
                // Rotate backwards ray by device rotation to cast at the ground behind the user
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].TransformCoordinatesToRef(this._teleportBackwardsVector, this._workingMatrix, this._workingVector);
                // Teleport if ray hit the ground and is not to far away eg. backwards off a cliff
                var ray = new _Culling_ray__WEBPACK_IMPORTED_MODULE_16__["Ray"](position, this._workingVector);
                var hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);
                if (hit && hit.pickedPoint && hit.pickedMesh && this._isTeleportationFloor(hit.pickedMesh) && hit.distance < 5) {
                    this.teleportCamera(hit.pickedPoint);
                }
                gazer._teleportationBackRequestInitiated = true;
            }
        }
        else {
            gazer._teleportationBackRequestInitiated = false;
        }
    };
    VRExperienceHelper.prototype._enableTeleportationOnController = function (controller) {
        var _this = this;
        var controllerMesh = controller.webVRController.mesh;
        if (controllerMesh) {
            if (!controller._interactionsEnabled) {
                this._enableInteractionOnController(controller);
            }
            controller._interactionsEnabled = true;
            controller._teleportationEnabled = true;
            if (controller.webVRController.controllerType === _Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_12__["PoseEnabledControllerType"].VIVE) {
                controller._dpadPressed = false;
                controller.webVRController.onPadStateChangedObservable.add(function (stateObject) {
                    controller._dpadPressed = stateObject.pressed;
                    if (!controller._dpadPressed) {
                        controller._rotationLeftAsked = false;
                        controller._rotationRightAsked = false;
                        controller._teleportationBackRequestInitiated = false;
                    }
                });
            }
            controller.webVRController.onPadValuesChangedObservable.add(function (stateObject) {
                if (_this.teleportationEnabled) {
                    _this._checkTeleportBackwards(stateObject, controller);
                    _this._checkTeleportWithRay(stateObject, controller);
                }
                _this._checkRotate(stateObject, controller);
            });
        }
    };
    VRExperienceHelper.prototype._createTeleportationCircles = function () {
        this._teleportationTarget = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__["Mesh"].CreateGround("teleportationTarget", 2, 2, 2, this._scene);
        this._teleportationTarget.isPickable = false;
        var length = 512;
        var dynamicTexture = new _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_19__["DynamicTexture"]("DynamicTexture", length, this._scene, true);
        dynamicTexture.hasAlpha = true;
        var context = dynamicTexture.getContext();
        var centerX = length / 2;
        var centerY = length / 2;
        var radius = 200;
        context.beginPath();
        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
        context.fillStyle = this._teleportationFillColor;
        context.fill();
        context.lineWidth = 10;
        context.strokeStyle = this._teleportationBorderColor;
        context.stroke();
        context.closePath();
        dynamicTexture.update();
        var teleportationCircleMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_18__["StandardMaterial"]("TextPlaneMaterial", this._scene);
        teleportationCircleMaterial.diffuseTexture = dynamicTexture;
        this._teleportationTarget.material = teleportationCircleMaterial;
        var torus = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_15__["Mesh"].CreateTorus("torusTeleportation", 0.75, 0.1, 25, this._scene, false);
        torus.isPickable = false;
        torus.parent = this._teleportationTarget;
        var animationInnerCircle = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationInnerCircle", "position.y", 30, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_FLOAT, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CYCLE);
        var keys = [];
        keys.push({
            frame: 0,
            value: 0
        });
        keys.push({
            frame: 30,
            value: 0.4
        });
        keys.push({
            frame: 60,
            value: 0
        });
        animationInnerCircle.setKeys(keys);
        var easingFunction = new _Animations_easing__WEBPACK_IMPORTED_MODULE_21__["SineEase"]();
        easingFunction.setEasingMode(_Animations_easing__WEBPACK_IMPORTED_MODULE_21__["EasingFunction"].EASINGMODE_EASEINOUT);
        animationInnerCircle.setEasingFunction(easingFunction);
        torus.animations = [];
        torus.animations.push(animationInnerCircle);
        this._scene.beginAnimation(torus, 0, 60, true);
        this._hideTeleportationTarget();
    };
    VRExperienceHelper.prototype._displayTeleportationTarget = function () {
        this._teleportActive = true;
        if (this._teleportationInitialized) {
            this._teleportationTarget.isVisible = true;
            if (this._isDefaultTeleportationTarget) {
                this._teleportationTarget.getChildren()[0].isVisible = true;
            }
        }
    };
    VRExperienceHelper.prototype._hideTeleportationTarget = function () {
        this._teleportActive = false;
        if (this._teleportationInitialized) {
            this._teleportationTarget.isVisible = false;
            if (this._isDefaultTeleportationTarget) {
                this._teleportationTarget.getChildren()[0].isVisible = false;
            }
        }
    };
    VRExperienceHelper.prototype._rotateCamera = function (right) {
        var _this = this;
        if (!(this.currentVRCamera instanceof _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_3__["FreeCamera"])) {
            return;
        }
        if (right) {
            this._rotationAngle++;
        }
        else {
            this._rotationAngle--;
        }
        this.currentVRCamera.animations = [];
        var target = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Quaternion"].FromRotationMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Matrix"].RotationY(Math.PI / 4 * this._rotationAngle));
        var animationRotation = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationRotation", "rotationQuaternion", 90, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_QUATERNION, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        var animationRotationKeys = [];
        animationRotationKeys.push({
            frame: 0,
            value: this.currentVRCamera.rotationQuaternion
        });
        animationRotationKeys.push({
            frame: 6,
            value: target
        });
        animationRotation.setKeys(animationRotationKeys);
        animationRotation.setEasingFunction(this._circleEase);
        this.currentVRCamera.animations.push(animationRotation);
        this._postProcessMove.animations = [];
        var animationPP = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationPP", "vignetteWeight", 90, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_FLOAT, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        var vignetteWeightKeys = [];
        vignetteWeightKeys.push({
            frame: 0,
            value: 0
        });
        vignetteWeightKeys.push({
            frame: 3,
            value: 4
        });
        vignetteWeightKeys.push({
            frame: 6,
            value: 0
        });
        animationPP.setKeys(vignetteWeightKeys);
        animationPP.setEasingFunction(this._circleEase);
        this._postProcessMove.animations.push(animationPP);
        var animationPP2 = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationPP2", "vignetteStretch", 90, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_FLOAT, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        var vignetteStretchKeys = [];
        vignetteStretchKeys.push({
            frame: 0,
            value: 0
        });
        vignetteStretchKeys.push({
            frame: 3,
            value: 10
        });
        vignetteStretchKeys.push({
            frame: 6,
            value: 0
        });
        animationPP2.setKeys(vignetteStretchKeys);
        animationPP2.setEasingFunction(this._circleEase);
        this._postProcessMove.animations.push(animationPP2);
        this._postProcessMove.imageProcessingConfiguration.vignetteWeight = 0;
        this._postProcessMove.imageProcessingConfiguration.vignetteStretch = 0;
        this._postProcessMove.samples = 4;
        this._webVRCamera.attachPostProcess(this._postProcessMove);
        this._scene.beginAnimation(this._postProcessMove, 0, 6, false, 1, function () {
            _this._webVRCamera.detachPostProcess(_this._postProcessMove);
        });
        this._scene.beginAnimation(this.currentVRCamera, 0, 6, false, 1);
    };
    VRExperienceHelper.prototype._moveTeleportationSelectorTo = function (hit, gazer, ray) {
        if (hit.pickedPoint) {
            if (gazer._teleportationRequestInitiated) {
                this._displayTeleportationTarget();
                this._haloCenter.copyFrom(hit.pickedPoint);
                this._teleportationTarget.position.copyFrom(hit.pickedPoint);
            }
            var pickNormal = this._convertNormalToDirectionOfRay(hit.getNormal(true, false), ray);
            if (pickNormal) {
                var axis1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Cross(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_29__["Axis"].Y, pickNormal);
                var axis2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Cross(pickNormal, axis1);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].RotationFromAxisToRef(axis2, pickNormal, axis1, this._teleportationTarget.rotation);
            }
            this._teleportationTarget.position.y += 0.1;
        }
    };
    /**
     * Teleports the users feet to the desired location
     * @param location The location where the user's feet should be placed
     */
    VRExperienceHelper.prototype.teleportCamera = function (location) {
        var _this = this;
        if (!(this.currentVRCamera instanceof _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_3__["FreeCamera"])) {
            return;
        }
        // Teleport the hmd to where the user is looking by moving the anchor to where they are looking minus the
        // offset of the headset from the anchor.
        if (this.webVRCamera.leftCamera) {
            this._workingVector.copyFrom(this.webVRCamera.leftCamera.globalPosition);
            this._workingVector.subtractInPlace(this.webVRCamera.position);
            location.subtractToRef(this._workingVector, this._workingVector);
        }
        else {
            this._workingVector.copyFrom(location);
        }
        // Add height to account for user's height offset
        if (this.isInVRMode) {
            this._workingVector.y += this.webVRCamera.deviceDistanceToRoomGround() * this._webVRCamera.deviceScaleFactor;
        }
        else {
            this._workingVector.y += this._defaultHeight;
        }
        this.onBeforeCameraTeleport.notifyObservers(this._workingVector);
        // Create animation from the camera's position to the new location
        this.currentVRCamera.animations = [];
        var animationCameraTeleportation = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationCameraTeleportation", "position", 90, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_VECTOR3, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        var animationCameraTeleportationKeys = [{
                frame: 0,
                value: this.currentVRCamera.position
            },
            {
                frame: 11,
                value: this._workingVector
            }
        ];
        animationCameraTeleportation.setKeys(animationCameraTeleportationKeys);
        animationCameraTeleportation.setEasingFunction(this._circleEase);
        this.currentVRCamera.animations.push(animationCameraTeleportation);
        this._postProcessMove.animations = [];
        var animationPP = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationPP", "vignetteWeight", 90, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_FLOAT, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        var vignetteWeightKeys = [];
        vignetteWeightKeys.push({
            frame: 0,
            value: 0
        });
        vignetteWeightKeys.push({
            frame: 5,
            value: 8
        });
        vignetteWeightKeys.push({
            frame: 11,
            value: 0
        });
        animationPP.setKeys(vignetteWeightKeys);
        this._postProcessMove.animations.push(animationPP);
        var animationPP2 = new _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"]("animationPP2", "vignetteStretch", 90, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONTYPE_FLOAT, _Animations_animation__WEBPACK_IMPORTED_MODULE_22__["Animation"].ANIMATIONLOOPMODE_CONSTANT);
        var vignetteStretchKeys = [];
        vignetteStretchKeys.push({
            frame: 0,
            value: 0
        });
        vignetteStretchKeys.push({
            frame: 5,
            value: 10
        });
        vignetteStretchKeys.push({
            frame: 11,
            value: 0
        });
        animationPP2.setKeys(vignetteStretchKeys);
        this._postProcessMove.animations.push(animationPP2);
        this._postProcessMove.imageProcessingConfiguration.vignetteWeight = 0;
        this._postProcessMove.imageProcessingConfiguration.vignetteStretch = 0;
        this._webVRCamera.attachPostProcess(this._postProcessMove);
        this._scene.beginAnimation(this._postProcessMove, 0, 11, false, 1, function () {
            _this._webVRCamera.detachPostProcess(_this._postProcessMove);
        });
        this._scene.beginAnimation(this.currentVRCamera, 0, 11, false, 1, function () {
            _this.onAfterCameraTeleport.notifyObservers(_this._workingVector);
        });
        this._hideTeleportationTarget();
    };
    VRExperienceHelper.prototype._convertNormalToDirectionOfRay = function (normal, ray) {
        if (normal) {
            var angle = Math.acos(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Dot(normal, ray.direction));
            if (angle < Math.PI / 2) {
                normal.scaleInPlace(-1);
            }
        }
        return normal;
    };
    VRExperienceHelper.prototype._castRayAndSelectObject = function (gazer) {
        if (!(this.currentVRCamera instanceof _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_3__["FreeCamera"])) {
            return;
        }
        var ray = gazer._getForwardRay(this._rayLength);
        var hit = this._scene.pickWithRay(ray, this._raySelectionPredicate);
        if (hit) {
            // Populate the controllers mesh that can be used for drag/drop
            if (gazer._laserPointer) {
                hit.originMesh = gazer._laserPointer.parent;
            }
            this._scene.simulatePointerMove(hit, { pointerId: gazer._id });
        }
        gazer._currentHit = hit;
        // Moving the gazeTracker on the mesh face targetted
        if (hit && hit.pickedPoint) {
            if (this._displayGaze) {
                var multiplier = 1;
                gazer._gazeTracker.isVisible = true;
                if (gazer._isActionableMesh) {
                    multiplier = 3;
                }
                if (this.updateGazeTrackerScale) {
                    gazer._gazeTracker.scaling.x = hit.distance * multiplier;
                    gazer._gazeTracker.scaling.y = hit.distance * multiplier;
                    gazer._gazeTracker.scaling.z = hit.distance * multiplier;
                }
                var pickNormal = this._convertNormalToDirectionOfRay(hit.getNormal(), ray);
                // To avoid z-fighting
                var deltaFighting = 0.002;
                if (pickNormal) {
                    var axis1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Cross(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_29__["Axis"].Y, pickNormal);
                    var axis2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].Cross(pickNormal, axis1);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_9__["Vector3"].RotationFromAxisToRef(axis2, pickNormal, axis1, gazer._gazeTracker.rotation);
                }
                gazer._gazeTracker.position.copyFrom(hit.pickedPoint);
                if (gazer._gazeTracker.position.x < 0) {
                    gazer._gazeTracker.position.x += deltaFighting;
                }
                else {
                    gazer._gazeTracker.position.x -= deltaFighting;
                }
                if (gazer._gazeTracker.position.y < 0) {
                    gazer._gazeTracker.position.y += deltaFighting;
                }
                else {
                    gazer._gazeTracker.position.y -= deltaFighting;
                }
                if (gazer._gazeTracker.position.z < 0) {
                    gazer._gazeTracker.position.z += deltaFighting;
                }
                else {
                    gazer._gazeTracker.position.z -= deltaFighting;
                }
            }
            // Changing the size of the laser pointer based on the distance from the targetted point
            gazer._updatePointerDistance(hit.distance);
        }
        else {
            gazer._updatePointerDistance();
            gazer._gazeTracker.isVisible = false;
        }
        if (hit && hit.pickedMesh) {
            // The object selected is the floor, we're in a teleportation scenario
            if (this._teleportationInitialized && this._isTeleportationFloor(hit.pickedMesh) && hit.pickedPoint) {
                // Moving the teleportation area to this targetted point
                //Raise onSelectedMeshUnselected observable if ray collided floor mesh/meshes and a non floor mesh was previously selected
                if (gazer._currentMeshSelected && !this._isTeleportationFloor(gazer._currentMeshSelected)) {
                    this._notifySelectedMeshUnselected(gazer._currentMeshSelected);
                }
                gazer._currentMeshSelected = null;
                if (gazer._teleportationRequestInitiated) {
                    this._moveTeleportationSelectorTo(hit, gazer, ray);
                }
                return;
            }
            // If not, we're in a selection scenario
            //this._teleportationAllowed = false;
            if (hit.pickedMesh !== gazer._currentMeshSelected) {
                if (this.meshSelectionPredicate(hit.pickedMesh)) {
                    this.onNewMeshPicked.notifyObservers(hit);
                    gazer._currentMeshSelected = hit.pickedMesh;
                    if (hit.pickedMesh.isPickable && hit.pickedMesh.actionManager) {
                        this.changeGazeColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0, 0, 1));
                        this.changeLaserColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.2, 0.2, 1));
                        gazer._isActionableMesh = true;
                    }
                    else {
                        this.changeGazeColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7));
                        this.changeLaserColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7));
                        gazer._isActionableMesh = false;
                    }
                    try {
                        this.onNewMeshSelected.notifyObservers(hit.pickedMesh);
                        var gazerAsControllerGazer = gazer;
                        if (gazerAsControllerGazer.webVRController) {
                            this.onMeshSelectedWithController.notifyObservers({ mesh: hit.pickedMesh, controller: gazerAsControllerGazer.webVRController });
                        }
                    }
                    catch (err) {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Error while raising onNewMeshSelected or onMeshSelectedWithController: " + err);
                    }
                }
                else {
                    this._notifySelectedMeshUnselected(gazer._currentMeshSelected);
                    gazer._currentMeshSelected = null;
                    this.changeGazeColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7));
                    this.changeLaserColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7));
                }
            }
        }
        else {
            this._notifySelectedMeshUnselected(gazer._currentMeshSelected);
            gazer._currentMeshSelected = null;
            //this._teleportationAllowed = false;
            this.changeGazeColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7));
            this.changeLaserColor(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.7, 0.7, 0.7));
        }
    };
    VRExperienceHelper.prototype._notifySelectedMeshUnselected = function (mesh) {
        if (mesh) {
            this.onSelectedMeshUnselected.notifyObservers(mesh);
        }
    };
    /**
     * Sets the color of the laser ray from the vr controllers.
     * @param color new color for the ray.
     */
    VRExperienceHelper.prototype.changeLaserColor = function (color) {
        if (this._leftController) {
            this._leftController._setLaserPointerColor(color);
        }
        if (this._rightController) {
            this._rightController._setLaserPointerColor(color);
        }
    };
    /**
     * Sets the color of the ray from the vr headsets gaze.
     * @param color new color for the ray.
     */
    VRExperienceHelper.prototype.changeGazeColor = function (color) {
        if (!this.updateGazeTrackerColor) {
            return;
        }
        if (!this._cameraGazer._gazeTracker.material) {
            return;
        }
        this._cameraGazer._gazeTracker.material.emissiveColor = color;
        if (this._leftController) {
            this._leftController._gazeTracker.material.emissiveColor = color;
        }
        if (this._rightController) {
            this._rightController._gazeTracker.material.emissiveColor = color;
        }
    };
    /**
     * Exits VR and disposes of the vr experience helper
     */
    VRExperienceHelper.prototype.dispose = function () {
        if (this.isInVRMode) {
            this.exitVR();
        }
        if (this._postProcessMove) {
            this._postProcessMove.dispose();
        }
        if (this._webVRCamera) {
            this._webVRCamera.dispose();
        }
        if (this._vrDeviceOrientationCamera) {
            this._vrDeviceOrientationCamera.dispose();
        }
        if (!this._useCustomVRButton && this._btnVR && this._btnVR.parentNode) {
            document.body.removeChild(this._btnVR);
        }
        if (this._deviceOrientationCamera && (this._scene.activeCamera != this._deviceOrientationCamera)) {
            this._deviceOrientationCamera.dispose();
        }
        if (this._cameraGazer) {
            this._cameraGazer.dispose();
        }
        if (this._leftController) {
            this._leftController.dispose();
        }
        if (this._rightController) {
            this._rightController.dispose();
        }
        if (this._teleportationTarget) {
            this._teleportationTarget.dispose();
        }
        this._floorMeshesCollection = [];
        document.removeEventListener("keydown", this._onKeyDown);
        window.removeEventListener('vrdisplaypresentchange', this._onVrDisplayPresentChange);
        window.removeEventListener("resize", this._onResize);
        document.removeEventListener("fullscreenchange", this._onFullscreenChange);
        document.removeEventListener("mozfullscreenchange", this._onFullscreenChange);
        document.removeEventListener("webkitfullscreenchange", this._onFullscreenChange);
        document.removeEventListener("msfullscreenchange", this._onFullscreenChange);
        document.onmsfullscreenchange = null;
        this._scene.getEngine().onVRDisplayChangedObservable.removeCallback(this._onVRDisplayChanged);
        this._scene.getEngine().onVRRequestPresentStart.removeCallback(this._onVRRequestPresentStart);
        this._scene.getEngine().onVRRequestPresentComplete.removeCallback(this._onVRRequestPresentComplete);
        window.removeEventListener('vrdisplaypresentchange', this._onVrDisplayPresentChange);
        this._scene.gamepadManager.onGamepadConnectedObservable.removeCallback(this._onNewGamepadConnected);
        this._scene.gamepadManager.onGamepadDisconnectedObservable.removeCallback(this._onNewGamepadDisconnected);
        this._scene.unregisterBeforeRender(this.beforeRender);
    };
    /**
     * Gets the name of the VRExperienceHelper class
     * @returns "VRExperienceHelper"
     */
    VRExperienceHelper.prototype.getClassName = function () {
        return "VRExperienceHelper";
    };
    return VRExperienceHelper;
}());



/***/ }),

/***/ "./Cameras/VR/webVRCamera.ts":
/*!***********************************!*\
  !*** ./Cameras/VR/webVRCamera.ts ***!
  \***********************************/
/*! exports provided: WebVRFreeCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebVRFreeCamera", function() { return WebVRFreeCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Gamepads/gamepad */ "./Gamepads/gamepad.ts");
/* harmony import */ var _Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Gamepads/Controllers/poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../node */ "./node.ts");
/* harmony import */ var _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Lights/hemisphericLight */ "./Lights/hemisphericLight.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _PostProcesses_vrMultiviewToSingleviewPostProcess__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../PostProcesses/vrMultiviewToSingleviewPostProcess */ "./PostProcesses/vrMultiviewToSingleviewPostProcess.ts");
/* harmony import */ var _RigModes_webVRRigMode__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../RigModes/webVRRigMode */ "./Cameras/RigModes/webVRRigMode.ts");
/* harmony import */ var _Engines_Extensions_engine_webVR__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../Engines/Extensions/engine.webVR */ "./Engines/Extensions/engine.webVR.ts");











// Side effect import to define the stereoscopic mode.

// Side effect import to add webvr support to engine

_node__WEBPACK_IMPORTED_MODULE_7__["Node"].AddNodeConstructor("WebVRFreeCamera", function (name, scene) {
    return function () { return new WebVRFreeCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero(), scene); };
});
_node__WEBPACK_IMPORTED_MODULE_7__["Node"].AddNodeConstructor("WebVRGamepadCamera", function (name, scene) {
    return function () { return new WebVRFreeCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero(), scene); };
});
/**
 * This represents a WebVR camera.
 * The WebVR camera is Babylon's simple interface to interaction with Windows Mixed Reality, HTC Vive and Oculus Rift.
 * @example http://doc.babylonjs.com/how_to/webvr_camera
 */
var WebVRFreeCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WebVRFreeCamera, _super);
    /**
     * Instantiates a WebVRFreeCamera.
     * @param name The name of the WebVRFreeCamera
     * @param position The starting anchor position for the camera
     * @param scene The scene the camera belongs to
     * @param webVROptions a set of customizable options for the webVRCamera
     */
    function WebVRFreeCamera(name, position, scene, webVROptions) {
        if (webVROptions === void 0) { webVROptions = {}; }
        var _this = _super.call(this, name, position, scene) || this;
        _this.webVROptions = webVROptions;
        /**
         * @hidden
         * The vrDisplay tied to the camera. See https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay
         */
        _this._vrDevice = null;
        /**
         * The rawPose of the vrDevice.
         */
        _this.rawPose = null;
        _this._specsVersion = "1.1";
        _this._attached = false;
        _this._descendants = [];
        // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
        _this._deviceRoomPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero();
        /** @hidden */
        _this._deviceRoomRotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].Identity();
        _this._standingMatrix = null;
        /**
         * Represents device position in babylon space.
         */
        _this.devicePosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero();
        /**
         * Represents device rotation in babylon space.
         */
        _this.deviceRotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].Identity();
        /**
         * The scale of the device to be used when translating from device space to babylon space.
         */
        _this.deviceScaleFactor = 1;
        _this._deviceToWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Identity();
        _this._worldToDevice = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Identity();
        /**
         * References to the webVR controllers for the vrDevice.
         */
        _this.controllers = [];
        /**
         * Emits an event when a controller is attached.
         */
        _this.onControllersAttachedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Emits an event when a controller's mesh has been loaded;
         */
        _this.onControllerMeshLoadedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Emits an event when the HMD's pose has been updated.
         */
        _this.onPoseUpdatedFromDeviceObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._poseSet = false;
        /**
         * If the rig cameras be used as parent instead of this camera.
         */
        _this.rigParenting = true;
        _this._defaultHeight = undefined;
        _this._htmlElementAttached = null;
        _this._detachIfAttached = function () {
            var vrDisplay = _this.getEngine().getVRDevice();
            if (vrDisplay && !vrDisplay.isPresenting && _this._htmlElementAttached) {
                _this.detachControl(_this._htmlElementAttached);
            }
        };
        _this._workingVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero();
        _this._oneVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].One();
        _this._workingMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Identity();
        _this._tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"]();
        _this._cache.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero();
        if (webVROptions.defaultHeight) {
            _this._defaultHeight = webVROptions.defaultHeight;
            _this.position.y = _this._defaultHeight;
        }
        _this.minZ = 0.1;
        //legacy support - the compensation boolean was removed.
        if (arguments.length === 5) {
            _this.webVROptions = arguments[4];
        }
        // default webVR options
        if (_this.webVROptions.trackPosition == undefined) {
            _this.webVROptions.trackPosition = true;
        }
        if (_this.webVROptions.controllerMeshes == undefined) {
            _this.webVROptions.controllerMeshes = true;
        }
        if (_this.webVROptions.defaultLightingOnControllers == undefined) {
            _this.webVROptions.defaultLightingOnControllers = true;
        }
        _this.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"]();
        if (_this.webVROptions && _this.webVROptions.positionScale) {
            _this.deviceScaleFactor = _this.webVROptions.positionScale;
        }
        //enable VR
        var engine = _this.getEngine();
        _this._onVREnabled = function (success) { if (success) {
            _this.initControllers();
        } };
        engine.onVRRequestPresentComplete.add(_this._onVREnabled);
        engine.initWebVR().add(function (event) {
            if (!event.vrDisplay || _this._vrDevice === event.vrDisplay) {
                return;
            }
            _this._vrDevice = event.vrDisplay;
            //reset the rig parameters.
            _this.setCameraRigMode(_Cameras_camera__WEBPACK_IMPORTED_MODULE_3__["Camera"].RIG_MODE_WEBVR, { parentCamera: _this, vrDisplay: _this._vrDevice, frameData: _this._frameData, specs: _this._specsVersion });
            if (_this._attached) {
                _this.getEngine().enableVR();
            }
        });
        if (typeof (VRFrameData) !== "undefined") {
            _this._frameData = new VRFrameData();
        }
        if (webVROptions.useMultiview) {
            if (!_this.getScene().getEngine().getCaps().multiview) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Warn("Multiview is not supported, falling back to standard rendering");
                _this._useMultiviewToSingleView = false;
            }
            else {
                _this._useMultiviewToSingleView = true;
                _this._rigPostProcess = new _PostProcesses_vrMultiviewToSingleviewPostProcess__WEBPACK_IMPORTED_MODULE_10__["VRMultiviewToSingleviewPostProcess"]("VRMultiviewToSingleview", _this, 1.0);
            }
        }
        /**
         * The idea behind the following lines:
         * objects that have the camera as parent should actually have the rig cameras as a parent.
         * BUT, each of those cameras has a different view matrix, which means that if we set the parent to the first rig camera,
         * the second will not show it correctly.
         *
         * To solve this - each object that has the camera as parent will be added to a protected array.
         * When the rig camera renders, it will take this array and set all of those to be its children.
         * This way, the right camera will be used as a parent, and the mesh will be rendered correctly.
         * Amazing!
         */
        scene.onBeforeCameraRenderObservable.add(function (camera) {
            if (camera.parent === _this && _this.rigParenting) {
                _this._descendants = _this.getDescendants(true, function (n) {
                    // don't take the cameras or the controllers!
                    var isController = _this.controllers.some(function (controller) { return controller._mesh === n; });
                    var isRigCamera = _this._rigCameras.indexOf(n) !== -1;
                    return !isController && !isRigCamera;
                });
                _this._descendants.forEach(function (node) {
                    node.parent = camera;
                });
            }
        });
        scene.onAfterCameraRenderObservable.add(function (camera) {
            if (camera.parent === _this && _this.rigParenting) {
                _this._descendants.forEach(function (node) {
                    node.parent = _this;
                });
            }
        });
        return _this;
    }
    /**
     * Gets the device distance from the ground in meters.
     * @returns the distance in meters from the vrDevice to ground in device space. If standing matrix is not supported for the vrDevice 0 is returned.
     */
    WebVRFreeCamera.prototype.deviceDistanceToRoomGround = function () {
        if (this._standingMatrix) {
            // Add standing matrix offset to get real offset from ground in room
            this._standingMatrix.getTranslationToRef(this._workingVector);
            return this._deviceRoomPosition.y + this._workingVector.y;
        }
        //If VRDisplay does not inform stage parameters and no default height is set we fallback to zero.
        return this._defaultHeight || 0;
    };
    /**
     * Enables the standing matrix when supported. This can be used to position the user's view the correct height from the ground.
     * @param callback will be called when the standing matrix is set. Callback parameter is if the standing matrix is supported.
     */
    WebVRFreeCamera.prototype.useStandingMatrix = function (callback) {
        var _this = this;
        if (callback === void 0) { callback = function (bool) { }; }
        // Use standing matrix if available
        this.getEngine().initWebVRAsync().then(function (result) {
            if (!result.vrDisplay || !result.vrDisplay.stageParameters || !result.vrDisplay.stageParameters.sittingToStandingTransform || !_this.webVROptions.trackPosition) {
                callback(false);
            }
            else {
                _this._standingMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"]();
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].FromFloat32ArrayToRefScaled(result.vrDisplay.stageParameters.sittingToStandingTransform, 0, 1, _this._standingMatrix);
                if (!_this.getScene().useRightHandedSystem) {
                    if (_this._standingMatrix) {
                        _this._standingMatrix.toggleModelMatrixHandInPlace();
                    }
                }
                callback(true);
            }
        });
    };
    /**
     * Enables the standing matrix when supported. This can be used to position the user's view the correct height from the ground.
     * @returns A promise with a boolean set to if the standing matrix is supported.
     */
    WebVRFreeCamera.prototype.useStandingMatrixAsync = function () {
        var _this = this;
        return new Promise(function (res) {
            _this.useStandingMatrix(function (supported) {
                res(supported);
            });
        });
    };
    /**
     * Disposes the camera
     */
    WebVRFreeCamera.prototype.dispose = function () {
        this._detachIfAttached();
        this.getEngine().onVRRequestPresentComplete.removeCallback(this._onVREnabled);
        if (this._updateCacheWhenTrackingDisabledObserver) {
            this._scene.onBeforeRenderObservable.remove(this._updateCacheWhenTrackingDisabledObserver);
        }
        _super.prototype.dispose.call(this);
    };
    /**
     * Gets a vrController by name.
     * @param name The name of the controller to retreive
     * @returns the controller matching the name specified or null if not found
     */
    WebVRFreeCamera.prototype.getControllerByName = function (name) {
        for (var _i = 0, _a = this.controllers; _i < _a.length; _i++) {
            var gp = _a[_i];
            if (gp.hand === name) {
                return gp;
            }
        }
        return null;
    };
    Object.defineProperty(WebVRFreeCamera.prototype, "leftController", {
        /**
         * The controller corresponding to the users left hand.
         */
        get: function () {
            if (!this._leftController) {
                this._leftController = this.getControllerByName("left");
            }
            return this._leftController;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebVRFreeCamera.prototype, "rightController", {
        /**
         * The controller corresponding to the users right hand.
         */
        get: function () {
            if (!this._rightController) {
                this._rightController = this.getControllerByName("right");
            }
            return this._rightController;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Casts a ray forward from the vrCamera's gaze.
     * @param length Length of the ray (default: 100)
     * @returns the ray corresponding to the gaze
     */
    WebVRFreeCamera.prototype.getForwardRay = function (length) {
        if (length === void 0) { length = 100; }
        if (this.leftCamera) {
            // Use left eye to avoid computation to compute center on every call
            return _super.prototype.getForwardRay.call(this, length, this.leftCamera.getWorldMatrix(), this.leftCamera.globalPosition); // Need the actual rendered camera
        }
        else {
            return _super.prototype.getForwardRay.call(this, length);
        }
    };
    /**
     * @hidden
     * Updates the camera based on device's frame data
     */
    WebVRFreeCamera.prototype._checkInputs = function () {
        if (this._vrDevice && this._vrDevice.isPresenting) {
            this._vrDevice.getFrameData(this._frameData);
            this.updateFromDevice(this._frameData.pose);
        }
        _super.prototype._checkInputs.call(this);
    };
    /**
     * Updates the poseControlled values based on the input device pose.
     * @param poseData Pose coming from the device
     */
    WebVRFreeCamera.prototype.updateFromDevice = function (poseData) {
        if (poseData && poseData.orientation && poseData.orientation.length === 4) {
            this.rawPose = poseData;
            this._deviceRoomRotationQuaternion.copyFromFloats(poseData.orientation[0], poseData.orientation[1], -poseData.orientation[2], -poseData.orientation[3]);
            if (this.getScene().useRightHandedSystem) {
                this._deviceRoomRotationQuaternion.z *= -1;
                this._deviceRoomRotationQuaternion.w *= -1;
            }
            if (this.webVROptions.trackPosition && this.rawPose.position) {
                this._deviceRoomPosition.copyFromFloats(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2]);
                if (this.getScene().useRightHandedSystem) {
                    this._deviceRoomPosition.z *= -1;
                }
            }
            this._poseSet = true;
        }
    };
    /**
     * WebVR's attach control will start broadcasting frames to the device.
     * Note that in certain browsers (chrome for example) this function must be called
     * within a user-interaction callback. Example:
     * <pre> scene.onPointerDown = function() { camera.attachControl(canvas); }</pre>
     *
     * @param element html element to attach the vrDevice to
     * @param noPreventDefault prevent the default html element operation when attaching the vrDevice
     */
    WebVRFreeCamera.prototype.attachControl = function (element, noPreventDefault) {
        _super.prototype.attachControl.call(this, element, noPreventDefault);
        this._attached = true;
        this._htmlElementAttached = element;
        noPreventDefault = _Cameras_camera__WEBPACK_IMPORTED_MODULE_3__["Camera"].ForceAttachControlToAlwaysPreventDefault ? false : noPreventDefault;
        if (this._vrDevice) {
            this.getEngine().enableVR();
        }
        var hostWindow = this._scene.getEngine().getHostWindow();
        hostWindow.addEventListener('vrdisplaypresentchange', this._detachIfAttached);
    };
    /**
     * Detaches the camera from the html element and disables VR
     *
     * @param element html element to detach from
     */
    WebVRFreeCamera.prototype.detachControl = function (element) {
        this.getScene().gamepadManager.onGamepadConnectedObservable.remove(this._onGamepadConnectedObserver);
        this.getScene().gamepadManager.onGamepadDisconnectedObservable.remove(this._onGamepadDisconnectedObserver);
        _super.prototype.detachControl.call(this, element);
        this._attached = false;
        this.getEngine().disableVR();
        window.removeEventListener('vrdisplaypresentchange', this._detachIfAttached);
    };
    /**
     * @returns the name of this class
     */
    WebVRFreeCamera.prototype.getClassName = function () {
        return "WebVRFreeCamera";
    };
    /**
     * Calls resetPose on the vrDisplay
     * See: https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay/resetPose
     */
    WebVRFreeCamera.prototype.resetToCurrentRotation = function () {
        //uses the vrDisplay's "resetPose()".
        //pitch and roll won't be affected.
        this._vrDevice.resetPose();
    };
    /**
     * @hidden
     * Updates the rig cameras (left and right eye)
     */
    WebVRFreeCamera.prototype._updateRigCameras = function () {
        var camLeft = this._rigCameras[0];
        var camRight = this._rigCameras[1];
        camLeft.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
        camRight.rotationQuaternion.copyFrom(this._deviceRoomRotationQuaternion);
        camLeft.position.copyFrom(this._deviceRoomPosition);
        camRight.position.copyFrom(this._deviceRoomPosition);
    };
    // Remove translation from 6dof headset if trackposition is set to false
    WebVRFreeCamera.prototype._correctPositionIfNotTrackPosition = function (matrix, isViewMatrix) {
        if (isViewMatrix === void 0) { isViewMatrix = false; }
        if (this.rawPose && this.rawPose.position && !this.webVROptions.trackPosition) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].TranslationToRef(this.rawPose.position[0], this.rawPose.position[1], -this.rawPose.position[2], this._tmpMatrix);
            if (!isViewMatrix) {
                this._tmpMatrix.invert();
            }
            this._tmpMatrix.multiplyToRef(matrix, matrix);
        }
    };
    /**
     * @hidden
     * Updates the cached values of the camera
     * @param ignoreParentClass ignores updating the parent class's cache (default: false)
     */
    WebVRFreeCamera.prototype._updateCache = function (ignoreParentClass) {
        var _this = this;
        if (!this.rotationQuaternion.equals(this._cache.rotationQuaternion) || !this.position.equals(this._cache.position)) {
            // Update to ensure devicePosition is up to date with most recent _deviceRoomPosition
            if (!this.updateCacheCalled) {
                // make sure it is only called once per loop. this.update() might cause an infinite loop.
                this.updateCacheCalled = true;
                this.update();
            }
            // Set working vector to the device position in room space rotated by the new rotation
            this.rotationQuaternion.toRotationMatrix(this._workingMatrix);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].TransformCoordinatesToRef(this._deviceRoomPosition, this._workingMatrix, this._workingVector);
            // Subtract this vector from the current device position in world to get the translation for the device world matrix
            this.devicePosition.subtractToRef(this._workingVector, this._workingVector);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].ComposeToRef(this._oneVector, this.rotationQuaternion, this._workingVector, this._deviceToWorld);
            // Add translation from anchor position
            this._deviceToWorld.getTranslationToRef(this._workingVector);
            this._workingVector.addInPlace(this.position);
            this._workingVector.subtractInPlace(this._cache.position);
            this._deviceToWorld.setTranslation(this._workingVector);
            // Set an inverted matrix to be used when updating the camera
            this._deviceToWorld.invertToRef(this._worldToDevice);
            // Update the gamepad to ensure the mesh is updated on the same frame as camera
            this.controllers.forEach(function (controller) {
                controller._deviceToWorld.copyFrom(_this._deviceToWorld);
                _this._correctPositionIfNotTrackPosition(controller._deviceToWorld);
                controller.update();
            });
        }
        if (!ignoreParentClass) {
            _super.prototype._updateCache.call(this);
        }
        this.updateCacheCalled = false;
    };
    /**
     * @hidden
     * Get current device position in babylon world
     */
    WebVRFreeCamera.prototype._computeDevicePosition = function () {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].TransformCoordinatesToRef(this._deviceRoomPosition, this._deviceToWorld, this.devicePosition);
    };
    /**
     * Updates the current device position and rotation in the babylon world
     */
    WebVRFreeCamera.prototype.update = function () {
        this._computeDevicePosition();
        // Get current device rotation in babylon world
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].FromQuaternionToRef(this._deviceRoomRotationQuaternion, this._workingMatrix);
        this._workingMatrix.multiplyToRef(this._deviceToWorld, this._workingMatrix);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Quaternion"].FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
        if (this._poseSet) {
            this.onPoseUpdatedFromDeviceObservable.notifyObservers(null);
        }
        _super.prototype.update.call(this);
    };
    /**
     * @hidden
     * Gets the view matrix of this camera (Always set to identity as left and right eye cameras contain the actual view matrix)
     * @returns an identity matrix
     */
    WebVRFreeCamera.prototype._getViewMatrix = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Identity();
    };
    /**
     * This function is called by the two RIG cameras.
     * 'this' is the left or right camera (and NOT (!!!) the WebVRFreeCamera instance)
     * @hidden
     */
    WebVRFreeCamera.prototype._getWebVRViewMatrix = function () {
        // Update the parent camera prior to using a child camera to avoid desynchronization
        var parentCamera = this._cameraRigParams["parentCamera"];
        parentCamera._updateCache();
        //WebVR 1.1
        var viewArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftViewMatrix : this._cameraRigParams["frameData"].rightViewMatrix;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].FromArrayToRef(viewArray, 0, this._webvrViewMatrix);
        if (!this.getScene().useRightHandedSystem) {
            this._webvrViewMatrix.toggleModelMatrixHandInPlace();
        }
        // update the camera rotation matrix
        this._webvrViewMatrix.getRotationMatrixToRef(this._cameraRotationMatrix);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
        // Computing target and final matrix
        this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
        // should the view matrix be updated with scale and position offset?
        if (parentCamera.deviceScaleFactor !== 1) {
            this._webvrViewMatrix.invert();
            // scale the position, if set
            if (parentCamera.deviceScaleFactor) {
                this._webvrViewMatrix.multiplyAtIndex(12, parentCamera.deviceScaleFactor);
                this._webvrViewMatrix.multiplyAtIndex(13, parentCamera.deviceScaleFactor);
                this._webvrViewMatrix.multiplyAtIndex(14, parentCamera.deviceScaleFactor);
            }
            this._webvrViewMatrix.invert();
        }
        // Remove translation from 6dof headset if trackposition is set to false
        parentCamera._correctPositionIfNotTrackPosition(this._webvrViewMatrix, true);
        parentCamera._worldToDevice.multiplyToRef(this._webvrViewMatrix, this._webvrViewMatrix);
        // Compute global position
        this._workingMatrix = this._workingMatrix || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Identity();
        this._webvrViewMatrix.invertToRef(this._workingMatrix);
        this._workingMatrix.multiplyToRef(parentCamera.getWorldMatrix(), this._workingMatrix);
        this._workingMatrix.getTranslationToRef(this._globalPosition);
        this._markSyncedWithParent();
        return this._webvrViewMatrix;
    };
    /** @hidden */
    WebVRFreeCamera.prototype._getWebVRProjectionMatrix = function () {
        var parentCamera = this.parent;
        parentCamera._vrDevice.depthNear = parentCamera.minZ;
        parentCamera._vrDevice.depthFar = parentCamera.maxZ;
        var projectionArray = this._cameraRigParams["left"] ? this._cameraRigParams["frameData"].leftProjectionMatrix : this._cameraRigParams["frameData"].rightProjectionMatrix;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].FromArrayToRef(projectionArray, 0, this._projectionMatrix);
        //babylon compatible matrix
        if (!this.getScene().useRightHandedSystem) {
            this._projectionMatrix.toggleProjectionMatrixHandInPlace();
        }
        return this._projectionMatrix;
    };
    /**
     * Initializes the controllers and their meshes
     */
    WebVRFreeCamera.prototype.initControllers = function () {
        var _this = this;
        this.controllers = [];
        var manager = this.getScene().gamepadManager;
        this._onGamepadDisconnectedObserver = manager.onGamepadDisconnectedObservable.add(function (gamepad) {
            if (gamepad.type === _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_5__["Gamepad"].POSE_ENABLED) {
                var webVrController = gamepad;
                if (webVrController.defaultModel) {
                    webVrController.defaultModel.setEnabled(false);
                }
                if (webVrController.hand === "right") {
                    _this._rightController = null;
                }
                if (webVrController.hand === "left") {
                    _this._leftController = null;
                }
                var controllerIndex = _this.controllers.indexOf(webVrController);
                if (controllerIndex !== -1) {
                    _this.controllers.splice(controllerIndex, 1);
                }
            }
        });
        this._onGamepadConnectedObserver = manager.onGamepadConnectedObservable.add(function (gamepad) {
            if (gamepad.type === _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_5__["Gamepad"].POSE_ENABLED) {
                var webVrController_1 = gamepad;
                if (!_this.webVROptions.trackPosition) {
                    webVrController_1._disableTrackPosition(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](webVrController_1.hand == "left" ? -0.15 : 0.15, -0.5, 0.25));
                    // Cache must be updated before rendering controllers to avoid them being one frame behind
                    if (!_this._updateCacheWhenTrackingDisabledObserver) {
                        _this._updateCacheWhenTrackingDisabledObserver = _this._scene.onBeforeRenderObservable.add(function () {
                            _this._updateCache();
                        });
                    }
                }
                webVrController_1.deviceScaleFactor = _this.deviceScaleFactor;
                webVrController_1._deviceToWorld.copyFrom(_this._deviceToWorld);
                _this._correctPositionIfNotTrackPosition(webVrController_1._deviceToWorld);
                if (_this.webVROptions.controllerMeshes) {
                    if (webVrController_1.defaultModel) {
                        webVrController_1.defaultModel.setEnabled(true);
                    }
                    else {
                        // Load the meshes
                        webVrController_1.initControllerMesh(_this.getScene(), function (loadedMesh) {
                            loadedMesh.scaling.scaleInPlace(_this.deviceScaleFactor);
                            _this.onControllerMeshLoadedObservable.notifyObservers(webVrController_1);
                            if (_this.webVROptions.defaultLightingOnControllers) {
                                if (!_this._lightOnControllers) {
                                    _this._lightOnControllers = new _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_8__["HemisphericLight"]("vrControllersLight", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](0, 1, 0), _this.getScene());
                                }
                                var activateLightOnSubMeshes_1 = function (mesh, light) {
                                    var children = mesh.getChildren();
                                    if (children && children.length !== 0) {
                                        children.forEach(function (mesh) {
                                            light.includedOnlyMeshes.push(mesh);
                                            activateLightOnSubMeshes_1(mesh, light);
                                        });
                                    }
                                };
                                _this._lightOnControllers.includedOnlyMeshes.push(loadedMesh);
                                activateLightOnSubMeshes_1(loadedMesh, _this._lightOnControllers);
                            }
                        });
                    }
                }
                webVrController_1.attachToPoseControlledCamera(_this);
                // since this is async - sanity check. Is the controller already stored?
                if (_this.controllers.indexOf(webVrController_1) === -1) {
                    //add to the controllers array
                    _this.controllers.push(webVrController_1);
                    // Forced to add some control code for Vive as it doesn't always fill properly the "hand" property
                    // Sometimes, both controllers are set correctly (left and right), sometimes none, sometimes only one of them...
                    // So we're overriding setting left & right manually to be sure
                    var firstViveWandDetected = false;
                    for (var i = 0; i < _this.controllers.length; i++) {
                        if (_this.controllers[i].controllerType === _Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_6__["PoseEnabledControllerType"].VIVE) {
                            if (!firstViveWandDetected) {
                                firstViveWandDetected = true;
                                _this.controllers[i].hand = "left";
                            }
                            else {
                                _this.controllers[i].hand = "right";
                            }
                        }
                    }
                    //did we find enough controllers? Great! let the developer know.
                    if (_this.controllers.length >= 2) {
                        _this.onControllersAttachedObservable.notifyObservers(_this.controllers);
                    }
                }
            }
        });
    };
    return WebVRFreeCamera;
}(_Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_2__["FreeCamera"]));



/***/ }),

/***/ "./Cameras/XR/index.ts":
/*!*****************************!*\
  !*** ./Cameras/XR/index.ts ***!
  \*****************************/
/*! exports provided: WebXRCamera, WebXREnterExitUIButton, WebXREnterExitUIOptions, WebXREnterExitUI, WebXRState, WebXRExperienceHelper, WebXRInput, WebXRControllerTeleportation, WebXRControllerPointerSelection, WebXRControllerModelLoader, WebXRController, WebXRManagedOutputCanvas, WebXRSessionManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _webXRCamera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./webXRCamera */ "./Cameras/XR/webXRCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRCamera", function() { return _webXRCamera__WEBPACK_IMPORTED_MODULE_0__["WebXRCamera"]; });

/* harmony import */ var _webXREnterExitUI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./webXREnterExitUI */ "./Cameras/XR/webXREnterExitUI.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIButton", function() { return _webXREnterExitUI__WEBPACK_IMPORTED_MODULE_1__["WebXREnterExitUIButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIOptions", function() { return _webXREnterExitUI__WEBPACK_IMPORTED_MODULE_1__["WebXREnterExitUIOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUI", function() { return _webXREnterExitUI__WEBPACK_IMPORTED_MODULE_1__["WebXREnterExitUI"]; });

/* harmony import */ var _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webXRExperienceHelper */ "./Cameras/XR/webXRExperienceHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRState", function() { return _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__["WebXRState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRExperienceHelper", function() { return _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__["WebXRExperienceHelper"]; });

/* harmony import */ var _webXRInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webXRInput */ "./Cameras/XR/webXRInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRInput", function() { return _webXRInput__WEBPACK_IMPORTED_MODULE_3__["WebXRInput"]; });

/* harmony import */ var _webXRControllerTeleportation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./webXRControllerTeleportation */ "./Cameras/XR/webXRControllerTeleportation.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerTeleportation", function() { return _webXRControllerTeleportation__WEBPACK_IMPORTED_MODULE_4__["WebXRControllerTeleportation"]; });

/* harmony import */ var _webXRControllerPointerSelection__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./webXRControllerPointerSelection */ "./Cameras/XR/webXRControllerPointerSelection.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerPointerSelection", function() { return _webXRControllerPointerSelection__WEBPACK_IMPORTED_MODULE_5__["WebXRControllerPointerSelection"]; });

/* harmony import */ var _webXRControllerModelLoader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./webXRControllerModelLoader */ "./Cameras/XR/webXRControllerModelLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerModelLoader", function() { return _webXRControllerModelLoader__WEBPACK_IMPORTED_MODULE_6__["WebXRControllerModelLoader"]; });

/* harmony import */ var _webXRController__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./webXRController */ "./Cameras/XR/webXRController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRController", function() { return _webXRController__WEBPACK_IMPORTED_MODULE_7__["WebXRController"]; });

/* harmony import */ var _webXRManagedOutputCanvas__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./webXRManagedOutputCanvas */ "./Cameras/XR/webXRManagedOutputCanvas.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRManagedOutputCanvas", function() { return _webXRManagedOutputCanvas__WEBPACK_IMPORTED_MODULE_8__["WebXRManagedOutputCanvas"]; });

/* harmony import */ var _webXRSessionManager__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./webXRSessionManager */ "./Cameras/XR/webXRSessionManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRSessionManager", function() { return _webXRSessionManager__WEBPACK_IMPORTED_MODULE_9__["WebXRSessionManager"]; });













/***/ }),

/***/ "./Cameras/XR/webXRCamera.ts":
/*!***********************************!*\
  !*** ./Cameras/XR/webXRCamera.ts ***!
  \***********************************/
/*! exports provided: WebXRCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRCamera", function() { return WebXRCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Cameras/freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Cameras_targetCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Cameras/targetCamera */ "./Cameras/targetCamera.ts");
/* harmony import */ var _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Maths/math.viewport */ "./Maths/math.viewport.ts");






/**
 * WebXR Camera which holds the views for the xrSession
 * @see https://doc.babylonjs.com/how_to/webxr
 */
var WebXRCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WebXRCamera, _super);
    /**
     * Creates a new webXRCamera, this should only be set at the camera after it has been updated by the xrSessionManager
     * @param name the name of the camera
     * @param scene the scene to add the camera to
     */
    function WebXRCamera(name, scene) {
        var _this = _super.call(this, name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), scene) || this;
        // Initial camera configuration
        _this.minZ = 0.1;
        _this.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]();
        _this.cameraRigMode = _Cameras_camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_CUSTOM;
        _this.updateUpVectorFromRotation = true;
        _this._updateNumberOfRigCameras(1);
        return _this;
    }
    WebXRCamera.prototype._updateNumberOfRigCameras = function (viewCount) {
        if (viewCount === void 0) { viewCount = 1; }
        while (this.rigCameras.length < viewCount) {
            var newCamera = new _Cameras_targetCamera__WEBPACK_IMPORTED_MODULE_4__["TargetCamera"]("view: " + this.rigCameras.length, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), this.getScene());
            newCamera.minZ = 0.1;
            newCamera.parent = this;
            newCamera.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]();
            newCamera.updateUpVectorFromRotation = true;
            this.rigCameras.push(newCamera);
        }
        while (this.rigCameras.length > viewCount) {
            var removedCamera = this.rigCameras.pop();
            if (removedCamera) {
                removedCamera.dispose();
            }
        }
    };
    /** @hidden */
    WebXRCamera.prototype._updateForDualEyeDebugging = function (pupilDistance) {
        if (pupilDistance === void 0) { pupilDistance = 0.01; }
        // Create initial camera rigs
        this._updateNumberOfRigCameras(2);
        this.rigCameras[0].viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_5__["Viewport"](0, 0, 0.5, 1.0);
        this.rigCameras[0].position.x = -pupilDistance / 2;
        this.rigCameras[0].outputRenderTarget = null;
        this.rigCameras[1].viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_5__["Viewport"](0.5, 0, 0.5, 1.0);
        this.rigCameras[1].position.x = pupilDistance / 2;
        this.rigCameras[1].outputRenderTarget = null;
    };
    /**
     * Updates the cameras position from the current pose information of the  XR session
     * @param xrSessionManager the session containing pose information
     * @returns true if the camera has been updated, false if the session did not contain pose or frame data
     */
    WebXRCamera.prototype.updateFromXRSessionManager = function (xrSessionManager) {
        var _this = this;
        // Ensure all frame data is available
        if (!xrSessionManager.currentFrame || !xrSessionManager.currentFrame.getViewerPose) {
            return false;
        }
        var pose = xrSessionManager.currentFrame.getViewerPose(xrSessionManager.referenceSpace);
        if (!pose || !pose.transform || !pose.transform.matrix) {
            return false;
        }
        // Update the parent cameras matrix
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromFloat32ArrayToRefScaled(pose.transform.matrix, 0, 1, WebXRCamera._TmpMatrix);
        if (!this._scene.useRightHandedSystem) {
            WebXRCamera._TmpMatrix.toggleModelMatrixHandInPlace();
        }
        WebXRCamera._TmpMatrix.getTranslationToRef(this.position);
        WebXRCamera._TmpMatrix.getRotationMatrixToRef(WebXRCamera._TmpMatrix);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].FromRotationMatrixToRef(WebXRCamera._TmpMatrix, this.rotationQuaternion);
        this.computeWorldMatrix();
        // Update camera rigs
        this._updateNumberOfRigCameras(pose.views.length);
        pose.views.forEach(function (view, i) {
            // Update view/projection matrix
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromFloat32ArrayToRefScaled(view.transform.matrix, 0, 1, _this.rigCameras[i]._computedViewMatrix);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromFloat32ArrayToRefScaled(view.projectionMatrix, 0, 1, _this.rigCameras[i]._projectionMatrix);
            if (!_this._scene.useRightHandedSystem) {
                _this.rigCameras[i]._computedViewMatrix.toggleModelMatrixHandInPlace();
                _this.rigCameras[i]._projectionMatrix.toggleProjectionMatrixHandInPlace();
            }
            // Update viewport
            if (xrSessionManager.session.renderState.baseLayer) {
                var viewport = xrSessionManager.session.renderState.baseLayer.getViewport(view);
                var width = xrSessionManager.session.renderState.baseLayer.framebufferWidth;
                var height = xrSessionManager.session.renderState.baseLayer.framebufferHeight;
                _this.rigCameras[i].viewport.width = viewport.width / width;
                _this.rigCameras[i].viewport.height = viewport.height / height;
                _this.rigCameras[i].viewport.x = viewport.x / width;
                _this.rigCameras[i].viewport.y = viewport.y / height;
            }
            // Set cameras to render to the session's render target
            _this.rigCameras[i].outputRenderTarget = xrSessionManager._sessionRenderTargetTexture;
        });
        return true;
    };
    WebXRCamera._TmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
    return WebXRCamera;
}(_Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_3__["FreeCamera"]));



/***/ }),

/***/ "./Cameras/XR/webXRController.ts":
/*!***************************************!*\
  !*** ./Cameras/XR/webXRController.ts ***!
  \***************************************/
/*! exports provided: WebXRController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRController", function() { return WebXRController; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");



/**
 * Represents an XR input
 */
var WebXRController = /** @class */ (function () {
    /**
     * Creates the controller
     * @see https://doc.babylonjs.com/how_to/webxr
     * @param scene the scene which the controller should be associated to
     * @param inputSource the underlying input source for the controller
     * @param parentContainer parent that the controller meshes should be children of
     */
    function WebXRController(scene,
    /** The underlying input source for the controller  */
    inputSource, parentContainer) {
        if (parentContainer === void 0) { parentContainer = null; }
        this.scene = scene;
        this.inputSource = inputSource;
        this.parentContainer = parentContainer;
        /**
         * Event that fires when the controller is removed/disposed
         */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this._tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        this._tmpQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        this._tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        this.pointer = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"]("controllerPointer", scene);
        if (parentContainer) {
            parentContainer.addChild(this.pointer);
        }
        if (this.inputSource.gripSpace) {
            this.grip = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"]("controllerGrip", this.scene);
            if (this.parentContainer) {
                this.parentContainer.addChild(this.grip);
            }
        }
    }
    /**
     * Updates the controller pose based on the given XRFrame
     * @param xrFrame xr frame to update the pose with
     * @param referenceSpace reference space to use
     */
    WebXRController.prototype.updateFromXRFrame = function (xrFrame, referenceSpace) {
        var pose = xrFrame.getPose(this.inputSource.targetRaySpace, referenceSpace);
        // Update the pointer mesh
        if (pose) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromFloat32ArrayToRefScaled(pose.transform.matrix, 0, 1, this._tmpMatrix);
            if (!this.pointer.getScene().useRightHandedSystem) {
                this._tmpMatrix.toggleModelMatrixHandInPlace();
            }
            if (!this.pointer.rotationQuaternion) {
                this.pointer.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
            }
            this._tmpMatrix.decompose(this.pointer.scaling, this.pointer.rotationQuaternion, this.pointer.position);
        }
        // Update the grip mesh if it exists
        if (this.inputSource.gripSpace && this.grip) {
            var pose_1 = xrFrame.getPose(this.inputSource.gripSpace, referenceSpace);
            if (pose_1) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromFloat32ArrayToRefScaled(pose_1.transform.matrix, 0, 1, this._tmpMatrix);
                if (!this.grip.getScene().useRightHandedSystem) {
                    this._tmpMatrix.toggleModelMatrixHandInPlace();
                }
                if (!this.grip.rotationQuaternion) {
                    this.grip.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
                }
                this._tmpMatrix.decompose(this.grip.scaling, this.grip.rotationQuaternion, this.grip.position);
            }
        }
    };
    /**
     * Gets a world space ray coming from the controller
     * @param result the resulting ray
     */
    WebXRController.prototype.getWorldPointerRayToRef = function (result) {
        // Force update to ensure picked point is synced with ray
        var worldMatrix = this.pointer.computeWorldMatrix(true);
        worldMatrix.decompose(undefined, this._tmpQuaternion, undefined);
        this._tmpVector.set(0, 0, 1);
        this._tmpVector.rotateByQuaternionToRef(this._tmpQuaternion, this._tmpVector);
        result.origin = this.pointer.absolutePosition;
        result.direction.copyFrom(this._tmpVector);
        result.length = 1000;
    };
    /**
     * Disposes of the object
     */
    WebXRController.prototype.dispose = function () {
        if (this.grip) {
            this.grip.dispose();
        }
        this.pointer.dispose();
        this.onDisposeObservable.notifyObservers({});
    };
    return WebXRController;
}());



/***/ }),

/***/ "./Cameras/XR/webXRControllerModelLoader.ts":
/*!**************************************************!*\
  !*** ./Cameras/XR/webXRControllerModelLoader.ts ***!
  \**************************************************/
/*! exports provided: WebXRControllerModelLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerModelLoader", function() { return WebXRControllerModelLoader; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Gamepads_Controllers_windowsMotionController__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Gamepads/Controllers/windowsMotionController */ "./Gamepads/Controllers/windowsMotionController.ts");
/* harmony import */ var _Gamepads_Controllers_oculusTouchController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Gamepads/Controllers/oculusTouchController */ "./Gamepads/Controllers/oculusTouchController.ts");
/* harmony import */ var _Gamepads_Controllers_viveController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Gamepads/Controllers/viveController */ "./Gamepads/Controllers/viveController.ts");




/**
 * Loads a controller model and adds it as a child of the WebXRControllers grip when the controller is created
 */
var WebXRControllerModelLoader = /** @class */ (function () {
    /**
     * Creates the WebXRControllerModelLoader
     * @param input xr input that creates the controllers
     */
    function WebXRControllerModelLoader(input) {
        input.onControllerAddedObservable.add(function (c) {
            if (c.inputSource.gamepad && c.inputSource.gamepad.id === "htc-vive") {
                var controllerModel_1 = new _Gamepads_Controllers_viveController__WEBPACK_IMPORTED_MODULE_3__["ViveController"](c.inputSource.gamepad);
                controllerModel_1.hand = c.inputSource.handedness;
                controllerModel_1.isXR = true;
                controllerModel_1.initControllerMesh(c.grip.getScene(), function (m) {
                    m.isPickable = false;
                    m.getChildMeshes(false).forEach(function (m) {
                        m.isPickable = false;
                    });
                    controllerModel_1.mesh.parent = c.grip;
                    controllerModel_1.mesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromEulerAngles(0, Math.PI, 0);
                });
            }
            else if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-touch") {
                var controllerModel_2 = new _Gamepads_Controllers_oculusTouchController__WEBPACK_IMPORTED_MODULE_2__["OculusTouchController"](c.inputSource.gamepad);
                controllerModel_2.hand = c.inputSource.handedness;
                controllerModel_2.isXR = true;
                controllerModel_2.initControllerMesh(c.grip.getScene(), function (m) {
                    controllerModel_2.mesh.parent = c.grip;
                    controllerModel_2.mesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromEulerAngles(0, Math.PI, 0);
                    controllerModel_2.mesh.position.y = 0.034;
                    controllerModel_2.mesh.position.z = 0.052;
                });
            }
            else if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-quest") {
                _Gamepads_Controllers_oculusTouchController__WEBPACK_IMPORTED_MODULE_2__["OculusTouchController"]._IsQuest = true;
                var controllerModel_3 = new _Gamepads_Controllers_oculusTouchController__WEBPACK_IMPORTED_MODULE_2__["OculusTouchController"](c.inputSource.gamepad);
                controllerModel_3.hand = c.inputSource.handedness;
                controllerModel_3.isXR = true;
                controllerModel_3.initControllerMesh(c.grip.getScene(), function (m) {
                    controllerModel_3.mesh.parent = c.grip;
                    controllerModel_3.mesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromEulerAngles(Math.PI / -4, Math.PI, 0);
                });
            }
            else {
                var controllerModel_4 = new _Gamepads_Controllers_windowsMotionController__WEBPACK_IMPORTED_MODULE_1__["WindowsMotionController"](c.inputSource.gamepad);
                controllerModel_4.hand = c.inputSource.handedness;
                controllerModel_4.isXR = true;
                controllerModel_4.initControllerMesh(c.grip.getScene(), function (m) {
                    controllerModel_4.mesh.parent = c.grip;
                    controllerModel_4.mesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromEulerAngles(0, Math.PI, 0);
                });
            }
        });
    }
    return WebXRControllerModelLoader;
}());



/***/ }),

/***/ "./Cameras/XR/webXRControllerPointerSelection.ts":
/*!*******************************************************!*\
  !*** ./Cameras/XR/webXRControllerPointerSelection.ts ***!
  \*******************************************************/
/*! exports provided: WebXRControllerPointerSelection */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerPointerSelection", function() { return WebXRControllerPointerSelection; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Maths/math.axis */ "./Maths/math.axis.ts");






/**
 * Handles pointer input automatically for the pointer of XR controllers
 */
var WebXRControllerPointerSelection = /** @class */ (function () {
    /**
     * Creates a WebXRControllerPointerSelection
     * @param input input manager to setup pointer selection
     */
    function WebXRControllerPointerSelection(input) {
        var _this = this;
        this._tmpRay = new _Culling_ray__WEBPACK_IMPORTED_MODULE_2__["Ray"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]());
        input.onControllerAddedObservable.add(function (controller) {
            var scene = controller.pointer.getScene();
            var laserPointer;
            var cursorMesh;
            var triggerDown = false;
            var id;
            id = WebXRControllerPointerSelection._idCounter++;
            // Create a laser pointer for the XR controller
            laserPointer = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateCylinder("laserPointer", 1, 0.0002, 0.004, 20, 1, scene, false);
            laserPointer.parent = controller.pointer;
            var laserPointerMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_3__["StandardMaterial"]("laserPointerMat", scene);
            laserPointerMaterial.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"](0.7, 0.7, 0.7);
            laserPointerMaterial.alpha = 0.6;
            laserPointer.material = laserPointerMaterial;
            laserPointer.rotation.x = Math.PI / 2;
            _this._updatePointerDistance(laserPointer, 1);
            laserPointer.isPickable = false;
            // Create a gaze tracker for the  XR controlelr
            cursorMesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateTorus("gazeTracker", 0.0035 * 3, 0.0025 * 3, 20, scene, false);
            cursorMesh.bakeCurrentTransformIntoVertices();
            cursorMesh.isPickable = false;
            cursorMesh.isVisible = false;
            var targetMat = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_3__["StandardMaterial"]("targetMat", scene);
            targetMat.specularColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Black();
            targetMat.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"](0.7, 0.7, 0.7);
            targetMat.backFaceCulling = false;
            cursorMesh.material = targetMat;
            var renderObserver = scene.onBeforeRenderObservable.add(function () {
                // Every frame check collisions/input
                controller.getWorldPointerRayToRef(_this._tmpRay);
                var pick = scene.pickWithRay(_this._tmpRay);
                if (pick) {
                    if (controller.inputSource.gamepad && controller.inputSource.gamepad.buttons[0] && controller.inputSource.gamepad.buttons[0].value > 0.7) {
                        if (!triggerDown) {
                            scene.simulatePointerDown(pick, { pointerId: id });
                        }
                        triggerDown = true;
                    }
                    else {
                        if (triggerDown) {
                            scene.simulatePointerUp(pick, { pointerId: id });
                        }
                        triggerDown = false;
                    }
                    scene.simulatePointerMove(pick, { pointerId: id });
                }
                if (pick && pick.pickedPoint && pick.hit) {
                    // Update laser state
                    _this._updatePointerDistance(laserPointer, pick.distance);
                    // Update cursor state
                    cursorMesh.position.copyFrom(pick.pickedPoint);
                    cursorMesh.scaling.x = Math.sqrt(pick.distance);
                    cursorMesh.scaling.y = Math.sqrt(pick.distance);
                    cursorMesh.scaling.z = Math.sqrt(pick.distance);
                    // To avoid z-fighting
                    var pickNormal = _this._convertNormalToDirectionOfRay(pick.getNormal(), _this._tmpRay);
                    var deltaFighting = 0.002;
                    cursorMesh.position.copyFrom(pick.pickedPoint);
                    if (pickNormal) {
                        var axis1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Y, pickNormal);
                        var axis2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(pickNormal, axis1);
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].RotationFromAxisToRef(axis2, pickNormal, axis1, cursorMesh.rotation);
                        cursorMesh.position.addInPlace(pickNormal.scale(deltaFighting));
                    }
                    cursorMesh.isVisible = true;
                }
                else {
                    cursorMesh.isVisible = false;
                }
            });
            controller.onDisposeObservable.addOnce(function () {
                laserPointer.dispose();
                cursorMesh.dispose();
                scene.onBeforeRenderObservable.remove(renderObserver);
            });
        });
    }
    WebXRControllerPointerSelection.prototype._convertNormalToDirectionOfRay = function (normal, ray) {
        if (normal) {
            var angle = Math.acos(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(normal, ray.direction));
            if (angle < Math.PI / 2) {
                normal.scaleInPlace(-1);
            }
        }
        return normal;
    };
    WebXRControllerPointerSelection.prototype._updatePointerDistance = function (_laserPointer, distance) {
        if (distance === void 0) { distance = 100; }
        _laserPointer.scaling.y = distance;
        _laserPointer.position.z = distance / 2;
    };
    WebXRControllerPointerSelection._idCounter = 0;
    return WebXRControllerPointerSelection;
}());



/***/ }),

/***/ "./Cameras/XR/webXRControllerTeleportation.ts":
/*!****************************************************!*\
  !*** ./Cameras/XR/webXRControllerTeleportation.ts ***!
  \****************************************************/
/*! exports provided: WebXRControllerTeleportation */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerTeleportation", function() { return WebXRControllerTeleportation; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/Textures/dynamicTexture */ "./Materials/Textures/dynamicTexture.ts");
/* harmony import */ var _Animations_easing__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Animations/easing */ "./Animations/easing.ts");
/* harmony import */ var _Animations_animation__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Animations/animation */ "./Animations/animation.ts");







/**
 * Enables teleportation
 */
var WebXRControllerTeleportation = /** @class */ (function () {
    /**
     * Creates a WebXRControllerTeleportation
     * @param input input manager to add teleportation to
     * @param floorMeshes floormeshes which can be teleported to
     */
    function WebXRControllerTeleportation(input, floorMeshes) {
        var _this = this;
        if (floorMeshes === void 0) { floorMeshes = []; }
        this._teleportationFillColor = "#444444";
        this._teleportationBorderColor = "#FFFFFF";
        this._tmpRay = new _Culling_ray__WEBPACK_IMPORTED_MODULE_2__["Ray"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]());
        this._tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
        input.onControllerAddedObservable.add(function (c) {
            var scene = c.pointer.getScene();
            var forwardReadyToTeleport = false;
            var backwardReadyToTeleport = false;
            var leftReadyToTeleport = false;
            var rightReadyToTeleport = false;
            // Teleport target abd it's animation
            var teleportationTarget = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateGround("teleportationTarget", 2, 2, 2, scene);
            teleportationTarget.isPickable = false;
            var length = 512;
            var dynamicTexture = new _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_4__["DynamicTexture"]("DynamicTexture", length, scene, true);
            dynamicTexture.hasAlpha = true;
            var context = dynamicTexture.getContext();
            var centerX = length / 2;
            var centerY = length / 2;
            var radius = 200;
            context.beginPath();
            context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            context.fillStyle = _this._teleportationFillColor;
            context.fill();
            context.lineWidth = 10;
            context.strokeStyle = _this._teleportationBorderColor;
            context.stroke();
            context.closePath();
            dynamicTexture.update();
            var teleportationCircleMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_3__["StandardMaterial"]("TextPlaneMaterial", scene);
            teleportationCircleMaterial.diffuseTexture = dynamicTexture;
            teleportationTarget.material = teleportationCircleMaterial;
            var torus = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateTorus("torusTeleportation", 0.75, 0.1, 25, scene, false);
            torus.isPickable = false;
            torus.parent = teleportationTarget;
            var animationInnerCircle = new _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"]("animationInnerCircle", "position.y", 30, _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONTYPE_FLOAT, _Animations_animation__WEBPACK_IMPORTED_MODULE_6__["Animation"].ANIMATIONLOOPMODE_CYCLE);
            var keys = [];
            keys.push({
                frame: 0,
                value: 0
            });
            keys.push({
                frame: 30,
                value: 0.4
            });
            keys.push({
                frame: 60,
                value: 0
            });
            animationInnerCircle.setKeys(keys);
            var easingFunction = new _Animations_easing__WEBPACK_IMPORTED_MODULE_5__["SineEase"]();
            easingFunction.setEasingMode(_Animations_easing__WEBPACK_IMPORTED_MODULE_5__["EasingFunction"].EASINGMODE_EASEINOUT);
            animationInnerCircle.setEasingFunction(easingFunction);
            torus.animations = [];
            torus.animations.push(animationInnerCircle);
            scene.beginAnimation(torus, 0, 60, true);
            // Handle user input on every frame
            var renderObserver = scene.onBeforeRenderObservable.add(function () {
                // Move the teleportationTarget to where the user is targetting to teleport to
                if (forwardReadyToTeleport) {
                    c.getWorldPointerRayToRef(_this._tmpRay);
                    var pick = scene.pickWithRay(_this._tmpRay, function (o) {
                        return floorMeshes.indexOf(o) !== -1;
                    });
                    if (pick && pick.pickedPoint) {
                        // To avoid z-fighting
                        teleportationTarget.position.copyFrom(pick.pickedPoint);
                        teleportationTarget.position.y += 0.002;
                    }
                    teleportationTarget.isVisible = true;
                    teleportationTarget.getChildren()[0].isVisible = true;
                }
                else {
                    teleportationTarget.isVisible = false;
                    teleportationTarget.getChildren()[0].isVisible = false;
                }
                if (c.inputSource.gamepad) {
                    if (c.inputSource.gamepad.axes[1] !== undefined) {
                        // Forward teleportation
                        if (c.inputSource.gamepad.axes[1] < -0.7) {
                            forwardReadyToTeleport = true;
                        }
                        else {
                            if (forwardReadyToTeleport) {
                                // Teleport the users feet to where they targetted
                                _this._tmpVector.copyFrom(teleportationTarget.position);
                                _this._tmpVector.y += input.baseExperience.camera.position.y;
                                input.baseExperience.setPositionOfCameraUsingContainer(_this._tmpVector);
                            }
                            forwardReadyToTeleport = false;
                        }
                        // Backward teleportation
                        if (c.inputSource.gamepad.axes[1] > 0.7) {
                            backwardReadyToTeleport = true;
                        }
                        else {
                            if (backwardReadyToTeleport) {
                                // Cast a ray down from behind the user
                                var camMat = input.baseExperience.camera.computeWorldMatrix();
                                var q = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"]();
                                camMat.decompose(undefined, q, _this._tmpRay.origin);
                                _this._tmpVector.set(0, 0, -1);
                                _this._tmpVector.rotateByQuaternionToRef(q, _this._tmpVector);
                                _this._tmpVector.y = 0;
                                _this._tmpVector.normalize();
                                _this._tmpVector.y = -1.5;
                                _this._tmpVector.normalize();
                                _this._tmpRay.direction.copyFrom(_this._tmpVector);
                                var pick = scene.pickWithRay(_this._tmpRay, function (o) {
                                    return floorMeshes.indexOf(o) !== -1;
                                });
                                if (pick && pick.pickedPoint) {
                                    // Teleport the users feet to where they targetted
                                    _this._tmpVector.copyFrom(pick.pickedPoint);
                                    _this._tmpVector.y += input.baseExperience.camera.position.y;
                                    input.baseExperience.setPositionOfCameraUsingContainer(_this._tmpVector);
                                }
                            }
                            backwardReadyToTeleport = false;
                        }
                    }
                    if (c.inputSource.gamepad.axes[0] !== undefined) {
                        if (c.inputSource.gamepad.axes[0] < -0.7) {
                            leftReadyToTeleport = true;
                        }
                        else {
                            if (leftReadyToTeleport) {
                                input.baseExperience.rotateCameraByQuaternionUsingContainer(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromEulerAngles(0, -Math.PI / 4, 0));
                            }
                            leftReadyToTeleport = false;
                        }
                        if (c.inputSource.gamepad.axes[0] > 0.7) {
                            rightReadyToTeleport = true;
                        }
                        else {
                            if (rightReadyToTeleport) {
                                input.baseExperience.rotateCameraByQuaternionUsingContainer(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromEulerAngles(0, Math.PI / 4, 0));
                            }
                            rightReadyToTeleport = false;
                        }
                    }
                }
            });
            c.onDisposeObservable.addOnce(function () {
                teleportationTarget.dispose();
                dynamicTexture.dispose();
                teleportationCircleMaterial.dispose();
                torus.dispose();
                scene.onBeforeRenderObservable.remove(renderObserver);
            });
        });
    }
    return WebXRControllerTeleportation;
}());



/***/ }),

/***/ "./Cameras/XR/webXRDefaultExperience.ts":
/*!**********************************************!*\
  !*** ./Cameras/XR/webXRDefaultExperience.ts ***!
  \**********************************************/
/*! exports provided: WebXRDefaultExperienceOptions, WebXRDefaultExperience */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRDefaultExperienceOptions", function() { return WebXRDefaultExperienceOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRDefaultExperience", function() { return WebXRDefaultExperience; });
/* harmony import */ var _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./webXRExperienceHelper */ "./Cameras/XR/webXRExperienceHelper.ts");
/* harmony import */ var _webXRInput__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./webXRInput */ "./Cameras/XR/webXRInput.ts");
/* harmony import */ var _webXRControllerModelLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webXRControllerModelLoader */ "./Cameras/XR/webXRControllerModelLoader.ts");
/* harmony import */ var _webXRControllerPointerSelection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webXRControllerPointerSelection */ "./Cameras/XR/webXRControllerPointerSelection.ts");
/* harmony import */ var _webXRControllerTeleportation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./webXRControllerTeleportation */ "./Cameras/XR/webXRControllerTeleportation.ts");
/* harmony import */ var _webXRManagedOutputCanvas__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./webXRManagedOutputCanvas */ "./Cameras/XR/webXRManagedOutputCanvas.ts");
/* harmony import */ var _webXREnterExitUI__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./webXREnterExitUI */ "./Cameras/XR/webXREnterExitUI.ts");







/**
 * Options for the default xr helper
 */
var WebXRDefaultExperienceOptions = /** @class */ (function () {
    function WebXRDefaultExperienceOptions() {
    }
    return WebXRDefaultExperienceOptions;
}());

/**
 * Default experience which provides a similar setup to the previous webVRExperience
 */
var WebXRDefaultExperience = /** @class */ (function () {
    function WebXRDefaultExperience() {
    }
    /**
     * Creates the default xr experience
     * @param scene scene
     * @param options options for basic configuration
     * @returns resulting WebXRDefaultExperience
     */
    WebXRDefaultExperience.CreateAsync = function (scene, options) {
        var result = new WebXRDefaultExperience();
        // Create base experience
        return _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_0__["WebXRExperienceHelper"].CreateAsync(scene).then(function (xrHelper) {
            result.baseExperience = xrHelper;
            // Add controller support
            result.input = new _webXRInput__WEBPACK_IMPORTED_MODULE_1__["WebXRInput"](xrHelper);
            result.controllerModelLoader = new _webXRControllerModelLoader__WEBPACK_IMPORTED_MODULE_2__["WebXRControllerModelLoader"](result.input);
            result.pointerSelection = new _webXRControllerPointerSelection__WEBPACK_IMPORTED_MODULE_3__["WebXRControllerPointerSelection"](result.input);
            result.teleportation = new _webXRControllerTeleportation__WEBPACK_IMPORTED_MODULE_4__["WebXRControllerTeleportation"](result.input, options.floorMeshes);
            // Create output canvas manager (this controls where the xr frames will be rendered)
            result.outputCanvas = new _webXRManagedOutputCanvas__WEBPACK_IMPORTED_MODULE_5__["WebXRManagedOutputCanvas"](xrHelper, scene.getEngine().getRenderingCanvas());
            // Create ui for entering/exiting xr
            return _webXREnterExitUI__WEBPACK_IMPORTED_MODULE_6__["WebXREnterExitUI"].CreateAsync(scene, result.baseExperience, { webXRManagedOutputCanvas: result.outputCanvas });
        }).then(function (ui) {
            result.enterExitUI = ui;
            return result;
        });
    };
    /**
     * DIsposes of the experience helper
     */
    WebXRDefaultExperience.prototype.dispose = function () {
        if (this.baseExperience) {
            this.baseExperience.dispose();
        }
        if (this.input) {
            this.input.dispose();
        }
        if (this.enterExitUI) {
            this.enterExitUI.dispose();
        }
        if (this.outputCanvas) {
            this.outputCanvas.dispose();
        }
    };
    return WebXRDefaultExperience;
}());



/***/ }),

/***/ "./Cameras/XR/webXREnterExitUI.ts":
/*!****************************************!*\
  !*** ./Cameras/XR/webXREnterExitUI.ts ***!
  \****************************************/
/*! exports provided: WebXREnterExitUIButton, WebXREnterExitUIOptions, WebXREnterExitUI */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIButton", function() { return WebXREnterExitUIButton; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIOptions", function() { return WebXREnterExitUIOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUI", function() { return WebXREnterExitUI; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webXRExperienceHelper */ "./Cameras/XR/webXRExperienceHelper.ts");



/**
 * Button which can be used to enter a different mode of XR
 */
var WebXREnterExitUIButton = /** @class */ (function () {
    /**
     * Creates a WebXREnterExitUIButton
     * @param element button element
     * @param sessionMode XR initialization session mode
     * @param referenceSpaceType the type of reference space to be used
     */
    function WebXREnterExitUIButton(
    /** button element */
    element,
    /** XR initialization options for the button */
    sessionMode,
    /** Reference space type */
    referenceSpaceType) {
        this.element = element;
        this.sessionMode = sessionMode;
        this.referenceSpaceType = referenceSpaceType;
    }
    /**
     * Overwritable function which can be used to update the button's visuals when the state changes
     * @param activeButton the current active button in the UI
     */
    WebXREnterExitUIButton.prototype.update = function (activeButton) {
    };
    return WebXREnterExitUIButton;
}());

/**
 * Options to create the webXR UI
 */
var WebXREnterExitUIOptions = /** @class */ (function () {
    function WebXREnterExitUIOptions() {
    }
    return WebXREnterExitUIOptions;
}());

/**
 * UI to allow the user to enter/exit XR mode
 */
var WebXREnterExitUI = /** @class */ (function () {
    function WebXREnterExitUI(scene, options) {
        var _this = this;
        this.scene = scene;
        this._buttons = [];
        this._activeButton = null;
        /**
         * Fired every time the active button is changed.
         *
         * When xr is entered via a button that launches xr that button will be the callback parameter
         *
         * When exiting xr the callback parameter will be null)
         */
        this.activeButtonChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._overlay = document.createElement("div");
        this._overlay.style.cssText = "z-index:11;position: absolute; right: 20px;bottom: 50px;";
        if (options.customButtons) {
            this._buttons = options.customButtons;
        }
        else {
            var hmdBtn = document.createElement("button");
            hmdBtn.style.cssText = "color: #868686; border-color: #868686; border-style: solid; margin-left: 10px; height: 50px; width: 80px; background-color: rgba(51,51,51,0.7); background-repeat:no-repeat; background-position: center; outline: none;";
            hmdBtn.innerText = "HMD";
            this._buttons.push(new WebXREnterExitUIButton(hmdBtn, "immersive-vr", "local-floor"));
            this._buttons[this._buttons.length - 1].update = function (activeButton) {
                this.element.style.display = (activeButton === null || activeButton === this) ? "" : "none";
                this.element.innerText = activeButton === this ? "EXIT" : "HMD";
            };
            this._updateButtons(null);
        }
        var renderCanvas = scene.getEngine().getRenderingCanvas();
        if (renderCanvas && renderCanvas.parentNode) {
            renderCanvas.parentNode.appendChild(this._overlay);
            scene.onDisposeObservable.addOnce(function () {
                _this.dispose();
            });
        }
    }
    /**
     * Creates UI to allow the user to enter/exit XR mode
     * @param scene the scene to add the ui to
     * @param helper the xr experience helper to enter/exit xr with
     * @param options options to configure the UI
     * @returns the created ui
     */
    WebXREnterExitUI.CreateAsync = function (scene, helper, options) {
        var _this = this;
        var ui = new WebXREnterExitUI(scene, options);
        var supportedPromises = ui._buttons.map(function (btn) {
            return helper.sessionManager.supportsSessionAsync(btn.sessionMode);
        });
        helper.onStateChangedObservable.add(function (state) {
            if (state == _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__["WebXRState"].NOT_IN_XR) {
                ui._updateButtons(null);
            }
        });
        return Promise.all(supportedPromises).then(function (results) {
            results.forEach(function (supported, i) {
                if (supported) {
                    ui._overlay.appendChild(ui._buttons[i].element);
                    ui._buttons[i].element.onclick = function () { return tslib__WEBPACK_IMPORTED_MODULE_0__["__awaiter"](_this, void 0, void 0, function () {
                        return tslib__WEBPACK_IMPORTED_MODULE_0__["__generator"](this, function (_a) {
                            switch (_a.label) {
                                case 0:
                                    if (!(helper.state == _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__["WebXRState"].IN_XR)) return [3 /*break*/, 2];
                                    ui._updateButtons(null);
                                    return [4 /*yield*/, helper.exitXRAsync()];
                                case 1:
                                    _a.sent();
                                    return [2 /*return*/];
                                case 2:
                                    if (!(helper.state == _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_2__["WebXRState"].NOT_IN_XR)) return [3 /*break*/, 4];
                                    ui._updateButtons(ui._buttons[i]);
                                    if (!options.webXRManagedOutputCanvas) return [3 /*break*/, 4];
                                    return [4 /*yield*/, helper.enterXRAsync(ui._buttons[i].sessionMode, ui._buttons[i].referenceSpaceType, options.webXRManagedOutputCanvas)];
                                case 3:
                                    _a.sent();
                                    _a.label = 4;
                                case 4: return [2 /*return*/];
                            }
                        });
                    }); };
                }
            });
            return ui;
        });
    };
    WebXREnterExitUI.prototype._updateButtons = function (activeButton) {
        var _this = this;
        this._activeButton = activeButton;
        this._buttons.forEach(function (b) {
            b.update(_this._activeButton);
        });
        this.activeButtonChangedObservable.notifyObservers(this._activeButton);
    };
    /**
     * Disposes of the object
     */
    WebXREnterExitUI.prototype.dispose = function () {
        var renderCanvas = this.scene.getEngine().getRenderingCanvas();
        if (renderCanvas && renderCanvas.parentNode && renderCanvas.parentNode.contains(this._overlay)) {
            renderCanvas.parentNode.removeChild(this._overlay);
        }
        this.activeButtonChangedObservable.clear();
    };
    return WebXREnterExitUI;
}());



/***/ }),

/***/ "./Cameras/XR/webXRExperienceHelper.ts":
/*!*********************************************!*\
  !*** ./Cameras/XR/webXRExperienceHelper.ts ***!
  \*********************************************/
/*! exports provided: WebXRState, WebXRExperienceHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRState", function() { return WebXRState; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRExperienceHelper", function() { return WebXRExperienceHelper; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _webXRSessionManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webXRSessionManager */ "./Cameras/XR/webXRSessionManager.ts");
/* harmony import */ var _webXRCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./webXRCamera */ "./Cameras/XR/webXRCamera.ts");





/**
 * States of the webXR experience
 */
var WebXRState;
(function (WebXRState) {
    /**
     * Transitioning to being in XR mode
     */
    WebXRState[WebXRState["ENTERING_XR"] = 0] = "ENTERING_XR";
    /**
     * Transitioning to non XR mode
     */
    WebXRState[WebXRState["EXITING_XR"] = 1] = "EXITING_XR";
    /**
     * In XR mode and presenting
     */
    WebXRState[WebXRState["IN_XR"] = 2] = "IN_XR";
    /**
     * Not entered XR mode
     */
    WebXRState[WebXRState["NOT_IN_XR"] = 3] = "NOT_IN_XR";
})(WebXRState || (WebXRState = {}));
/**
 * Base set of functionality needed to create an XR experince (WebXRSessionManager, Camera, StateManagement, etc.)
 * @see https://doc.babylonjs.com/how_to/webxr
 */
var WebXRExperienceHelper = /** @class */ (function () {
    /**
     * Creates a WebXRExperienceHelper
     * @param scene The scene the helper should be created in
     */
    function WebXRExperienceHelper(scene) {
        var _this = this;
        this.scene = scene;
        /**
         * The current state of the XR experience (eg. transitioning, in XR or not in XR)
         */
        this.state = WebXRState.NOT_IN_XR;
        /**
         * Fires when the state of the experience helper has changed
         */
        this.onStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this._nonVRCamera = null;
        this._originalSceneAutoClear = true;
        this._supported = false;
        this.camera = new _webXRCamera__WEBPACK_IMPORTED_MODULE_4__["WebXRCamera"]("", scene);
        this.sessionManager = new _webXRSessionManager__WEBPACK_IMPORTED_MODULE_3__["WebXRSessionManager"](scene);
        this.container = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"]("WebXR Container", scene);
        this.camera.parent = this.container;
        scene.onDisposeObservable.add(function () {
            _this.exitXRAsync();
        });
    }
    WebXRExperienceHelper.prototype._setState = function (val) {
        this.state = val;
        this.onStateChangedObservable.notifyObservers(this.state);
    };
    /**
     * Creates the experience helper
     * @param scene the scene to attach the experience helper to
     * @returns a promise for the experience helper
     */
    WebXRExperienceHelper.CreateAsync = function (scene) {
        var helper = new WebXRExperienceHelper(scene);
        return helper.sessionManager.initializeAsync().then(function () {
            helper._supported = true;
            return helper;
        }).catch(function () {
            return helper;
        });
    };
    /**
     * Exits XR mode and returns the scene to its original state
     * @returns promise that resolves after xr mode has exited
     */
    WebXRExperienceHelper.prototype.exitXRAsync = function () {
        this._setState(WebXRState.EXITING_XR);
        return this.sessionManager.exitXRAsync();
    };
    /**
     * Enters XR mode (This must be done within a user interaction in most browsers eg. button click)
     * @param sessionCreationOptions options for the XR session
     * @param referenceSpaceType frame of reference of the XR session
     * @param outputCanvas the output canvas that will be used to enter XR mode
     * @returns promise that resolves after xr mode has entered
     */
    WebXRExperienceHelper.prototype.enterXRAsync = function (sessionCreationOptions, referenceSpaceType, outputCanvas) {
        var _this = this;
        if (!this._supported) {
            throw "XR session not supported by this browser";
        }
        this._setState(WebXRState.ENTERING_XR);
        return this.sessionManager.initializeSessionAsync(sessionCreationOptions).then(function () {
            return _this.sessionManager.setReferenceSpaceAsync(referenceSpaceType);
        }).then(function () {
            return outputCanvas.initializeXRLayerAsync(_this.sessionManager.session);
        }).then(function () {
            return _this.sessionManager.updateRenderStateAsync({ depthFar: _this.camera.maxZ, depthNear: _this.camera.minZ, baseLayer: outputCanvas.xrLayer });
        }).then(function () {
            return _this.sessionManager.startRenderingToXRAsync();
        }).then(function () {
            // Cache pre xr scene settings
            _this._originalSceneAutoClear = _this.scene.autoClear;
            _this._nonVRCamera = _this.scene.activeCamera;
            // Overwrite current scene settings
            _this.scene.autoClear = false;
            _this.scene.activeCamera = _this.camera;
            _this.sessionManager.onXRFrameObservable.add(function () {
                _this.camera.updateFromXRSessionManager(_this.sessionManager);
            });
            _this.sessionManager.onXRSessionEnded.addOnce(function () {
                // Reset camera rigs output render target to ensure sessions render target is not drawn after it ends
                _this.camera.rigCameras.forEach(function (c) {
                    c.outputRenderTarget = null;
                });
                // Restore scene settings
                _this.scene.autoClear = _this._originalSceneAutoClear;
                _this.scene.activeCamera = _this._nonVRCamera;
                _this._setState(WebXRState.NOT_IN_XR);
            });
            // Wait until the first frame arrives before setting state to in xr
            _this.sessionManager.onXRFrameObservable.addOnce(function () {
                _this._setState(WebXRState.IN_XR);
            });
        }).catch(function (e) {
            console.log(e);
            console.log(e.message);
        });
    };
    /**
     * Updates the global position of the camera by moving the camera's container
     * This should be used instead of modifying the camera's position as it will be overwritten by an xrSessions's update frame
     * @param position The desired global position of the camera
     */
    WebXRExperienceHelper.prototype.setPositionOfCameraUsingContainer = function (position) {
        this.camera.globalPosition.subtractToRef(position, WebXRExperienceHelper._TmpVector);
        this.container.position.subtractInPlace(WebXRExperienceHelper._TmpVector);
    };
    /**
     * Rotates the xr camera by rotating the camera's container around the camera's position
     * This should be used instead of modifying the camera's rotation as it will be overwritten by an xrSessions's update frame
     * @param rotation the desired quaternion rotation to apply to the camera
     */
    WebXRExperienceHelper.prototype.rotateCameraByQuaternionUsingContainer = function (rotation) {
        if (!this.container.rotationQuaternion) {
            this.container.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].FromEulerVector(this.container.rotation);
        }
        this.container.rotationQuaternion.multiplyInPlace(rotation);
        this.container.position.rotateByQuaternionAroundPointToRef(rotation, this.camera.globalPosition, this.container.position);
    };
    /**
     * Disposes of the experience helper
     */
    WebXRExperienceHelper.prototype.dispose = function () {
        this.camera.dispose();
        this.container.dispose();
        this.onStateChangedObservable.clear();
        this.sessionManager.dispose();
    };
    WebXRExperienceHelper._TmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]();
    return WebXRExperienceHelper;
}());



/***/ }),

/***/ "./Cameras/XR/webXRInput.ts":
/*!**********************************!*\
  !*** ./Cameras/XR/webXRInput.ts ***!
  \**********************************/
/*! exports provided: WebXRInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRInput", function() { return WebXRInput; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./webXRExperienceHelper */ "./Cameras/XR/webXRExperienceHelper.ts");
/* harmony import */ var _webXRController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webXRController */ "./Cameras/XR/webXRController.ts");



/**
 * XR input used to track XR inputs such as controllers/rays
 */
var WebXRInput = /** @class */ (function () {
    /**
     * Initializes the WebXRInput
     * @param baseExperience experience helper which the input should be created for
     */
    function WebXRInput(
    /**
     * Base experience the input listens to
     */
    baseExperience) {
        var _this = this;
        this.baseExperience = baseExperience;
        /**
         * XR controllers being tracked
         */
        this.controllers = [];
        /**
         * Event when a controller has been connected/added
         */
        this.onControllerAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /**
         * Event when a controller has been removed/disconnected
         */
        this.onControllerRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this._onInputSourcesChange = function (event) {
            _this._addAndRemoveControllers(event.added, event.removed);
        };
        // Remove controllers when exiting XR
        this._stateObserver = baseExperience.onStateChangedObservable.add(function (s) {
            if (s === _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_1__["WebXRState"].NOT_IN_XR) {
                _this._addAndRemoveControllers([], _this.controllers.map(function (c) { return c.inputSource; }));
            }
        });
        this._frameObserver = baseExperience.sessionManager.onXRFrameObservable.add(function () {
            if (!baseExperience.sessionManager.currentFrame) {
                return;
            }
            // Start listing to input add/remove event
            if (_this.controllers.length == 0 && baseExperience.sessionManager.session.inputSources) {
                _this._addAndRemoveControllers(baseExperience.sessionManager.session.inputSources, []);
                baseExperience.sessionManager.session.addEventListener("inputsourceschange", _this._onInputSourcesChange);
            }
            // Update controller pose info
            _this.controllers.forEach(function (controller) {
                controller.updateFromXRFrame(baseExperience.sessionManager.currentFrame, baseExperience.sessionManager.referenceSpace);
            });
        });
    }
    WebXRInput.prototype._addAndRemoveControllers = function (addInputs, removeInputs) {
        var _this = this;
        // Add controllers if they don't already exist
        var sources = this.controllers.map(function (c) { return c.inputSource; });
        for (var _i = 0, addInputs_1 = addInputs; _i < addInputs_1.length; _i++) {
            var input = addInputs_1[_i];
            if (sources.indexOf(input) === -1) {
                var controller = new _webXRController__WEBPACK_IMPORTED_MODULE_2__["WebXRController"](this.baseExperience.camera._scene, input, this.baseExperience.container);
                this.controllers.push(controller);
                this.onControllerAddedObservable.notifyObservers(controller);
            }
        }
        // Remove and dispose of controllers to be disposed
        var keepControllers = [];
        var removedControllers = [];
        this.controllers.forEach(function (c) {
            if (removeInputs.indexOf(c.inputSource) === -1) {
                keepControllers.push(c);
            }
            else {
                removedControllers.push(c);
            }
        });
        this.controllers = keepControllers;
        removedControllers.forEach(function (c) {
            _this.onControllerRemovedObservable.notifyObservers(c);
            c.dispose();
        });
    };
    /**
     * Disposes of the object
     */
    WebXRInput.prototype.dispose = function () {
        this.controllers.forEach(function (c) {
            c.dispose();
        });
        this.baseExperience.sessionManager.onXRFrameObservable.remove(this._frameObserver);
        this.baseExperience.onStateChangedObservable.remove(this._stateObserver);
    };
    return WebXRInput;
}());



/***/ }),

/***/ "./Cameras/XR/webXRManagedOutputCanvas.ts":
/*!************************************************!*\
  !*** ./Cameras/XR/webXRManagedOutputCanvas.ts ***!
  \************************************************/
/*! exports provided: WebXRManagedOutputCanvas */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRManagedOutputCanvas", function() { return WebXRManagedOutputCanvas; });
/* harmony import */ var _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./webXRExperienceHelper */ "./Cameras/XR/webXRExperienceHelper.ts");

/**
 * Creates a canvas that is added/removed from the webpage when entering/exiting XR
 */
var WebXRManagedOutputCanvas = /** @class */ (function () {
    /**
     * Initializes the canvas to be added/removed upon entering/exiting xr
     * @param helper the xr experience helper used to trigger adding/removing of the canvas
     * @param canvas The canvas to be added/removed (If not specified a full screen canvas will be created)
     */
    function WebXRManagedOutputCanvas(helper, canvas) {
        var _this = this;
        this.helper = helper;
        this._canvas = null;
        /**
         * xr layer for the canvas
         */
        this.xrLayer = null;
        if (!canvas) {
            canvas = document.createElement('canvas');
            canvas.style.cssText = "position:absolute; bottom:0px;right:0px;z-index:10;width:90%;height:100%;background-color: #000000;";
        }
        this._setManagedOutputCanvas(canvas);
        helper.onStateChangedObservable.add(function (stateInfo) {
            if (stateInfo == _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_0__["WebXRState"].ENTERING_XR) {
                // The canvas is added to the screen before entering XR because currently the xr session must be initialized while the canvas is added render properly
                _this._addCanvas();
            }
            else if (helper.state == _webXRExperienceHelper__WEBPACK_IMPORTED_MODULE_0__["WebXRState"].NOT_IN_XR) {
                _this._removeCanvas();
            }
        });
    }
    /**
     * Initializes the xr layer for the session
     * @param xrSession xr session
     * @returns a promise that will resolve once the XR Layer has been created
     */
    WebXRManagedOutputCanvas.prototype.initializeXRLayerAsync = function (xrSession) {
        var _this = this;
        return this.canvasContext.makeXRCompatible().then(function () {
            _this.xrLayer = new XRWebGLLayer(xrSession, _this.canvasContext);
        });
    };
    /**
     * Disposes of the object
     */
    WebXRManagedOutputCanvas.prototype.dispose = function () {
        this._removeCanvas();
        this._setManagedOutputCanvas(null);
    };
    WebXRManagedOutputCanvas.prototype._setManagedOutputCanvas = function (canvas) {
        this._removeCanvas();
        if (!canvas) {
            this._canvas = null;
            this.canvasContext = null;
        }
        else {
            this._canvas = canvas;
            this.canvasContext = this._canvas.getContext('webgl');
            if (!this.canvasContext) {
                this.canvasContext = this._canvas.getContext('webgl2');
            }
        }
    };
    WebXRManagedOutputCanvas.prototype._addCanvas = function () {
        if (this._canvas && this._canvas !== this.helper.container.getScene().getEngine().getRenderingCanvas()) {
            document.body.appendChild(this._canvas);
        }
    };
    WebXRManagedOutputCanvas.prototype._removeCanvas = function () {
        if (this._canvas && document.body.contains(this._canvas) && this._canvas !== this.helper.container.getScene().getEngine().getRenderingCanvas()) {
            document.body.removeChild(this._canvas);
        }
    };
    return WebXRManagedOutputCanvas;
}());



/***/ }),

/***/ "./Cameras/XR/webXRSessionManager.ts":
/*!*******************************************!*\
  !*** ./Cameras/XR/webXRSessionManager.ts ***!
  \*******************************************/
/*! exports provided: WebXRSessionManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebXRSessionManager", function() { return WebXRSessionManager; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");




/**
 * Manages an XRSession to work with Babylon's engine
 * @see https://doc.babylonjs.com/how_to/webxr
 */
var WebXRSessionManager = /** @class */ (function () {
    /**
     * Constructs a WebXRSessionManager, this must be initialized within a user action before usage
     * @param scene The scene which the session should be created for
     */
    function WebXRSessionManager(scene) {
        this.scene = scene;
        /**
         * Fires every time a new xrFrame arrives which can be used to update the camera
         */
        this.onXRFrameObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fires when the xr session is ended either by the device or manually done
         */
        this.onXRSessionEnded = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** @hidden */
        this._sessionRenderTargetTexture = null;
        this.baseLayer = null;
    }
    /**
     * Initializes the manager
     * After initialization enterXR can be called to start an XR session
     * @returns Promise which resolves after it is initialized
     */
    WebXRSessionManager.prototype.initializeAsync = function () {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("The WebXR APIs are still under development and are subject to change in the future.");
        // Check if the browser supports webXR
        this._xrNavigator = navigator;
        if (!this._xrNavigator.xr) {
            return Promise.reject("webXR not supported by this browser");
        }
        return Promise.resolve();
    };
    /**
     * Initializes an xr session
     * @param xrSessionMode mode to initialize
     * @returns a promise which will resolve once the session has been initialized
     */
    WebXRSessionManager.prototype.initializeSessionAsync = function (xrSessionMode) {
        var _this = this;
        return this._xrNavigator.xr.requestSession(xrSessionMode).then(function (session) {
            _this.session = session;
            // handle when the session is ended (By calling session.end or device ends its own session eg. pressing home button on phone)
            _this.session.addEventListener("end", function () {
                // Remove render target texture and notify frame obervers
                _this._sessionRenderTargetTexture = null;
                // Restore frame buffer to avoid clear on xr framebuffer after session end
                _this.scene.getEngine().restoreDefaultFramebuffer();
                // Need to restart render loop as after the session is ended the last request for new frame will never call callback
                _this.scene.getEngine().customAnimationFrameRequester = null;
                _this.onXRSessionEnded.notifyObservers(null);
                _this.scene.getEngine()._renderLoop();
            }, { once: true });
        });
    };
    /**
     * Sets the reference space on the xr session
     * @param referenceSpace space to set
     * @returns a promise that will resolve once the reference space has been set
     */
    WebXRSessionManager.prototype.setReferenceSpaceAsync = function (referenceSpace) {
        var _this = this;
        return this.session.requestReferenceSpace(referenceSpace).then(function (referenceSpace) {
            _this.referenceSpace = referenceSpace;
        });
    };
    /**
     * Updates the render state of the session
     * @param state state to set
     * @returns a promise that resolves once the render state has been updated
     */
    WebXRSessionManager.prototype.updateRenderStateAsync = function (state) {
        if (state.baseLayer) {
            this.baseLayer = state.baseLayer;
        }
        return this.session.updateRenderState(state);
    };
    /**
     * Starts rendering to the xr layer
     * @returns a promise that will resolve once rendering has started
     */
    WebXRSessionManager.prototype.startRenderingToXRAsync = function () {
        var _this = this;
        // Tell the engine's render loop to be driven by the xr session's refresh rate and provide xr pose information
        this.scene.getEngine().customAnimationFrameRequester = {
            requestAnimationFrame: this.session.requestAnimationFrame.bind(this.session),
            renderFunction: function (timestamp, xrFrame) {
                // Store the XR frame in the manager to be consumed by the XR camera to update pose
                _this.currentFrame = xrFrame;
                _this.onXRFrameObservable.notifyObservers(null);
                _this.scene.getEngine()._renderLoop();
            }
        };
        // Create render target texture from xr's webgl render target
        this._sessionRenderTargetTexture = WebXRSessionManager._CreateRenderTargetTextureFromSession(this.session, this.scene, this.baseLayer);
        // Stop window's animation frame and trigger sessions animation frame
        window.cancelAnimationFrame(this.scene.getEngine()._frameHandler);
        this.scene.getEngine()._renderLoop();
        return Promise.resolve();
    };
    /**
     * Stops the xrSession and restores the renderloop
     * @returns Promise which resolves after it exits XR
     */
    WebXRSessionManager.prototype.exitXRAsync = function () {
        if (this.session) {
            this.session.end();
        }
        return new Promise(function () { });
    };
    /**
     * Checks if a session would be supported for the creation options specified
     * @param sessionMode session mode to check if supported eg. immersive-vr
     * @returns true if supported
     */
    WebXRSessionManager.prototype.supportsSessionAsync = function (sessionMode) {
        if (!navigator.xr || !navigator.xr.supportsSession) {
            return Promise.resolve(false);
        }
        else {
            return navigator.xr.supportsSession(sessionMode).then(function () {
                return Promise.resolve(true);
            }).catch(function (e) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(e);
                return Promise.resolve(false);
            });
        }
    };
    /**
     * @hidden
     * Converts the render layer of xrSession to a render target
     * @param session session to create render target for
     * @param scene scene the new render target should be created for
     */
    WebXRSessionManager._CreateRenderTargetTextureFromSession = function (session, scene, baseLayer) {
        if (!baseLayer) {
            throw "no layer";
        }
        // Create internal texture
        var internalTexture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](scene.getEngine(), _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_UNKNOWN, true);
        internalTexture.width = baseLayer.framebufferWidth;
        internalTexture.height = baseLayer.framebufferHeight;
        internalTexture._framebuffer = baseLayer.framebuffer;
        // Create render target texture from the internal texture
        var renderTargetTexture = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_3__["RenderTargetTexture"]("XR renderTargetTexture", { width: internalTexture.width, height: internalTexture.height }, scene, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true);
        renderTargetTexture._texture = internalTexture;
        return renderTargetTexture;
    };
    /**
     * Disposes of the session manager
     */
    WebXRSessionManager.prototype.dispose = function () {
        this.onXRFrameObservable.clear();
        this.onXRSessionEnded.clear();
    };
    return WebXRSessionManager;
}());



/***/ }),

/***/ "./Cameras/arcRotateCamera.ts":
/*!************************************!*\
  !*** ./Cameras/arcRotateCamera.ts ***!
  \************************************/
/*! exports provided: ArcRotateCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCamera", function() { return ArcRotateCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Behaviors_Cameras_autoRotationBehavior__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Behaviors/Cameras/autoRotationBehavior */ "./Behaviors/Cameras/autoRotationBehavior.ts");
/* harmony import */ var _Behaviors_Cameras_bouncingBehavior__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Behaviors/Cameras/bouncingBehavior */ "./Behaviors/Cameras/bouncingBehavior.ts");
/* harmony import */ var _Behaviors_Cameras_framingBehavior__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Behaviors/Cameras/framingBehavior */ "./Behaviors/Cameras/framingBehavior.ts");
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./camera */ "./Cameras/camera.ts");
/* harmony import */ var _targetCamera__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./targetCamera */ "./Cameras/targetCamera.ts");
/* harmony import */ var _Cameras_arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Cameras/arcRotateCameraInputsManager */ "./Cameras/arcRotateCameraInputsManager.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");













_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("ArcRotateCamera", function (name, scene) {
    return function () { return new ArcRotateCamera(name, 0, 0, 1.0, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), scene); };
});
/**
 * This represents an orbital type of camera.
 *
 * This camera always points towards a given target position and can be rotated around that target with the target as the centre of rotation. It can be controlled with cursors and mouse, or with touch events.
 * Think of this camera as one orbiting its target position, or more imaginatively as a spy satellite orbiting the earth. Its position relative to the target (earth) can be set by three parameters, alpha (radians) the longitudinal rotation, beta (radians) the latitudinal rotation and radius the distance from the target position.
 * @see http://doc.babylonjs.com/babylon101/cameras#arc-rotate-camera
 */
var ArcRotateCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ArcRotateCamera, _super);
    /**
     * Instantiates a new ArcRotateCamera in a given scene
     * @param name Defines the name of the camera
     * @param alpha Defines the camera rotation along the logitudinal axis
     * @param beta Defines the camera rotation along the latitudinal axis
     * @param radius Defines the camera distance from its target
     * @param target Defines the camera target
     * @param scene Defines the scene the camera belongs to
     * @param setActiveOnSceneIfNoneActive Defines wheter the camera should be marked as active if not other active cameras have been defined
     */
    function ArcRotateCamera(name, alpha, beta, radius, target, scene, setActiveOnSceneIfNoneActive) {
        if (setActiveOnSceneIfNoneActive === void 0) { setActiveOnSceneIfNoneActive = true; }
        var _this = _super.call(this, name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), scene, setActiveOnSceneIfNoneActive) || this;
        _this._upVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Up();
        /**
         * Current inertia value on the longitudinal axis.
         * The bigger this number the longer it will take for the camera to stop.
         */
        _this.inertialAlphaOffset = 0;
        /**
         * Current inertia value on the latitudinal axis.
         * The bigger this number the longer it will take for the camera to stop.
         */
        _this.inertialBetaOffset = 0;
        /**
         * Current inertia value on the radius axis.
         * The bigger this number the longer it will take for the camera to stop.
         */
        _this.inertialRadiusOffset = 0;
        /**
         * Minimum allowed angle on the longitudinal axis.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.lowerAlphaLimit = null;
        /**
         * Maximum allowed angle on the longitudinal axis.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.upperAlphaLimit = null;
        /**
         * Minimum allowed angle on the latitudinal axis.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.lowerBetaLimit = 0.01;
        /**
         * Maximum allowed angle on the latitudinal axis.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.upperBetaLimit = Math.PI - 0.01;
        /**
         * Minimum allowed distance of the camera to the target (The camera can not get closer).
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.lowerRadiusLimit = null;
        /**
         * Maximum allowed distance of the camera to the target (The camera can not get further).
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.upperRadiusLimit = null;
        /**
         * Defines the current inertia value used during panning of the camera along the X axis.
         */
        _this.inertialPanningX = 0;
        /**
         * Defines the current inertia value used during panning of the camera along the Y axis.
         */
        _this.inertialPanningY = 0;
        /**
         * Defines the distance used to consider the camera in pan mode vs pinch/zoom.
         * Basically if your fingers moves away from more than this distance you will be considered
         * in pinch mode.
         */
        _this.pinchToPanMaxDistance = 20;
        /**
         * Defines the maximum distance the camera can pan.
         * This could help keeping the cammera always in your scene.
         */
        _this.panningDistanceLimit = null;
        /**
         * Defines the target of the camera before paning.
         */
        _this.panningOriginTarget = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        /**
         * Defines the value of the inertia used during panning.
         * 0 would mean stop inertia and one would mean no decelleration at all.
         */
        _this.panningInertia = 0.9;
        //-- end properties for backward compatibility for inputs
        /**
         * Defines how much the radius should be scaled while zomming on a particular mesh (through the zoomOn function)
         */
        _this.zoomOnFactor = 1;
        /**
         * Defines a screen offset for the camera position.
         */
        _this.targetScreenOffset = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
        /**
         * Allows the camera to be completely reversed.
         * If false the camera can not arrive upside down.
         */
        _this.allowUpsideDown = true;
        /**
         * Define if double tap/click is used to restore the previously saved state of the camera.
         */
        _this.useInputToRestoreState = true;
        /** @hidden */
        _this._viewMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
        /**
         * Defines the allowed panning axis.
         */
        _this.panningAxis = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 1, 0);
        /**
         * Observable triggered when the mesh target has been changed on the camera.
         */
        _this.onMeshTargetChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Defines whether the camera should check collision with the objects oh the scene.
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity#how-can-i-do-this
         */
        _this.checkCollisions = false;
        /**
         * Defines the collision radius of the camera.
         * This simulates a sphere around the camera.
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity#arcrotatecamera
         */
        _this.collisionRadius = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0.5, 0.5, 0.5);
        _this._previousPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._collisionVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._newPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._computationVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
            if (collidedMesh === void 0) { collidedMesh = null; }
            if (!collidedMesh) {
                _this._previousPosition.copyFrom(_this._position);
            }
            else {
                _this.setPosition(newPosition);
                if (_this.onCollide) {
                    _this.onCollide(collidedMesh);
                }
            }
            // Recompute because of constraints
            var cosa = Math.cos(_this.alpha);
            var sina = Math.sin(_this.alpha);
            var cosb = Math.cos(_this.beta);
            var sinb = Math.sin(_this.beta);
            if (sinb === 0) {
                sinb = 0.0001;
            }
            var target = _this._getTargetPosition();
            _this._computationVector.copyFromFloats(_this.radius * cosa * sinb, _this.radius * cosb, _this.radius * sina * sinb);
            target.addToRef(_this._computationVector, _this._newPosition);
            _this._position.copyFrom(_this._newPosition);
            var up = _this.upVector;
            if (_this.allowUpsideDown && _this.beta < 0) {
                up = up.clone();
                up = up.negate();
            }
            _this._computeViewMatrix(_this._position, target, up);
            _this._viewMatrix.addAtIndex(12, _this.targetScreenOffset.x);
            _this._viewMatrix.addAtIndex(13, _this.targetScreenOffset.y);
            _this._collisionTriggered = false;
        };
        _this._target = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        if (target) {
            _this.setTarget(target);
        }
        _this.alpha = alpha;
        _this.beta = beta;
        _this.radius = radius;
        _this.getViewMatrix();
        _this.inputs = new _Cameras_arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_11__["ArcRotateCameraInputsManager"](_this);
        _this.inputs.addKeyboard().addMouseWheel().addPointers();
        return _this;
    }
    Object.defineProperty(ArcRotateCamera.prototype, "target", {
        /**
         * Defines the target point of the camera.
         * The camera looks towards it form the radius distance.
         */
        get: function () {
            return this._target;
        },
        set: function (value) {
            this.setTarget(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "position", {
        /**
         * Define the current local position of the camera in the scene
         */
        get: function () {
            return this._position;
        },
        set: function (newPosition) {
            this.setPosition(newPosition);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "upVector", {
        get: function () {
            return this._upVector;
        },
        /**
         * The vector the camera should consider as up. (default is Vector3(0, 1, 0) as returned by Vector3.Up())
         * Setting this will copy the given vector to the camera's upVector, and set rotation matrices to and from Y up.
         * DO NOT set the up vector using copyFrom or copyFromFloats, as this bypasses setting the above matrices.
         */
        set: function (vec) {
            if (!this._upToYMatrix) {
                this._YToUpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
                this._upToYMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
                this._upVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
            }
            vec.normalize();
            this._upVector.copyFrom(vec);
            this.setMatUp();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets the Y-up to camera up-vector rotation matrix, and the up-vector to Y-up rotation matrix.
     */
    ArcRotateCamera.prototype.setMatUp = function () {
        // from y-up to custom-up (used in _getViewMatrix)
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationAlignToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].UpReadOnly, this._upVector, this._YToUpMatrix);
        // from custom-up to y-up (used in rebuildAnglesAndRadius)
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationAlignToRef(this._upVector, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].UpReadOnly, this._upToYMatrix);
    };
    Object.defineProperty(ArcRotateCamera.prototype, "angularSensibilityX", {
        //-- begin properties for backward compatibility for inputs
        /**
         * Gets or Set the pointer angular sensibility  along the X axis or how fast is the camera rotating.
         */
        get: function () {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                return pointers.angularSensibilityX;
            }
            return 0;
        },
        set: function (value) {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                pointers.angularSensibilityX = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "angularSensibilityY", {
        /**
         * Gets or Set the pointer angular sensibility along the Y axis or how fast is the camera rotating.
         */
        get: function () {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                return pointers.angularSensibilityY;
            }
            return 0;
        },
        set: function (value) {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                pointers.angularSensibilityY = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "pinchPrecision", {
        /**
         * Gets or Set the pointer pinch precision or how fast is the camera zooming.
         */
        get: function () {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                return pointers.pinchPrecision;
            }
            return 0;
        },
        set: function (value) {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                pointers.pinchPrecision = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "pinchDeltaPercentage", {
        /**
         * Gets or Set the pointer pinch delta percentage or how fast is the camera zooming.
         * It will be used instead of pinchDeltaPrecision if different from 0.
         * It defines the percentage of current camera.radius to use as delta when pinch zoom is used.
         */
        get: function () {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                return pointers.pinchDeltaPercentage;
            }
            return 0;
        },
        set: function (value) {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                pointers.pinchDeltaPercentage = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "panningSensibility", {
        /**
         * Gets or Set the pointer panning sensibility or how fast is the camera moving.
         */
        get: function () {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                return pointers.panningSensibility;
            }
            return 0;
        },
        set: function (value) {
            var pointers = this.inputs.attached["pointers"];
            if (pointers) {
                pointers.panningSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "keysUp", {
        /**
         * Gets or Set the list of keyboard keys used to control beta angle in a positive direction.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysUp;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysUp = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "keysDown", {
        /**
         * Gets or Set the list of keyboard keys used to control beta angle in a negative direction.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysDown;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysDown = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "keysLeft", {
        /**
         * Gets or Set the list of keyboard keys used to control alpha angle in a negative direction.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysLeft;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysLeft = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "keysRight", {
        /**
         * Gets or Set the list of keyboard keys used to control alpha angle in a positive direction.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysRight;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysRight = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "wheelPrecision", {
        /**
         * Gets or Set the mouse wheel precision or how fast is the camera zooming.
         */
        get: function () {
            var mousewheel = this.inputs.attached["mousewheel"];
            if (mousewheel) {
                return mousewheel.wheelPrecision;
            }
            return 0;
        },
        set: function (value) {
            var mousewheel = this.inputs.attached["mousewheel"];
            if (mousewheel) {
                mousewheel.wheelPrecision = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "wheelDeltaPercentage", {
        /**
         * Gets or Set the mouse wheel delta percentage or how fast is the camera zooming.
         * It will be used instead of pinchDeltaPrecision if different from 0.
         * It defines the percentage of current camera.radius to use as delta when pinch zoom is used.
         */
        get: function () {
            var mousewheel = this.inputs.attached["mousewheel"];
            if (mousewheel) {
                return mousewheel.wheelDeltaPercentage;
            }
            return 0;
        },
        set: function (value) {
            var mousewheel = this.inputs.attached["mousewheel"];
            if (mousewheel) {
                mousewheel.wheelDeltaPercentage = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "bouncingBehavior", {
        /**
         * Gets the bouncing behavior of the camera if it has been enabled.
         * @see http://doc.babylonjs.com/how_to/camera_behaviors#bouncing-behavior
         */
        get: function () {
            return this._bouncingBehavior;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "useBouncingBehavior", {
        /**
         * Defines if the bouncing behavior of the camera is enabled on the camera.
         * @see http://doc.babylonjs.com/how_to/camera_behaviors#bouncing-behavior
         */
        get: function () {
            return this._bouncingBehavior != null;
        },
        set: function (value) {
            if (value === this.useBouncingBehavior) {
                return;
            }
            if (value) {
                this._bouncingBehavior = new _Behaviors_Cameras_bouncingBehavior__WEBPACK_IMPORTED_MODULE_7__["BouncingBehavior"]();
                this.addBehavior(this._bouncingBehavior);
            }
            else if (this._bouncingBehavior) {
                this.removeBehavior(this._bouncingBehavior);
                this._bouncingBehavior = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "framingBehavior", {
        /**
         * Gets the framing behavior of the camera if it has been enabled.
         * @see http://doc.babylonjs.com/how_to/camera_behaviors#framing-behavior
         */
        get: function () {
            return this._framingBehavior;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "useFramingBehavior", {
        /**
         * Defines if the framing behavior of the camera is enabled on the camera.
         * @see http://doc.babylonjs.com/how_to/camera_behaviors#framing-behavior
         */
        get: function () {
            return this._framingBehavior != null;
        },
        set: function (value) {
            if (value === this.useFramingBehavior) {
                return;
            }
            if (value) {
                this._framingBehavior = new _Behaviors_Cameras_framingBehavior__WEBPACK_IMPORTED_MODULE_8__["FramingBehavior"]();
                this.addBehavior(this._framingBehavior);
            }
            else if (this._framingBehavior) {
                this.removeBehavior(this._framingBehavior);
                this._framingBehavior = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "autoRotationBehavior", {
        /**
         * Gets the auto rotation behavior of the camera if it has been enabled.
         * @see http://doc.babylonjs.com/how_to/camera_behaviors#autorotation-behavior
         */
        get: function () {
            return this._autoRotationBehavior;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArcRotateCamera.prototype, "useAutoRotationBehavior", {
        /**
         * Defines if the auto rotation behavior of the camera is enabled on the camera.
         * @see http://doc.babylonjs.com/how_to/camera_behaviors#autorotation-behavior
         */
        get: function () {
            return this._autoRotationBehavior != null;
        },
        set: function (value) {
            if (value === this.useAutoRotationBehavior) {
                return;
            }
            if (value) {
                this._autoRotationBehavior = new _Behaviors_Cameras_autoRotationBehavior__WEBPACK_IMPORTED_MODULE_6__["AutoRotationBehavior"]();
                this.addBehavior(this._autoRotationBehavior);
            }
            else if (this._autoRotationBehavior) {
                this.removeBehavior(this._autoRotationBehavior);
                this._autoRotationBehavior = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    // Cache
    /** @hidden */
    ArcRotateCamera.prototype._initCache = function () {
        _super.prototype._initCache.call(this);
        this._cache._target = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._cache.alpha = undefined;
        this._cache.beta = undefined;
        this._cache.radius = undefined;
        this._cache.targetScreenOffset = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
    };
    /** @hidden */
    ArcRotateCamera.prototype._updateCache = function (ignoreParentClass) {
        if (!ignoreParentClass) {
            _super.prototype._updateCache.call(this);
        }
        this._cache._target.copyFrom(this._getTargetPosition());
        this._cache.alpha = this.alpha;
        this._cache.beta = this.beta;
        this._cache.radius = this.radius;
        this._cache.targetScreenOffset.copyFrom(this.targetScreenOffset);
    };
    ArcRotateCamera.prototype._getTargetPosition = function () {
        if (this._targetHost && this._targetHost.getAbsolutePosition) {
            var pos = this._targetHost.absolutePosition;
            if (this._targetBoundingCenter) {
                pos.addToRef(this._targetBoundingCenter, this._target);
            }
            else {
                this._target.copyFrom(pos);
            }
        }
        var lockedTargetPosition = this._getLockedTargetPosition();
        if (lockedTargetPosition) {
            return lockedTargetPosition;
        }
        return this._target;
    };
    /**
     * Stores the current state of the camera (alpha, beta, radius and target)
     * @returns the camera itself
     */
    ArcRotateCamera.prototype.storeState = function () {
        this._storedAlpha = this.alpha;
        this._storedBeta = this.beta;
        this._storedRadius = this.radius;
        this._storedTarget = this._getTargetPosition().clone();
        this._storedTargetScreenOffset = this.targetScreenOffset.clone();
        return _super.prototype.storeState.call(this);
    };
    /**
     * @hidden
     * Restored camera state. You must call storeState() first
     */
    ArcRotateCamera.prototype._restoreStateValues = function () {
        if (!_super.prototype._restoreStateValues.call(this)) {
            return false;
        }
        this.setTarget(this._storedTarget.clone());
        this.alpha = this._storedAlpha;
        this.beta = this._storedBeta;
        this.radius = this._storedRadius;
        this.targetScreenOffset = this._storedTargetScreenOffset.clone();
        this.inertialAlphaOffset = 0;
        this.inertialBetaOffset = 0;
        this.inertialRadiusOffset = 0;
        this.inertialPanningX = 0;
        this.inertialPanningY = 0;
        return true;
    };
    // Synchronized
    /** @hidden */
    ArcRotateCamera.prototype._isSynchronizedViewMatrix = function () {
        if (!_super.prototype._isSynchronizedViewMatrix.call(this)) {
            return false;
        }
        return this._cache._target.equals(this._getTargetPosition())
            && this._cache.alpha === this.alpha
            && this._cache.beta === this.beta
            && this._cache.radius === this.radius
            && this._cache.targetScreenOffset.equals(this.targetScreenOffset);
    };
    /**
     * Attached controls to the current camera.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     * @param useCtrlForPanning  Defines whether ctrl is used for paning within the controls
     * @param panningMouseButton Defines whether panning is allowed through mouse click button
     */
    ArcRotateCamera.prototype.attachControl = function (element, noPreventDefault, useCtrlForPanning, panningMouseButton) {
        var _this = this;
        if (useCtrlForPanning === void 0) { useCtrlForPanning = true; }
        if (panningMouseButton === void 0) { panningMouseButton = 2; }
        this._useCtrlForPanning = useCtrlForPanning;
        this._panningMouseButton = panningMouseButton;
        this.inputs.attachElement(element, noPreventDefault);
        this._reset = function () {
            _this.inertialAlphaOffset = 0;
            _this.inertialBetaOffset = 0;
            _this.inertialRadiusOffset = 0;
            _this.inertialPanningX = 0;
            _this.inertialPanningY = 0;
        };
    };
    /**
     * Detach the current controls from the camera.
     * The camera will stop reacting to inputs.
     * @param element Defines the element to stop listening the inputs from
     */
    ArcRotateCamera.prototype.detachControl = function (element) {
        this.inputs.detachElement(element);
        if (this._reset) {
            this._reset();
        }
    };
    /** @hidden */
    ArcRotateCamera.prototype._checkInputs = function () {
        //if (async) collision inspection was triggered, don't update the camera's position - until the collision callback was called.
        if (this._collisionTriggered) {
            return;
        }
        this.inputs.checkInputs();
        // Inertia
        if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0 || this.inertialRadiusOffset !== 0) {
            var inertialAlphaOffset = this.inertialAlphaOffset;
            if (this.beta <= 0) {
                inertialAlphaOffset *= -1;
            }
            if (this.getScene().useRightHandedSystem) {
                inertialAlphaOffset *= -1;
            }
            if (this.parent && this.parent._getWorldMatrixDeterminant() < 0) {
                inertialAlphaOffset *= -1;
            }
            this.alpha += inertialAlphaOffset;
            this.beta += this.inertialBetaOffset;
            this.radius -= this.inertialRadiusOffset;
            this.inertialAlphaOffset *= this.inertia;
            this.inertialBetaOffset *= this.inertia;
            this.inertialRadiusOffset *= this.inertia;
            if (Math.abs(this.inertialAlphaOffset) < _Maths_math_constants__WEBPACK_IMPORTED_MODULE_12__["Epsilon"]) {
                this.inertialAlphaOffset = 0;
            }
            if (Math.abs(this.inertialBetaOffset) < _Maths_math_constants__WEBPACK_IMPORTED_MODULE_12__["Epsilon"]) {
                this.inertialBetaOffset = 0;
            }
            if (Math.abs(this.inertialRadiusOffset) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_12__["Epsilon"]) {
                this.inertialRadiusOffset = 0;
            }
        }
        // Panning inertia
        if (this.inertialPanningX !== 0 || this.inertialPanningY !== 0) {
            if (!this._localDirection) {
                this._localDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
                this._transformedDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
            }
            this._localDirection.copyFromFloats(this.inertialPanningX, this.inertialPanningY, this.inertialPanningY);
            this._localDirection.multiplyInPlace(this.panningAxis);
            this._viewMatrix.invertToRef(this._cameraTransformMatrix);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormalToRef(this._localDirection, this._cameraTransformMatrix, this._transformedDirection);
            //Eliminate y if map panning is enabled (panningAxis == 1,0,1)
            if (!this.panningAxis.y) {
                this._transformedDirection.y = 0;
            }
            if (!this._targetHost) {
                if (this.panningDistanceLimit) {
                    this._transformedDirection.addInPlace(this._target);
                    var distanceSquared = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].DistanceSquared(this._transformedDirection, this.panningOriginTarget);
                    if (distanceSquared <= (this.panningDistanceLimit * this.panningDistanceLimit)) {
                        this._target.copyFrom(this._transformedDirection);
                    }
                }
                else {
                    this._target.addInPlace(this._transformedDirection);
                }
            }
            this.inertialPanningX *= this.panningInertia;
            this.inertialPanningY *= this.panningInertia;
            if (Math.abs(this.inertialPanningX) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_12__["Epsilon"]) {
                this.inertialPanningX = 0;
            }
            if (Math.abs(this.inertialPanningY) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_12__["Epsilon"]) {
                this.inertialPanningY = 0;
            }
        }
        // Limits
        this._checkLimits();
        _super.prototype._checkInputs.call(this);
    };
    ArcRotateCamera.prototype._checkLimits = function () {
        if (this.lowerBetaLimit === null || this.lowerBetaLimit === undefined) {
            if (this.allowUpsideDown && this.beta > Math.PI) {
                this.beta = this.beta - (2 * Math.PI);
            }
        }
        else {
            if (this.beta < this.lowerBetaLimit) {
                this.beta = this.lowerBetaLimit;
            }
        }
        if (this.upperBetaLimit === null || this.upperBetaLimit === undefined) {
            if (this.allowUpsideDown && this.beta < -Math.PI) {
                this.beta = this.beta + (2 * Math.PI);
            }
        }
        else {
            if (this.beta > this.upperBetaLimit) {
                this.beta = this.upperBetaLimit;
            }
        }
        if (this.lowerAlphaLimit !== null && this.alpha < this.lowerAlphaLimit) {
            this.alpha = this.lowerAlphaLimit;
        }
        if (this.upperAlphaLimit !== null && this.alpha > this.upperAlphaLimit) {
            this.alpha = this.upperAlphaLimit;
        }
        if (this.lowerRadiusLimit !== null && this.radius < this.lowerRadiusLimit) {
            this.radius = this.lowerRadiusLimit;
            this.inertialRadiusOffset = 0;
        }
        if (this.upperRadiusLimit !== null && this.radius > this.upperRadiusLimit) {
            this.radius = this.upperRadiusLimit;
            this.inertialRadiusOffset = 0;
        }
    };
    /**
     * Rebuilds angles (alpha, beta) and radius from the give position and target
     */
    ArcRotateCamera.prototype.rebuildAnglesAndRadius = function () {
        this._position.subtractToRef(this._getTargetPosition(), this._computationVector);
        // need to rotate to Y up equivalent if up vector not Axis.Y
        if (this._upVector.x !== 0 || this._upVector.y !== 1.0 || this._upVector.z !== 0) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._computationVector, this._upToYMatrix, this._computationVector);
        }
        this.radius = this._computationVector.length();
        if (this.radius === 0) {
            this.radius = 0.0001; // Just to avoid division by zero
        }
        // Alpha
        if (this._computationVector.x === 0 && this._computationVector.z === 0) {
            this.alpha = Math.PI / 2; // avoid division by zero when looking along up axis, and set to acos(0)
        }
        else {
            this.alpha = Math.acos(this._computationVector.x / Math.sqrt(Math.pow(this._computationVector.x, 2) + Math.pow(this._computationVector.z, 2)));
        }
        if (this._computationVector.z < 0) {
            this.alpha = 2 * Math.PI - this.alpha;
        }
        // Beta
        this.beta = Math.acos(this._computationVector.y / this.radius);
        this._checkLimits();
    };
    /**
     * Use a position to define the current camera related information like aplha, beta and radius
     * @param position Defines the position to set the camera at
     */
    ArcRotateCamera.prototype.setPosition = function (position) {
        if (this._position.equals(position)) {
            return;
        }
        this._position.copyFrom(position);
        this.rebuildAnglesAndRadius();
    };
    /**
     * Defines the target the camera should look at.
     * This will automatically adapt alpha beta and radius to fit within the new target.
     * @param target Defines the new target as a Vector or a mesh
     * @param toBoundingCenter In case of a mesh target, defines wether to target the mesh position or its bounding information center
     * @param allowSamePosition If false, prevents reapplying the new computed position if it is identical to the current one (optim)
     */
    ArcRotateCamera.prototype.setTarget = function (target, toBoundingCenter, allowSamePosition) {
        if (toBoundingCenter === void 0) { toBoundingCenter = false; }
        if (allowSamePosition === void 0) { allowSamePosition = false; }
        if (target.getBoundingInfo) {
            if (toBoundingCenter) {
                this._targetBoundingCenter = target.getBoundingInfo().boundingBox.centerWorld.clone();
            }
            else {
                this._targetBoundingCenter = null;
            }
            target.computeWorldMatrix();
            this._targetHost = target;
            this._target = this._getTargetPosition();
            this.onMeshTargetChangedObservable.notifyObservers(this._targetHost);
        }
        else {
            var newTarget = target;
            var currentTarget = this._getTargetPosition();
            if (currentTarget && !allowSamePosition && currentTarget.equals(newTarget)) {
                return;
            }
            this._targetHost = null;
            this._target = newTarget;
            this._targetBoundingCenter = null;
            this.onMeshTargetChangedObservable.notifyObservers(null);
        }
        this.rebuildAnglesAndRadius();
    };
    /** @hidden */
    ArcRotateCamera.prototype._getViewMatrix = function () {
        // Compute
        var cosa = Math.cos(this.alpha);
        var sina = Math.sin(this.alpha);
        var cosb = Math.cos(this.beta);
        var sinb = Math.sin(this.beta);
        if (sinb === 0) {
            sinb = 0.0001;
        }
        var target = this._getTargetPosition();
        this._computationVector.copyFromFloats(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb);
        // Rotate according to up vector
        if (this._upVector.x !== 0 || this._upVector.y !== 1.0 || this._upVector.z !== 0) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._computationVector, this._YToUpMatrix, this._computationVector);
        }
        target.addToRef(this._computationVector, this._newPosition);
        if (this.getScene().collisionsEnabled && this.checkCollisions) {
            var coordinator = this.getScene().collisionCoordinator;
            if (!this._collider) {
                this._collider = coordinator.createCollider();
            }
            this._collider._radius = this.collisionRadius;
            this._newPosition.subtractToRef(this._position, this._collisionVelocity);
            this._collisionTriggered = true;
            coordinator.getNewPosition(this._position, this._collisionVelocity, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId);
        }
        else {
            this._position.copyFrom(this._newPosition);
            var up = this.upVector;
            if (this.allowUpsideDown && sinb < 0) {
                up = up.negate();
            }
            this._computeViewMatrix(this._position, target, up);
            this._viewMatrix.addAtIndex(12, this.targetScreenOffset.x);
            this._viewMatrix.addAtIndex(13, this.targetScreenOffset.y);
        }
        this._currentTarget = target;
        return this._viewMatrix;
    };
    /**
     * Zooms on a mesh to be at the min distance where we could see it fully in the current viewport.
     * @param meshes Defines the mesh to zoom on
     * @param doNotUpdateMaxZ Defines whether or not maxZ should be updated whilst zooming on the mesh (this can happen if the mesh is big and the maxradius pretty small for instance)
     */
    ArcRotateCamera.prototype.zoomOn = function (meshes, doNotUpdateMaxZ) {
        if (doNotUpdateMaxZ === void 0) { doNotUpdateMaxZ = false; }
        meshes = meshes || this.getScene().meshes;
        var minMaxVector = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].MinMax(meshes);
        var distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Distance(minMaxVector.min, minMaxVector.max);
        this.radius = distance * this.zoomOnFactor;
        this.focusOn({ min: minMaxVector.min, max: minMaxVector.max, distance: distance }, doNotUpdateMaxZ);
    };
    /**
     * Focus on a mesh or a bounding box. This adapts the target and maxRadius if necessary but does not update the current radius.
     * The target will be changed but the radius
     * @param meshesOrMinMaxVectorAndDistance Defines the mesh or bounding info to focus on
     * @param doNotUpdateMaxZ Defines whether or not maxZ should be updated whilst zooming on the mesh (this can happen if the mesh is big and the maxradius pretty small for instance)
     */
    ArcRotateCamera.prototype.focusOn = function (meshesOrMinMaxVectorAndDistance, doNotUpdateMaxZ) {
        if (doNotUpdateMaxZ === void 0) { doNotUpdateMaxZ = false; }
        var meshesOrMinMaxVector;
        var distance;
        if (meshesOrMinMaxVectorAndDistance.min === undefined) { // meshes
            var meshes = meshesOrMinMaxVectorAndDistance || this.getScene().meshes;
            meshesOrMinMaxVector = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].MinMax(meshes);
            distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Distance(meshesOrMinMaxVector.min, meshesOrMinMaxVector.max);
        }
        else { //minMaxVector and distance
            var minMaxVectorAndDistance = meshesOrMinMaxVectorAndDistance;
            meshesOrMinMaxVector = minMaxVectorAndDistance;
            distance = minMaxVectorAndDistance.distance;
        }
        this._target = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].Center(meshesOrMinMaxVector);
        if (!doNotUpdateMaxZ) {
            this.maxZ = distance * 2;
        }
    };
    /**
     * @override
     * Override Camera.createRigCamera
     */
    ArcRotateCamera.prototype.createRigCamera = function (name, cameraIndex) {
        var alphaShift = 0;
        switch (this.cameraRigMode) {
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH:
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER:
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_VR:
                alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? 1 : -1);
                break;
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                alphaShift = this._cameraRigParams.stereoHalfAngle * (cameraIndex === 0 ? -1 : 1);
                break;
        }
        var rigCam = new ArcRotateCamera(name, this.alpha + alphaShift, this.beta, this.radius, this._target, this.getScene());
        rigCam._cameraRigParams = {};
        return rigCam;
    };
    /**
     * @hidden
     * @override
     * Override Camera._updateRigCameras
     */
    ArcRotateCamera.prototype._updateRigCameras = function () {
        var camLeft = this._rigCameras[0];
        var camRight = this._rigCameras[1];
        camLeft.beta = camRight.beta = this.beta;
        switch (this.cameraRigMode) {
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH:
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER:
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_VR:
                camLeft.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;
                camRight.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;
                break;
            case _camera__WEBPACK_IMPORTED_MODULE_9__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
                camLeft.alpha = this.alpha + this._cameraRigParams.stereoHalfAngle;
                camRight.alpha = this.alpha - this._cameraRigParams.stereoHalfAngle;
                break;
        }
        _super.prototype._updateRigCameras.call(this);
    };
    /**
     * Destroy the camera and release the current resources hold by it.
     */
    ArcRotateCamera.prototype.dispose = function () {
        this.inputs.clear();
        _super.prototype.dispose.call(this);
    };
    /**
     * Gets the current object class name.
     * @return the class name
     */
    ArcRotateCamera.prototype.getClassName = function () {
        return "ArcRotateCamera";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "alpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "beta", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "radius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])("target")
    ], ArcRotateCamera.prototype, "_target", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])("upVector")
    ], ArcRotateCamera.prototype, "_upVector", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "inertialAlphaOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "inertialBetaOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "inertialRadiusOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "lowerAlphaLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "upperAlphaLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "lowerBetaLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "upperBetaLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "lowerRadiusLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "upperRadiusLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "inertialPanningX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "inertialPanningY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "pinchToPanMaxDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "panningDistanceLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], ArcRotateCamera.prototype, "panningOriginTarget", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "panningInertia", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "zoomOnFactor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "targetScreenOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "allowUpsideDown", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ArcRotateCamera.prototype, "useInputToRestoreState", void 0);
    return ArcRotateCamera;
}(_targetCamera__WEBPACK_IMPORTED_MODULE_10__["TargetCamera"]));



/***/ }),

/***/ "./Cameras/arcRotateCameraInputsManager.ts":
/*!*************************************************!*\
  !*** ./Cameras/arcRotateCameraInputsManager.ts ***!
  \*************************************************/
/*! exports provided: ArcRotateCameraInputsManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraInputsManager", function() { return ArcRotateCameraInputsManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Cameras_Inputs_arcRotateCameraPointersInput__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Cameras/Inputs/arcRotateCameraPointersInput */ "./Cameras/Inputs/arcRotateCameraPointersInput.ts");
/* harmony import */ var _Cameras_Inputs_arcRotateCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Cameras/Inputs/arcRotateCameraKeyboardMoveInput */ "./Cameras/Inputs/arcRotateCameraKeyboardMoveInput.ts");
/* harmony import */ var _Cameras_Inputs_arcRotateCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Cameras/Inputs/arcRotateCameraMouseWheelInput */ "./Cameras/Inputs/arcRotateCameraMouseWheelInput.ts");
/* harmony import */ var _Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Cameras/cameraInputsManager */ "./Cameras/cameraInputsManager.ts");





/**
 * Default Inputs manager for the ArcRotateCamera.
 * It groups all the default supported inputs for ease of use.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var ArcRotateCameraInputsManager = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ArcRotateCameraInputsManager, _super);
    /**
     * Instantiates a new ArcRotateCameraInputsManager.
     * @param camera Defines the camera the inputs belong to
     */
    function ArcRotateCameraInputsManager(camera) {
        return _super.call(this, camera) || this;
    }
    /**
     * Add mouse wheel input support to the input manager.
     * @returns the current input manager
     */
    ArcRotateCameraInputsManager.prototype.addMouseWheel = function () {
        this.add(new _Cameras_Inputs_arcRotateCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_3__["ArcRotateCameraMouseWheelInput"]());
        return this;
    };
    /**
     * Add pointers input support to the input manager.
     * @returns the current input manager
     */
    ArcRotateCameraInputsManager.prototype.addPointers = function () {
        this.add(new _Cameras_Inputs_arcRotateCameraPointersInput__WEBPACK_IMPORTED_MODULE_1__["ArcRotateCameraPointersInput"]());
        return this;
    };
    /**
     * Add keyboard input support to the input manager.
     * @returns the current input manager
     */
    ArcRotateCameraInputsManager.prototype.addKeyboard = function () {
        this.add(new _Cameras_Inputs_arcRotateCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_2__["ArcRotateCameraKeyboardMoveInput"]());
        return this;
    };
    return ArcRotateCameraInputsManager;
}(_Cameras_cameraInputsManager__WEBPACK_IMPORTED_MODULE_4__["CameraInputsManager"]));



/***/ }),

/***/ "./Cameras/camera.ts":
/*!***************************!*\
  !*** ./Cameras/camera.ts ***!
  \***************************/
/*! exports provided: Camera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return Camera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Maths/math.viewport */ "./Maths/math.viewport.ts");
/* harmony import */ var _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Maths/math.frustum */ "./Maths/math.frustum.ts");












/**
 * This is the base class of all the camera used in the application.
 * @see http://doc.babylonjs.com/features/cameras
 */
var Camera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Camera, _super);
    /**
     * Instantiates a new camera object.
     * This should not be used directly but through the inherited cameras: ArcRotate, Free...
     * @see http://doc.babylonjs.com/features/cameras
     * @param name Defines the name of the camera in the scene
     * @param position Defines the position of the camera
     * @param scene Defines the scene the camera belongs too
     * @param setActiveOnSceneIfNoneActive Defines if the camera should be set as active after creation if no other camera have been defined in the scene
     */
    function Camera(name, position, scene, setActiveOnSceneIfNoneActive) {
        if (setActiveOnSceneIfNoneActive === void 0) { setActiveOnSceneIfNoneActive = true; }
        var _this = _super.call(this, name, scene) || this;
        /** @hidden */
        _this._position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
        /**
         * The vector the camera should consider as up.
         * (default is Vector3(0, 1, 0) aka Vector3.Up())
         */
        _this.upVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Up();
        /**
         * Define the current limit on the left side for an orthographic camera
         * In scene unit
         */
        _this.orthoLeft = null;
        /**
         * Define the current limit on the right side for an orthographic camera
         * In scene unit
         */
        _this.orthoRight = null;
        /**
         * Define the current limit on the bottom side for an orthographic camera
         * In scene unit
         */
        _this.orthoBottom = null;
        /**
         * Define the current limit on the top side for an orthographic camera
         * In scene unit
         */
        _this.orthoTop = null;
        /**
         * Field Of View is set in Radians. (default is 0.8)
         */
        _this.fov = 0.8;
        /**
         * Define the minimum distance the camera can see from.
         * This is important to note that the depth buffer are not infinite and the closer it starts
         * the more your scene might encounter depth fighting issue.
         */
        _this.minZ = 1;
        /**
         * Define the maximum distance the camera can see to.
         * This is important to note that the depth buffer are not infinite and the further it end
         * the more your scene might encounter depth fighting issue.
         */
        _this.maxZ = 10000.0;
        /**
         * Define the default inertia of the camera.
         * This helps giving a smooth feeling to the camera movement.
         */
        _this.inertia = 0.9;
        /**
         * Define the mode of the camera (Camera.PERSPECTIVE_CAMERA or Camera.ORTHOGRAPHIC_CAMERA)
         */
        _this.mode = Camera.PERSPECTIVE_CAMERA;
        /**
         * Define wether the camera is intermediate.
         * This is useful to not present the output directly to the screen in case of rig without post process for instance
         */
        _this.isIntermediate = false;
        /**
         * Define the viewport of the camera.
         * This correspond to the portion of the screen the camera will render to in normalized 0 to 1 unit.
         */
        _this.viewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_10__["Viewport"](0, 0, 1.0, 1.0);
        /**
         * Restricts the camera to viewing objects with the same layerMask.
         * A camera with a layerMask of 1 will render mesh.layerMask & camera.layerMask!== 0
         */
        _this.layerMask = 0x0FFFFFFF;
        /**
         * fovMode sets the camera frustum bounds to the viewport bounds. (default is FOVMODE_VERTICAL_FIXED)
         */
        _this.fovMode = Camera.FOVMODE_VERTICAL_FIXED;
        /**
         * Rig mode of the camera.
         * This is useful to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
         * This is normally controlled byt the camera themselves as internal use.
         */
        _this.cameraRigMode = Camera.RIG_MODE_NONE;
        /**
         * Defines the list of custom render target which are rendered to and then used as the input to this camera's render. Eg. display another camera view on a TV in the main scene
         * This is pretty helpfull if you wish to make a camera render to a texture you could reuse somewhere
         * else in the scene. (Eg. security camera)
         *
         * To change the final output target of the camera, camera.outputRenderTarget should be used instead (eg. webXR renders to a render target corrisponding to an HMD)
         */
        _this.customRenderTargets = new Array();
        /**
         * When set, the camera will render to this render target instead of the default canvas
         *
         * If the desire is to use the output of a camera as a texture in the scene consider using camera.customRenderTargets instead
         */
        _this.outputRenderTarget = null;
        /**
         * Observable triggered when the camera view matrix has changed.
         */
        _this.onViewMatrixChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
        /**
         * Observable triggered when the camera Projection matrix has changed.
         */
        _this.onProjectionMatrixChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
        /**
         * Observable triggered when the inputs have been processed.
         */
        _this.onAfterCheckInputsObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
        /**
         * Observable triggered when reset has been called and applied to the camera.
         */
        _this.onRestoreStateObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_4__["Observable"]();
        /** @hidden */
        _this._rigCameras = new Array();
        _this._webvrViewMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
        /** @hidden */
        _this._skipRendering = false;
        /** @hidden */
        _this._projectionMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"]();
        /** @hidden */
        _this._postProcesses = new Array();
        /** @hidden */
        _this._activeMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_2__["SmartArray"](256);
        _this._globalPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
        /** @hidden */
        _this._computedViewMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
        _this._doNotComputeProjectionMatrix = false;
        _this._transformMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Zero();
        _this._refreshFrustumPlanes = true;
        /** @hidden */
        _this._isCamera = true;
        /** @hidden */
        _this._isLeftCamera = false;
        /** @hidden */
        _this._isRightCamera = false;
        _this.getScene().addCamera(_this);
        if (setActiveOnSceneIfNoneActive && !_this.getScene().activeCamera) {
            _this.getScene().activeCamera = _this;
        }
        _this.position = position;
        return _this;
    }
    Object.defineProperty(Camera.prototype, "position", {
        /**
         * Define the current local position of the camera in the scene
         */
        get: function () {
            return this._position;
        },
        set: function (newPosition) {
            this._position = newPosition;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Store current camera state (fov, position, etc..)
     * @returns the camera
     */
    Camera.prototype.storeState = function () {
        this._stateStored = true;
        this._storedFov = this.fov;
        return this;
    };
    /**
     * Restores the camera state values if it has been stored. You must call storeState() first
     */
    Camera.prototype._restoreStateValues = function () {
        if (!this._stateStored) {
            return false;
        }
        this.fov = this._storedFov;
        return true;
    };
    /**
     * Restored camera state. You must call storeState() first.
     * @returns true if restored and false otherwise
     */
    Camera.prototype.restoreState = function () {
        if (this._restoreStateValues()) {
            this.onRestoreStateObservable.notifyObservers(this);
            return true;
        }
        return false;
    };
    /**
     * Gets the class name of the camera.
     * @returns the class name
     */
    Camera.prototype.getClassName = function () {
        return "Camera";
    };
    /**
     * Gets a string representation of the camera useful for debug purpose.
     * @param fullDetails Defines that a more verboe level of logging is required
     * @returns the string representation
     */
    Camera.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name;
        ret += ", type: " + this.getClassName();
        if (this.animations) {
            for (var i = 0; i < this.animations.length; i++) {
                ret += ", animation[0]: " + this.animations[i].toString(fullDetails);
            }
        }
        if (fullDetails) {
        }
        return ret;
    };
    Object.defineProperty(Camera.prototype, "globalPosition", {
        /**
         * Gets the current world space position of the camera.
         */
        get: function () {
            return this._globalPosition;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the list of active meshes this frame (meshes no culled or excluded by lod s in the frame)
     * @returns the active meshe list
     */
    Camera.prototype.getActiveMeshes = function () {
        return this._activeMeshes;
    };
    /**
     * Check wether a mesh is part of the current active mesh list of the camera
     * @param mesh Defines the mesh to check
     * @returns true if active, false otherwise
     */
    Camera.prototype.isActiveMesh = function (mesh) {
        return (this._activeMeshes.indexOf(mesh) !== -1);
    };
    /**
     * Is this camera ready to be used/rendered
     * @param completeCheck defines if a complete check (including post processes) has to be done (false by default)
     * @return true if the camera is ready
     */
    Camera.prototype.isReady = function (completeCheck) {
        if (completeCheck === void 0) { completeCheck = false; }
        if (completeCheck) {
            for (var _i = 0, _a = this._postProcesses; _i < _a.length; _i++) {
                var pp = _a[_i];
                if (pp && !pp.isReady()) {
                    return false;
                }
            }
        }
        return _super.prototype.isReady.call(this, completeCheck);
    };
    /** @hidden */
    Camera.prototype._initCache = function () {
        _super.prototype._initCache.call(this);
        this._cache.position = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._cache.upVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._cache.mode = undefined;
        this._cache.minZ = undefined;
        this._cache.maxZ = undefined;
        this._cache.fov = undefined;
        this._cache.fovMode = undefined;
        this._cache.aspectRatio = undefined;
        this._cache.orthoLeft = undefined;
        this._cache.orthoRight = undefined;
        this._cache.orthoBottom = undefined;
        this._cache.orthoTop = undefined;
        this._cache.renderWidth = undefined;
        this._cache.renderHeight = undefined;
    };
    /** @hidden */
    Camera.prototype._updateCache = function (ignoreParentClass) {
        if (!ignoreParentClass) {
            _super.prototype._updateCache.call(this);
        }
        this._cache.position.copyFrom(this.position);
        this._cache.upVector.copyFrom(this.upVector);
    };
    /** @hidden */
    Camera.prototype._isSynchronized = function () {
        return this._isSynchronizedViewMatrix() && this._isSynchronizedProjectionMatrix();
    };
    /** @hidden */
    Camera.prototype._isSynchronizedViewMatrix = function () {
        if (!_super.prototype._isSynchronized.call(this)) {
            return false;
        }
        return this._cache.position.equals(this.position)
            && this._cache.upVector.equals(this.upVector)
            && this.isSynchronizedWithParent();
    };
    /** @hidden */
    Camera.prototype._isSynchronizedProjectionMatrix = function () {
        var check = this._cache.mode === this.mode
            && this._cache.minZ === this.minZ
            && this._cache.maxZ === this.maxZ;
        if (!check) {
            return false;
        }
        var engine = this.getEngine();
        if (this.mode === Camera.PERSPECTIVE_CAMERA) {
            check = this._cache.fov === this.fov
                && this._cache.fovMode === this.fovMode
                && this._cache.aspectRatio === engine.getAspectRatio(this);
        }
        else {
            check = this._cache.orthoLeft === this.orthoLeft
                && this._cache.orthoRight === this.orthoRight
                && this._cache.orthoBottom === this.orthoBottom
                && this._cache.orthoTop === this.orthoTop
                && this._cache.renderWidth === engine.getRenderWidth()
                && this._cache.renderHeight === engine.getRenderHeight();
        }
        return check;
    };
    /**
     * Attach the input controls to a specific dom element to get the input from.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    Camera.prototype.attachControl = function (element, noPreventDefault) {
    };
    /**
     * Detach the current controls from the specified dom element.
     * @param element Defines the element to stop listening the inputs from
     */
    Camera.prototype.detachControl = function (element) {
    };
    /**
     * Update the camera state according to the different inputs gathered during the frame.
     */
    Camera.prototype.update = function () {
        this._checkInputs();
        if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
            this._updateRigCameras();
        }
    };
    /** @hidden */
    Camera.prototype._checkInputs = function () {
        this.onAfterCheckInputsObservable.notifyObservers(this);
    };
    Object.defineProperty(Camera.prototype, "rigCameras", {
        /** @hidden */
        get: function () {
            return this._rigCameras;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Camera.prototype, "rigPostProcess", {
        /**
         * Gets the post process used by the rig cameras
         */
        get: function () {
            return this._rigPostProcess;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Internal, gets the first post proces.
     * @returns the first post process to be run on this camera.
     */
    Camera.prototype._getFirstPostProcess = function () {
        for (var ppIndex = 0; ppIndex < this._postProcesses.length; ppIndex++) {
            if (this._postProcesses[ppIndex] !== null) {
                return this._postProcesses[ppIndex];
            }
        }
        return null;
    };
    Camera.prototype._cascadePostProcessesToRigCams = function () {
        // invalidate framebuffer
        var firstPostProcess = this._getFirstPostProcess();
        if (firstPostProcess) {
            firstPostProcess.markTextureDirty();
        }
        // glue the rigPostProcess to the end of the user postprocesses & assign to each sub-camera
        for (var i = 0, len = this._rigCameras.length; i < len; i++) {
            var cam = this._rigCameras[i];
            var rigPostProcess = cam._rigPostProcess;
            // for VR rig, there does not have to be a post process
            if (rigPostProcess) {
                var isPass = rigPostProcess.getEffectName() === "pass";
                if (isPass) {
                    // any rig which has a PassPostProcess for rig[0], cannot be isIntermediate when there are also user postProcesses
                    cam.isIntermediate = this._postProcesses.length === 0;
                }
                cam._postProcesses = this._postProcesses.slice(0).concat(rigPostProcess);
                rigPostProcess.markTextureDirty();
            }
            else {
                cam._postProcesses = this._postProcesses.slice(0);
            }
        }
    };
    /**
     * Attach a post process to the camera.
     * @see http://doc.babylonjs.com/how_to/how_to_use_postprocesses#attach-postprocess
     * @param postProcess The post process to attach to the camera
     * @param insertAt The position of the post process in case several of them are in use in the scene
     * @returns the position the post process has been inserted at
     */
    Camera.prototype.attachPostProcess = function (postProcess, insertAt) {
        if (insertAt === void 0) { insertAt = null; }
        if (!postProcess.isReusable() && this._postProcesses.indexOf(postProcess) > -1) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_7__["Logger"].Error("You're trying to reuse a post process not defined as reusable.");
            return 0;
        }
        if (insertAt == null || insertAt < 0) {
            this._postProcesses.push(postProcess);
        }
        else if (this._postProcesses[insertAt] === null) {
            this._postProcesses[insertAt] = postProcess;
        }
        else {
            this._postProcesses.splice(insertAt, 0, postProcess);
        }
        this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
        return this._postProcesses.indexOf(postProcess);
    };
    /**
     * Detach a post process to the camera.
     * @see http://doc.babylonjs.com/how_to/how_to_use_postprocesses#attach-postprocess
     * @param postProcess The post process to detach from the camera
     */
    Camera.prototype.detachPostProcess = function (postProcess) {
        var idx = this._postProcesses.indexOf(postProcess);
        if (idx !== -1) {
            this._postProcesses[idx] = null;
        }
        this._cascadePostProcessesToRigCams(); // also ensures framebuffer invalidated
    };
    /**
     * Gets the current world matrix of the camera
     */
    Camera.prototype.getWorldMatrix = function () {
        if (this._isSynchronizedViewMatrix()) {
            return this._worldMatrix;
        }
        // Getting the the view matrix will also compute the world matrix.
        this.getViewMatrix();
        return this._worldMatrix;
    };
    /** @hidden */
    Camera.prototype._getViewMatrix = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
    };
    /**
     * Gets the current view matrix of the camera.
     * @param force forces the camera to recompute the matrix without looking at the cached state
     * @returns the view matrix
     */
    Camera.prototype.getViewMatrix = function (force) {
        if (!force && this._isSynchronizedViewMatrix()) {
            return this._computedViewMatrix;
        }
        this.updateCache();
        this._computedViewMatrix = this._getViewMatrix();
        this._currentRenderId = this.getScene().getRenderId();
        this._childUpdateId++;
        this._refreshFrustumPlanes = true;
        if (this._cameraRigParams && this._cameraRigParams.vrPreViewMatrix) {
            this._computedViewMatrix.multiplyToRef(this._cameraRigParams.vrPreViewMatrix, this._computedViewMatrix);
        }
        // Notify parent camera if rig camera is changed
        if (this.parent && this.parent.onViewMatrixChangedObservable) {
            this.parent.onViewMatrixChangedObservable.notifyObservers(this.parent);
        }
        this.onViewMatrixChangedObservable.notifyObservers(this);
        this._computedViewMatrix.invertToRef(this._worldMatrix);
        return this._computedViewMatrix;
    };
    /**
     * Freeze the projection matrix.
     * It will prevent the cache check of the camera projection compute and can speed up perf
     * if no parameter of the camera are meant to change
     * @param projection Defines manually a projection if necessary
     */
    Camera.prototype.freezeProjectionMatrix = function (projection) {
        this._doNotComputeProjectionMatrix = true;
        if (projection !== undefined) {
            this._projectionMatrix = projection;
        }
    };
    /**
     * Unfreeze the projection matrix if it has previously been freezed by freezeProjectionMatrix.
     */
    Camera.prototype.unfreezeProjectionMatrix = function () {
        this._doNotComputeProjectionMatrix = false;
    };
    /**
     * Gets the current projection matrix of the camera.
     * @param force forces the camera to recompute the matrix without looking at the cached state
     * @returns the projection matrix
     */
    Camera.prototype.getProjectionMatrix = function (force) {
        if (this._doNotComputeProjectionMatrix || (!force && this._isSynchronizedProjectionMatrix())) {
            return this._projectionMatrix;
        }
        // Cache
        this._cache.mode = this.mode;
        this._cache.minZ = this.minZ;
        this._cache.maxZ = this.maxZ;
        // Matrix
        this._refreshFrustumPlanes = true;
        var engine = this.getEngine();
        var scene = this.getScene();
        if (this.mode === Camera.PERSPECTIVE_CAMERA) {
            this._cache.fov = this.fov;
            this._cache.fovMode = this.fovMode;
            this._cache.aspectRatio = engine.getAspectRatio(this);
            if (this.minZ <= 0) {
                this.minZ = 0.1;
            }
            if (scene.useRightHandedSystem) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].PerspectiveFovRHToRef(this.fov, engine.getAspectRatio(this), this.minZ, this.maxZ, this._projectionMatrix, this.fovMode === Camera.FOVMODE_VERTICAL_FIXED);
            }
            else {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].PerspectiveFovLHToRef(this.fov, engine.getAspectRatio(this), this.minZ, this.maxZ, this._projectionMatrix, this.fovMode === Camera.FOVMODE_VERTICAL_FIXED);
            }
        }
        else {
            var halfWidth = engine.getRenderWidth() / 2.0;
            var halfHeight = engine.getRenderHeight() / 2.0;
            if (scene.useRightHandedSystem) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].OrthoOffCenterRHToRef(this.orthoLeft || -halfWidth, this.orthoRight || halfWidth, this.orthoBottom || -halfHeight, this.orthoTop || halfHeight, this.minZ, this.maxZ, this._projectionMatrix);
            }
            else {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].OrthoOffCenterLHToRef(this.orthoLeft || -halfWidth, this.orthoRight || halfWidth, this.orthoBottom || -halfHeight, this.orthoTop || halfHeight, this.minZ, this.maxZ, this._projectionMatrix);
            }
            this._cache.orthoLeft = this.orthoLeft;
            this._cache.orthoRight = this.orthoRight;
            this._cache.orthoBottom = this.orthoBottom;
            this._cache.orthoTop = this.orthoTop;
            this._cache.renderWidth = engine.getRenderWidth();
            this._cache.renderHeight = engine.getRenderHeight();
        }
        this.onProjectionMatrixChangedObservable.notifyObservers(this);
        return this._projectionMatrix;
    };
    /**
     * Gets the transformation matrix (ie. the multiplication of view by projection matrices)
     * @returns a Matrix
     */
    Camera.prototype.getTransformationMatrix = function () {
        this._computedViewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
        return this._transformMatrix;
    };
    Camera.prototype._updateFrustumPlanes = function () {
        if (!this._refreshFrustumPlanes) {
            return;
        }
        this.getTransformationMatrix();
        if (!this._frustumPlanes) {
            this._frustumPlanes = _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_11__["Frustum"].GetPlanes(this._transformMatrix);
        }
        else {
            _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_11__["Frustum"].GetPlanesToRef(this._transformMatrix, this._frustumPlanes);
        }
        this._refreshFrustumPlanes = false;
    };
    /**
     * Checks if a cullable object (mesh...) is in the camera frustum
     * This checks the bounding box center. See isCompletelyInFrustum for a full bounding check
     * @param target The object to check
     * @param checkRigCameras If the rig cameras should be checked (eg. with webVR camera both eyes should be checked) (Default: false)
     * @returns true if the object is in frustum otherwise false
     */
    Camera.prototype.isInFrustum = function (target, checkRigCameras) {
        if (checkRigCameras === void 0) { checkRigCameras = false; }
        this._updateFrustumPlanes();
        if (checkRigCameras && this.rigCameras.length > 0) {
            var result = false;
            this.rigCameras.forEach(function (cam) {
                cam._updateFrustumPlanes();
                result = result || target.isInFrustum(cam._frustumPlanes);
            });
            return result;
        }
        else {
            return target.isInFrustum(this._frustumPlanes);
        }
    };
    /**
     * Checks if a cullable object (mesh...) is in the camera frustum
     * Unlike isInFrustum this cheks the full bounding box
     * @param target The object to check
     * @returns true if the object is in frustum otherwise false
     */
    Camera.prototype.isCompletelyInFrustum = function (target) {
        this._updateFrustumPlanes();
        return target.isCompletelyInFrustum(this._frustumPlanes);
    };
    /**
     * Gets a ray in the forward direction from the camera.
     * @param length Defines the length of the ray to create
     * @param transform Defines the transform to apply to the ray, by default the world matrx is used to create a workd space ray
     * @param origin Defines the start point of the ray which defaults to the camera position
     * @returns the forward ray
     */
    Camera.prototype.getForwardRay = function (length, transform, origin) {
        if (length === void 0) { length = 100; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Releases resources associated with this node.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    Camera.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        // Observables
        this.onViewMatrixChangedObservable.clear();
        this.onProjectionMatrixChangedObservable.clear();
        this.onAfterCheckInputsObservable.clear();
        this.onRestoreStateObservable.clear();
        // Inputs
        if (this.inputs) {
            this.inputs.clear();
        }
        // Animations
        this.getScene().stopAnimation(this);
        // Remove from scene
        this.getScene().removeCamera(this);
        while (this._rigCameras.length > 0) {
            var camera = this._rigCameras.pop();
            if (camera) {
                camera.dispose();
            }
        }
        // Postprocesses
        if (this._rigPostProcess) {
            this._rigPostProcess.dispose(this);
            this._rigPostProcess = null;
            this._postProcesses = [];
        }
        else if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
            this._rigPostProcess = null;
            this._postProcesses = [];
        }
        else {
            var i = this._postProcesses.length;
            while (--i >= 0) {
                var postProcess = this._postProcesses[i];
                if (postProcess) {
                    postProcess.dispose(this);
                }
            }
        }
        // Render targets
        var i = this.customRenderTargets.length;
        while (--i >= 0) {
            this.customRenderTargets[i].dispose();
        }
        this.customRenderTargets = [];
        // Active Meshes
        this._activeMeshes.dispose();
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    Object.defineProperty(Camera.prototype, "isLeftCamera", {
        /**
         * Gets the left camera of a rig setup in case of Rigged Camera
         */
        get: function () {
            return this._isLeftCamera;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Camera.prototype, "isRightCamera", {
        /**
         * Gets the right camera of a rig setup in case of Rigged Camera
         */
        get: function () {
            return this._isRightCamera;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Camera.prototype, "leftCamera", {
        /**
         * Gets the left camera of a rig setup in case of Rigged Camera
         */
        get: function () {
            if (this._rigCameras.length < 1) {
                return null;
            }
            return this._rigCameras[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Camera.prototype, "rightCamera", {
        /**
         * Gets the right camera of a rig setup in case of Rigged Camera
         */
        get: function () {
            if (this._rigCameras.length < 2) {
                return null;
            }
            return this._rigCameras[1];
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the left camera target of a rig setup in case of Rigged Camera
     * @returns the target position
     */
    Camera.prototype.getLeftTarget = function () {
        if (this._rigCameras.length < 1) {
            return null;
        }
        return this._rigCameras[0].getTarget();
    };
    /**
     * Gets the right camera target of a rig setup in case of Rigged Camera
     * @returns the target position
     */
    Camera.prototype.getRightTarget = function () {
        if (this._rigCameras.length < 2) {
            return null;
        }
        return this._rigCameras[1].getTarget();
    };
    /**
     * @hidden
     */
    Camera.prototype.setCameraRigMode = function (mode, rigParams) {
        if (this.cameraRigMode === mode) {
            return;
        }
        while (this._rigCameras.length > 0) {
            var camera = this._rigCameras.pop();
            if (camera) {
                camera.dispose();
            }
        }
        this.cameraRigMode = mode;
        this._cameraRigParams = {};
        //we have to implement stereo camera calcultating left and right viewpoints from interaxialDistance and target,
        //not from a given angle as it is now, but until that complete code rewriting provisional stereoHalfAngle value is introduced
        this._cameraRigParams.interaxialDistance = rigParams.interaxialDistance || 0.0637;
        this._cameraRigParams.stereoHalfAngle = _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].ToRadians(this._cameraRigParams.interaxialDistance / 0.0637);
        // create the rig cameras, unless none
        if (this.cameraRigMode !== Camera.RIG_MODE_NONE) {
            var leftCamera = this.createRigCamera(this.name + "_L", 0);
            if (leftCamera) {
                leftCamera._isLeftCamera = true;
            }
            var rightCamera = this.createRigCamera(this.name + "_R", 1);
            if (rightCamera) {
                rightCamera._isRightCamera = true;
            }
            if (leftCamera && rightCamera) {
                this._rigCameras.push(leftCamera);
                this._rigCameras.push(rightCamera);
            }
        }
        switch (this.cameraRigMode) {
            case Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH:
                Camera._setStereoscopicAnaglyphRigMode(this);
                break;
            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
            case Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
            case Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER:
                Camera._setStereoscopicRigMode(this);
                break;
            case Camera.RIG_MODE_VR:
                Camera._setVRRigMode(this, rigParams);
                break;
            case Camera.RIG_MODE_WEBVR:
                Camera._setWebVRRigMode(this, rigParams);
                break;
        }
        this._cascadePostProcessesToRigCams();
        this.update();
    };
    /** @hidden */
    Camera._setStereoscopicRigMode = function (camera) {
        throw "Import Cameras/RigModes/stereoscopicRigMode before using stereoscopic rig mode";
    };
    /** @hidden */
    Camera._setStereoscopicAnaglyphRigMode = function (camera) {
        throw "Import Cameras/RigModes/stereoscopicAnaglyphRigMode before using stereoscopic anaglyph rig mode";
    };
    /** @hidden */
    Camera._setVRRigMode = function (camera, rigParams) {
        throw "Import Cameras/RigModes/vrRigMode before using VR rig mode";
    };
    /** @hidden */
    Camera._setWebVRRigMode = function (camera, rigParams) {
        throw "Import Cameras/RigModes/WebVRRigMode before using Web VR rig mode";
    };
    /** @hidden */
    Camera.prototype._getVRProjectionMatrix = function () {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].PerspectiveFovLHToRef(this._cameraRigParams.vrMetrics.aspectRatioFov, this._cameraRigParams.vrMetrics.aspectRatio, this.minZ, this.maxZ, this._cameraRigParams.vrWorkMatrix);
        this._cameraRigParams.vrWorkMatrix.multiplyToRef(this._cameraRigParams.vrHMatrix, this._projectionMatrix);
        return this._projectionMatrix;
    };
    Camera.prototype._updateCameraRotationMatrix = function () {
        //Here for WebVR
    };
    Camera.prototype._updateWebVRCameraRotationMatrix = function () {
        //Here for WebVR
    };
    /**
     * This function MUST be overwritten by the different WebVR cameras available.
     * The context in which it is running is the RIG camera. So 'this' is the TargetCamera, left or right.
     * @hidden
     */
    Camera.prototype._getWebVRProjectionMatrix = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
    };
    /**
     * This function MUST be overwritten by the different WebVR cameras available.
     * The context in which it is running is the RIG camera. So 'this' is the TargetCamera, left or right.
     * @hidden
     */
    Camera.prototype._getWebVRViewMatrix = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
    };
    /** @hidden */
    Camera.prototype.setCameraRigParameter = function (name, value) {
        if (!this._cameraRigParams) {
            this._cameraRigParams = {};
        }
        this._cameraRigParams[name] = value;
        //provisionnally:
        if (name === "interaxialDistance") {
            this._cameraRigParams.stereoHalfAngle = _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].ToRadians(value / 0.0637);
        }
    };
    /**
     * needs to be overridden by children so sub has required properties to be copied
     * @hidden
     */
    Camera.prototype.createRigCamera = function (name, cameraIndex) {
        return null;
    };
    /**
     * May need to be overridden by children
     * @hidden
     */
    Camera.prototype._updateRigCameras = function () {
        for (var i = 0; i < this._rigCameras.length; i++) {
            this._rigCameras[i].minZ = this.minZ;
            this._rigCameras[i].maxZ = this.maxZ;
            this._rigCameras[i].fov = this.fov;
            this._rigCameras[i].upVector.copyFrom(this.upVector);
        }
        // only update viewport when ANAGLYPH
        if (this.cameraRigMode === Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH) {
            this._rigCameras[0].viewport = this._rigCameras[1].viewport = this.viewport;
        }
    };
    /** @hidden */
    Camera.prototype._setupInputs = function () {
    };
    /**
     * Serialiaze the camera setup to a json represention
     * @returns the JSON representation
     */
    Camera.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        // Type
        serializationObject.type = this.getClassName();
        // Parent
        if (this.parent) {
            serializationObject.parentId = this.parent.id;
        }
        if (this.inputs) {
            this.inputs.serialize(serializationObject);
        }
        // Animations
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].AppendSerializedAnimations(this, serializationObject);
        serializationObject.ranges = this.serializeAnimationRanges();
        return serializationObject;
    };
    /**
     * Clones the current camera.
     * @param name The cloned camera name
     * @returns the cloned camera
     */
    Camera.prototype.clone = function (name) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(Camera.GetConstructorFromName(this.getClassName(), name, this.getScene(), this.interaxialDistance, this.isStereoscopicSideBySide), this);
    };
    /**
     * Gets the direction of the camera relative to a given local axis.
     * @param localAxis Defines the reference axis to provide a relative direction.
     * @return the direction
     */
    Camera.prototype.getDirection = function (localAxis) {
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
        this.getDirectionToRef(localAxis, result);
        return result;
    };
    /**
     * Gets the direction of the camera relative to a given local axis into a passed vector.
     * @param localAxis Defines the reference axis to provide a relative direction.
     * @param result Defines the vector to store the result in
     */
    Camera.prototype.getDirectionToRef = function (localAxis, result) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].TransformNormalToRef(localAxis, this.getWorldMatrix(), result);
    };
    /**
     * Gets a camera constructor for a given camera type
     * @param type The type of the camera to construct (should be equal to one of the camera class name)
     * @param name The name of the camera the result will be able to instantiate
     * @param scene The scene the result will construct the camera in
     * @param interaxial_distance In case of stereoscopic setup, the distance between both eyes
     * @param isStereoscopicSideBySide In case of stereoscopic setup, should the sereo be side b side
     * @returns a factory method to construc the camera
     */
    Camera.GetConstructorFromName = function (type, name, scene, interaxial_distance, isStereoscopicSideBySide) {
        if (interaxial_distance === void 0) { interaxial_distance = 0; }
        if (isStereoscopicSideBySide === void 0) { isStereoscopicSideBySide = true; }
        var constructorFunc = _node__WEBPACK_IMPORTED_MODULE_6__["Node"].Construct(type, name, scene, {
            interaxial_distance: interaxial_distance,
            isStereoscopicSideBySide: isStereoscopicSideBySide
        });
        if (constructorFunc) {
            return constructorFunc;
        }
        // Default to universal camera
        return function () { return Camera._createDefaultParsedCamera(name, scene); };
    };
    /**
     * Compute the world  matrix of the camera.
     * @returns the camera workd matrix
     */
    Camera.prototype.computeWorldMatrix = function () {
        return this.getWorldMatrix();
    };
    /**
     * Parse a JSON and creates the camera from the parsed information
     * @param parsedCamera The JSON to parse
     * @param scene The scene to instantiate the camera in
     * @returns the newly constructed camera
     */
    Camera.Parse = function (parsedCamera, scene) {
        var type = parsedCamera.type;
        var construct = Camera.GetConstructorFromName(type, parsedCamera.name, scene, parsedCamera.interaxial_distance, parsedCamera.isStereoscopicSideBySide);
        var camera = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(construct, parsedCamera, scene);
        // Parent
        if (parsedCamera.parentId) {
            camera._waitingParentId = parsedCamera.parentId;
        }
        //If camera has an input manager, let it parse inputs settings
        if (camera.inputs) {
            camera.inputs.parse(parsedCamera);
            camera._setupInputs();
        }
        if (camera.setPosition) { // need to force position
            camera.position.copyFromFloats(0, 0, 0);
            camera.setPosition(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedCamera.position));
        }
        // Target
        if (parsedCamera.target) {
            if (camera.setTarget) {
                camera.setTarget(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedCamera.target));
            }
        }
        // Apply 3d rig, when found
        if (parsedCamera.cameraRigMode) {
            var rigParams = (parsedCamera.interaxial_distance) ? { interaxialDistance: parsedCamera.interaxial_distance } : {};
            camera.setCameraRigMode(parsedCamera.cameraRigMode, rigParams);
        }
        // Animations
        if (parsedCamera.animations) {
            for (var animationIndex = 0; animationIndex < parsedCamera.animations.length; animationIndex++) {
                var parsedAnimation = parsedCamera.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_8__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    camera.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
            _node__WEBPACK_IMPORTED_MODULE_6__["Node"].ParseAnimationRanges(camera, parsedCamera, scene);
        }
        if (parsedCamera.autoAnimate) {
            scene.beginAnimation(camera, parsedCamera.autoAnimateFrom, parsedCamera.autoAnimateTo, parsedCamera.autoAnimateLoop, parsedCamera.autoAnimateSpeed || 1.0);
        }
        return camera;
    };
    /** @hidden */
    Camera._createDefaultParsedCamera = function (name, scene) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__["_DevTools"].WarnImport("UniversalCamera");
    };
    /**
     * This is the default projection mode used by the cameras.
     * It helps recreating a feeling of perspective and better appreciate depth.
     * This is the best way to simulate real life cameras.
     */
    Camera.PERSPECTIVE_CAMERA = 0;
    /**
     * This helps creating camera with an orthographic mode.
     * Orthographic is commonly used in engineering as a means to produce object specifications that communicate dimensions unambiguously, each line of 1 unit length (cm, meter..whatever) will appear to have the same length everywhere on the drawing. This allows the drafter to dimension only a subset of lines and let the reader know that other lines of that length on the drawing are also that length in reality. Every parallel line in the drawing is also parallel in the object.
     */
    Camera.ORTHOGRAPHIC_CAMERA = 1;
    /**
     * This is the default FOV mode for perspective cameras.
     * This setting aligns the upper and lower bounds of the viewport to the upper and lower bounds of the camera frustum.
     */
    Camera.FOVMODE_VERTICAL_FIXED = 0;
    /**
     * This setting aligns the left and right bounds of the viewport to the left and right bounds of the camera frustum.
     */
    Camera.FOVMODE_HORIZONTAL_FIXED = 1;
    /**
     * This specifies ther is no need for a camera rig.
     * Basically only one eye is rendered corresponding to the camera.
     */
    Camera.RIG_MODE_NONE = 0;
    /**
     * Simulates a camera Rig with one blue eye and one red eye.
     * This can be use with 3d blue and red glasses.
     */
    Camera.RIG_MODE_STEREOSCOPIC_ANAGLYPH = 10;
    /**
     * Defines that both eyes of the camera will be rendered side by side with a parallel target.
     */
    Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL = 11;
    /**
     * Defines that both eyes of the camera will be rendered side by side with a none parallel target.
     */
    Camera.RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED = 12;
    /**
     * Defines that both eyes of the camera will be rendered over under each other.
     */
    Camera.RIG_MODE_STEREOSCOPIC_OVERUNDER = 13;
    /**
     * Defines that both eyes of the camera should be renderered in a VR mode (carbox).
     */
    Camera.RIG_MODE_VR = 20;
    /**
     * Defines that both eyes of the camera should be renderered in a VR mode (webVR).
     */
    Camera.RIG_MODE_WEBVR = 21;
    /**
     * Custom rig mode allowing rig cameras to be populated manually with any number of cameras
     */
    Camera.RIG_MODE_CUSTOM = 22;
    /**
     * Defines if by default attaching controls should prevent the default javascript event to continue.
     */
    Camera.ForceAttachControlToAlwaysPreventDefault = false;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])("position")
    ], Camera.prototype, "_position", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], Camera.prototype, "upVector", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "orthoLeft", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "orthoRight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "orthoBottom", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "orthoTop", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "fov", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "minZ", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "maxZ", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "inertia", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "mode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "layerMask", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "fovMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "cameraRigMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "interaxialDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Camera.prototype, "isStereoscopicSideBySide", void 0);
    return Camera;
}(_node__WEBPACK_IMPORTED_MODULE_6__["Node"]));



/***/ }),

/***/ "./Cameras/cameraInputsManager.ts":
/*!****************************************!*\
  !*** ./Cameras/cameraInputsManager.ts ***!
  \****************************************/
/*! exports provided: CameraInputTypes, CameraInputsManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CameraInputTypes", function() { return CameraInputTypes; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CameraInputsManager", function() { return CameraInputsManager; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./camera */ "./Cameras/camera.ts");



/**
 * @ignore
 * This is a list of all the different input types that are available in the application.
 * Fo instance: ArcRotateCameraGamepadInput...
 */
var CameraInputTypes = {};
/**
 * This represents the input manager used within a camera.
 * It helps dealing with all the different kind of input attached to a camera.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var CameraInputsManager = /** @class */ (function () {
    /**
     * Instantiate a new Camera Input Manager.
     * @param camera Defines the camera the input manager blongs to
     */
    function CameraInputsManager(camera) {
        this.attached = {};
        this.camera = camera;
        this.checkInputs = function () { };
    }
    /**
     * Add an input method to a camera
     * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
     * @param input camera input method
     */
    CameraInputsManager.prototype.add = function (input) {
        var type = input.getSimpleName();
        if (this.attached[type]) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("camera input of type " + type + " already exists on camera");
            return;
        }
        this.attached[type] = input;
        input.camera = this.camera;
        //for checkInputs, we are dynamically creating a function
        //the goal is to avoid the performance penalty of looping for inputs in the render loop
        if (input.checkInputs) {
            this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));
        }
        if (this.attachedElement) {
            input.attachControl(this.attachedElement);
        }
    };
    /**
     * Remove a specific input method from a camera
     * example: camera.inputs.remove(camera.inputs.attached.mouse);
     * @param inputToRemove camera input method
     */
    CameraInputsManager.prototype.remove = function (inputToRemove) {
        for (var cam in this.attached) {
            var input = this.attached[cam];
            if (input === inputToRemove) {
                input.detachControl(this.attachedElement);
                input.camera = null;
                delete this.attached[cam];
                this.rebuildInputCheck();
            }
        }
    };
    /**
     * Remove a specific input type from a camera
     * example: camera.inputs.remove("ArcRotateCameraGamepadInput");
     * @param inputType the type of the input to remove
     */
    CameraInputsManager.prototype.removeByType = function (inputType) {
        for (var cam in this.attached) {
            var input = this.attached[cam];
            if (input.getClassName() === inputType) {
                input.detachControl(this.attachedElement);
                input.camera = null;
                delete this.attached[cam];
                this.rebuildInputCheck();
            }
        }
    };
    CameraInputsManager.prototype._addCheckInputs = function (fn) {
        var current = this.checkInputs;
        return function () {
            current();
            fn();
        };
    };
    /**
     * Attach the input controls to the currently attached dom element to listen the events from.
     * @param input Defines the input to attach
     */
    CameraInputsManager.prototype.attachInput = function (input) {
        if (this.attachedElement) {
            input.attachControl(this.attachedElement, this.noPreventDefault);
        }
    };
    /**
     * Attach the current manager inputs controls to a specific dom element to listen the events from.
     * @param element Defines the dom element to collect the events from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    CameraInputsManager.prototype.attachElement = function (element, noPreventDefault) {
        if (noPreventDefault === void 0) { noPreventDefault = false; }
        if (this.attachedElement) {
            return;
        }
        noPreventDefault = _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].ForceAttachControlToAlwaysPreventDefault ? false : noPreventDefault;
        this.attachedElement = element;
        this.noPreventDefault = noPreventDefault;
        for (var cam in this.attached) {
            this.attached[cam].attachControl(element, noPreventDefault);
        }
    };
    /**
     * Detach the current manager inputs controls from a specific dom element.
     * @param element Defines the dom element to collect the events from
     * @param disconnect Defines whether the input should be removed from the current list of attached inputs
     */
    CameraInputsManager.prototype.detachElement = function (element, disconnect) {
        if (disconnect === void 0) { disconnect = false; }
        if (this.attachedElement !== element) {
            return;
        }
        for (var cam in this.attached) {
            this.attached[cam].detachControl(element);
            if (disconnect) {
                this.attached[cam].camera = null;
            }
        }
        this.attachedElement = null;
    };
    /**
     * Rebuild the dynamic inputCheck function from the current list of
     * defined inputs in the manager.
     */
    CameraInputsManager.prototype.rebuildInputCheck = function () {
        this.checkInputs = function () { };
        for (var cam in this.attached) {
            var input = this.attached[cam];
            if (input.checkInputs) {
                this.checkInputs = this._addCheckInputs(input.checkInputs.bind(input));
            }
        }
    };
    /**
     * Remove all attached input methods from a camera
     */
    CameraInputsManager.prototype.clear = function () {
        if (this.attachedElement) {
            this.detachElement(this.attachedElement, true);
        }
        this.attached = {};
        this.attachedElement = null;
        this.checkInputs = function () { };
    };
    /**
     * Serialize the current input manager attached to a camera.
     * This ensures than once parsed,
     * the input associated to the camera will be identical to the current ones
     * @param serializedCamera Defines the camera serialization JSON the input serialization should write to
     */
    CameraInputsManager.prototype.serialize = function (serializedCamera) {
        var inputs = {};
        for (var cam in this.attached) {
            var input = this.attached[cam];
            var res = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(input);
            inputs[input.getClassName()] = res;
        }
        serializedCamera.inputsmgr = inputs;
    };
    /**
     * Parses an input manager serialized JSON to restore the previous list of inputs
     * and states associated to a camera.
     * @param parsedCamera Defines the JSON to parse
     */
    CameraInputsManager.prototype.parse = function (parsedCamera) {
        var parsedInputs = parsedCamera.inputsmgr;
        if (parsedInputs) {
            this.clear();
            for (var n in parsedInputs) {
                var construct = CameraInputTypes[n];
                if (construct) {
                    var parsedinput = parsedInputs[n];
                    var input = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new construct(); }, parsedinput, null);
                    this.add(input);
                }
            }
        }
        else {
            //2016-03-08 this part is for managing backward compatibility
            for (var n in this.attached) {
                var construct = CameraInputTypes[this.attached[n].getClassName()];
                if (construct) {
                    var input = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new construct(); }, parsedCamera, null);
                    this.remove(this.attached[n]);
                    this.add(input);
                }
            }
        }
    };
    return CameraInputsManager;
}());



/***/ }),

/***/ "./Cameras/deviceOrientationCamera.ts":
/*!********************************************!*\
  !*** ./Cameras/deviceOrientationCamera.ts ***!
  \********************************************/
/*! exports provided: DeviceOrientationCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DeviceOrientationCamera", function() { return DeviceOrientationCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _freeCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Inputs_freeCameraDeviceOrientationInput__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Inputs/freeCameraDeviceOrientationInput */ "./Cameras/Inputs/freeCameraDeviceOrientationInput.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");






_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("DeviceOrientationCamera", function (name, scene) {
    return function () { return new DeviceOrientationCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
// We're mainly based on the logic defined into the FreeCamera code
/**
 * This is a camera specifically designed to react to device orientation events such as a modern mobile device
 * being tilted forward or back and left or right.
 */
var DeviceOrientationCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DeviceOrientationCamera, _super);
    /**
     * Creates a new device orientation camera
     * @param name The name of the camera
     * @param position The start position camera
     * @param scene The scene the camera belongs to
     */
    function DeviceOrientationCamera(name, position, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this._tmpDragQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        _this._disablePointerInputWhenUsingDeviceOrientation = true;
        _this._dragFactor = 0;
        _this._quaternionCache = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        _this.inputs.addDeviceOrientation();
        // When the orientation sensor fires it's first event, disable mouse input
        if (_this.inputs._deviceOrientationInput) {
            _this.inputs._deviceOrientationInput._onDeviceOrientationChangedObservable.addOnce(function () {
                if (_this._disablePointerInputWhenUsingDeviceOrientation) {
                    if (_this.inputs._mouseInput) {
                        _this.inputs._mouseInput._allowCameraRotation = false;
                        _this.inputs._mouseInput.onPointerMovedObservable.add(function (e) {
                            if (_this._dragFactor != 0) {
                                if (!_this._initialQuaternion) {
                                    _this._initialQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
                                }
                                // Rotate the initial space around the y axis to allow users to "turn around" via touch/mouse
                                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].FromEulerAnglesToRef(0, e.offsetX * _this._dragFactor, 0, _this._tmpDragQuaternion);
                                _this._initialQuaternion.multiplyToRef(_this._tmpDragQuaternion, _this._initialQuaternion);
                            }
                        });
                    }
                }
            });
        }
        return _this;
    }
    Object.defineProperty(DeviceOrientationCamera.prototype, "disablePointerInputWhenUsingDeviceOrientation", {
        /**
         * Gets or sets a boolean indicating that pointer input must be disabled on first orientation sensor update (Default: true)
         */
        get: function () {
            return this._disablePointerInputWhenUsingDeviceOrientation;
        },
        set: function (value) {
            this._disablePointerInputWhenUsingDeviceOrientation = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Enabled turning on the y axis when the orientation sensor is active
     * @param dragFactor the factor that controls the turn speed (default: 1/300)
     */
    DeviceOrientationCamera.prototype.enableHorizontalDragging = function (dragFactor) {
        if (dragFactor === void 0) { dragFactor = 1 / 300; }
        this._dragFactor = dragFactor;
    };
    /**
     * Gets the current instance class name ("DeviceOrientationCamera").
     * This helps avoiding instanceof at run time.
     * @returns the class name
     */
    DeviceOrientationCamera.prototype.getClassName = function () {
        return "DeviceOrientationCamera";
    };
    /**
     * @hidden
     * Checks and applies the current values of the inputs to the camera. (Internal use only)
     */
    DeviceOrientationCamera.prototype._checkInputs = function () {
        _super.prototype._checkInputs.call(this);
        this._quaternionCache.copyFrom(this.rotationQuaternion);
        if (this._initialQuaternion) {
            this._initialQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);
        }
    };
    /**
     * Reset the camera to its default orientation on the specified axis only.
     * @param axis The axis to reset
     */
    DeviceOrientationCamera.prototype.resetToCurrentRotation = function (axis) {
        var _this = this;
        if (axis === void 0) { axis = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Y; }
        //can only work if this camera has a rotation quaternion already.
        if (!this.rotationQuaternion) {
            return;
        }
        if (!this._initialQuaternion) {
            this._initialQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        }
        this._initialQuaternion.copyFrom(this._quaternionCache || this.rotationQuaternion);
        ['x', 'y', 'z'].forEach(function (axisName) {
            if (!axis[axisName]) {
                _this._initialQuaternion[axisName] = 0;
            }
            else {
                _this._initialQuaternion[axisName] *= -1;
            }
        });
        this._initialQuaternion.normalize();
        //force rotation update
        this._initialQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);
    };
    return DeviceOrientationCamera;
}(_freeCamera__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"]));



/***/ }),

/***/ "./Cameras/flyCamera.ts":
/*!******************************!*\
  !*** ./Cameras/flyCamera.ts ***!
  \******************************/
/*! exports provided: FlyCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FlyCamera", function() { return FlyCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _targetCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./targetCamera */ "./Cameras/targetCamera.ts");
/* harmony import */ var _flyCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./flyCameraInputsManager */ "./Cameras/flyCameraInputsManager.ts");






/**
 * This is a flying camera, designed for 3D movement and rotation in all directions,
 * such as in a 3D Space Shooter or a Flight Simulator.
 */
var FlyCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FlyCamera, _super);
    /**
     * Instantiates a FlyCamera.
     * This is a flying camera, designed for 3D movement and rotation in all directions,
     * such as in a 3D Space Shooter or a Flight Simulator.
     * @param name Define the name of the camera in the scene.
     * @param position Define the starting position of the camera in the scene.
     * @param scene Define the scene the camera belongs to.
     * @param setActiveOnSceneIfNoneActive Defines wheter the camera should be marked as active, if no other camera has been defined as active.
    */
    function FlyCamera(name, position, scene, setActiveOnSceneIfNoneActive) {
        if (setActiveOnSceneIfNoneActive === void 0) { setActiveOnSceneIfNoneActive = true; }
        var _this = _super.call(this, name, position, scene, setActiveOnSceneIfNoneActive) || this;
        /**
         * Define the collision ellipsoid of the camera.
         * This is helpful for simulating a camera body, like a player's body.
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity#arcrotatecamera
         */
        _this.ellipsoid = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](1, 1, 1);
        /**
         * Define an offset for the position of the ellipsoid around the camera.
         * This can be helpful if the camera is attached away from the player's body center,
         * such as at its head.
         */
        _this.ellipsoidOffset = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 0, 0);
        /**
         * Enable or disable collisions of the camera with the rest of the scene objects.
         */
        _this.checkCollisions = false;
        /**
         * Enable or disable gravity on the camera.
         */
        _this.applyGravity = false;
        /**
         * Define the current direction the camera is moving to.
         */
        _this.cameraDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        /**
         * Track Roll to maintain the wanted Rolling when looking around.
         */
        _this._trackRoll = 0;
        /**
        * Slowly correct the Roll to its original value after a Pitch+Yaw rotation.
        */
        _this.rollCorrect = 100;
        /**
         * Mimic a banked turn, Rolling the camera when Yawing.
         * It's recommended to use rollCorrect = 10 for faster banking correction.
         */
        _this.bankedTurn = false;
        /**
         * Limit in radians for how much Roll banking will add. (Default: 90°)
         */
        _this.bankedTurnLimit = Math.PI / 2;
        /**
         * Value of 0 disables the banked Roll.
         * Value of 1 is equal to the Yaw angle in radians.
         */
        _this.bankedTurnMultiplier = 1;
        _this._needMoveForGravity = false;
        _this._oldPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._diffPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._newPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        // Collisions.
        _this._collisionMask = -1;
        /** @hidden */
        _this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
            if (collidedMesh === void 0) { collidedMesh = null; }
            var updatePosition = function (newPos) {
                _this._newPosition.copyFrom(newPos);
                _this._newPosition.subtractToRef(_this._oldPosition, _this._diffPosition);
                if (_this._diffPosition.length() > _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].CollisionsEpsilon) {
                    _this.position.addInPlace(_this._diffPosition);
                    if (_this.onCollide && collidedMesh) {
                        _this.onCollide(collidedMesh);
                    }
                }
            };
            updatePosition(newPosition);
        };
        _this.inputs = new _flyCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__["FlyCameraInputsManager"](_this);
        _this.inputs.addKeyboard().addMouse();
        return _this;
    }
    Object.defineProperty(FlyCamera.prototype, "angularSensibility", {
        /**
         * Gets the input sensibility for mouse input.
         * Higher values reduce sensitivity.
         */
        get: function () {
            var mouse = this.inputs.attached["mouse"];
            if (mouse) {
                return mouse.angularSensibility;
            }
            return 0;
        },
        /**
         * Sets the input sensibility for a mouse input.
         * Higher values reduce sensitivity.
         */
        set: function (value) {
            var mouse = this.inputs.attached["mouse"];
            if (mouse) {
                mouse.angularSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FlyCamera.prototype, "keysForward", {
        /**
         * Get the keys for camera movement forward.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysForward;
            }
            return [];
        },
        /**
        * Set the keys for camera movement forward.
        */
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysForward = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FlyCamera.prototype, "keysBackward", {
        /**
         * Get the keys for camera movement backward.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysBackward;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysBackward = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FlyCamera.prototype, "keysUp", {
        /**
         * Get the keys for camera movement up.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysUp;
            }
            return [];
        },
        /**
        * Set the keys for camera movement up.
        */
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysUp = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FlyCamera.prototype, "keysDown", {
        /**
         * Get the keys for camera movement down.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysDown;
            }
            return [];
        },
        /**
        * Set the keys for camera movement down.
        */
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysDown = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FlyCamera.prototype, "keysLeft", {
        /**
         * Get the keys for camera movement left.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysLeft;
            }
            return [];
        },
        /**
        * Set the keys for camera movement left.
        */
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysLeft = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FlyCamera.prototype, "keysRight", {
        /**
         * Set the keys for camera movement right.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysRight;
            }
            return [];
        },
        /**
        * Set the keys for camera movement right.
        */
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysRight = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attach a control to the HTML DOM element.
     * @param element Defines the element that listens to the input events.
     * @param noPreventDefault Defines whether events caught by the controls should call preventdefault(). https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
     */
    FlyCamera.prototype.attachControl = function (element, noPreventDefault) {
        this.inputs.attachElement(element, noPreventDefault);
    };
    /**
     * Detach a control from the HTML DOM element.
     * The camera will stop reacting to that input.
     * @param element Defines the element that listens to the input events.
     */
    FlyCamera.prototype.detachControl = function (element) {
        this.inputs.detachElement(element);
        this.cameraDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 0, 0);
    };
    Object.defineProperty(FlyCamera.prototype, "collisionMask", {
        /**
         * Get the mask that the camera ignores in collision events.
         */
        get: function () {
            return this._collisionMask;
        },
        /**
        * Set the mask that the camera ignores in collision events.
        */
        set: function (mask) {
            this._collisionMask = !isNaN(mask) ? mask : -1;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    FlyCamera.prototype._collideWithWorld = function (displacement) {
        var globalPosition;
        if (this.parent) {
            globalPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinates(this.position, this.parent.getWorldMatrix());
        }
        else {
            globalPosition = this.position;
        }
        globalPosition.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPosition);
        this._oldPosition.addInPlace(this.ellipsoidOffset);
        var coordinator = this.getScene().collisionCoordinator;
        if (!this._collider) {
            this._collider = coordinator.createCollider();
        }
        this._collider._radius = this.ellipsoid;
        this._collider.collisionMask = this._collisionMask;
        // No need for clone, as long as gravity is not on.
        var actualDisplacement = displacement;
        // Add gravity to direction to prevent dual-collision checking.
        if (this.applyGravity) {
            // This prevents mending with cameraDirection, a global variable of the fly camera class.
            actualDisplacement = displacement.add(this.getScene().gravity);
        }
        coordinator.getNewPosition(this._oldPosition, actualDisplacement, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId);
    };
    /** @hidden */
    FlyCamera.prototype._checkInputs = function () {
        if (!this._localDirection) {
            this._localDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
            this._transformedDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        }
        this.inputs.checkInputs();
        _super.prototype._checkInputs.call(this);
    };
    /** @hidden */
    FlyCamera.prototype._decideIfNeedsToMove = function () {
        return this._needMoveForGravity || Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0;
    };
    /** @hidden */
    FlyCamera.prototype._updatePosition = function () {
        if (this.checkCollisions && this.getScene().collisionsEnabled) {
            this._collideWithWorld(this.cameraDirection);
        }
        else {
            _super.prototype._updatePosition.call(this);
        }
    };
    /**
     * Restore the Roll to its target value at the rate specified.
     * @param rate - Higher means slower restoring.
     * @hidden
     */
    FlyCamera.prototype.restoreRoll = function (rate) {
        var limit = this._trackRoll; // Target Roll.
        var z = this.rotation.z; // Current Roll.
        var delta = limit - z; // Difference in Roll.
        var minRad = 0.001; // Tenth of a radian is a barely noticable difference.
        // If the difference is noticable, restore the Roll.
        if (Math.abs(delta) >= minRad) {
            // Change Z rotation towards the target Roll.
            this.rotation.z += delta / rate;
            // Match when near enough.
            if (Math.abs(limit - this.rotation.z) <= minRad) {
                this.rotation.z = limit;
            }
        }
    };
    /**
     * Destroy the camera and release the current resources held by it.
     */
    FlyCamera.prototype.dispose = function () {
        this.inputs.clear();
        _super.prototype.dispose.call(this);
    };
    /**
     * Get the current object class name.
     * @returns the class name.
     */
    FlyCamera.prototype.getClassName = function () {
        return "FlyCamera";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], FlyCamera.prototype, "ellipsoid", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], FlyCamera.prototype, "ellipsoidOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCamera.prototype, "checkCollisions", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FlyCamera.prototype, "applyGravity", void 0);
    return FlyCamera;
}(_targetCamera__WEBPACK_IMPORTED_MODULE_4__["TargetCamera"]));



/***/ }),

/***/ "./Cameras/flyCameraInputsManager.ts":
/*!*******************************************!*\
  !*** ./Cameras/flyCameraInputsManager.ts ***!
  \*******************************************/
/*! exports provided: FlyCameraInputsManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FlyCameraInputsManager", function() { return FlyCameraInputsManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Cameras_Inputs_flyCameraMouseInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Cameras/Inputs/flyCameraMouseInput */ "./Cameras/Inputs/flyCameraMouseInput.ts");
/* harmony import */ var _Cameras_Inputs_flyCameraKeyboardInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Cameras/Inputs/flyCameraKeyboardInput */ "./Cameras/Inputs/flyCameraKeyboardInput.ts");




/**
 * Default Inputs manager for the FlyCamera.
 * It groups all the default supported inputs for ease of use.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FlyCameraInputsManager = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FlyCameraInputsManager, _super);
    /**
     * Instantiates a new FlyCameraInputsManager.
     * @param camera Defines the camera the inputs belong to.
     */
    function FlyCameraInputsManager(camera) {
        return _super.call(this, camera) || this;
    }
    /**
     * Add keyboard input support to the input manager.
     * @returns the new FlyCameraKeyboardMoveInput().
     */
    FlyCameraInputsManager.prototype.addKeyboard = function () {
        this.add(new _Cameras_Inputs_flyCameraKeyboardInput__WEBPACK_IMPORTED_MODULE_3__["FlyCameraKeyboardInput"]());
        return this;
    };
    /**
     * Add mouse input support to the input manager.
     * @param touchEnabled Enable touch screen support.
     * @returns the new FlyCameraMouseInput().
     */
    FlyCameraInputsManager.prototype.addMouse = function (touchEnabled) {
        if (touchEnabled === void 0) { touchEnabled = true; }
        this.add(new _Cameras_Inputs_flyCameraMouseInput__WEBPACK_IMPORTED_MODULE_2__["FlyCameraMouseInput"](touchEnabled));
        return this;
    };
    return FlyCameraInputsManager;
}(_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputsManager"]));



/***/ }),

/***/ "./Cameras/followCamera.ts":
/*!*********************************!*\
  !*** ./Cameras/followCamera.ts ***!
  \*********************************/
/*! exports provided: FollowCamera, ArcFollowCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FollowCamera", function() { return FollowCamera; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArcFollowCamera", function() { return ArcFollowCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _targetCamera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./targetCamera */ "./Cameras/targetCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _followCameraInputsManager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./followCameraInputsManager */ "./Cameras/followCameraInputsManager.ts");







_node__WEBPACK_IMPORTED_MODULE_5__["Node"].AddNodeConstructor("FollowCamera", function (name, scene) {
    return function () { return new FollowCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero(), scene); };
});
_node__WEBPACK_IMPORTED_MODULE_5__["Node"].AddNodeConstructor("ArcFollowCamera", function (name, scene) {
    return function () { return new ArcFollowCamera(name, 0, 0, 1.0, null, scene); };
});
/**
 * A follow camera takes a mesh as a target and follows it as it moves. Both a free camera version followCamera and
 * an arc rotate version arcFollowCamera are available.
 * @see http://doc.babylonjs.com/features/cameras#follow-camera
 */
var FollowCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FollowCamera, _super);
    /**
     * Instantiates the follow camera.
     * @see http://doc.babylonjs.com/features/cameras#follow-camera
     * @param name Define the name of the camera in the scene
     * @param position Define the position of the camera
     * @param scene Define the scene the camera belong to
     * @param lockedTarget Define the target of the camera
     */
    function FollowCamera(name, position, scene, lockedTarget) {
        if (lockedTarget === void 0) { lockedTarget = null; }
        var _this = _super.call(this, name, position, scene) || this;
        /**
         * Distance the follow camera should follow an object at
         */
        _this.radius = 12;
        /**
         * Minimum allowed distance of the camera to the axis of rotation
         * (The camera can not get closer).
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.lowerRadiusLimit = null;
        /**
         * Maximum allowed distance of the camera to the axis of rotation
         * (The camera can not get further).
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.upperRadiusLimit = null;
        /**
         * Define a rotation offset between the camera and the object it follows
         */
        _this.rotationOffset = 0;
        /**
         * Minimum allowed angle to camera position relative to target object.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.lowerRotationOffsetLimit = null;
        /**
         * Maximum allowed angle to camera position relative to target object.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.upperRotationOffsetLimit = null;
        /**
         * Define a height offset between the camera and the object it follows.
         * It can help following an object from the top (like a car chaing a plane)
         */
        _this.heightOffset = 4;
        /**
         * Minimum allowed height of camera position relative to target object.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.lowerHeightOffsetLimit = null;
        /**
         * Maximum allowed height of camera position relative to target object.
         * This can help limiting how the Camera is able to move in the scene.
         */
        _this.upperHeightOffsetLimit = null;
        /**
         * Define how fast the camera can accelerate to follow it s target.
         */
        _this.cameraAcceleration = 0.05;
        /**
         * Define the speed limit of the camera following an object.
         */
        _this.maxCameraSpeed = 20;
        _this.lockedTarget = lockedTarget;
        _this.inputs = new _followCameraInputsManager__WEBPACK_IMPORTED_MODULE_6__["FollowCameraInputsManager"](_this);
        _this.inputs.addKeyboard().addMouseWheel().addPointers();
        return _this;
        // Uncomment the following line when the relevant handlers have been implemented.
        // this.inputs.addKeyboard().addMouseWheel().addPointers().addVRDeviceOrientation();
    }
    FollowCamera.prototype._follow = function (cameraTarget) {
        if (!cameraTarget) {
            return;
        }
        var yRotation;
        if (cameraTarget.rotationQuaternion) {
            var rotMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"]();
            cameraTarget.rotationQuaternion.toRotationMatrix(rotMatrix);
            yRotation = Math.atan2(rotMatrix.m[8], rotMatrix.m[10]);
        }
        else {
            yRotation = cameraTarget.rotation.y;
        }
        var radians = _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].ToRadians(this.rotationOffset) + yRotation;
        var targetPosition = cameraTarget.getAbsolutePosition();
        var targetX = targetPosition.x + Math.sin(radians) * this.radius;
        var targetZ = targetPosition.z + Math.cos(radians) * this.radius;
        var dx = targetX - this.position.x;
        var dy = (targetPosition.y + this.heightOffset) - this.position.y;
        var dz = (targetZ) - this.position.z;
        var vx = dx * this.cameraAcceleration * 2; //this is set to .05
        var vy = dy * this.cameraAcceleration;
        var vz = dz * this.cameraAcceleration * 2;
        if (vx > this.maxCameraSpeed || vx < -this.maxCameraSpeed) {
            vx = vx < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;
        }
        if (vy > this.maxCameraSpeed || vy < -this.maxCameraSpeed) {
            vy = vy < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;
        }
        if (vz > this.maxCameraSpeed || vz < -this.maxCameraSpeed) {
            vz = vz < 1 ? -this.maxCameraSpeed : this.maxCameraSpeed;
        }
        this.position = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](this.position.x + vx, this.position.y + vy, this.position.z + vz);
        this.setTarget(targetPosition);
    };
    /**
     * Attached controls to the current camera.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FollowCamera.prototype.attachControl = function (element, noPreventDefault) {
        this.inputs.attachElement(element, noPreventDefault);
        this._reset = function () {
        };
    };
    /**
     * Detach the current controls from the camera.
     * The camera will stop reacting to inputs.
     * @param element Defines the element to stop listening the inputs from
     */
    FollowCamera.prototype.detachControl = function (element) {
        this.inputs.detachElement(element);
        if (this._reset) {
            this._reset();
        }
    };
    /** @hidden */
    FollowCamera.prototype._checkInputs = function () {
        this.inputs.checkInputs();
        this._checkLimits();
        _super.prototype._checkInputs.call(this);
        if (this.lockedTarget) {
            this._follow(this.lockedTarget);
        }
    };
    FollowCamera.prototype._checkLimits = function () {
        if (this.lowerRadiusLimit !== null && this.radius < this.lowerRadiusLimit) {
            this.radius = this.lowerRadiusLimit;
        }
        if (this.upperRadiusLimit !== null && this.radius > this.upperRadiusLimit) {
            this.radius = this.upperRadiusLimit;
        }
        if (this.lowerHeightOffsetLimit !== null &&
            this.heightOffset < this.lowerHeightOffsetLimit) {
            this.heightOffset = this.lowerHeightOffsetLimit;
        }
        if (this.upperHeightOffsetLimit !== null &&
            this.heightOffset > this.upperHeightOffsetLimit) {
            this.heightOffset = this.upperHeightOffsetLimit;
        }
        if (this.lowerRotationOffsetLimit !== null &&
            this.rotationOffset < this.lowerRotationOffsetLimit) {
            this.rotationOffset = this.lowerRotationOffsetLimit;
        }
        if (this.upperRotationOffsetLimit !== null &&
            this.rotationOffset > this.upperRotationOffsetLimit) {
            this.rotationOffset = this.upperRotationOffsetLimit;
        }
    };
    /**
     * Gets the camera class name.
     * @returns the class name
     */
    FollowCamera.prototype.getClassName = function () {
        return "FollowCamera";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "radius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "lowerRadiusLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "upperRadiusLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "rotationOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "lowerRotationOffsetLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "upperRotationOffsetLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "heightOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "lowerHeightOffsetLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "upperHeightOffsetLimit", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "cameraAcceleration", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FollowCamera.prototype, "maxCameraSpeed", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsMeshReference"])("lockedTargetId")
    ], FollowCamera.prototype, "lockedTarget", void 0);
    return FollowCamera;
}(_targetCamera__WEBPACK_IMPORTED_MODULE_3__["TargetCamera"]));

/**
 * Arc Rotate version of the follow camera.
 * It still follows a Defined mesh but in an Arc Rotate Camera fashion.
 * @see http://doc.babylonjs.com/features/cameras#follow-camera
 */
var ArcFollowCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ArcFollowCamera, _super);
    /**
     * Instantiates a new ArcFollowCamera
     * @see http://doc.babylonjs.com/features/cameras#follow-camera
     * @param name Define the name of the camera
     * @param alpha Define the rotation angle of the camera around the logitudinal axis
     * @param beta Define the rotation angle of the camera around the elevation axis
     * @param radius Define the radius of the camera from its target point
     * @param target Define the target of the camera
     * @param scene Define the scene the camera belongs to
     */
    function ArcFollowCamera(name,
    /** The longitudinal angle of the camera */
    alpha,
    /** The latitudinal angle of the camera */
    beta,
    /** The radius of the camera from its target */
    radius,
    /** Define the camera target (the messh it should follow) */
    target, scene) {
        var _this = _super.call(this, name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero(), scene) || this;
        _this.alpha = alpha;
        _this.beta = beta;
        _this.radius = radius;
        _this.target = target;
        _this._cartesianCoordinates = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero();
        _this._follow();
        return _this;
    }
    ArcFollowCamera.prototype._follow = function () {
        if (!this.target) {
            return;
        }
        this._cartesianCoordinates.x = this.radius * Math.cos(this.alpha) * Math.cos(this.beta);
        this._cartesianCoordinates.y = this.radius * Math.sin(this.beta);
        this._cartesianCoordinates.z = this.radius * Math.sin(this.alpha) * Math.cos(this.beta);
        var targetPosition = this.target.getAbsolutePosition();
        this.position = targetPosition.add(this._cartesianCoordinates);
        this.setTarget(targetPosition);
    };
    /** @hidden */
    ArcFollowCamera.prototype._checkInputs = function () {
        _super.prototype._checkInputs.call(this);
        this._follow();
    };
    /**
     * Returns the class name of the object.
     * It is mostly used internally for serialization purposes.
     */
    ArcFollowCamera.prototype.getClassName = function () {
        return "ArcFollowCamera";
    };
    return ArcFollowCamera;
}(_targetCamera__WEBPACK_IMPORTED_MODULE_3__["TargetCamera"]));



/***/ }),

/***/ "./Cameras/followCameraInputsManager.ts":
/*!**********************************************!*\
  !*** ./Cameras/followCameraInputsManager.ts ***!
  \**********************************************/
/*! exports provided: FollowCameraInputsManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FollowCameraInputsManager", function() { return FollowCameraInputsManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Inputs_followCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Inputs/followCameraKeyboardMoveInput */ "./Cameras/Inputs/followCameraKeyboardMoveInput.ts");
/* harmony import */ var _Inputs_followCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Inputs/followCameraMouseWheelInput */ "./Cameras/Inputs/followCameraMouseWheelInput.ts");
/* harmony import */ var _Inputs_followCameraPointersInput__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Inputs/followCameraPointersInput */ "./Cameras/Inputs/followCameraPointersInput.ts");





/**
 * Default Inputs manager for the FollowCamera.
 * It groups all the default supported inputs for ease of use.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FollowCameraInputsManager = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FollowCameraInputsManager, _super);
    /**
     * Instantiates a new FollowCameraInputsManager.
     * @param camera Defines the camera the inputs belong to
     */
    function FollowCameraInputsManager(camera) {
        return _super.call(this, camera) || this;
    }
    /**
     * Add keyboard input support to the input manager.
     * @returns the current input manager
     */
    FollowCameraInputsManager.prototype.addKeyboard = function () {
        this.add(new _Inputs_followCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_2__["FollowCameraKeyboardMoveInput"]());
        return this;
    };
    /**
     * Add mouse wheel input support to the input manager.
     * @returns the current input manager
     */
    FollowCameraInputsManager.prototype.addMouseWheel = function () {
        this.add(new _Inputs_followCameraMouseWheelInput__WEBPACK_IMPORTED_MODULE_3__["FollowCameraMouseWheelInput"]());
        return this;
    };
    /**
     * Add pointers input support to the input manager.
     * @returns the current input manager
     */
    FollowCameraInputsManager.prototype.addPointers = function () {
        this.add(new _Inputs_followCameraPointersInput__WEBPACK_IMPORTED_MODULE_4__["FollowCameraPointersInput"]());
        return this;
    };
    /**
     * Add orientation input support to the input manager.
     * @returns the current input manager
     */
    FollowCameraInputsManager.prototype.addVRDeviceOrientation = function () {
        console.warn("DeviceOrientation support not yet implemented for FollowCamera.");
        return this;
    };
    return FollowCameraInputsManager;
}(_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputsManager"]));



/***/ }),

/***/ "./Cameras/freeCamera.ts":
/*!*******************************!*\
  !*** ./Cameras/freeCamera.ts ***!
  \*******************************/
/*! exports provided: FreeCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCamera", function() { return FreeCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _targetCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./targetCamera */ "./Cameras/targetCamera.ts");
/* harmony import */ var _freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./freeCameraInputsManager */ "./Cameras/freeCameraInputsManager.ts");






/**
 * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
 * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.
 * @see http://doc.babylonjs.com/features/cameras#universal-camera
 */
var FreeCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FreeCamera, _super);
    /**
     * Instantiates a Free Camera.
     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
     * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.
     * @see http://doc.babylonjs.com/features/cameras#universal-camera
     * @param name Define the name of the camera in the scene
     * @param position Define the start position of the camera in the scene
     * @param scene Define the scene the camera belongs to
     * @param setActiveOnSceneIfNoneActive Defines wheter the camera should be marked as active if not other active cameras have been defined
     */
    function FreeCamera(name, position, scene, setActiveOnSceneIfNoneActive) {
        if (setActiveOnSceneIfNoneActive === void 0) { setActiveOnSceneIfNoneActive = true; }
        var _this = _super.call(this, name, position, scene, setActiveOnSceneIfNoneActive) || this;
        /**
         * Define the collision ellipsoid of the camera.
         * This is helpful to simulate a camera body like the player body around the camera
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity#arcrotatecamera
         */
        _this.ellipsoid = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0.5, 1, 0.5);
        /**
         * Define an offset for the position of the ellipsoid around the camera.
         * This can be helpful to determine the center of the body near the gravity center of the body
         * instead of its head.
         */
        _this.ellipsoidOffset = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 0, 0);
        /**
         * Enable or disable collisions of the camera with the rest of the scene objects.
         */
        _this.checkCollisions = false;
        /**
         * Enable or disable gravity on the camera.
         */
        _this.applyGravity = false;
        _this._needMoveForGravity = false;
        _this._oldPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._diffPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._newPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        // Collisions
        _this._collisionMask = -1;
        _this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
            if (collidedMesh === void 0) { collidedMesh = null; }
            var updatePosition = function (newPos) {
                _this._newPosition.copyFrom(newPos);
                _this._newPosition.subtractToRef(_this._oldPosition, _this._diffPosition);
                if (_this._diffPosition.length() > _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].CollisionsEpsilon) {
                    _this.position.addInPlace(_this._diffPosition);
                    if (_this.onCollide && collidedMesh) {
                        _this.onCollide(collidedMesh);
                    }
                }
            };
            updatePosition(newPosition);
        };
        _this.inputs = new _freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__["FreeCameraInputsManager"](_this);
        _this.inputs.addKeyboard().addMouse();
        return _this;
    }
    Object.defineProperty(FreeCamera.prototype, "angularSensibility", {
        /**
         * Gets the input sensibility for a mouse input. (default is 2000.0)
         * Higher values reduce sensitivity.
         */
        get: function () {
            var mouse = this.inputs.attached["mouse"];
            if (mouse) {
                return mouse.angularSensibility;
            }
            return 0;
        },
        /**
         * Sets the input sensibility for a mouse input. (default is 2000.0)
         * Higher values reduce sensitivity.
         */
        set: function (value) {
            var mouse = this.inputs.attached["mouse"];
            if (mouse) {
                mouse.angularSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FreeCamera.prototype, "keysUp", {
        /**
         * Gets or Set the list of keyboard keys used to control the forward move of the camera.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysUp;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysUp = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FreeCamera.prototype, "keysDown", {
        /**
         * Gets or Set the list of keyboard keys used to control the backward move of the camera.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysDown;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysDown = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FreeCamera.prototype, "keysLeft", {
        /**
         * Gets or Set the list of keyboard keys used to control the left strafe move of the camera.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysLeft;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysLeft = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FreeCamera.prototype, "keysRight", {
        /**
         * Gets or Set the list of keyboard keys used to control the right strafe move of the camera.
         */
        get: function () {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                return keyboard.keysRight;
            }
            return [];
        },
        set: function (value) {
            var keyboard = this.inputs.attached["keyboard"];
            if (keyboard) {
                keyboard.keysRight = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attached controls to the current camera.
     * @param element Defines the element the controls should be listened from
     * @param noPreventDefault Defines whether event caught by the controls should call preventdefault() (https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)
     */
    FreeCamera.prototype.attachControl = function (element, noPreventDefault) {
        this.inputs.attachElement(element, noPreventDefault);
    };
    /**
     * Detach the current controls from the camera.
     * The camera will stop reacting to inputs.
     * @param element Defines the element to stop listening the inputs from
     */
    FreeCamera.prototype.detachControl = function (element) {
        this.inputs.detachElement(element);
        this.cameraDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 0, 0);
        this.cameraRotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](0, 0);
    };
    Object.defineProperty(FreeCamera.prototype, "collisionMask", {
        /**
         * Define a collision mask to limit the list of object the camera can collide with
         */
        get: function () {
            return this._collisionMask;
        },
        set: function (mask) {
            this._collisionMask = !isNaN(mask) ? mask : -1;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    FreeCamera.prototype._collideWithWorld = function (displacement) {
        var globalPosition;
        if (this.parent) {
            globalPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinates(this.position, this.parent.getWorldMatrix());
        }
        else {
            globalPosition = this.position;
        }
        globalPosition.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPosition);
        this._oldPosition.addInPlace(this.ellipsoidOffset);
        var coordinator = this.getScene().collisionCoordinator;
        if (!this._collider) {
            this._collider = coordinator.createCollider();
        }
        this._collider._radius = this.ellipsoid;
        this._collider.collisionMask = this._collisionMask;
        //no need for clone, as long as gravity is not on.
        var actualDisplacement = displacement;
        //add gravity to the direction to prevent the dual-collision checking
        if (this.applyGravity) {
            //this prevents mending with cameraDirection, a global variable of the free camera class.
            actualDisplacement = displacement.add(this.getScene().gravity);
        }
        coordinator.getNewPosition(this._oldPosition, actualDisplacement, this._collider, 3, null, this._onCollisionPositionChange, this.uniqueId);
    };
    /** @hidden */
    FreeCamera.prototype._checkInputs = function () {
        if (!this._localDirection) {
            this._localDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
            this._transformedDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        }
        this.inputs.checkInputs();
        _super.prototype._checkInputs.call(this);
    };
    /** @hidden */
    FreeCamera.prototype._decideIfNeedsToMove = function () {
        return this._needMoveForGravity || Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0;
    };
    /** @hidden */
    FreeCamera.prototype._updatePosition = function () {
        if (this.checkCollisions && this.getScene().collisionsEnabled) {
            this._collideWithWorld(this.cameraDirection);
        }
        else {
            _super.prototype._updatePosition.call(this);
        }
    };
    /**
     * Destroy the camera and release the current resources hold by it.
     */
    FreeCamera.prototype.dispose = function () {
        this.inputs.clear();
        _super.prototype.dispose.call(this);
    };
    /**
     * Gets the current object class name.
     * @return the class name
     */
    FreeCamera.prototype.getClassName = function () {
        return "FreeCamera";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], FreeCamera.prototype, "ellipsoid", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], FreeCamera.prototype, "ellipsoidOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCamera.prototype, "checkCollisions", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], FreeCamera.prototype, "applyGravity", void 0);
    return FreeCamera;
}(_targetCamera__WEBPACK_IMPORTED_MODULE_4__["TargetCamera"]));



/***/ }),

/***/ "./Cameras/freeCameraInputsManager.ts":
/*!********************************************!*\
  !*** ./Cameras/freeCameraInputsManager.ts ***!
  \********************************************/
/*! exports provided: FreeCameraInputsManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FreeCameraInputsManager", function() { return FreeCameraInputsManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony import */ var _Cameras_Inputs_freeCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Cameras/Inputs/freeCameraKeyboardMoveInput */ "./Cameras/Inputs/freeCameraKeyboardMoveInput.ts");
/* harmony import */ var _Cameras_Inputs_freeCameraMouseInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Cameras/Inputs/freeCameraMouseInput */ "./Cameras/Inputs/freeCameraMouseInput.ts");
/* harmony import */ var _Cameras_Inputs_freeCameraTouchInput__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Cameras/Inputs/freeCameraTouchInput */ "./Cameras/Inputs/freeCameraTouchInput.ts");





/**
 * Default Inputs manager for the FreeCamera.
 * It groups all the default supported inputs for ease of use.
 * @see http://doc.babylonjs.com/how_to/customizing_camera_inputs
 */
var FreeCameraInputsManager = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FreeCameraInputsManager, _super);
    /**
     * Instantiates a new FreeCameraInputsManager.
     * @param camera Defines the camera the inputs belong to
     */
    function FreeCameraInputsManager(camera) {
        var _this = _super.call(this, camera) || this;
        /**
         * @hidden
         */
        _this._mouseInput = null;
        return _this;
    }
    /**
     * Add keyboard input support to the input manager.
     * @returns the current input manager
     */
    FreeCameraInputsManager.prototype.addKeyboard = function () {
        this.add(new _Cameras_Inputs_freeCameraKeyboardMoveInput__WEBPACK_IMPORTED_MODULE_2__["FreeCameraKeyboardMoveInput"]());
        return this;
    };
    /**
     * Add mouse input support to the input manager.
     * @param touchEnabled if the FreeCameraMouseInput should support touch (default: true)
     * @returns the current input manager
     */
    FreeCameraInputsManager.prototype.addMouse = function (touchEnabled) {
        if (touchEnabled === void 0) { touchEnabled = true; }
        if (!this._mouseInput) {
            this._mouseInput = new _Cameras_Inputs_freeCameraMouseInput__WEBPACK_IMPORTED_MODULE_3__["FreeCameraMouseInput"](touchEnabled);
            this.add(this._mouseInput);
        }
        return this;
    };
    /**
     * Removes the mouse input support from the manager
     * @returns the current input manager
     */
    FreeCameraInputsManager.prototype.removeMouse = function () {
        if (this._mouseInput) {
            this.remove(this._mouseInput);
        }
        return this;
    };
    /**
     * Add touch input support to the input manager.
     * @returns the current input manager
     */
    FreeCameraInputsManager.prototype.addTouch = function () {
        this.add(new _Cameras_Inputs_freeCameraTouchInput__WEBPACK_IMPORTED_MODULE_4__["FreeCameraTouchInput"]());
        return this;
    };
    /**
     * Remove all attached input methods from a camera
     */
    FreeCameraInputsManager.prototype.clear = function () {
        _super.prototype.clear.call(this);
        this._mouseInput = null;
    };
    return FreeCameraInputsManager;
}(_cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputsManager"]));



/***/ }),

/***/ "./Cameras/gamepadCamera.ts":
/*!**********************************!*\
  !*** ./Cameras/gamepadCamera.ts ***!
  \**********************************/
/*! exports provided: GamepadCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GamepadCamera", function() { return GamepadCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _universalCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./universalCamera */ "./Cameras/universalCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");




_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("GamepadCamera", function (name, scene) {
    return function () { return new GamepadCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
/**
 * This represents a FPS type of camera. This is only here for back compat purpose.
 * Please use the UniversalCamera instead as both are identical.
 * @see http://doc.babylonjs.com/features/cameras#universal-camera
 */
var GamepadCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GamepadCamera, _super);
    /**
     * Instantiates a new Gamepad Camera
     * This represents a FPS type of camera. This is only here for back compat purpose.
     * Please use the UniversalCamera instead as both are identical.
     * @see http://doc.babylonjs.com/features/cameras#universal-camera
     * @param name Define the name of the camera in the scene
     * @param position Define the start position of the camera in the scene
     * @param scene Define the scene the camera belongs to
     */
    function GamepadCamera(name, position, scene) {
        return _super.call(this, name, position, scene) || this;
    }
    /**
     * Gets the current object class name.
     * @return the class name
     */
    GamepadCamera.prototype.getClassName = function () {
        return "GamepadCamera";
    };
    return GamepadCamera;
}(_universalCamera__WEBPACK_IMPORTED_MODULE_1__["UniversalCamera"]));



/***/ }),

/***/ "./Cameras/index.ts":
/*!**************************!*\
  !*** ./Cameras/index.ts ***!
  \**************************/
/*! exports provided: CameraInputTypes, CameraInputsManager, Camera, TargetCamera, FreeCamera, FreeCameraInputsManager, TouchCamera, ArcRotateCamera, ArcRotateCameraInputsManager, DeviceOrientationCamera, FlyCamera, FlyCameraInputsManager, FollowCamera, ArcFollowCamera, FollowCameraInputsManager, GamepadCamera, UniversalCamera, VirtualJoysticksCamera, ArcRotateCameraGamepadInput, ArcRotateCameraKeyboardMoveInput, ArcRotateCameraMouseWheelInput, ArcRotateCameraPointersInput, ArcRotateCameraVRDeviceOrientationInput, FlyCameraKeyboardInput, FlyCameraMouseInput, FollowCameraKeyboardMoveInput, FollowCameraMouseWheelInput, FollowCameraPointersInput, FreeCameraDeviceOrientationInput, FreeCameraGamepadInput, FreeCameraKeyboardMoveInput, FreeCameraMouseInput, FreeCameraTouchInput, FreeCameraVirtualJoystickInput, AnaglyphArcRotateCamera, AnaglyphFreeCamera, AnaglyphGamepadCamera, AnaglyphUniversalCamera, StereoscopicArcRotateCamera, StereoscopicFreeCamera, StereoscopicGamepadCamera, StereoscopicUniversalCamera, VRCameraMetrics, VRDeviceOrientationArcRotateCamera, VRDeviceOrientationFreeCamera, VRDeviceOrientationGamepadCamera, OnAfterEnteringVRObservableEvent, VRExperienceHelper, WebVRFreeCamera, WebXRCamera, WebXREnterExitUIButton, WebXREnterExitUIOptions, WebXREnterExitUI, WebXRState, WebXRExperienceHelper, WebXRInput, WebXRControllerTeleportation, WebXRControllerPointerSelection, WebXRControllerModelLoader, WebXRController, WebXRManagedOutputCanvas, WebXRSessionManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Inputs_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Inputs/index */ "./Cameras/Inputs/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraGamepadInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraGamepadInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraKeyboardMoveInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraMouseWheelInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraMouseWheelInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraPointersInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraPointersInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraVRDeviceOrientationInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraVRDeviceOrientationInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraKeyboardInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FlyCameraKeyboardInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraMouseInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FlyCameraMouseInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraKeyboardMoveInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraMouseWheelInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraMouseWheelInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraPointersInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraPointersInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraDeviceOrientationInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraDeviceOrientationInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraGamepadInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraGamepadInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraKeyboardMoveInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraMouseInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraMouseInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraTouchInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraTouchInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraVirtualJoystickInput", function() { return _Inputs_index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraVirtualJoystickInput"]; });

/* harmony import */ var _cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cameraInputsManager */ "./Cameras/cameraInputsManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CameraInputTypes", function() { return _cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CameraInputsManager", function() { return _cameraInputsManager__WEBPACK_IMPORTED_MODULE_1__["CameraInputsManager"]; });

/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./camera */ "./Cameras/camera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"]; });

/* harmony import */ var _targetCamera__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./targetCamera */ "./Cameras/targetCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TargetCamera", function() { return _targetCamera__WEBPACK_IMPORTED_MODULE_3__["TargetCamera"]; });

/* harmony import */ var _freeCamera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./freeCamera */ "./Cameras/freeCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCamera", function() { return _freeCamera__WEBPACK_IMPORTED_MODULE_4__["FreeCamera"]; });

/* harmony import */ var _freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./freeCameraInputsManager */ "./Cameras/freeCameraInputsManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraInputsManager", function() { return _freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__["FreeCameraInputsManager"]; });

/* harmony import */ var _touchCamera__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./touchCamera */ "./Cameras/touchCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TouchCamera", function() { return _touchCamera__WEBPACK_IMPORTED_MODULE_6__["TouchCamera"]; });

/* harmony import */ var _arcRotateCamera__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./arcRotateCamera */ "./Cameras/arcRotateCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCamera", function() { return _arcRotateCamera__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCamera"]; });

/* harmony import */ var _arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./arcRotateCameraInputsManager */ "./Cameras/arcRotateCameraInputsManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraInputsManager", function() { return _arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_8__["ArcRotateCameraInputsManager"]; });

/* harmony import */ var _deviceOrientationCamera__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./deviceOrientationCamera */ "./Cameras/deviceOrientationCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DeviceOrientationCamera", function() { return _deviceOrientationCamera__WEBPACK_IMPORTED_MODULE_9__["DeviceOrientationCamera"]; });

/* harmony import */ var _flyCamera__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./flyCamera */ "./Cameras/flyCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCamera", function() { return _flyCamera__WEBPACK_IMPORTED_MODULE_10__["FlyCamera"]; });

/* harmony import */ var _flyCameraInputsManager__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./flyCameraInputsManager */ "./Cameras/flyCameraInputsManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraInputsManager", function() { return _flyCameraInputsManager__WEBPACK_IMPORTED_MODULE_11__["FlyCameraInputsManager"]; });

/* harmony import */ var _followCamera__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./followCamera */ "./Cameras/followCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCamera", function() { return _followCamera__WEBPACK_IMPORTED_MODULE_12__["FollowCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcFollowCamera", function() { return _followCamera__WEBPACK_IMPORTED_MODULE_12__["ArcFollowCamera"]; });

/* harmony import */ var _followCameraInputsManager__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./followCameraInputsManager */ "./Cameras/followCameraInputsManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraInputsManager", function() { return _followCameraInputsManager__WEBPACK_IMPORTED_MODULE_13__["FollowCameraInputsManager"]; });

/* harmony import */ var _gamepadCamera__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./gamepadCamera */ "./Cameras/gamepadCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadCamera", function() { return _gamepadCamera__WEBPACK_IMPORTED_MODULE_14__["GamepadCamera"]; });

/* harmony import */ var _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Stereoscopic/index */ "./Cameras/Stereoscopic/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphArcRotateCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["AnaglyphArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphFreeCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["AnaglyphFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphGamepadCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["AnaglyphGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphUniversalCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["AnaglyphUniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicArcRotateCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["StereoscopicArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicFreeCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["StereoscopicFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicGamepadCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["StereoscopicGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicUniversalCamera", function() { return _Stereoscopic_index__WEBPACK_IMPORTED_MODULE_15__["StereoscopicUniversalCamera"]; });

/* harmony import */ var _universalCamera__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./universalCamera */ "./Cameras/universalCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UniversalCamera", function() { return _universalCamera__WEBPACK_IMPORTED_MODULE_16__["UniversalCamera"]; });

/* harmony import */ var _virtualJoysticksCamera__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./virtualJoysticksCamera */ "./Cameras/virtualJoysticksCamera.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualJoysticksCamera", function() { return _virtualJoysticksCamera__WEBPACK_IMPORTED_MODULE_17__["VirtualJoysticksCamera"]; });

/* harmony import */ var _VR_index__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./VR/index */ "./Cameras/VR/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRCameraMetrics", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["VRCameraMetrics"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationArcRotateCamera", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["VRDeviceOrientationArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationFreeCamera", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["VRDeviceOrientationFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationGamepadCamera", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["VRDeviceOrientationGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OnAfterEnteringVRObservableEvent", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["OnAfterEnteringVRObservableEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRExperienceHelper", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["VRExperienceHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRFreeCamera", function() { return _VR_index__WEBPACK_IMPORTED_MODULE_18__["WebVRFreeCamera"]; });

/* harmony import */ var _XR_index__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./XR/index */ "./Cameras/XR/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRCamera", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIButton", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXREnterExitUIButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIOptions", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXREnterExitUIOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUI", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXREnterExitUI"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRState", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRExperienceHelper", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRExperienceHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRInput", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerTeleportation", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRControllerTeleportation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerPointerSelection", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRControllerPointerSelection"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerModelLoader", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRControllerModelLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRController", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRManagedOutputCanvas", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRManagedOutputCanvas"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRSessionManager", function() { return _XR_index__WEBPACK_IMPORTED_MODULE_19__["WebXRSessionManager"]; });























/***/ }),

/***/ "./Cameras/targetCamera.ts":
/*!*********************************!*\
  !*** ./Cameras/targetCamera.ts ***!
  \*********************************/
/*! exports provided: TargetCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TargetCamera", function() { return TargetCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./camera */ "./Cameras/camera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");






/**
 * A target camera takes a mesh or position as a target and continues to look at it while it moves.
 * This is the base of the follow, arc rotate cameras and Free camera
 * @see http://doc.babylonjs.com/features/cameras
 */
var TargetCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TargetCamera, _super);
    /**
     * Instantiates a target camera that takes a mesh or position as a target and continues to look at it while it moves.
     * This is the base of the follow, arc rotate cameras and Free camera
     * @see http://doc.babylonjs.com/features/cameras
     * @param name Defines the name of the camera in the scene
     * @param position Defines the start position of the camera in the scene
     * @param scene Defines the scene the camera belongs to
     * @param setActiveOnSceneIfNoneActive Defines wheter the camera should be marked as active if not other active cameras have been defined
     */
    function TargetCamera(name, position, scene, setActiveOnSceneIfNoneActive) {
        if (setActiveOnSceneIfNoneActive === void 0) { setActiveOnSceneIfNoneActive = true; }
        var _this = _super.call(this, name, position, scene, setActiveOnSceneIfNoneActive) || this;
        /**
         * Define the current direction the camera is moving to
         */
        _this.cameraDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        /**
         * Define the current rotation the camera is rotating to
         */
        _this.cameraRotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](0, 0);
        /**
         * When set, the up vector of the camera will be updated by the rotation of the camera
         */
        _this.updateUpVectorFromRotation = false;
        _this._tmpQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        /**
         * Define the current rotation of the camera
         */
        _this.rotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        /**
         * Define the current speed of the camera
         */
        _this.speed = 2.0;
        /**
         * Add cconstraint to the camera to prevent it to move freely in all directions and
         * around all axis.
         */
        _this.noRotationConstraint = false;
        /**
         * Define the current target of the camera as an object or a position.
         */
        _this.lockedTarget = null;
        /** @hidden */
        _this._currentTarget = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        /** @hidden */
        _this._initialFocalDistance = 1;
        /** @hidden */
        _this._viewMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        /** @hidden */
        _this._camMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        /** @hidden */
        _this._cameraTransformMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        /** @hidden */
        _this._cameraRotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        /** @hidden */
        _this._referencePoint = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 1);
        /** @hidden */
        _this._transformedReferencePoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._globalCurrentTarget = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._globalCurrentUpVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._defaultUp = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Up();
        _this._cachedRotationZ = 0;
        _this._cachedQuaternionRotationZ = 0;
        return _this;
    }
    /**
     * Gets the position in front of the camera at a given distance.
     * @param distance The distance from the camera we want the position to be
     * @returns the position
     */
    TargetCamera.prototype.getFrontPosition = function (distance) {
        this.getWorldMatrix();
        var direction = this.getTarget().subtract(this.position);
        direction.normalize();
        direction.scaleInPlace(distance);
        return this.globalPosition.add(direction);
    };
    /** @hidden */
    TargetCamera.prototype._getLockedTargetPosition = function () {
        if (!this.lockedTarget) {
            return null;
        }
        if (this.lockedTarget.absolutePosition) {
            this.lockedTarget.computeWorldMatrix();
        }
        return this.lockedTarget.absolutePosition || this.lockedTarget;
    };
    /**
     * Store current camera state of the camera (fov, position, rotation, etc..)
     * @returns the camera
     */
    TargetCamera.prototype.storeState = function () {
        this._storedPosition = this.position.clone();
        this._storedRotation = this.rotation.clone();
        if (this.rotationQuaternion) {
            this._storedRotationQuaternion = this.rotationQuaternion.clone();
        }
        return _super.prototype.storeState.call(this);
    };
    /**
     * Restored camera state. You must call storeState() first
     * @returns whether it was successful or not
     * @hidden
     */
    TargetCamera.prototype._restoreStateValues = function () {
        if (!_super.prototype._restoreStateValues.call(this)) {
            return false;
        }
        this.position = this._storedPosition.clone();
        this.rotation = this._storedRotation.clone();
        if (this.rotationQuaternion) {
            this.rotationQuaternion = this._storedRotationQuaternion.clone();
        }
        this.cameraDirection.copyFromFloats(0, 0, 0);
        this.cameraRotation.copyFromFloats(0, 0);
        return true;
    };
    /** @hidden */
    TargetCamera.prototype._initCache = function () {
        _super.prototype._initCache.call(this);
        this._cache.lockedTarget = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._cache.rotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._cache.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
    };
    /** @hidden */
    TargetCamera.prototype._updateCache = function (ignoreParentClass) {
        if (!ignoreParentClass) {
            _super.prototype._updateCache.call(this);
        }
        var lockedTargetPosition = this._getLockedTargetPosition();
        if (!lockedTargetPosition) {
            this._cache.lockedTarget = null;
        }
        else {
            if (!this._cache.lockedTarget) {
                this._cache.lockedTarget = lockedTargetPosition.clone();
            }
            else {
                this._cache.lockedTarget.copyFrom(lockedTargetPosition);
            }
        }
        this._cache.rotation.copyFrom(this.rotation);
        if (this.rotationQuaternion) {
            this._cache.rotationQuaternion.copyFrom(this.rotationQuaternion);
        }
    };
    // Synchronized
    /** @hidden */
    TargetCamera.prototype._isSynchronizedViewMatrix = function () {
        if (!_super.prototype._isSynchronizedViewMatrix.call(this)) {
            return false;
        }
        var lockedTargetPosition = this._getLockedTargetPosition();
        return (this._cache.lockedTarget ? this._cache.lockedTarget.equals(lockedTargetPosition) : !lockedTargetPosition)
            && (this.rotationQuaternion ? this.rotationQuaternion.equals(this._cache.rotationQuaternion) : this._cache.rotation.equals(this.rotation));
    };
    // Methods
    /** @hidden */
    TargetCamera.prototype._computeLocalCameraSpeed = function () {
        var engine = this.getEngine();
        return this.speed * Math.sqrt((engine.getDeltaTime() / (engine.getFps() * 100.0)));
    };
    // Target
    /**
     * Defines the target the camera should look at.
     * @param target Defines the new target as a Vector or a mesh
     */
    TargetCamera.prototype.setTarget = function (target) {
        this.upVector.normalize();
        this._initialFocalDistance = target.subtract(this.position).length();
        if (this.position.z === target.z) {
            this.position.z += _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["Epsilon"];
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].LookAtLHToRef(this.position, target, this._defaultUp, this._camMatrix);
        this._camMatrix.invert();
        this.rotation.x = Math.atan(this._camMatrix.m[6] / this._camMatrix.m[10]);
        var vDir = target.subtract(this.position);
        if (vDir.x >= 0.0) {
            this.rotation.y = (-Math.atan(vDir.z / vDir.x) + Math.PI / 2.0);
        }
        else {
            this.rotation.y = (-Math.atan(vDir.z / vDir.x) - Math.PI / 2.0);
        }
        this.rotation.z = 0;
        if (isNaN(this.rotation.x)) {
            this.rotation.x = 0;
        }
        if (isNaN(this.rotation.y)) {
            this.rotation.y = 0;
        }
        if (isNaN(this.rotation.z)) {
            this.rotation.z = 0;
        }
        if (this.rotationQuaternion) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this.rotationQuaternion);
        }
    };
    /**
     * Return the current target position of the camera. This value is expressed in local space.
     * @returns the target position
     */
    TargetCamera.prototype.getTarget = function () {
        return this._currentTarget;
    };
    /** @hidden */
    TargetCamera.prototype._decideIfNeedsToMove = function () {
        return Math.abs(this.cameraDirection.x) > 0 || Math.abs(this.cameraDirection.y) > 0 || Math.abs(this.cameraDirection.z) > 0;
    };
    /** @hidden */
    TargetCamera.prototype._updatePosition = function () {
        if (this.parent) {
            this.parent.getWorldMatrix().invertToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormalToRef(this.cameraDirection, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0], _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0]);
            this.position.addInPlace(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0]);
            return;
        }
        this.position.addInPlace(this.cameraDirection);
    };
    /** @hidden */
    TargetCamera.prototype._checkInputs = function () {
        var needToMove = this._decideIfNeedsToMove();
        var needToRotate = Math.abs(this.cameraRotation.x) > 0 || Math.abs(this.cameraRotation.y) > 0;
        // Move
        if (needToMove) {
            this._updatePosition();
        }
        // Rotate
        if (needToRotate) {
            this.rotation.x += this.cameraRotation.x;
            this.rotation.y += this.cameraRotation.y;
            //rotate, if quaternion is set and rotation was used
            if (this.rotationQuaternion) {
                var len = this.rotation.lengthSquared();
                if (len) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this.rotationQuaternion);
                }
            }
            if (!this.noRotationConstraint) {
                var limit = 1.570796;
                if (this.rotation.x > limit) {
                    this.rotation.x = limit;
                }
                if (this.rotation.x < -limit) {
                    this.rotation.x = -limit;
                }
            }
        }
        // Inertia
        if (needToMove) {
            if (Math.abs(this.cameraDirection.x) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["Epsilon"]) {
                this.cameraDirection.x = 0;
            }
            if (Math.abs(this.cameraDirection.y) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["Epsilon"]) {
                this.cameraDirection.y = 0;
            }
            if (Math.abs(this.cameraDirection.z) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["Epsilon"]) {
                this.cameraDirection.z = 0;
            }
            this.cameraDirection.scaleInPlace(this.inertia);
        }
        if (needToRotate) {
            if (Math.abs(this.cameraRotation.x) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["Epsilon"]) {
                this.cameraRotation.x = 0;
            }
            if (Math.abs(this.cameraRotation.y) < this.speed * _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["Epsilon"]) {
                this.cameraRotation.y = 0;
            }
            this.cameraRotation.scaleInPlace(this.inertia);
        }
        _super.prototype._checkInputs.call(this);
    };
    TargetCamera.prototype._updateCameraRotationMatrix = function () {
        if (this.rotationQuaternion) {
            this.rotationQuaternion.toRotationMatrix(this._cameraRotationMatrix);
        }
        else {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._cameraRotationMatrix);
        }
    };
    /**
     * Update the up vector to apply the rotation of the camera (So if you changed the camera rotation.z this will let you update the up vector as well)
     * @returns the current camera
     */
    TargetCamera.prototype._rotateUpVectorWithCameraRotationMatrix = function () {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormalToRef(this._defaultUp, this._cameraRotationMatrix, this.upVector);
        return this;
    };
    /** @hidden */
    TargetCamera.prototype._getViewMatrix = function () {
        if (this.lockedTarget) {
            this.setTarget(this._getLockedTargetPosition());
        }
        // Compute
        this._updateCameraRotationMatrix();
        // Apply the changed rotation to the upVector
        if (this.rotationQuaternion && this._cachedQuaternionRotationZ != this.rotationQuaternion.z) {
            this._rotateUpVectorWithCameraRotationMatrix();
            this._cachedQuaternionRotationZ = this.rotationQuaternion.z;
        }
        else if (this._cachedRotationZ != this.rotation.z) {
            this._rotateUpVectorWithCameraRotationMatrix();
            this._cachedRotationZ = this.rotation.z;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
        // Computing target and final matrix
        this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
        if (this.updateUpVectorFromRotation) {
            if (this.rotationQuaternion) {
                _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Y.rotateByQuaternionToRef(this.rotationQuaternion, this.upVector);
            }
            else {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].FromEulerVectorToRef(this.rotation, this._tmpQuaternion);
                _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Y.rotateByQuaternionToRef(this._tmpQuaternion, this.upVector);
            }
        }
        this._computeViewMatrix(this.position, this._currentTarget, this.upVector);
        return this._viewMatrix;
    };
    TargetCamera.prototype._computeViewMatrix = function (position, target, up) {
        if (this.parent) {
            var parentWorldMatrix = this.parent.getWorldMatrix();
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(position, parentWorldMatrix, this._globalPosition);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(target, parentWorldMatrix, this._globalCurrentTarget);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormalToRef(up, parentWorldMatrix, this._globalCurrentUpVector);
            this._markSyncedWithParent();
        }
        else {
            this._globalPosition.copyFrom(position);
            this._globalCurrentTarget.copyFrom(target);
            this._globalCurrentUpVector.copyFrom(up);
        }
        if (this.getScene().useRightHandedSystem) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].LookAtRHToRef(this._globalPosition, this._globalCurrentTarget, this._globalCurrentUpVector, this._viewMatrix);
        }
        else {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].LookAtLHToRef(this._globalPosition, this._globalCurrentTarget, this._globalCurrentUpVector, this._viewMatrix);
        }
    };
    /**
     * @hidden
     */
    TargetCamera.prototype.createRigCamera = function (name, cameraIndex) {
        if (this.cameraRigMode !== _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_NONE) {
            var rigCamera = new TargetCamera(name, this.position.clone(), this.getScene());
            if (this.cameraRigMode === _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_VR || this.cameraRigMode === _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_WEBVR) {
                if (!this.rotationQuaternion) {
                    this.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
                }
                rigCamera._cameraRigParams = {};
                rigCamera.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
            }
            return rigCamera;
        }
        return null;
    };
    /**
     * @hidden
     */
    TargetCamera.prototype._updateRigCameras = function () {
        var camLeft = this._rigCameras[0];
        var camRight = this._rigCameras[1];
        this.computeWorldMatrix();
        switch (this.cameraRigMode) {
            case _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_STEREOSCOPIC_ANAGLYPH:
            case _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_PARALLEL:
            case _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED:
            case _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_STEREOSCOPIC_OVERUNDER:
                //provisionnaly using _cameraRigParams.stereoHalfAngle instead of calculations based on _cameraRigParams.interaxialDistance:
                var leftSign = (this.cameraRigMode === _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? 1 : -1;
                var rightSign = (this.cameraRigMode === _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_STEREOSCOPIC_SIDEBYSIDE_CROSSEYED) ? -1 : 1;
                this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * leftSign, camLeft);
                this._getRigCamPositionAndTarget(this._cameraRigParams.stereoHalfAngle * rightSign, camRight);
                break;
            case _camera__WEBPACK_IMPORTED_MODULE_2__["Camera"].RIG_MODE_VR:
                if (camLeft.rotationQuaternion) {
                    camLeft.rotationQuaternion.copyFrom(this.rotationQuaternion);
                    camRight.rotationQuaternion.copyFrom(this.rotationQuaternion);
                }
                else {
                    camLeft.rotation.copyFrom(this.rotation);
                    camRight.rotation.copyFrom(this.rotation);
                }
                camLeft.position.copyFrom(this.position);
                camRight.position.copyFrom(this.position);
                break;
        }
        _super.prototype._updateRigCameras.call(this);
    };
    TargetCamera.prototype._getRigCamPositionAndTarget = function (halfSpace, rigCamera) {
        var target = this.getTarget();
        target.subtractToRef(this.position, TargetCamera._TargetFocalPoint);
        TargetCamera._TargetFocalPoint.normalize().scaleInPlace(this._initialFocalDistance);
        var newFocalTarget = TargetCamera._TargetFocalPoint.addInPlace(this.position);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].TranslationToRef(-newFocalTarget.x, -newFocalTarget.y, -newFocalTarget.z, TargetCamera._TargetTransformMatrix);
        TargetCamera._TargetTransformMatrix.multiplyToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationY(halfSpace), TargetCamera._RigCamTransformMatrix);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].TranslationToRef(newFocalTarget.x, newFocalTarget.y, newFocalTarget.z, TargetCamera._TargetTransformMatrix);
        TargetCamera._RigCamTransformMatrix.multiplyToRef(TargetCamera._TargetTransformMatrix, TargetCamera._RigCamTransformMatrix);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(this.position, TargetCamera._RigCamTransformMatrix, rigCamera.position);
        rigCamera.setTarget(newFocalTarget);
    };
    /**
     * Gets the current object class name.
     * @return the class name
     */
    TargetCamera.prototype.getClassName = function () {
        return "TargetCamera";
    };
    TargetCamera._RigCamTransformMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
    TargetCamera._TargetTransformMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
    TargetCamera._TargetFocalPoint = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"]();
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], TargetCamera.prototype, "rotation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], TargetCamera.prototype, "speed", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsMeshReference"])("lockedTargetId")
    ], TargetCamera.prototype, "lockedTarget", void 0);
    return TargetCamera;
}(_camera__WEBPACK_IMPORTED_MODULE_2__["Camera"]));



/***/ }),

/***/ "./Cameras/touchCamera.ts":
/*!********************************!*\
  !*** ./Cameras/touchCamera.ts ***!
  \********************************/
/*! exports provided: TouchCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TouchCamera", function() { return TouchCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _freeCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");




_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("TouchCamera", function (name, scene) {
    return function () { return new TouchCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
/**
 * This represents a FPS type of camera controlled by touch.
 * This is like a universal camera minus the Gamepad controls.
 * @see http://doc.babylonjs.com/features/cameras#universal-camera
 */
var TouchCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TouchCamera, _super);
    /**
     * Instantiates a new touch camera.
     * This represents a FPS type of camera controlled by touch.
     * This is like a universal camera minus the Gamepad controls.
     * @see http://doc.babylonjs.com/features/cameras#universal-camera
     * @param name Define the name of the camera in the scene
     * @param position Define the start position of the camera in the scene
     * @param scene Define the scene the camera belongs to
     */
    function TouchCamera(name, position, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.inputs.addTouch();
        _this._setupInputs();
        return _this;
    }
    Object.defineProperty(TouchCamera.prototype, "touchAngularSensibility", {
        /**
         * Defines the touch sensibility for rotation.
         * The higher the faster.
         */
        get: function () {
            var touch = this.inputs.attached["touch"];
            if (touch) {
                return touch.touchAngularSensibility;
            }
            return 0;
        },
        set: function (value) {
            var touch = this.inputs.attached["touch"];
            if (touch) {
                touch.touchAngularSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TouchCamera.prototype, "touchMoveSensibility", {
        /**
         * Defines the touch sensibility for move.
         * The higher the faster.
         */
        get: function () {
            var touch = this.inputs.attached["touch"];
            if (touch) {
                return touch.touchMoveSensibility;
            }
            return 0;
        },
        set: function (value) {
            var touch = this.inputs.attached["touch"];
            if (touch) {
                touch.touchMoveSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current object class name.
     * @return the class name
     */
    TouchCamera.prototype.getClassName = function () {
        return "TouchCamera";
    };
    /** @hidden */
    TouchCamera.prototype._setupInputs = function () {
        var mouse = this.inputs.attached["mouse"];
        if (mouse) {
            mouse.touchEnabled = false;
        }
    };
    return TouchCamera;
}(_freeCamera__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"]));



/***/ }),

/***/ "./Cameras/universalCamera.ts":
/*!************************************!*\
  !*** ./Cameras/universalCamera.ts ***!
  \************************************/
/*! exports provided: UniversalCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UniversalCamera", function() { return UniversalCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _touchCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./touchCamera */ "./Cameras/touchCamera.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _camera__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./camera */ "./Cameras/camera.ts");
/* harmony import */ var _Gamepads_gamepadSceneComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Gamepads/gamepadSceneComponent */ "./Gamepads/gamepadSceneComponent.ts");






_node__WEBPACK_IMPORTED_MODULE_2__["Node"].AddNodeConstructor("FreeCamera", function (name, scene) {
    // Forcing to use the Universal camera
    return function () { return new UniversalCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), scene); };
});
/**
 * The Universal Camera is the one to choose for first person shooter type games, and works with all the keyboard, mouse, touch and gamepads. This replaces the earlier Free Camera,
 * which still works and will still be found in many Playgrounds.
 * @see http://doc.babylonjs.com/features/cameras#universal-camera
 */
var UniversalCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](UniversalCamera, _super);
    /**
     * The Universal Camera is the one to choose for first person shooter type games, and works with all the keyboard, mouse, touch and gamepads. This replaces the earlier Free Camera,
     * which still works and will still be found in many Playgrounds.
     * @see http://doc.babylonjs.com/features/cameras#universal-camera
     * @param name Define the name of the camera in the scene
     * @param position Define the start position of the camera in the scene
     * @param scene Define the scene the camera belongs to
     */
    function UniversalCamera(name, position, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.inputs.addGamepad();
        return _this;
    }
    Object.defineProperty(UniversalCamera.prototype, "gamepadAngularSensibility", {
        /**
         * Defines the gamepad rotation sensiblity.
         * This is the threshold from when rotation starts to be accounted for to prevent jittering.
         */
        get: function () {
            var gamepad = this.inputs.attached["gamepad"];
            if (gamepad) {
                return gamepad.gamepadAngularSensibility;
            }
            return 0;
        },
        set: function (value) {
            var gamepad = this.inputs.attached["gamepad"];
            if (gamepad) {
                gamepad.gamepadAngularSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(UniversalCamera.prototype, "gamepadMoveSensibility", {
        /**
         * Defines the gamepad move sensiblity.
         * This is the threshold from when moving starts to be accounted for for to prevent jittering.
         */
        get: function () {
            var gamepad = this.inputs.attached["gamepad"];
            if (gamepad) {
                return gamepad.gamepadMoveSensibility;
            }
            return 0;
        },
        set: function (value) {
            var gamepad = this.inputs.attached["gamepad"];
            if (gamepad) {
                gamepad.gamepadMoveSensibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current object class name.
     * @return the class name
     */
    UniversalCamera.prototype.getClassName = function () {
        return "UniversalCamera";
    };
    return UniversalCamera;
}(_touchCamera__WEBPACK_IMPORTED_MODULE_1__["TouchCamera"]));

_camera__WEBPACK_IMPORTED_MODULE_4__["Camera"]._createDefaultParsedCamera = function (name, scene) {
    return new UniversalCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(), scene);
};


/***/ }),

/***/ "./Cameras/virtualJoysticksCamera.ts":
/*!*******************************************!*\
  !*** ./Cameras/virtualJoysticksCamera.ts ***!
  \*******************************************/
/*! exports provided: VirtualJoysticksCamera */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualJoysticksCamera", function() { return VirtualJoysticksCamera; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _freeCamera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Inputs_freeCameraVirtualJoystickInput__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Inputs/freeCameraVirtualJoystickInput */ "./Cameras/Inputs/freeCameraVirtualJoystickInput.ts");





_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("VirtualJoysticksCamera", function (name, scene) {
    return function () { return new VirtualJoysticksCamera(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
/**
 * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
 * It is identical to the Free Camera and simply adds by default a virtual joystick.
 * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
 * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
 */
var VirtualJoysticksCamera = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VirtualJoysticksCamera, _super);
    /**
     * Intantiates a VirtualJoysticksCamera. It can be useful in First Person Shooter game for instance.
     * It is identical to the Free Camera and simply adds by default a virtual joystick.
     * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
     * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
     * @param name Define the name of the camera in the scene
     * @param position Define the start position of the camera in the scene
     * @param scene Define the scene the camera belongs to
     */
    function VirtualJoysticksCamera(name, position, scene) {
        var _this = _super.call(this, name, position, scene) || this;
        _this.inputs.addVirtualJoystick();
        return _this;
    }
    /**
     * Gets the current object class name.
     * @return the class name
     */
    VirtualJoysticksCamera.prototype.getClassName = function () {
        return "VirtualJoysticksCamera";
    };
    return VirtualJoysticksCamera;
}(_freeCamera__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"]));



/***/ }),

/***/ "./Collisions/collider.ts":
/*!********************************!*\
  !*** ./Collisions/collider.ts ***!
  \********************************/
/*! exports provided: Collider */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Collider", function() { return Collider; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_plane__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.plane */ "./Maths/math.plane.ts");


var intersectBoxAASphere = function (boxMin, boxMax, sphereCenter, sphereRadius) {
    if (boxMin.x > sphereCenter.x + sphereRadius) {
        return false;
    }
    if (sphereCenter.x - sphereRadius > boxMax.x) {
        return false;
    }
    if (boxMin.y > sphereCenter.y + sphereRadius) {
        return false;
    }
    if (sphereCenter.y - sphereRadius > boxMax.y) {
        return false;
    }
    if (boxMin.z > sphereCenter.z + sphereRadius) {
        return false;
    }
    if (sphereCenter.z - sphereRadius > boxMax.z) {
        return false;
    }
    return true;
};
var getLowestRoot = (function () {
    var result = { root: 0, found: false };
    return function (a, b, c, maxR) {
        result.root = 0;
        result.found = false;
        var determinant = b * b - 4.0 * a * c;
        if (determinant < 0) {
            return result;
        }
        var sqrtD = Math.sqrt(determinant);
        var r1 = (-b - sqrtD) / (2.0 * a);
        var r2 = (-b + sqrtD) / (2.0 * a);
        if (r1 > r2) {
            var temp = r2;
            r2 = r1;
            r1 = temp;
        }
        if (r1 > 0 && r1 < maxR) {
            result.root = r1;
            result.found = true;
            return result;
        }
        if (r2 > 0 && r2 < maxR) {
            result.root = r2;
            result.found = true;
            return result;
        }
        return result;
    };
})();
/** @hidden */
var Collider = /** @class */ (function () {
    function Collider() {
        this._collisionPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._planeIntersectionPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._tempVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._tempVector2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._tempVector3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._tempVector4 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._edge = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._baseToVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._destinationPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._slidePlaneNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._displacementVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /** @hidden */
        this._radius = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].One();
        /** @hidden */
        this._retry = 0;
        /** @hidden */
        this._basePointWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._velocityWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._normalizedVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._collisionMask = -1;
    }
    Object.defineProperty(Collider.prototype, "collisionMask", {
        get: function () {
            return this._collisionMask;
        },
        set: function (mask) {
            this._collisionMask = !isNaN(mask) ? mask : -1;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Collider.prototype, "slidePlaneNormal", {
        /**
         * Gets the plane normal used to compute the sliding response (in local space)
         */
        get: function () {
            return this._slidePlaneNormal;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /** @hidden */
    Collider.prototype._initialize = function (source, dir, e) {
        this._velocity = dir;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].NormalizeToRef(dir, this._normalizedVelocity);
        this._basePoint = source;
        source.multiplyToRef(this._radius, this._basePointWorld);
        dir.multiplyToRef(this._radius, this._velocityWorld);
        this._velocityWorldLength = this._velocityWorld.length();
        this._epsilon = e;
        this.collisionFound = false;
    };
    /** @hidden */
    Collider.prototype._checkPointInTriangle = function (point, pa, pb, pc, n) {
        pa.subtractToRef(point, this._tempVector);
        pb.subtractToRef(point, this._tempVector2);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(this._tempVector, this._tempVector2, this._tempVector4);
        var d = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._tempVector4, n);
        if (d < 0) {
            return false;
        }
        pc.subtractToRef(point, this._tempVector3);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(this._tempVector2, this._tempVector3, this._tempVector4);
        d = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._tempVector4, n);
        if (d < 0) {
            return false;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(this._tempVector3, this._tempVector, this._tempVector4);
        d = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._tempVector4, n);
        return d >= 0;
    };
    /** @hidden */
    Collider.prototype._canDoCollision = function (sphereCenter, sphereRadius, vecMin, vecMax) {
        var distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Distance(this._basePointWorld, sphereCenter);
        var max = Math.max(this._radius.x, this._radius.y, this._radius.z);
        if (distance > this._velocityWorldLength + max + sphereRadius) {
            return false;
        }
        if (!intersectBoxAASphere(vecMin, vecMax, this._basePointWorld, this._velocityWorldLength + max)) {
            return false;
        }
        return true;
    };
    /** @hidden */
    Collider.prototype._testTriangle = function (faceIndex, trianglePlaneArray, p1, p2, p3, hasMaterial, hostMesh) {
        var t0;
        var embeddedInPlane = false;
        //defensive programming, actually not needed.
        if (!trianglePlaneArray) {
            trianglePlaneArray = [];
        }
        if (!trianglePlaneArray[faceIndex]) {
            trianglePlaneArray[faceIndex] = new _Maths_math_plane__WEBPACK_IMPORTED_MODULE_1__["Plane"](0, 0, 0, 0);
            trianglePlaneArray[faceIndex].copyFromPoints(p1, p2, p3);
        }
        var trianglePlane = trianglePlaneArray[faceIndex];
        if ((!hasMaterial) && !trianglePlane.isFrontFacingTo(this._normalizedVelocity, 0)) {
            return;
        }
        var signedDistToTrianglePlane = trianglePlane.signedDistanceTo(this._basePoint);
        var normalDotVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(trianglePlane.normal, this._velocity);
        if (normalDotVelocity == 0) {
            if (Math.abs(signedDistToTrianglePlane) >= 1.0) {
                return;
            }
            embeddedInPlane = true;
            t0 = 0;
        }
        else {
            t0 = (-1.0 - signedDistToTrianglePlane) / normalDotVelocity;
            var t1 = (1.0 - signedDistToTrianglePlane) / normalDotVelocity;
            if (t0 > t1) {
                var temp = t1;
                t1 = t0;
                t0 = temp;
            }
            if (t0 > 1.0 || t1 < 0.0) {
                return;
            }
            if (t0 < 0) {
                t0 = 0;
            }
            if (t0 > 1.0) {
                t0 = 1.0;
            }
        }
        this._collisionPoint.copyFromFloats(0, 0, 0);
        var found = false;
        var t = 1.0;
        if (!embeddedInPlane) {
            this._basePoint.subtractToRef(trianglePlane.normal, this._planeIntersectionPoint);
            this._velocity.scaleToRef(t0, this._tempVector);
            this._planeIntersectionPoint.addInPlace(this._tempVector);
            if (this._checkPointInTriangle(this._planeIntersectionPoint, p1, p2, p3, trianglePlane.normal)) {
                found = true;
                t = t0;
                this._collisionPoint.copyFrom(this._planeIntersectionPoint);
            }
        }
        if (!found) {
            var velocitySquaredLength = this._velocity.lengthSquared();
            var a = velocitySquaredLength;
            this._basePoint.subtractToRef(p1, this._tempVector);
            var b = 2.0 * (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._velocity, this._tempVector));
            var c = this._tempVector.lengthSquared() - 1.0;
            var lowestRoot = getLowestRoot(a, b, c, t);
            if (lowestRoot.found) {
                t = lowestRoot.root;
                found = true;
                this._collisionPoint.copyFrom(p1);
            }
            this._basePoint.subtractToRef(p2, this._tempVector);
            b = 2.0 * (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._velocity, this._tempVector));
            c = this._tempVector.lengthSquared() - 1.0;
            lowestRoot = getLowestRoot(a, b, c, t);
            if (lowestRoot.found) {
                t = lowestRoot.root;
                found = true;
                this._collisionPoint.copyFrom(p2);
            }
            this._basePoint.subtractToRef(p3, this._tempVector);
            b = 2.0 * (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._velocity, this._tempVector));
            c = this._tempVector.lengthSquared() - 1.0;
            lowestRoot = getLowestRoot(a, b, c, t);
            if (lowestRoot.found) {
                t = lowestRoot.root;
                found = true;
                this._collisionPoint.copyFrom(p3);
            }
            p2.subtractToRef(p1, this._edge);
            p1.subtractToRef(this._basePoint, this._baseToVertex);
            var edgeSquaredLength = this._edge.lengthSquared();
            var edgeDotVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._edge, this._velocity);
            var edgeDotBaseToVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._edge, this._baseToVertex);
            a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
            b = edgeSquaredLength * (2.0 * _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._velocity, this._baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
            lowestRoot = getLowestRoot(a, b, c, t);
            if (lowestRoot.found) {
                var f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;
                if (f >= 0.0 && f <= 1.0) {
                    t = lowestRoot.root;
                    found = true;
                    this._edge.scaleInPlace(f);
                    p1.addToRef(this._edge, this._collisionPoint);
                }
            }
            p3.subtractToRef(p2, this._edge);
            p2.subtractToRef(this._basePoint, this._baseToVertex);
            edgeSquaredLength = this._edge.lengthSquared();
            edgeDotVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._edge, this._velocity);
            edgeDotBaseToVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._edge, this._baseToVertex);
            a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
            b = edgeSquaredLength * (2.0 * _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._velocity, this._baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
            lowestRoot = getLowestRoot(a, b, c, t);
            if (lowestRoot.found) {
                f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;
                if (f >= 0.0 && f <= 1.0) {
                    t = lowestRoot.root;
                    found = true;
                    this._edge.scaleInPlace(f);
                    p2.addToRef(this._edge, this._collisionPoint);
                }
            }
            p1.subtractToRef(p3, this._edge);
            p3.subtractToRef(this._basePoint, this._baseToVertex);
            edgeSquaredLength = this._edge.lengthSquared();
            edgeDotVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._edge, this._velocity);
            edgeDotBaseToVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._edge, this._baseToVertex);
            a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
            b = edgeSquaredLength * (2.0 * _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._velocity, this._baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
            lowestRoot = getLowestRoot(a, b, c, t);
            if (lowestRoot.found) {
                f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;
                if (f >= 0.0 && f <= 1.0) {
                    t = lowestRoot.root;
                    found = true;
                    this._edge.scaleInPlace(f);
                    p3.addToRef(this._edge, this._collisionPoint);
                }
            }
        }
        if (found) {
            var distToCollision = t * this._velocity.length();
            if (!this.collisionFound || distToCollision < this._nearestDistance) {
                if (!this.intersectionPoint) {
                    this.intersectionPoint = this._collisionPoint.clone();
                }
                else {
                    this.intersectionPoint.copyFrom(this._collisionPoint);
                }
                this._nearestDistance = distToCollision;
                this.collisionFound = true;
                this.collidedMesh = hostMesh;
            }
        }
    };
    /** @hidden */
    Collider.prototype._collide = function (trianglePlaneArray, pts, indices, indexStart, indexEnd, decal, hasMaterial, hostMesh) {
        for (var i = indexStart; i < indexEnd; i += 3) {
            var p1 = pts[indices[i] - decal];
            var p2 = pts[indices[i + 1] - decal];
            var p3 = pts[indices[i + 2] - decal];
            this._testTriangle(i, trianglePlaneArray, p3, p2, p1, hasMaterial, hostMesh);
        }
    };
    /** @hidden */
    Collider.prototype._getResponse = function (pos, vel) {
        pos.addToRef(vel, this._destinationPoint);
        vel.scaleInPlace((this._nearestDistance / vel.length()));
        this._basePoint.addToRef(vel, pos);
        pos.subtractToRef(this.intersectionPoint, this._slidePlaneNormal);
        this._slidePlaneNormal.normalize();
        this._slidePlaneNormal.scaleToRef(this._epsilon, this._displacementVector);
        pos.addInPlace(this._displacementVector);
        this.intersectionPoint.addInPlace(this._displacementVector);
        this._slidePlaneNormal.scaleInPlace(_Maths_math_plane__WEBPACK_IMPORTED_MODULE_1__["Plane"].SignedDistanceToPlaneFromPositionAndNormal(this.intersectionPoint, this._slidePlaneNormal, this._destinationPoint));
        this._destinationPoint.subtractInPlace(this._slidePlaneNormal);
        this._destinationPoint.subtractToRef(this.intersectionPoint, vel);
    };
    return Collider;
}());



/***/ }),

/***/ "./Collisions/collisionCoordinator.ts":
/*!********************************************!*\
  !*** ./Collisions/collisionCoordinator.ts ***!
  \********************************************/
/*! exports provided: DefaultCollisionCoordinator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefaultCollisionCoordinator", function() { return DefaultCollisionCoordinator; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _collider__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./collider */ "./Collisions/collider.ts");




/** @hidden */
var DefaultCollisionCoordinator = /** @class */ (function () {
    function DefaultCollisionCoordinator() {
        this._scaledPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this._scaledVelocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this._finalPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
    }
    DefaultCollisionCoordinator.prototype.getNewPosition = function (position, displacement, collider, maximumRetry, excludedMesh, onNewPosition, collisionIndex) {
        position.divideToRef(collider._radius, this._scaledPosition);
        displacement.divideToRef(collider._radius, this._scaledVelocity);
        collider.collidedMesh = null;
        collider._retry = 0;
        collider._initialVelocity = this._scaledVelocity;
        collider._initialPosition = this._scaledPosition;
        this._collideWithWorld(this._scaledPosition, this._scaledVelocity, collider, maximumRetry, this._finalPosition, excludedMesh);
        this._finalPosition.multiplyInPlace(collider._radius);
        //run the callback
        onNewPosition(collisionIndex, this._finalPosition, collider.collidedMesh);
    };
    DefaultCollisionCoordinator.prototype.createCollider = function () {
        return new _collider__WEBPACK_IMPORTED_MODULE_3__["Collider"]();
    };
    DefaultCollisionCoordinator.prototype.init = function (scene) {
        this._scene = scene;
    };
    DefaultCollisionCoordinator.prototype._collideWithWorld = function (position, velocity, collider, maximumRetry, finalPosition, excludedMesh) {
        if (excludedMesh === void 0) { excludedMesh = null; }
        var closeDistance = _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].CollisionsEpsilon * 10.0;
        if (collider._retry >= maximumRetry) {
            finalPosition.copyFrom(position);
            return;
        }
        // Check if this is a mesh else camera or -1
        var collisionMask = (excludedMesh ? excludedMesh.collisionMask : collider.collisionMask);
        collider._initialize(position, velocity, closeDistance);
        // Check all meshes
        for (var index = 0; index < this._scene.meshes.length; index++) {
            var mesh = this._scene.meshes[index];
            if (mesh.isEnabled() && mesh.checkCollisions && mesh.subMeshes && mesh !== excludedMesh && ((collisionMask & mesh.collisionGroup) !== 0)) {
                mesh._checkCollision(collider);
            }
        }
        if (!collider.collisionFound) {
            position.addToRef(velocity, finalPosition);
            return;
        }
        if (velocity.x !== 0 || velocity.y !== 0 || velocity.z !== 0) {
            collider._getResponse(position, velocity);
        }
        if (velocity.length() <= closeDistance) {
            finalPosition.copyFrom(position);
            return;
        }
        collider._retry++;
        this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh);
    };
    return DefaultCollisionCoordinator;
}());

_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].CollisionCoordinatorFactory = function () {
    return new DefaultCollisionCoordinator();
};


/***/ }),

/***/ "./Collisions/index.ts":
/*!*****************************!*\
  !*** ./Collisions/index.ts ***!
  \*****************************/
/*! exports provided: Collider, DefaultCollisionCoordinator, PickingInfo, IntersectionInfo, _MeshCollisionData */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _collider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./collider */ "./Collisions/collider.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Collider", function() { return _collider__WEBPACK_IMPORTED_MODULE_0__["Collider"]; });

/* harmony import */ var _collisionCoordinator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./collisionCoordinator */ "./Collisions/collisionCoordinator.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultCollisionCoordinator", function() { return _collisionCoordinator__WEBPACK_IMPORTED_MODULE_1__["DefaultCollisionCoordinator"]; });

/* harmony import */ var _pickingInfo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./pickingInfo */ "./Collisions/pickingInfo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PickingInfo", function() { return _pickingInfo__WEBPACK_IMPORTED_MODULE_2__["PickingInfo"]; });

/* harmony import */ var _intersectionInfo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./intersectionInfo */ "./Collisions/intersectionInfo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IntersectionInfo", function() { return _intersectionInfo__WEBPACK_IMPORTED_MODULE_3__["IntersectionInfo"]; });

/* harmony import */ var _meshCollisionData__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./meshCollisionData */ "./Collisions/meshCollisionData.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_MeshCollisionData", function() { return _meshCollisionData__WEBPACK_IMPORTED_MODULE_4__["_MeshCollisionData"]; });








/***/ }),

/***/ "./Collisions/intersectionInfo.ts":
/*!****************************************!*\
  !*** ./Collisions/intersectionInfo.ts ***!
  \****************************************/
/*! exports provided: IntersectionInfo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IntersectionInfo", function() { return IntersectionInfo; });
/**
 * @hidden
 */
var IntersectionInfo = /** @class */ (function () {
    function IntersectionInfo(bu, bv, distance) {
        this.bu = bu;
        this.bv = bv;
        this.distance = distance;
        this.faceId = 0;
        this.subMeshId = 0;
    }
    return IntersectionInfo;
}());



/***/ }),

/***/ "./Collisions/meshCollisionData.ts":
/*!*****************************************!*\
  !*** ./Collisions/meshCollisionData.ts ***!
  \*****************************************/
/*! exports provided: _MeshCollisionData */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_MeshCollisionData", function() { return _MeshCollisionData; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");

/**
 * @hidden
 */
var _MeshCollisionData = /** @class */ (function () {
    function _MeshCollisionData() {
        this._checkCollisions = false;
        this._collisionMask = -1;
        this._collisionGroup = -1;
        this._collider = null;
        this._oldPositionForCollisions = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
        this._diffPositionForCollisions = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
    }
    return _MeshCollisionData;
}());



/***/ }),

/***/ "./Collisions/pickingInfo.ts":
/*!***********************************!*\
  !*** ./Collisions/pickingInfo.ts ***!
  \***********************************/
/*! exports provided: PickingInfo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PickingInfo", function() { return PickingInfo; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");


/**
     * Information about the result of picking within a scene
     * @see https://doc.babylonjs.com/babylon101/picking_collisions
     */
var PickingInfo = /** @class */ (function () {
    function PickingInfo() {
        /** @hidden */
        this._pickingUnavailable = false;
        /**
         * If the pick collided with an object
         */
        this.hit = false;
        /**
         * Distance away where the pick collided
         */
        this.distance = 0;
        /**
         * The location of pick collision
         */
        this.pickedPoint = null;
        /**
         * The mesh corresponding the the pick collision
         */
        this.pickedMesh = null;
        /** (See getTextureCoordinates) The barycentric U coordinate that is used when calculating the texture coordinates of the collision.*/
        this.bu = 0;
        /** (See getTextureCoordinates) The barycentric V coordinate that is used when calculating the texture coordinates of the collision.*/
        this.bv = 0;
        /** The index of the face on the mesh that was picked, or the index of the Line if the picked Mesh is a LinesMesh */
        this.faceId = -1;
        /** Id of the the submesh that was picked */
        this.subMeshId = 0;
        /** If a sprite was picked, this will be the sprite the pick collided with */
        this.pickedSprite = null;
        /**
         * If a mesh was used to do the picking (eg. 6dof controller) this will be populated.
         */
        this.originMesh = null;
        /**
         * The ray that was used to perform the picking.
         */
        this.ray = null;
    }
    /**
     * Gets the normal correspodning to the face the pick collided with
     * @param useWorldCoordinates If the resulting normal should be relative to the world (default: false)
     * @param useVerticesNormals If the vertices normals should be used to calculate the normal instead of the normal map
     * @returns The normal correspodning to the face the pick collided with
     */
    PickingInfo.prototype.getNormal = function (useWorldCoordinates, useVerticesNormals) {
        if (useWorldCoordinates === void 0) { useWorldCoordinates = false; }
        if (useVerticesNormals === void 0) { useVerticesNormals = true; }
        if (!this.pickedMesh || !this.pickedMesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind)) {
            return null;
        }
        var indices = this.pickedMesh.getIndices();
        if (!indices) {
            return null;
        }
        var result;
        if (useVerticesNormals) {
            var normals = this.pickedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind);
            var normal0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(normals, indices[this.faceId * 3] * 3);
            var normal1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(normals, indices[this.faceId * 3 + 1] * 3);
            var normal2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(normals, indices[this.faceId * 3 + 2] * 3);
            normal0 = normal0.scale(this.bu);
            normal1 = normal1.scale(this.bv);
            normal2 = normal2.scale(1.0 - this.bu - this.bv);
            result = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](normal0.x + normal1.x + normal2.x, normal0.y + normal1.y + normal2.y, normal0.z + normal1.z + normal2.z);
        }
        else {
            var positions = this.pickedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
            var vertex1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(positions, indices[this.faceId * 3] * 3);
            var vertex2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(positions, indices[this.faceId * 3 + 1] * 3);
            var vertex3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(positions, indices[this.faceId * 3 + 2] * 3);
            var p1p2 = vertex1.subtract(vertex2);
            var p3p2 = vertex3.subtract(vertex2);
            result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(p1p2, p3p2);
        }
        if (useWorldCoordinates) {
            var wm = this.pickedMesh.getWorldMatrix();
            if (this.pickedMesh.nonUniformScaling) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0].copyFrom(wm);
                wm = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
                wm.setTranslationFromFloats(0, 0, 0);
                wm.invert();
                wm.transposeToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[1]);
                wm = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[1];
            }
            result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(result, wm);
        }
        result.normalize();
        return result;
    };
    /**
     * Gets the texture coordinates of where the pick occured
     * @returns the vector containing the coordnates of the texture
     */
    PickingInfo.prototype.getTextureCoordinates = function () {
        if (!this.pickedMesh || !this.pickedMesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind)) {
            return null;
        }
        var indices = this.pickedMesh.getIndices();
        if (!indices) {
            return null;
        }
        var uvs = this.pickedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind);
        if (!uvs) {
            return null;
        }
        var uv0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].FromArray(uvs, indices[this.faceId * 3] * 2);
        var uv1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].FromArray(uvs, indices[this.faceId * 3 + 1] * 2);
        var uv2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].FromArray(uvs, indices[this.faceId * 3 + 2] * 2);
        uv0 = uv0.scale(this.bu);
        uv1 = uv1.scale(this.bv);
        uv2 = uv2.scale(1.0 - this.bu - this.bv);
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](uv0.x + uv1.x + uv2.x, uv0.y + uv1.y + uv2.y);
    };
    return PickingInfo;
}());



/***/ }),

/***/ "./Culling/Octrees/index.ts":
/*!**********************************!*\
  !*** ./Culling/Octrees/index.ts ***!
  \**********************************/
/*! exports provided: Octree, OctreeBlock, OctreeSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _octree__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./octree */ "./Culling/Octrees/octree.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Octree", function() { return _octree__WEBPACK_IMPORTED_MODULE_0__["Octree"]; });

/* harmony import */ var _octreeBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./octreeBlock */ "./Culling/Octrees/octreeBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeBlock", function() { return _octreeBlock__WEBPACK_IMPORTED_MODULE_1__["OctreeBlock"]; });

/* harmony import */ var _octreeSceneComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./octreeSceneComponent */ "./Culling/Octrees/octreeSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeSceneComponent", function() { return _octreeSceneComponent__WEBPACK_IMPORTED_MODULE_2__["OctreeSceneComponent"]; });






/***/ }),

/***/ "./Culling/Octrees/octree.ts":
/*!***********************************!*\
  !*** ./Culling/Octrees/octree.ts ***!
  \***********************************/
/*! exports provided: Octree */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Octree", function() { return Octree; });
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _octreeBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./octreeBlock */ "./Culling/Octrees/octreeBlock.ts");


/**
 * Octrees are a really powerful data structure that can quickly select entities based on space coordinates.
 * @see https://doc.babylonjs.com/how_to/optimizing_your_scene_with_octrees
 */
var Octree = /** @class */ (function () {
    /**
     * Creates a octree
     * @see https://doc.babylonjs.com/how_to/optimizing_your_scene_with_octrees
     * @param creationFunc function to be used to instatiate the octree
     * @param maxBlockCapacity defines the maximum number of meshes you want on your octree's leaves (default: 64)
     * @param maxDepth defines the maximum depth (sub-levels) for your octree. Default value is 2, which means 8 8 8 = 512 blocks :) (This parameter takes precedence over capacity.)
     */
    function Octree(creationFunc, maxBlockCapacity,
    /** Defines the maximum depth (sub-levels) for your octree. Default value is 2, which means 8 8 8 = 512 blocks :) (This parameter takes precedence over capacity.) */
    maxDepth) {
        if (maxDepth === void 0) { maxDepth = 2; }
        this.maxDepth = maxDepth;
        /**
         * Content stored in the octree
         */
        this.dynamicContent = new Array();
        this._maxBlockCapacity = maxBlockCapacity || 64;
        this._selectionContent = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArrayNoDuplicate"](1024);
        this._creationFunc = creationFunc;
    }
    // Methods
    /**
     * Updates the octree by adding blocks for the passed in meshes within the min and max world parameters
     * @param worldMin worldMin for the octree blocks var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
     * @param worldMax worldMax for the octree blocks var blockSize = new Vector3((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
     * @param entries meshes to be added to the octree blocks
     */
    Octree.prototype.update = function (worldMin, worldMax, entries) {
        _octreeBlock__WEBPACK_IMPORTED_MODULE_1__["OctreeBlock"]._CreateBlocks(worldMin, worldMax, entries, this._maxBlockCapacity, 0, this.maxDepth, this, this._creationFunc);
    };
    /**
     * Adds a mesh to the octree
     * @param entry Mesh to add to the octree
     */
    Octree.prototype.addMesh = function (entry) {
        for (var index = 0; index < this.blocks.length; index++) {
            var block = this.blocks[index];
            block.addEntry(entry);
        }
    };
    /**
     * Remove an element from the octree
     * @param entry defines the element to remove
     */
    Octree.prototype.removeMesh = function (entry) {
        for (var index = 0; index < this.blocks.length; index++) {
            var block = this.blocks[index];
            block.removeEntry(entry);
        }
    };
    /**
     * Selects an array of meshes within the frustum
     * @param frustumPlanes The frustum planes to use which will select all meshes within it
     * @param allowDuplicate If duplicate objects are allowed in the resulting object array
     * @returns array of meshes within the frustum
     */
    Octree.prototype.select = function (frustumPlanes, allowDuplicate) {
        this._selectionContent.reset();
        for (var index = 0; index < this.blocks.length; index++) {
            var block = this.blocks[index];
            block.select(frustumPlanes, this._selectionContent, allowDuplicate);
        }
        if (allowDuplicate) {
            this._selectionContent.concat(this.dynamicContent);
        }
        else {
            this._selectionContent.concatWithNoDuplicate(this.dynamicContent);
        }
        return this._selectionContent;
    };
    /**
     * Test if the octree intersect with the given bounding sphere and if yes, then add its content to the selection array
     * @param sphereCenter defines the bounding sphere center
     * @param sphereRadius defines the bounding sphere radius
     * @param allowDuplicate defines if the selection array can contains duplicated entries
     * @returns an array of objects that intersect the sphere
     */
    Octree.prototype.intersects = function (sphereCenter, sphereRadius, allowDuplicate) {
        this._selectionContent.reset();
        for (var index = 0; index < this.blocks.length; index++) {
            var block = this.blocks[index];
            block.intersects(sphereCenter, sphereRadius, this._selectionContent, allowDuplicate);
        }
        if (allowDuplicate) {
            this._selectionContent.concat(this.dynamicContent);
        }
        else {
            this._selectionContent.concatWithNoDuplicate(this.dynamicContent);
        }
        return this._selectionContent;
    };
    /**
    * Test if the octree intersect with the given ray and if yes, then add its content to resulting array
     * @param ray defines the ray to test with
     * @returns array of intersected objects
     */
    Octree.prototype.intersectsRay = function (ray) {
        this._selectionContent.reset();
        for (var index = 0; index < this.blocks.length; index++) {
            var block = this.blocks[index];
            block.intersectsRay(ray, this._selectionContent);
        }
        this._selectionContent.concatWithNoDuplicate(this.dynamicContent);
        return this._selectionContent;
    };
    /**
     * Adds a mesh into the octree block if it intersects the block
     */
    Octree.CreationFuncForMeshes = function (entry, block) {
        var boundingInfo = entry.getBoundingInfo();
        if (!entry.isBlocked && boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
            block.entries.push(entry);
        }
    };
    /**
     * Adds a submesh into the octree block if it intersects the block
     */
    Octree.CreationFuncForSubMeshes = function (entry, block) {
        var boundingInfo = entry.getBoundingInfo();
        if (boundingInfo.boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
            block.entries.push(entry);
        }
    };
    return Octree;
}());



/***/ }),

/***/ "./Culling/Octrees/octreeBlock.ts":
/*!****************************************!*\
  !*** ./Culling/Octrees/octreeBlock.ts ***!
  \****************************************/
/*! exports provided: OctreeBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OctreeBlock", function() { return OctreeBlock; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Culling_boundingBox__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Culling/boundingBox */ "./Culling/boundingBox.ts");


/**
 * Class used to store a cell in an octree
 * @see http://doc.babylonjs.com/how_to/optimizing_your_scene_with_octrees
 */
var OctreeBlock = /** @class */ (function () {
    /**
     * Creates a new block
     * @param minPoint defines the minimum vector (in world space) of the block's bounding box
     * @param maxPoint defines the maximum vector (in world space) of the block's bounding box
     * @param capacity defines the maximum capacity of this block (if capacity is reached the block will be split into sub blocks)
     * @param depth defines the current depth of this block in the octree
     * @param maxDepth defines the maximal depth allowed (beyond this value, the capacity is ignored)
     * @param creationFunc defines a callback to call when an element is added to the block
     */
    function OctreeBlock(minPoint, maxPoint, capacity, depth, maxDepth, creationFunc) {
        /**
         * Gets the content of the current block
         */
        this.entries = new Array();
        this._boundingVectors = new Array();
        this._capacity = capacity;
        this._depth = depth;
        this._maxDepth = maxDepth;
        this._creationFunc = creationFunc;
        this._minPoint = minPoint;
        this._maxPoint = maxPoint;
        this._boundingVectors.push(minPoint.clone());
        this._boundingVectors.push(maxPoint.clone());
        this._boundingVectors.push(minPoint.clone());
        this._boundingVectors[2].x = maxPoint.x;
        this._boundingVectors.push(minPoint.clone());
        this._boundingVectors[3].y = maxPoint.y;
        this._boundingVectors.push(minPoint.clone());
        this._boundingVectors[4].z = maxPoint.z;
        this._boundingVectors.push(maxPoint.clone());
        this._boundingVectors[5].z = minPoint.z;
        this._boundingVectors.push(maxPoint.clone());
        this._boundingVectors[6].x = minPoint.x;
        this._boundingVectors.push(maxPoint.clone());
        this._boundingVectors[7].y = minPoint.y;
    }
    Object.defineProperty(OctreeBlock.prototype, "capacity", {
        // Property
        /**
         * Gets the maximum capacity of this block (if capacity is reached the block will be split into sub blocks)
         */
        get: function () {
            return this._capacity;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(OctreeBlock.prototype, "minPoint", {
        /**
         * Gets the minimum vector (in world space) of the block's bounding box
         */
        get: function () {
            return this._minPoint;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(OctreeBlock.prototype, "maxPoint", {
        /**
         * Gets the maximum vector (in world space) of the block's bounding box
         */
        get: function () {
            return this._maxPoint;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /**
     * Add a new element to this block
     * @param entry defines the element to add
     */
    OctreeBlock.prototype.addEntry = function (entry) {
        if (this.blocks) {
            for (var index = 0; index < this.blocks.length; index++) {
                var block = this.blocks[index];
                block.addEntry(entry);
            }
            return;
        }
        this._creationFunc(entry, this);
        if (this.entries.length > this.capacity && this._depth < this._maxDepth) {
            this.createInnerBlocks();
        }
    };
    /**
     * Remove an element from this block
     * @param entry defines the element to remove
     */
    OctreeBlock.prototype.removeEntry = function (entry) {
        if (this.blocks) {
            for (var index = 0; index < this.blocks.length; index++) {
                var block = this.blocks[index];
                block.removeEntry(entry);
            }
            return;
        }
        var entryIndex = this.entries.indexOf(entry);
        if (entryIndex > -1) {
            this.entries.splice(entryIndex, 1);
        }
    };
    /**
     * Add an array of elements to this block
     * @param entries defines the array of elements to add
     */
    OctreeBlock.prototype.addEntries = function (entries) {
        for (var index = 0; index < entries.length; index++) {
            var mesh = entries[index];
            this.addEntry(mesh);
        }
    };
    /**
     * Test if the current block intersects the furstum planes and if yes, then add its content to the selection array
     * @param frustumPlanes defines the frustum planes to test
     * @param selection defines the array to store current content if selection is positive
     * @param allowDuplicate defines if the selection array can contains duplicated entries
     */
    OctreeBlock.prototype.select = function (frustumPlanes, selection, allowDuplicate) {
        if (_Culling_boundingBox__WEBPACK_IMPORTED_MODULE_1__["BoundingBox"].IsInFrustum(this._boundingVectors, frustumPlanes)) {
            if (this.blocks) {
                for (var index = 0; index < this.blocks.length; index++) {
                    var block = this.blocks[index];
                    block.select(frustumPlanes, selection, allowDuplicate);
                }
                return;
            }
            if (allowDuplicate) {
                selection.concat(this.entries);
            }
            else {
                selection.concatWithNoDuplicate(this.entries);
            }
        }
    };
    /**
     * Test if the current block intersect with the given bounding sphere and if yes, then add its content to the selection array
     * @param sphereCenter defines the bounding sphere center
     * @param sphereRadius defines the bounding sphere radius
     * @param selection defines the array to store current content if selection is positive
     * @param allowDuplicate defines if the selection array can contains duplicated entries
     */
    OctreeBlock.prototype.intersects = function (sphereCenter, sphereRadius, selection, allowDuplicate) {
        if (_Culling_boundingBox__WEBPACK_IMPORTED_MODULE_1__["BoundingBox"].IntersectsSphere(this._minPoint, this._maxPoint, sphereCenter, sphereRadius)) {
            if (this.blocks) {
                for (var index = 0; index < this.blocks.length; index++) {
                    var block = this.blocks[index];
                    block.intersects(sphereCenter, sphereRadius, selection, allowDuplicate);
                }
                return;
            }
            if (allowDuplicate) {
                selection.concat(this.entries);
            }
            else {
                selection.concatWithNoDuplicate(this.entries);
            }
        }
    };
    /**
     * Test if the current block intersect with the given ray and if yes, then add its content to the selection array
     * @param ray defines the ray to test with
     * @param selection defines the array to store current content if selection is positive
     */
    OctreeBlock.prototype.intersectsRay = function (ray, selection) {
        if (ray.intersectsBoxMinMax(this._minPoint, this._maxPoint)) {
            if (this.blocks) {
                for (var index = 0; index < this.blocks.length; index++) {
                    var block = this.blocks[index];
                    block.intersectsRay(ray, selection);
                }
                return;
            }
            selection.concatWithNoDuplicate(this.entries);
        }
    };
    /**
     * Subdivide the content into child blocks (this block will then be empty)
     */
    OctreeBlock.prototype.createInnerBlocks = function () {
        OctreeBlock._CreateBlocks(this._minPoint, this._maxPoint, this.entries, this._capacity, this._depth, this._maxDepth, this, this._creationFunc);
    };
    /**
     * @hidden
     */
    OctreeBlock._CreateBlocks = function (worldMin, worldMax, entries, maxBlockCapacity, currentDepth, maxDepth, target, creationFunc) {
        target.blocks = new Array();
        var blockSize = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]((worldMax.x - worldMin.x) / 2, (worldMax.y - worldMin.y) / 2, (worldMax.z - worldMin.z) / 2);
        // Segmenting space
        for (var x = 0; x < 2; x++) {
            for (var y = 0; y < 2; y++) {
                for (var z = 0; z < 2; z++) {
                    var localMin = worldMin.add(blockSize.multiplyByFloats(x, y, z));
                    var localMax = worldMin.add(blockSize.multiplyByFloats(x + 1, y + 1, z + 1));
                    var block = new OctreeBlock(localMin, localMax, maxBlockCapacity, currentDepth + 1, maxDepth, creationFunc);
                    block.addEntries(entries);
                    target.blocks.push(block);
                }
            }
        }
    };
    return OctreeBlock;
}());



/***/ }),

/***/ "./Culling/Octrees/octreeSceneComponent.ts":
/*!*************************************************!*\
  !*** ./Culling/Octrees/octreeSceneComponent.ts ***!
  \*************************************************/
/*! exports provided: OctreeSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OctreeSceneComponent", function() { return OctreeSceneComponent; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _octree__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./octree */ "./Culling/Octrees/octree.ts");






_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype.createOrUpdateSelectionOctree = function (maxCapacity, maxDepth) {
    if (maxCapacity === void 0) { maxCapacity = 64; }
    if (maxDepth === void 0) { maxDepth = 2; }
    var component = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_OCTREE);
    if (!component) {
        component = new OctreeSceneComponent(this);
        this._addComponent(component);
    }
    if (!this._selectionOctree) {
        this._selectionOctree = new _octree__WEBPACK_IMPORTED_MODULE_5__["Octree"](_octree__WEBPACK_IMPORTED_MODULE_5__["Octree"].CreationFuncForMeshes, maxCapacity, maxDepth);
    }
    var worldExtends = this.getWorldExtends();
    // Update octree
    this._selectionOctree.update(worldExtends.min, worldExtends.max, this.meshes);
    return this._selectionOctree;
};
Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype, "selectionOctree", {
    get: function () {
        return this._selectionOctree;
    },
    enumerable: true,
    configurable: true
});
/**
 * This function will create an octree to help to select the right submeshes for rendering, picking and collision computations.
 * Please note that you must have a decent number of submeshes to get performance improvements when using an octree
 * @param maxCapacity defines the maximum size of each block (64 by default)
 * @param maxDepth defines the maximum depth to use (no more than 2 levels by default)
 * @returns the new octree
 * @see https://www.babylonjs-playground.com/#NA4OQ#12
 * @see http://doc.babylonjs.com/how_to/optimizing_your_scene_with_octrees
 */
_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype.createOrUpdateSubmeshesOctree = function (maxCapacity, maxDepth) {
    if (maxCapacity === void 0) { maxCapacity = 64; }
    if (maxDepth === void 0) { maxDepth = 2; }
    var scene = this.getScene();
    var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_OCTREE);
    if (!component) {
        component = new OctreeSceneComponent(scene);
        scene._addComponent(component);
    }
    if (!this._submeshesOctree) {
        this._submeshesOctree = new _octree__WEBPACK_IMPORTED_MODULE_5__["Octree"](_octree__WEBPACK_IMPORTED_MODULE_5__["Octree"].CreationFuncForSubMeshes, maxCapacity, maxDepth);
    }
    this.computeWorldMatrix(true);
    var boundingInfo = this.getBoundingInfo();
    // Update octree
    var bbox = boundingInfo.boundingBox;
    this._submeshesOctree.update(bbox.minimumWorld, bbox.maximumWorld, this.subMeshes);
    return this._submeshesOctree;
};
/**
 * Defines the octree scene component responsible to manage any octrees
 * in a given scene.
 */
var OctreeSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function OctreeSceneComponent(scene) {
        /**
         * The component name help to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_OCTREE;
        /**
         * Indicates if the meshes have been checked to make sure they are isEnabled()
         */
        this.checksIsEnabled = true;
        this._tempRay = new _Culling_ray__WEBPACK_IMPORTED_MODULE_3__["Ray"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](1, 1, 1));
        this.scene = scene;
        this.scene.getActiveMeshCandidates = this.getActiveMeshCandidates.bind(this);
        this.scene.getActiveSubMeshCandidates = this.getActiveSubMeshCandidates.bind(this);
        this.scene.getCollidingSubMeshCandidates = this.getCollidingSubMeshCandidates.bind(this);
        this.scene.getIntersectingSubMeshCandidates = this.getIntersectingSubMeshCandidates.bind(this);
    }
    /**
     * Registers the component in a given scene
     */
    OctreeSceneComponent.prototype.register = function () {
        var _this = this;
        this.scene.onMeshRemovedObservable.add(function (mesh) {
            var sceneOctree = _this.scene.selectionOctree;
            if (sceneOctree !== undefined && sceneOctree !== null) {
                var index = sceneOctree.dynamicContent.indexOf(mesh);
                if (index !== -1) {
                    sceneOctree.dynamicContent.splice(index, 1);
                }
            }
        });
        this.scene.onMeshImportedObservable.add(function (mesh) {
            var sceneOctree = _this.scene.selectionOctree;
            if (sceneOctree !== undefined && sceneOctree !== null) {
                sceneOctree.addMesh(mesh);
            }
        });
    };
    /**
     * Return the list of active meshes
     * @returns the list of active meshes
     */
    OctreeSceneComponent.prototype.getActiveMeshCandidates = function () {
        if (this.scene._selectionOctree) {
            var selection = this.scene._selectionOctree.select(this.scene.frustumPlanes);
            return selection;
        }
        return this.scene._getDefaultMeshCandidates();
    };
    /**
     * Return the list of active sub meshes
     * @param mesh The mesh to get the candidates sub meshes from
     * @returns the list of active sub meshes
     */
    OctreeSceneComponent.prototype.getActiveSubMeshCandidates = function (mesh) {
        if (mesh._submeshesOctree && mesh.useOctreeForRenderingSelection) {
            var intersections = mesh._submeshesOctree.select(this.scene.frustumPlanes);
            return intersections;
        }
        return this.scene._getDefaultSubMeshCandidates(mesh);
    };
    /**
     * Return the list of sub meshes intersecting with a given local ray
     * @param mesh defines the mesh to find the submesh for
     * @param localRay defines the ray in local space
     * @returns the list of intersecting sub meshes
     */
    OctreeSceneComponent.prototype.getIntersectingSubMeshCandidates = function (mesh, localRay) {
        if (mesh._submeshesOctree && mesh.useOctreeForPicking) {
            _Culling_ray__WEBPACK_IMPORTED_MODULE_3__["Ray"].TransformToRef(localRay, mesh.getWorldMatrix(), this._tempRay);
            var intersections = mesh._submeshesOctree.intersectsRay(this._tempRay);
            return intersections;
        }
        return this.scene._getDefaultSubMeshCandidates(mesh);
    };
    /**
     * Return the list of sub meshes colliding with a collider
     * @param mesh defines the mesh to find the submesh for
     * @param collider defines the collider to evaluate the collision against
     * @returns the list of colliding sub meshes
     */
    OctreeSceneComponent.prototype.getCollidingSubMeshCandidates = function (mesh, collider) {
        if (mesh._submeshesOctree && mesh.useOctreeForCollisions) {
            var radius = collider._velocityWorldLength + Math.max(collider._radius.x, collider._radius.y, collider._radius.z);
            var intersections = mesh._submeshesOctree.intersects(collider._basePointWorld, radius);
            return intersections;
        }
        return this.scene._getDefaultSubMeshCandidates(mesh);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    OctreeSceneComponent.prototype.rebuild = function () {
        // Nothing to do here.
    };
    /**
     * Disposes the component and the associated ressources.
     */
    OctreeSceneComponent.prototype.dispose = function () {
        // Nothing to do here.
    };
    return OctreeSceneComponent;
}());



/***/ }),

/***/ "./Culling/boundingBox.ts":
/*!********************************!*\
  !*** ./Culling/boundingBox.ts ***!
  \********************************/
/*! exports provided: BoundingBox */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoundingBox", function() { return BoundingBox; });
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");



/**
 * Class used to store bounding box information
 */
var BoundingBox = /** @class */ (function () {
    /**
     * Creates a new bounding box
     * @param min defines the minimum vector (in local space)
     * @param max defines the maximum vector (in local space)
     * @param worldMatrix defines the new world matrix
     */
    function BoundingBox(min, max, worldMatrix) {
        /**
         * Gets the 8 vectors representing the bounding box in local space
         */
        this.vectors = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(8, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
        /**
         * Gets the center of the bounding box in local space
         */
        this.center = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the center of the bounding box in world space
         */
        this.centerWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the extend size in local space
         */
        this.extendSize = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the extend size in world space
         */
        this.extendSizeWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the OBB (object bounding box) directions
         */
        this.directions = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(3, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
        /**
         * Gets the 8 vectors representing the bounding box in world space
         */
        this.vectorsWorld = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(8, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
        /**
         * Gets the minimum vector in world space
         */
        this.minimumWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the maximum vector in world space
         */
        this.maximumWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the minimum vector in local space
         */
        this.minimum = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the maximum vector in local space
         */
        this.maximum = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.reConstruct(min, max, worldMatrix);
    }
    // Methods
    /**
     * Recreates the entire bounding box from scratch as if we call the constructor in place
     * @param min defines the new minimum vector (in local space)
     * @param max defines the new maximum vector (in local space)
     * @param worldMatrix defines the new world matrix
     */
    BoundingBox.prototype.reConstruct = function (min, max, worldMatrix) {
        var minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
        var vectors = this.vectors;
        this.minimum.copyFromFloats(minX, minY, minZ);
        this.maximum.copyFromFloats(maxX, maxY, maxZ);
        vectors[0].copyFromFloats(minX, minY, minZ);
        vectors[1].copyFromFloats(maxX, maxY, maxZ);
        vectors[2].copyFromFloats(maxX, minY, minZ);
        vectors[3].copyFromFloats(minX, maxY, minZ);
        vectors[4].copyFromFloats(minX, minY, maxZ);
        vectors[5].copyFromFloats(maxX, maxY, minZ);
        vectors[6].copyFromFloats(minX, maxY, maxZ);
        vectors[7].copyFromFloats(maxX, minY, maxZ);
        // OBB
        max.addToRef(min, this.center).scaleInPlace(0.5);
        max.subtractToRef(min, this.extendSize).scaleInPlace(0.5);
        this._worldMatrix = worldMatrix || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly;
        this._update(this._worldMatrix);
    };
    /**
     * Scale the current bounding box by applying a scale factor
     * @param factor defines the scale factor to apply
     * @returns the current bounding box
     */
    BoundingBox.prototype.scale = function (factor) {
        var tmpVectors = BoundingBox.TmpVector3;
        var diff = this.maximum.subtractToRef(this.minimum, tmpVectors[0]);
        var len = diff.length();
        diff.normalizeFromLength(len);
        var distance = len * factor;
        var newRadius = diff.scaleInPlace(distance * 0.5);
        var min = this.center.subtractToRef(newRadius, tmpVectors[1]);
        var max = this.center.addToRef(newRadius, tmpVectors[2]);
        this.reConstruct(min, max, this._worldMatrix);
        return this;
    };
    /**
     * Gets the world matrix of the bounding box
     * @returns a matrix
     */
    BoundingBox.prototype.getWorldMatrix = function () {
        return this._worldMatrix;
    };
    /** @hidden */
    BoundingBox.prototype._update = function (world) {
        var minWorld = this.minimumWorld;
        var maxWorld = this.maximumWorld;
        var directions = this.directions;
        var vectorsWorld = this.vectorsWorld;
        var vectors = this.vectors;
        if (!world.isIdentity()) {
            minWorld.setAll(Number.MAX_VALUE);
            maxWorld.setAll(-Number.MAX_VALUE);
            for (var index = 0; index < 8; ++index) {
                var v = vectorsWorld[index];
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(vectors[index], world, v);
                minWorld.minimizeInPlace(v);
                maxWorld.maximizeInPlace(v);
            }
            // Extend
            maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
            maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
        }
        else {
            minWorld.copyFrom(this.minimum);
            maxWorld.copyFrom(this.maximum);
            for (var index = 0; index < 8; ++index) {
                vectorsWorld[index].copyFrom(vectors[index]);
            }
            // Extend
            this.extendSizeWorld.copyFrom(this.extendSize);
            this.centerWorld.copyFrom(this.center);
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(world.m, 0, directions[0]);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(world.m, 4, directions[1]);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(world.m, 8, directions[2]);
        this._worldMatrix = world;
    };
    /**
     * Tests if the bounding box is intersecting the frustum planes
     * @param frustumPlanes defines the frustum planes to test
     * @returns true if there is an intersection
     */
    BoundingBox.prototype.isInFrustum = function (frustumPlanes) {
        return BoundingBox.IsInFrustum(this.vectorsWorld, frustumPlanes);
    };
    /**
     * Tests if the bounding box is entirely inside the frustum planes
     * @param frustumPlanes defines the frustum planes to test
     * @returns true if there is an inclusion
     */
    BoundingBox.prototype.isCompletelyInFrustum = function (frustumPlanes) {
        return BoundingBox.IsCompletelyInFrustum(this.vectorsWorld, frustumPlanes);
    };
    /**
     * Tests if a point is inside the bounding box
     * @param point defines the point to test
     * @returns true if the point is inside the bounding box
     */
    BoundingBox.prototype.intersectsPoint = function (point) {
        var min = this.minimumWorld;
        var max = this.maximumWorld;
        var minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
        var pointX = point.x, pointY = point.y, pointZ = point.z;
        var delta = -_Maths_math_constants__WEBPACK_IMPORTED_MODULE_2__["Epsilon"];
        if (maxX - pointX < delta || delta > pointX - minX) {
            return false;
        }
        if (maxY - pointY < delta || delta > pointY - minY) {
            return false;
        }
        if (maxZ - pointZ < delta || delta > pointZ - minZ) {
            return false;
        }
        return true;
    };
    /**
     * Tests if the bounding box intersects with a bounding sphere
     * @param sphere defines the sphere to test
     * @returns true if there is an intersection
     */
    BoundingBox.prototype.intersectsSphere = function (sphere) {
        return BoundingBox.IntersectsSphere(this.minimumWorld, this.maximumWorld, sphere.centerWorld, sphere.radiusWorld);
    };
    /**
     * Tests if the bounding box intersects with a box defined by a min and max vectors
     * @param min defines the min vector to use
     * @param max defines the max vector to use
     * @returns true if there is an intersection
     */
    BoundingBox.prototype.intersectsMinMax = function (min, max) {
        var myMin = this.minimumWorld;
        var myMax = this.maximumWorld;
        var myMinX = myMin.x, myMinY = myMin.y, myMinZ = myMin.z, myMaxX = myMax.x, myMaxY = myMax.y, myMaxZ = myMax.z;
        var minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
        if (myMaxX < minX || myMinX > maxX) {
            return false;
        }
        if (myMaxY < minY || myMinY > maxY) {
            return false;
        }
        if (myMaxZ < minZ || myMinZ > maxZ) {
            return false;
        }
        return true;
    };
    // Statics
    /**
     * Tests if two bounding boxes are intersections
     * @param box0 defines the first box to test
     * @param box1 defines the second box to test
     * @returns true if there is an intersection
     */
    BoundingBox.Intersects = function (box0, box1) {
        return box0.intersectsMinMax(box1.minimumWorld, box1.maximumWorld);
    };
    /**
     * Tests if a bounding box defines by a min/max vectors intersects a sphere
     * @param minPoint defines the minimum vector of the bounding box
     * @param maxPoint defines the maximum vector of the bounding box
     * @param sphereCenter defines the sphere center
     * @param sphereRadius defines the sphere radius
     * @returns true if there is an intersection
     */
    BoundingBox.IntersectsSphere = function (minPoint, maxPoint, sphereCenter, sphereRadius) {
        var vector = BoundingBox.TmpVector3[0];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].ClampToRef(sphereCenter, minPoint, maxPoint, vector);
        var num = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].DistanceSquared(sphereCenter, vector);
        return (num <= (sphereRadius * sphereRadius));
    };
    /**
     * Tests if a bounding box defined with 8 vectors is entirely inside frustum planes
     * @param boundingVectors defines an array of 8 vectors representing a bounding box
     * @param frustumPlanes defines the frustum planes to test
     * @return true if there is an inclusion
     */
    BoundingBox.IsCompletelyInFrustum = function (boundingVectors, frustumPlanes) {
        for (var p = 0; p < 6; ++p) {
            var frustumPlane = frustumPlanes[p];
            for (var i = 0; i < 8; ++i) {
                if (frustumPlane.dotCoordinate(boundingVectors[i]) < 0) {
                    return false;
                }
            }
        }
        return true;
    };
    /**
     * Tests if a bounding box defined with 8 vectors intersects frustum planes
     * @param boundingVectors defines an array of 8 vectors representing a bounding box
     * @param frustumPlanes defines the frustum planes to test
     * @return true if there is an intersection
     */
    BoundingBox.IsInFrustum = function (boundingVectors, frustumPlanes) {
        for (var p = 0; p < 6; ++p) {
            var canReturnFalse = true;
            var frustumPlane = frustumPlanes[p];
            for (var i = 0; i < 8; ++i) {
                if (frustumPlane.dotCoordinate(boundingVectors[i]) >= 0) {
                    canReturnFalse = false;
                    break;
                }
            }
            if (canReturnFalse) {
                return false;
            }
        }
        return true;
    };
    BoundingBox.TmpVector3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(3, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
    return BoundingBox;
}());



/***/ }),

/***/ "./Culling/boundingInfo.ts":
/*!*********************************!*\
  !*** ./Culling/boundingInfo.ts ***!
  \*********************************/
/*! exports provided: BoundingInfo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoundingInfo", function() { return BoundingInfo; });
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _boundingBox__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./boundingBox */ "./Culling/boundingBox.ts");
/* harmony import */ var _boundingSphere__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./boundingSphere */ "./Culling/boundingSphere.ts");





var _result0 = { min: 0, max: 0 };
var _result1 = { min: 0, max: 0 };
var computeBoxExtents = function (axis, box, result) {
    var p = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(box.centerWorld, axis);
    var r0 = Math.abs(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(box.directions[0], axis)) * box.extendSize.x;
    var r1 = Math.abs(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(box.directions[1], axis)) * box.extendSize.y;
    var r2 = Math.abs(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(box.directions[2], axis)) * box.extendSize.z;
    var r = r0 + r1 + r2;
    result.min = p - r;
    result.max = p + r;
};
var axisOverlap = function (axis, box0, box1) {
    computeBoxExtents(axis, box0, _result0);
    computeBoxExtents(axis, box1, _result1);
    return !(_result0.min > _result1.max || _result1.min > _result0.max);
};
/**
 * Info for a bounding data of a mesh
 */
var BoundingInfo = /** @class */ (function () {
    /**
     * Constructs bounding info
     * @param minimum min vector of the bounding box/sphere
     * @param maximum max vector of the bounding box/sphere
     * @param worldMatrix defines the new world matrix
     */
    function BoundingInfo(minimum, maximum, worldMatrix) {
        this._isLocked = false;
        this.boundingBox = new _boundingBox__WEBPACK_IMPORTED_MODULE_3__["BoundingBox"](minimum, maximum, worldMatrix);
        this.boundingSphere = new _boundingSphere__WEBPACK_IMPORTED_MODULE_4__["BoundingSphere"](minimum, maximum, worldMatrix);
    }
    /**
     * Recreates the entire bounding info from scratch as if we call the constructor in place
     * @param min defines the new minimum vector (in local space)
     * @param max defines the new maximum vector (in local space)
     * @param worldMatrix defines the new world matrix
     */
    BoundingInfo.prototype.reConstruct = function (min, max, worldMatrix) {
        this.boundingBox.reConstruct(min, max, worldMatrix);
        this.boundingSphere.reConstruct(min, max, worldMatrix);
    };
    Object.defineProperty(BoundingInfo.prototype, "minimum", {
        /**
         * min vector of the bounding box/sphere
         */
        get: function () {
            return this.boundingBox.minimum;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BoundingInfo.prototype, "maximum", {
        /**
         * max vector of the bounding box/sphere
         */
        get: function () {
            return this.boundingBox.maximum;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BoundingInfo.prototype, "isLocked", {
        /**
         * If the info is locked and won't be updated to avoid perf overhead
         */
        get: function () {
            return this._isLocked;
        },
        set: function (value) {
            this._isLocked = value;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /**
     * Updates the bounding sphere and box
     * @param world world matrix to be used to update
     */
    BoundingInfo.prototype.update = function (world) {
        if (this._isLocked) {
            return;
        }
        this.boundingBox._update(world);
        this.boundingSphere._update(world);
    };
    /**
     * Recreate the bounding info to be centered around a specific point given a specific extend.
     * @param center New center of the bounding info
     * @param extend New extend of the bounding info
     * @returns the current bounding info
     */
    BoundingInfo.prototype.centerOn = function (center, extend) {
        var minimum = BoundingInfo.TmpVector3[0].copyFrom(center).subtractInPlace(extend);
        var maximum = BoundingInfo.TmpVector3[1].copyFrom(center).addInPlace(extend);
        this.boundingBox.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());
        this.boundingSphere.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix());
        return this;
    };
    /**
     * Scale the current bounding info by applying a scale factor
     * @param factor defines the scale factor to apply
     * @returns the current bounding info
     */
    BoundingInfo.prototype.scale = function (factor) {
        this.boundingBox.scale(factor);
        this.boundingSphere.scale(factor);
        return this;
    };
    /**
     * Returns `true` if the bounding info is within the frustum defined by the passed array of planes.
     * @param frustumPlanes defines the frustum to test
     * @param strategy defines the strategy to use for the culling (default is BABYLON.AbstractMesh.CULLINGSTRATEGY_STANDARD)
     * @returns true if the bounding info is in the frustum planes
     */
    BoundingInfo.prototype.isInFrustum = function (frustumPlanes, strategy) {
        if (strategy === void 0) { strategy = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].MESHES_CULLINGSTRATEGY_STANDARD; }
        var inclusionTest = (strategy === _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION || strategy === _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY);
        if (inclusionTest) {
            if (this.boundingSphere.isCenterInFrustum(frustumPlanes)) {
                return true;
            }
        }
        if (!this.boundingSphere.isInFrustum(frustumPlanes)) {
            return false;
        }
        var bSphereOnlyTest = (strategy === _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY || strategy === _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY);
        if (bSphereOnlyTest) {
            return true;
        }
        return this.boundingBox.isInFrustum(frustumPlanes);
    };
    Object.defineProperty(BoundingInfo.prototype, "diagonalLength", {
        /**
         * Gets the world distance between the min and max points of the bounding box
         */
        get: function () {
            var boundingBox = this.boundingBox;
            var diag = boundingBox.maximumWorld.subtractToRef(boundingBox.minimumWorld, BoundingInfo.TmpVector3[0]);
            return diag.length();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Checks if a cullable object (mesh...) is in the camera frustum
     * Unlike isInFrustum this cheks the full bounding box
     * @param frustumPlanes Camera near/planes
     * @returns true if the object is in frustum otherwise false
     */
    BoundingInfo.prototype.isCompletelyInFrustum = function (frustumPlanes) {
        return this.boundingBox.isCompletelyInFrustum(frustumPlanes);
    };
    /** @hidden */
    BoundingInfo.prototype._checkCollision = function (collider) {
        return collider._canDoCollision(this.boundingSphere.centerWorld, this.boundingSphere.radiusWorld, this.boundingBox.minimumWorld, this.boundingBox.maximumWorld);
    };
    /**
     * Checks if a point is inside the bounding box and bounding sphere or the mesh
     * @see https://doc.babylonjs.com/babylon101/intersect_collisions_-_mesh
     * @param point the point to check intersection with
     * @returns if the point intersects
     */
    BoundingInfo.prototype.intersectsPoint = function (point) {
        if (!this.boundingSphere.centerWorld) {
            return false;
        }
        if (!this.boundingSphere.intersectsPoint(point)) {
            return false;
        }
        if (!this.boundingBox.intersectsPoint(point)) {
            return false;
        }
        return true;
    };
    /**
     * Checks if another bounding info intersects the bounding box and bounding sphere or the mesh
     * @see https://doc.babylonjs.com/babylon101/intersect_collisions_-_mesh
     * @param boundingInfo the bounding info to check intersection with
     * @param precise if the intersection should be done using OBB
     * @returns if the bounding info intersects
     */
    BoundingInfo.prototype.intersects = function (boundingInfo, precise) {
        if (!_boundingSphere__WEBPACK_IMPORTED_MODULE_4__["BoundingSphere"].Intersects(this.boundingSphere, boundingInfo.boundingSphere)) {
            return false;
        }
        if (!_boundingBox__WEBPACK_IMPORTED_MODULE_3__["BoundingBox"].Intersects(this.boundingBox, boundingInfo.boundingBox)) {
            return false;
        }
        if (!precise) {
            return true;
        }
        var box0 = this.boundingBox;
        var box1 = boundingInfo.boundingBox;
        if (!axisOverlap(box0.directions[0], box0, box1)) {
            return false;
        }
        if (!axisOverlap(box0.directions[1], box0, box1)) {
            return false;
        }
        if (!axisOverlap(box0.directions[2], box0, box1)) {
            return false;
        }
        if (!axisOverlap(box1.directions[0], box0, box1)) {
            return false;
        }
        if (!axisOverlap(box1.directions[1], box0, box1)) {
            return false;
        }
        if (!axisOverlap(box1.directions[2], box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[0], box1.directions[0]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[0], box1.directions[1]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[0], box1.directions[2]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[1], box1.directions[0]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[1], box1.directions[1]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[1], box1.directions[2]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[2], box1.directions[0]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[2], box1.directions[1]), box0, box1)) {
            return false;
        }
        if (!axisOverlap(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(box0.directions[2], box1.directions[2]), box0, box1)) {
            return false;
        }
        return true;
    };
    BoundingInfo.TmpVector3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(2, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
    return BoundingInfo;
}());



/***/ }),

/***/ "./Culling/boundingSphere.ts":
/*!***********************************!*\
  !*** ./Culling/boundingSphere.ts ***!
  \***********************************/
/*! exports provided: BoundingSphere */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoundingSphere", function() { return BoundingSphere; });
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");


/**
 * Class used to store bounding sphere information
 */
var BoundingSphere = /** @class */ (function () {
    /**
     * Creates a new bounding sphere
     * @param min defines the minimum vector (in local space)
     * @param max defines the maximum vector (in local space)
     * @param worldMatrix defines the new world matrix
     */
    function BoundingSphere(min, max, worldMatrix) {
        /**
         * Gets the center of the bounding sphere in local space
         */
        this.center = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the center of the bounding sphere in world space
         */
        this.centerWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the minimum vector in local space
         */
        this.minimum = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        /**
         * Gets the maximum vector in local space
         */
        this.maximum = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this.reConstruct(min, max, worldMatrix);
    }
    /**
     * Recreates the entire bounding sphere from scratch as if we call the constructor in place
     * @param min defines the new minimum vector (in local space)
     * @param max defines the new maximum vector (in local space)
     * @param worldMatrix defines the new world matrix
     */
    BoundingSphere.prototype.reConstruct = function (min, max, worldMatrix) {
        this.minimum.copyFrom(min);
        this.maximum.copyFrom(max);
        var distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Distance(min, max);
        max.addToRef(min, this.center).scaleInPlace(0.5);
        this.radius = distance * 0.5;
        this._update(worldMatrix || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly);
    };
    /**
     * Scale the current bounding sphere by applying a scale factor
     * @param factor defines the scale factor to apply
     * @returns the current bounding box
     */
    BoundingSphere.prototype.scale = function (factor) {
        var newRadius = this.radius * factor;
        var tmpVectors = BoundingSphere.TmpVector3;
        var tempRadiusVector = tmpVectors[0].setAll(newRadius);
        var min = this.center.subtractToRef(tempRadiusVector, tmpVectors[1]);
        var max = this.center.addToRef(tempRadiusVector, tmpVectors[2]);
        this.reConstruct(min, max, this._worldMatrix);
        return this;
    };
    /**
     * Gets the world matrix of the bounding box
     * @returns a matrix
     */
    BoundingSphere.prototype.getWorldMatrix = function () {
        return this._worldMatrix;
    };
    // Methods
    /** @hidden */
    BoundingSphere.prototype._update = function (worldMatrix) {
        if (!worldMatrix.isIdentity()) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(this.center, worldMatrix, this.centerWorld);
            var tempVector = BoundingSphere.TmpVector3[0];
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, worldMatrix, tempVector);
            this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
        }
        else {
            this.centerWorld.copyFrom(this.center);
            this.radiusWorld = this.radius;
        }
    };
    /**
     * Tests if the bounding sphere is intersecting the frustum planes
     * @param frustumPlanes defines the frustum planes to test
     * @returns true if there is an intersection
     */
    BoundingSphere.prototype.isInFrustum = function (frustumPlanes) {
        var center = this.centerWorld;
        var radius = this.radiusWorld;
        for (var i = 0; i < 6; i++) {
            if (frustumPlanes[i].dotCoordinate(center) <= -radius) {
                return false;
            }
        }
        return true;
    };
    /**
     * Tests if the bounding sphere center is in between the frustum planes.
     * Used for optimistic fast inclusion.
     * @param frustumPlanes defines the frustum planes to test
     * @returns true if the sphere center is in between the frustum planes
     */
    BoundingSphere.prototype.isCenterInFrustum = function (frustumPlanes) {
        var center = this.centerWorld;
        for (var i = 0; i < 6; i++) {
            if (frustumPlanes[i].dotCoordinate(center) < 0) {
                return false;
            }
        }
        return true;
    };
    /**
     * Tests if a point is inside the bounding sphere
     * @param point defines the point to test
     * @returns true if the point is inside the bounding sphere
     */
    BoundingSphere.prototype.intersectsPoint = function (point) {
        var squareDistance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].DistanceSquared(this.centerWorld, point);
        if (this.radiusWorld * this.radiusWorld < squareDistance) {
            return false;
        }
        return true;
    };
    // Statics
    /**
     * Checks if two sphere intersct
     * @param sphere0 sphere 0
     * @param sphere1 sphere 1
     * @returns true if the speres intersect
     */
    BoundingSphere.Intersects = function (sphere0, sphere1) {
        var squareDistance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].DistanceSquared(sphere0.centerWorld, sphere1.centerWorld);
        var radiusSum = sphere0.radiusWorld + sphere1.radiusWorld;
        if (radiusSum * radiusSum < squareDistance) {
            return false;
        }
        return true;
    };
    BoundingSphere.TmpVector3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(3, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
    return BoundingSphere;
}());



/***/ }),

/***/ "./Culling/index.ts":
/*!**************************!*\
  !*** ./Culling/index.ts ***!
  \**************************/
/*! exports provided: BoundingBox, BoundingInfo, BoundingSphere, Ray, Octree, OctreeBlock, OctreeSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _boundingBox__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./boundingBox */ "./Culling/boundingBox.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBox", function() { return _boundingBox__WEBPACK_IMPORTED_MODULE_0__["BoundingBox"]; });

/* harmony import */ var _boundingInfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingInfo", function() { return _boundingInfo__WEBPACK_IMPORTED_MODULE_1__["BoundingInfo"]; });

/* harmony import */ var _boundingSphere__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./boundingSphere */ "./Culling/boundingSphere.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingSphere", function() { return _boundingSphere__WEBPACK_IMPORTED_MODULE_2__["BoundingSphere"]; });

/* harmony import */ var _Octrees_index__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Octrees/index */ "./Culling/Octrees/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Octree", function() { return _Octrees_index__WEBPACK_IMPORTED_MODULE_3__["Octree"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeBlock", function() { return _Octrees_index__WEBPACK_IMPORTED_MODULE_3__["OctreeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeSceneComponent", function() { return _Octrees_index__WEBPACK_IMPORTED_MODULE_3__["OctreeSceneComponent"]; });

/* harmony import */ var _ray__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ray */ "./Culling/ray.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Ray", function() { return _ray__WEBPACK_IMPORTED_MODULE_4__["Ray"]; });








/***/ }),

/***/ "./Culling/ray.ts":
/*!************************!*\
  !*** ./Culling/ray.ts ***!
  \************************/
/*! exports provided: Ray */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Ray", function() { return Ray; });
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Collisions/pickingInfo */ "./Collisions/pickingInfo.ts");
/* harmony import */ var _Collisions_intersectionInfo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Collisions/intersectionInfo */ "./Collisions/intersectionInfo.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Cameras/camera */ "./Cameras/camera.ts");






/**
 * Class representing a ray with position and direction
 */
var Ray = /** @class */ (function () {
    /**
     * Creates a new ray
     * @param origin origin point
     * @param direction direction
     * @param length length of the ray
     */
    function Ray(
    /** origin point */
    origin,
    /** direction */
    direction,
    /** length of the ray */
    length) {
        if (length === void 0) { length = Number.MAX_VALUE; }
        this.origin = origin;
        this.direction = direction;
        this.length = length;
    }
    // Methods
    /**
     * Checks if the ray intersects a box
     * @param minimum bound of the box
     * @param maximum bound of the box
     * @param intersectionTreshold extra extend to be added to the box in all direction
     * @returns if the box was hit
     */
    Ray.prototype.intersectsBoxMinMax = function (minimum, maximum, intersectionTreshold) {
        if (intersectionTreshold === void 0) { intersectionTreshold = 0; }
        var newMinimum = Ray.TmpVector3[0].copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);
        var newMaximum = Ray.TmpVector3[1].copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);
        var d = 0.0;
        var maxValue = Number.MAX_VALUE;
        var inv;
        var min;
        var max;
        var temp;
        if (Math.abs(this.direction.x) < 0.0000001) {
            if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {
                return false;
            }
        }
        else {
            inv = 1.0 / this.direction.x;
            min = (newMinimum.x - this.origin.x) * inv;
            max = (newMaximum.x - this.origin.x) * inv;
            if (max === -Infinity) {
                max = Infinity;
            }
            if (min > max) {
                temp = min;
                min = max;
                max = temp;
            }
            d = Math.max(min, d);
            maxValue = Math.min(max, maxValue);
            if (d > maxValue) {
                return false;
            }
        }
        if (Math.abs(this.direction.y) < 0.0000001) {
            if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {
                return false;
            }
        }
        else {
            inv = 1.0 / this.direction.y;
            min = (newMinimum.y - this.origin.y) * inv;
            max = (newMaximum.y - this.origin.y) * inv;
            if (max === -Infinity) {
                max = Infinity;
            }
            if (min > max) {
                temp = min;
                min = max;
                max = temp;
            }
            d = Math.max(min, d);
            maxValue = Math.min(max, maxValue);
            if (d > maxValue) {
                return false;
            }
        }
        if (Math.abs(this.direction.z) < 0.0000001) {
            if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {
                return false;
            }
        }
        else {
            inv = 1.0 / this.direction.z;
            min = (newMinimum.z - this.origin.z) * inv;
            max = (newMaximum.z - this.origin.z) * inv;
            if (max === -Infinity) {
                max = Infinity;
            }
            if (min > max) {
                temp = min;
                min = max;
                max = temp;
            }
            d = Math.max(min, d);
            maxValue = Math.min(max, maxValue);
            if (d > maxValue) {
                return false;
            }
        }
        return true;
    };
    /**
     * Checks if the ray intersects a box
     * @param box the bounding box to check
     * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
     * @returns if the box was hit
     */
    Ray.prototype.intersectsBox = function (box, intersectionTreshold) {
        if (intersectionTreshold === void 0) { intersectionTreshold = 0; }
        return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);
    };
    /**
     * If the ray hits a sphere
     * @param sphere the bounding sphere to check
     * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction
     * @returns true if it hits the sphere
     */
    Ray.prototype.intersectsSphere = function (sphere, intersectionTreshold) {
        if (intersectionTreshold === void 0) { intersectionTreshold = 0; }
        var x = sphere.center.x - this.origin.x;
        var y = sphere.center.y - this.origin.y;
        var z = sphere.center.z - this.origin.z;
        var pyth = (x * x) + (y * y) + (z * z);
        var radius = sphere.radius + intersectionTreshold;
        var rr = radius * radius;
        if (pyth <= rr) {
            return true;
        }
        var dot = (x * this.direction.x) + (y * this.direction.y) + (z * this.direction.z);
        if (dot < 0.0) {
            return false;
        }
        var temp = pyth - (dot * dot);
        return temp <= rr;
    };
    /**
     * If the ray hits a triange
     * @param vertex0 triangle vertex
     * @param vertex1 triangle vertex
     * @param vertex2 triangle vertex
     * @returns intersection information if hit
     */
    Ray.prototype.intersectsTriangle = function (vertex0, vertex1, vertex2) {
        var edge1 = Ray.TmpVector3[0];
        var edge2 = Ray.TmpVector3[1];
        var pvec = Ray.TmpVector3[2];
        var tvec = Ray.TmpVector3[3];
        var qvec = Ray.TmpVector3[4];
        vertex1.subtractToRef(vertex0, edge1);
        vertex2.subtractToRef(vertex0, edge2);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(this.direction, edge2, pvec);
        var det = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(edge1, pvec);
        if (det === 0) {
            return null;
        }
        var invdet = 1 / det;
        this.origin.subtractToRef(vertex0, tvec);
        var bv = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(tvec, pvec) * invdet;
        if (bv < 0 || bv > 1.0) {
            return null;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(tvec, edge1, qvec);
        var bw = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(this.direction, qvec) * invdet;
        if (bw < 0 || bv + bw > 1.0) {
            return null;
        }
        //check if the distance is longer than the predefined length.
        var distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(edge2, qvec) * invdet;
        if (distance > this.length) {
            return null;
        }
        return new _Collisions_intersectionInfo__WEBPACK_IMPORTED_MODULE_3__["IntersectionInfo"](1 - bv - bw, bv, distance);
    };
    /**
     * Checks if ray intersects a plane
     * @param plane the plane to check
     * @returns the distance away it was hit
     */
    Ray.prototype.intersectsPlane = function (plane) {
        var distance;
        var result1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(plane.normal, this.direction);
        if (Math.abs(result1) < 9.99999997475243E-07) {
            return null;
        }
        else {
            var result2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(plane.normal, this.origin);
            distance = (-plane.d - result2) / result1;
            if (distance < 0.0) {
                if (distance < -9.99999997475243E-07) {
                    return null;
                }
                else {
                    return 0;
                }
            }
            return distance;
        }
    };
    /**
     * Calculate the intercept of a ray on a given axis
     * @param axis to check 'x' | 'y' | 'z'
     * @param offset from axis interception (i.e. an offset of 1y is intercepted above ground)
     * @returns a vector containing the coordinates where 'axis' is equal to zero (else offset), or null if there is no intercept.
     */
    Ray.prototype.intersectsAxis = function (axis, offset) {
        if (offset === void 0) { offset = 0; }
        switch (axis) {
            case 'y':
                var t = (this.origin.y - offset) / this.direction.y;
                if (t > 0) {
                    return null;
                }
                return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](this.origin.x + (this.direction.x * -t), offset, this.origin.z + (this.direction.z * -t));
            case 'x':
                var t = (this.origin.x - offset) / this.direction.x;
                if (t > 0) {
                    return null;
                }
                return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](offset, this.origin.y + (this.direction.y * -t), this.origin.z + (this.direction.z * -t));
            case 'z':
                var t = (this.origin.z - offset) / this.direction.z;
                if (t > 0) {
                    return null;
                }
                return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](this.origin.x + (this.direction.x * -t), this.origin.y + (this.direction.y * -t), offset);
            default:
                return null;
        }
    };
    /**
     * Checks if ray intersects a mesh
     * @param mesh the mesh to check
     * @param fastCheck if only the bounding box should checked
     * @returns picking info of the intersecton
     */
    Ray.prototype.intersectsMesh = function (mesh, fastCheck) {
        var tm = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Matrix[0];
        mesh.getWorldMatrix().invertToRef(tm);
        if (this._tmpRay) {
            Ray.TransformToRef(this, tm, this._tmpRay);
        }
        else {
            this._tmpRay = Ray.Transform(this, tm);
        }
        return mesh.intersects(this._tmpRay, fastCheck);
    };
    /**
     * Checks if ray intersects a mesh
     * @param meshes the meshes to check
     * @param fastCheck if only the bounding box should checked
     * @param results array to store result in
     * @returns Array of picking infos
     */
    Ray.prototype.intersectsMeshes = function (meshes, fastCheck, results) {
        if (results) {
            results.length = 0;
        }
        else {
            results = [];
        }
        for (var i = 0; i < meshes.length; i++) {
            var pickInfo = this.intersectsMesh(meshes[i], fastCheck);
            if (pickInfo.hit) {
                results.push(pickInfo);
            }
        }
        results.sort(this._comparePickingInfo);
        return results;
    };
    Ray.prototype._comparePickingInfo = function (pickingInfoA, pickingInfoB) {
        if (pickingInfoA.distance < pickingInfoB.distance) {
            return -1;
        }
        else if (pickingInfoA.distance > pickingInfoB.distance) {
            return 1;
        }
        else {
            return 0;
        }
    };
    /**
     * Intersection test between the ray and a given segment whithin a given tolerance (threshold)
     * @param sega the first point of the segment to test the intersection against
     * @param segb the second point of the segment to test the intersection against
     * @param threshold the tolerance margin, if the ray doesn't intersect the segment but is close to the given threshold, the intersection is successful
     * @return the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection
     */
    Ray.prototype.intersectionSegment = function (sega, segb, threshold) {
        var o = this.origin;
        var u = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[0];
        var rsegb = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[1];
        var v = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[2];
        var w = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[3];
        segb.subtractToRef(sega, u);
        this.direction.scaleToRef(Ray.rayl, v);
        o.addToRef(v, rsegb);
        sega.subtractToRef(o, w);
        var a = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(u, u); // always >= 0
        var b = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(u, v);
        var c = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(v, v); // always >= 0
        var d = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(u, w);
        var e = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(v, w);
        var D = a * c - b * b; // always >= 0
        var sc, sN, sD = D; // sc = sN / sD, default sD = D >= 0
        var tc, tN, tD = D; // tc = tN / tD, default tD = D >= 0
        // compute the line parameters of the two closest points
        if (D < Ray.smallnum) { // the lines are almost parallel
            sN = 0.0; // force using point P0 on segment S1
            sD = 1.0; // to prevent possible division by 0.0 later
            tN = e;
            tD = c;
        }
        else { // get the closest points on the infinite lines
            sN = (b * e - c * d);
            tN = (a * e - b * d);
            if (sN < 0.0) { // sc < 0 => the s=0 edge is visible
                sN = 0.0;
                tN = e;
                tD = c;
            }
            else if (sN > sD) { // sc > 1 => the s=1 edge is visible
                sN = sD;
                tN = e + b;
                tD = c;
            }
        }
        if (tN < 0.0) { // tc < 0 => the t=0 edge is visible
            tN = 0.0;
            // recompute sc for this edge
            if (-d < 0.0) {
                sN = 0.0;
            }
            else if (-d > a) {
                sN = sD;
            }
            else {
                sN = -d;
                sD = a;
            }
        }
        else if (tN > tD) { // tc > 1 => the t=1 edge is visible
            tN = tD;
            // recompute sc for this edge
            if ((-d + b) < 0.0) {
                sN = 0;
            }
            else if ((-d + b) > a) {
                sN = sD;
            }
            else {
                sN = (-d + b);
                sD = a;
            }
        }
        // finally do the division to get sc and tc
        sc = (Math.abs(sN) < Ray.smallnum ? 0.0 : sN / sD);
        tc = (Math.abs(tN) < Ray.smallnum ? 0.0 : tN / tD);
        // get the difference of the two closest points
        var qtc = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[4];
        v.scaleToRef(tc, qtc);
        var qsc = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[5];
        u.scaleToRef(sc, qsc);
        qsc.addInPlace(w);
        var dP = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[6];
        qsc.subtractToRef(qtc, dP); // = S1(sc) - S2(tc)
        var isIntersected = (tc > 0) && (tc <= this.length) && (dP.lengthSquared() < (threshold * threshold)); // return intersection result
        if (isIntersected) {
            return qsc.length();
        }
        return -1;
    };
    /**
     * Update the ray from viewport position
     * @param x position
     * @param y y position
     * @param viewportWidth viewport width
     * @param viewportHeight viewport height
     * @param world world matrix
     * @param view view matrix
     * @param projection projection matrix
     * @returns this ray updated
     */
    Ray.prototype.update = function (x, y, viewportWidth, viewportHeight, world, view, projection) {
        this.unprojectRayToRef(x, y, viewportWidth, viewportHeight, world, view, projection);
        return this;
    };
    // Statics
    /**
     * Creates a ray with origin and direction of 0,0,0
     * @returns the new ray
     */
    Ray.Zero = function () {
        return new Ray(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero());
    };
    /**
     * Creates a new ray from screen space and viewport
     * @param x position
     * @param y y position
     * @param viewportWidth viewport width
     * @param viewportHeight viewport height
     * @param world world matrix
     * @param view view matrix
     * @param projection projection matrix
     * @returns new ray
     */
    Ray.CreateNew = function (x, y, viewportWidth, viewportHeight, world, view, projection) {
        var result = Ray.Zero();
        return result.update(x, y, viewportWidth, viewportHeight, world, view, projection);
    };
    /**
    * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be
    * transformed to the given world matrix.
    * @param origin The origin point
    * @param end The end point
    * @param world a matrix to transform the ray to. Default is the identity matrix.
    * @returns the new ray
    */
    Ray.CreateNewFromTo = function (origin, end, world) {
        if (world === void 0) { world = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly; }
        var direction = end.subtract(origin);
        var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
        direction.normalize();
        return Ray.Transform(new Ray(origin, direction, length), world);
    };
    /**
     * Transforms a ray by a matrix
     * @param ray ray to transform
     * @param matrix matrix to apply
     * @returns the resulting new ray
     */
    Ray.Transform = function (ray, matrix) {
        var result = new Ray(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, 0));
        Ray.TransformToRef(ray, matrix, result);
        return result;
    };
    /**
     * Transforms a ray by a matrix
     * @param ray ray to transform
     * @param matrix matrix to apply
     * @param result ray to store result in
     */
    Ray.TransformToRef = function (ray, matrix, result) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(ray.origin, matrix, result.origin);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalToRef(ray.direction, matrix, result.direction);
        result.length = ray.length;
        var dir = result.direction;
        var len = dir.length();
        if (!(len === 0 || len === 1)) {
            var num = 1.0 / len;
            dir.x *= num;
            dir.y *= num;
            dir.z *= num;
            result.length *= len;
        }
    };
    /**
      * Unproject a ray from screen space to object space
      * @param sourceX defines the screen space x coordinate to use
      * @param sourceY defines the screen space y coordinate to use
      * @param viewportWidth defines the current width of the viewport
      * @param viewportHeight defines the current height of the viewport
      * @param world defines the world matrix to use (can be set to Identity to go to world space)
      * @param view defines the view matrix to use
      * @param projection defines the projection matrix to use
      */
    Ray.prototype.unprojectRayToRef = function (sourceX, sourceY, viewportWidth, viewportHeight, world, view, projection) {
        var matrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Matrix[0];
        world.multiplyToRef(view, matrix);
        matrix.multiplyToRef(projection, matrix);
        matrix.invert();
        var nearScreenSource = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[0];
        nearScreenSource.x = sourceX / viewportWidth * 2 - 1;
        nearScreenSource.y = -(sourceY / viewportHeight * 2 - 1);
        nearScreenSource.z = -1.0;
        var farScreenSource = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0);
        var nearVec3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[2];
        var farVec3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[3];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]._UnprojectFromInvertedMatrixToRef(nearScreenSource, matrix, nearVec3);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]._UnprojectFromInvertedMatrixToRef(farScreenSource, matrix, farVec3);
        this.origin.copyFrom(nearVec3);
        farVec3.subtractToRef(nearVec3, this.direction);
        this.direction.normalize();
    };
    Ray.TmpVector3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_0__["ArrayTools"].BuildArray(6, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero);
    Ray.smallnum = 0.00000001;
    Ray.rayl = 10e8;
    return Ray;
}());

_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.createPickingRay = function (x, y, world, camera, cameraViewSpace) {
    if (cameraViewSpace === void 0) { cameraViewSpace = false; }
    var result = Ray.Zero();
    this.createPickingRayToRef(x, y, world, result, camera, cameraViewSpace);
    return result;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.createPickingRayToRef = function (x, y, world, result, camera, cameraViewSpace) {
    if (cameraViewSpace === void 0) { cameraViewSpace = false; }
    var engine = this.getEngine();
    if (!camera) {
        if (!this.activeCamera) {
            throw new Error("Active camera not set");
        }
        camera = this.activeCamera;
    }
    var cameraViewport = camera.viewport;
    var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
    // Moving coordinates to local viewport world
    x = x / engine.getHardwareScalingLevel() - viewport.x;
    y = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);
    result.update(x, y, viewport.width, viewport.height, world ? world : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly, cameraViewSpace ? _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix());
    return this;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.createPickingRayInCameraSpace = function (x, y, camera) {
    var result = Ray.Zero();
    this.createPickingRayInCameraSpaceToRef(x, y, result, camera);
    return result;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.createPickingRayInCameraSpaceToRef = function (x, y, result, camera) {
    if (!_Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_2__["PickingInfo"]) {
        return this;
    }
    var engine = this.getEngine();
    if (!camera) {
        if (!this.activeCamera) {
            throw new Error("Active camera not set");
        }
        camera = this.activeCamera;
    }
    var cameraViewport = camera.viewport;
    var viewport = cameraViewport.toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
    var identity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
    // Moving coordinates to local viewport world
    x = x / engine.getHardwareScalingLevel() - viewport.x;
    y = y / engine.getHardwareScalingLevel() - (engine.getRenderHeight() - viewport.y - viewport.height);
    result.update(x, y, viewport.width, viewport.height, identity, identity, camera.getProjectionMatrix());
    return this;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype._internalPick = function (rayFunction, predicate, fastCheck, trianglePredicate) {
    if (!_Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_2__["PickingInfo"]) {
        return null;
    }
    var pickingInfo = null;
    for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
        var mesh = this.meshes[meshIndex];
        if (predicate) {
            if (!predicate(mesh)) {
                continue;
            }
        }
        else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
            continue;
        }
        var world = mesh.getWorldMatrix();
        var ray = rayFunction(world);
        var result = mesh.intersects(ray, fastCheck, trianglePredicate);
        if (!result || !result.hit) {
            continue;
        }
        if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
            continue;
        }
        pickingInfo = result;
        if (fastCheck) {
            break;
        }
    }
    return pickingInfo || new _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_2__["PickingInfo"]();
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype._internalMultiPick = function (rayFunction, predicate, trianglePredicate) {
    if (!_Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_2__["PickingInfo"]) {
        return null;
    }
    var pickingInfos = new Array();
    for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
        var mesh = this.meshes[meshIndex];
        if (predicate) {
            if (!predicate(mesh)) {
                continue;
            }
        }
        else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
            continue;
        }
        var world = mesh.getWorldMatrix();
        var ray = rayFunction(world);
        var result = mesh.intersects(ray, false, trianglePredicate);
        if (!result || !result.hit) {
            continue;
        }
        pickingInfos.push(result);
    }
    return pickingInfos;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.pick = function (x, y, predicate, fastCheck, camera, trianglePredicate) {
    var _this = this;
    if (!_Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_2__["PickingInfo"]) {
        return null;
    }
    var result = this._internalPick(function (world) {
        if (!_this._tempPickingRay) {
            _this._tempPickingRay = Ray.Zero();
        }
        _this.createPickingRayToRef(x, y, world, _this._tempPickingRay, camera || null);
        return _this._tempPickingRay;
    }, predicate, fastCheck, trianglePredicate);
    if (result) {
        result.ray = this.createPickingRay(x, y, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity(), camera || null);
    }
    return result;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.pickWithRay = function (ray, predicate, fastCheck, trianglePredicate) {
    var _this = this;
    var result = this._internalPick(function (world) {
        if (!_this._pickWithRayInverseMatrix) {
            _this._pickWithRayInverseMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        }
        world.invertToRef(_this._pickWithRayInverseMatrix);
        if (!_this._cachedRayForTransform) {
            _this._cachedRayForTransform = Ray.Zero();
        }
        Ray.TransformToRef(ray, _this._pickWithRayInverseMatrix, _this._cachedRayForTransform);
        return _this._cachedRayForTransform;
    }, predicate, fastCheck, trianglePredicate);
    if (result) {
        result.ray = ray;
    }
    return result;
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.multiPick = function (x, y, predicate, camera, trianglePredicate) {
    var _this = this;
    return this._internalMultiPick(function (world) { return _this.createPickingRay(x, y, world, camera || null); }, predicate, trianglePredicate);
};
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.multiPickWithRay = function (ray, predicate, trianglePredicate) {
    var _this = this;
    return this._internalMultiPick(function (world) {
        if (!_this._pickWithRayInverseMatrix) {
            _this._pickWithRayInverseMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        }
        world.invertToRef(_this._pickWithRayInverseMatrix);
        if (!_this._cachedRayForTransform) {
            _this._cachedRayForTransform = Ray.Zero();
        }
        Ray.TransformToRef(ray, _this._pickWithRayInverseMatrix, _this._cachedRayForTransform);
        return _this._cachedRayForTransform;
    }, predicate, trianglePredicate);
};
_Cameras_camera__WEBPACK_IMPORTED_MODULE_5__["Camera"].prototype.getForwardRay = function (length, transform, origin) {
    if (length === void 0) { length = 100; }
    if (!transform) {
        transform = this.getWorldMatrix();
    }
    if (!origin) {
        origin = this.position;
    }
    var forward = this._scene.useRightHandedSystem ? new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, -1) : new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, 1);
    var forwardWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormal(forward, transform);
    var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Normalize(forwardWorld);
    return new Ray(origin, direction, length);
};


/***/ }),

/***/ "./Debug/axesViewer.ts":
/*!*****************************!*\
  !*** ./Debug/axesViewer.ts ***!
  \*****************************/
/*! exports provided: AxesViewer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AxesViewer", function() { return AxesViewer; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Gizmos/axisDragGizmo */ "./Gizmos/axisDragGizmo.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");




/**
     * The Axes viewer will show 3 axes in a specific point in space
     */
var AxesViewer = /** @class */ (function () {
    /**
     * Creates a new AxesViewer
     * @param scene defines the hosting scene
     * @param scaleLines defines a number used to scale line length (1 by default)
     * @param renderingGroupId defines a number used to set the renderingGroupId of the meshes (2 by default)
     * @param xAxis defines the node hierarchy used to render the x-axis
     * @param yAxis defines the node hierarchy used to render the y-axis
     * @param zAxis defines the node hierarchy used to render the z-axis
     */
    function AxesViewer(scene, scaleLines, renderingGroupId, xAxis, yAxis, zAxis) {
        if (scaleLines === void 0) { scaleLines = 1; }
        if (renderingGroupId === void 0) { renderingGroupId = 2; }
        this._scaleLinesFactor = 4;
        this._instanced = false;
        /**
         * Gets or sets a number used to scale line length
         */
        this.scaleLines = 1;
        this.scaleLines = scaleLines;
        if (!xAxis) {
            var redColoredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_1__["StandardMaterial"]("", scene);
            redColoredMaterial.disableLighting = true;
            redColoredMaterial.emissiveColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].Red().scale(0.5);
            xAxis = _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__["AxisDragGizmo"]._CreateArrow(scene, redColoredMaterial);
        }
        if (!yAxis) {
            var greenColoredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_1__["StandardMaterial"]("", scene);
            greenColoredMaterial.disableLighting = true;
            greenColoredMaterial.emissiveColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].Green().scale(0.5);
            yAxis = _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__["AxisDragGizmo"]._CreateArrow(scene, greenColoredMaterial);
        }
        if (!zAxis) {
            var blueColoredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_1__["StandardMaterial"]("", scene);
            blueColoredMaterial.disableLighting = true;
            blueColoredMaterial.emissiveColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].Blue().scale(0.5);
            zAxis = _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__["AxisDragGizmo"]._CreateArrow(scene, blueColoredMaterial);
        }
        this._xAxis = xAxis;
        this._xAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
        this._yAxis = yAxis;
        this._yAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
        this._zAxis = zAxis;
        this._zAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
        if (renderingGroupId != null) {
            AxesViewer._SetRenderingGroupId(this._xAxis, renderingGroupId);
            AxesViewer._SetRenderingGroupId(this._yAxis, renderingGroupId);
            AxesViewer._SetRenderingGroupId(this._zAxis, renderingGroupId);
        }
        this.scene = scene;
        this.update(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Right(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Forward());
    }
    Object.defineProperty(AxesViewer.prototype, "xAxis", {
        /** Gets the node hierarchy used to render x-axis */
        get: function () {
            return this._xAxis;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AxesViewer.prototype, "yAxis", {
        /** Gets the node hierarchy used to render y-axis */
        get: function () {
            return this._yAxis;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AxesViewer.prototype, "zAxis", {
        /** Gets the node hierarchy used to render z-axis */
        get: function () {
            return this._zAxis;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Force the viewer to update
     * @param position defines the position of the viewer
     * @param xaxis defines the x axis of the viewer
     * @param yaxis defines the y axis of the viewer
     * @param zaxis defines the z axis of the viewer
     */
    AxesViewer.prototype.update = function (position, xaxis, yaxis, zaxis) {
        this._xAxis.position.copyFrom(position);
        this._xAxis.setDirection(xaxis);
        this._xAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
        this._yAxis.position.copyFrom(position);
        this._yAxis.setDirection(yaxis);
        this._yAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
        this._zAxis.position.copyFrom(position);
        this._zAxis.setDirection(zaxis);
        this._zAxis.scaling.setAll(this.scaleLines * this._scaleLinesFactor);
    };
    /**
     * Creates an instance of this axes viewer.
     * @returns a new axes viewer with instanced meshes
     */
    AxesViewer.prototype.createInstance = function () {
        var xAxis = _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__["AxisDragGizmo"]._CreateArrowInstance(this.scene, this._xAxis);
        var yAxis = _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__["AxisDragGizmo"]._CreateArrowInstance(this.scene, this._yAxis);
        var zAxis = _Gizmos_axisDragGizmo__WEBPACK_IMPORTED_MODULE_2__["AxisDragGizmo"]._CreateArrowInstance(this.scene, this._zAxis);
        var axesViewer = new AxesViewer(this.scene, this.scaleLines, null, xAxis, yAxis, zAxis);
        axesViewer._instanced = true;
        return axesViewer;
    };
    /** Releases resources */
    AxesViewer.prototype.dispose = function () {
        if (this._xAxis) {
            this._xAxis.dispose(false, !this._instanced);
            delete this._xAxis;
        }
        if (this._yAxis) {
            this._yAxis.dispose(false, !this._instanced);
            delete this._yAxis;
        }
        if (this._zAxis) {
            this._zAxis.dispose(false, !this._instanced);
            delete this._zAxis;
        }
        delete this.scene;
    };
    AxesViewer._SetRenderingGroupId = function (node, id) {
        node.getChildMeshes().forEach(function (mesh) {
            mesh.renderingGroupId = id;
        });
    };
    return AxesViewer;
}());



/***/ }),

/***/ "./Debug/boneAxesViewer.ts":
/*!*********************************!*\
  !*** ./Debug/boneAxesViewer.ts ***!
  \*********************************/
/*! exports provided: BoneAxesViewer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoneAxesViewer", function() { return BoneAxesViewer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Debug_axesViewer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Debug/axesViewer */ "./Debug/axesViewer.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");




/**
     * The BoneAxesViewer will attach 3 axes to a specific bone of a specific mesh
     * @see demo here: https://www.babylonjs-playground.com/#0DE8F4#8
     */
var BoneAxesViewer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BoneAxesViewer, _super);
    /**
     * Creates a new BoneAxesViewer
     * @param scene defines the hosting scene
     * @param bone defines the target bone
     * @param mesh defines the target mesh
     * @param scaleLines defines a scaling factor for line length (1 by default)
     */
    function BoneAxesViewer(scene, bone, mesh, scaleLines) {
        if (scaleLines === void 0) { scaleLines = 1; }
        var _this = _super.call(this, scene, scaleLines) || this;
        /** Gets current position */
        _this.pos = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        /** Gets direction of X axis */
        _this.xaxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        /** Gets direction of Y axis */
        _this.yaxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        /** Gets direction of Z axis */
        _this.zaxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this.mesh = mesh;
        _this.bone = bone;
        return _this;
    }
    /**
     * Force the viewer to update
     */
    BoneAxesViewer.prototype.update = function () {
        if (!this.mesh || !this.bone) {
            return;
        }
        var bone = this.bone;
        bone._markAsDirtyAndCompose();
        bone.getAbsolutePositionToRef(this.mesh, this.pos);
        bone.getDirectionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_3__["Axis"].X, this.mesh, this.xaxis);
        bone.getDirectionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_3__["Axis"].Y, this.mesh, this.yaxis);
        bone.getDirectionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_3__["Axis"].Z, this.mesh, this.zaxis);
        _super.prototype.update.call(this, this.pos, this.xaxis, this.yaxis, this.zaxis);
    };
    /** Releases resources */
    BoneAxesViewer.prototype.dispose = function () {
        if (this.mesh) {
            this.mesh = null;
            this.bone = null;
            _super.prototype.dispose.call(this);
        }
    };
    return BoneAxesViewer;
}(_Debug_axesViewer__WEBPACK_IMPORTED_MODULE_1__["AxesViewer"]));



/***/ }),

/***/ "./Debug/debugLayer.ts":
/*!*****************************!*\
  !*** ./Debug/debugLayer.ts ***!
  \*****************************/
/*! exports provided: DebugLayer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DebugLayer", function() { return DebugLayer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");





Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].prototype, "debugLayer", {
    get: function () {
        if (!this._debugLayer) {
            this._debugLayer = new DebugLayer(this);
        }
        return this._debugLayer;
    },
    enumerable: true,
    configurable: true
});
/**
 * The debug layer (aka Inspector) is the go to tool in order to better understand
 * what is happening in your scene
 * @see http://doc.babylonjs.com/features/playground_debuglayer
 */
var DebugLayer = /** @class */ (function () {
    /**
     * Instantiates a new debug layer.
     * The debug layer (aka Inspector) is the go to tool in order to better understand
     * what is happening in your scene
     * @see http://doc.babylonjs.com/features/playground_debuglayer
     * @param scene Defines the scene to inspect
     */
    function DebugLayer(scene) {
        var _this = this;
        this.BJSINSPECTOR = this._getGlobalInspector();
        this._scene = scene;
        this._scene.onDisposeObservable.add(function () {
            // Debug layer
            if (_this._scene._debugLayer) {
                _this._scene._debugLayer.hide();
            }
        });
    }
    Object.defineProperty(DebugLayer.prototype, "onPropertyChangedObservable", {
        /**
         * Observable triggered when a property is changed through the inspector.
         */
        get: function () {
            if (this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector) {
                return this.BJSINSPECTOR.Inspector.OnPropertyChangedObservable;
            }
            if (!this._onPropertyChangedObservable) {
                this._onPropertyChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
            }
            return this._onPropertyChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    /** Creates the inspector window. */
    DebugLayer.prototype._createInspector = function (config) {
        if (this.isVisible()) {
            return;
        }
        if (this._onPropertyChangedObservable) {
            for (var _i = 0, _a = this._onPropertyChangedObservable.observers; _i < _a.length; _i++) {
                var observer = _a[_i];
                this.BJSINSPECTOR.Inspector.OnPropertyChangedObservable.add(observer);
            }
            this._onPropertyChangedObservable.clear();
            this._onPropertyChangedObservable = undefined;
        }
        var userOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ overlay: false, showExplorer: true, showInspector: true, embedMode: false, handleResize: true, enablePopup: true }, config);
        this.BJSINSPECTOR = this.BJSINSPECTOR || this._getGlobalInspector();
        this.BJSINSPECTOR.Inspector.Show(this._scene, userOptions);
    };
    /**
     * Select a specific entity in the scene explorer and highlight a specific block in that entity property grid
     * @param entity defines the entity to select
     * @param lineContainerTitle defines the specific block to highlight
     */
    DebugLayer.prototype.select = function (entity, lineContainerTitle) {
        if (this.BJSINSPECTOR) {
            this.BJSINSPECTOR.Inspector.MarkLineContainerTitleForHighlighting(lineContainerTitle);
            this.BJSINSPECTOR.Inspector.OnSelectionChangeObservable.notifyObservers(entity);
        }
    };
    /** Get the inspector from bundle or global */
    DebugLayer.prototype._getGlobalInspector = function () {
        // UMD Global name detection from Webpack Bundle UMD Name.
        if (typeof INSPECTOR !== 'undefined') {
            return INSPECTOR;
        }
        // In case of module let s check the global emitted from the Inspector entry point.
        if (typeof BABYLON !== 'undefined' && typeof BABYLON.Inspector !== 'undefined') {
            return BABYLON;
        }
        return undefined;
    };
    /**
     * Get if the inspector is visible or not.
     * @returns true if visible otherwise, false
     */
    DebugLayer.prototype.isVisible = function () {
        return this.BJSINSPECTOR && this.BJSINSPECTOR.Inspector.IsVisible;
    };
    /**
     * Hide the inspector and close its window.
     */
    DebugLayer.prototype.hide = function () {
        if (this.BJSINSPECTOR) {
            this.BJSINSPECTOR.Inspector.Hide();
        }
    };
    /**
      * Launch the debugLayer.
      * @param config Define the configuration of the inspector
      * @return a promise fulfilled when the debug layer is visible
      */
    DebugLayer.prototype.show = function (config) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            if (typeof _this.BJSINSPECTOR == 'undefined') {
                var inspectorUrl = config && config.inspectorURL ? config.inspectorURL : DebugLayer.InspectorURL;
                // Load inspector and add it to the DOM
                _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].LoadScript(inspectorUrl, function () {
                    _this._createInspector(config);
                    resolve(_this);
                });
            }
            else {
                // Otherwise creates the inspector
                _this._createInspector(config);
                resolve(_this);
            }
        });
    };
    /**
     * Define the url to get the inspector script from.
     * By default it uses the babylonjs CDN.
     * @ignoreNaming
     */
    DebugLayer.InspectorURL = "https://unpkg.com/babylonjs-inspector@" + _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].Version + "/babylon.inspector.bundle.js";
    return DebugLayer;
}());



/***/ }),

/***/ "./Debug/index.ts":
/*!************************!*\
  !*** ./Debug/index.ts ***!
  \************************/
/*! exports provided: AxesViewer, BoneAxesViewer, DebugLayer, PhysicsViewer, RayHelper, SkeletonViewer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _axesViewer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./axesViewer */ "./Debug/axesViewer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxesViewer", function() { return _axesViewer__WEBPACK_IMPORTED_MODULE_0__["AxesViewer"]; });

/* harmony import */ var _boneAxesViewer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./boneAxesViewer */ "./Debug/boneAxesViewer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneAxesViewer", function() { return _boneAxesViewer__WEBPACK_IMPORTED_MODULE_1__["BoneAxesViewer"]; });

/* harmony import */ var _debugLayer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./debugLayer */ "./Debug/debugLayer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DebugLayer", function() { return _debugLayer__WEBPACK_IMPORTED_MODULE_2__["DebugLayer"]; });

/* harmony import */ var _physicsViewer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./physicsViewer */ "./Debug/physicsViewer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsViewer", function() { return _physicsViewer__WEBPACK_IMPORTED_MODULE_3__["PhysicsViewer"]; });

/* harmony import */ var _rayHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./rayHelper */ "./Debug/rayHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RayHelper", function() { return _rayHelper__WEBPACK_IMPORTED_MODULE_4__["RayHelper"]; });

/* harmony import */ var _skeletonViewer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./skeletonViewer */ "./Debug/skeletonViewer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SkeletonViewer", function() { return _skeletonViewer__WEBPACK_IMPORTED_MODULE_5__["SkeletonViewer"]; });









/***/ }),

/***/ "./Debug/physicsViewer.ts":
/*!********************************!*\
  !*** ./Debug/physicsViewer.ts ***!
  \********************************/
/*! exports provided: PhysicsViewer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsViewer", function() { return PhysicsViewer; });
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Physics/physicsImpostor */ "./Physics/physicsImpostor.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Meshes/Builders/cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");










/**
     * Used to show the physics impostor around the specific mesh
     */
var PhysicsViewer = /** @class */ (function () {
    /**
     * Creates a new PhysicsViewer
     * @param scene defines the hosting scene
     */
    function PhysicsViewer(scene) {
        /** @hidden */
        this._impostors = [];
        /** @hidden */
        this._meshes = [];
        /** @hidden */
        this._numMeshes = 0;
        this._debugMeshMeshes = new Array();
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene;
        var physicEngine = this._scene.getPhysicsEngine();
        if (physicEngine) {
            this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();
        }
        this._utilityLayer = new _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__["UtilityLayerRenderer"](this._scene, false);
        this._utilityLayer.pickUtilitySceneFirst = false;
        this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = true;
    }
    /** @hidden */
    PhysicsViewer.prototype._updateDebugMeshes = function () {
        var plugin = this._physicsEnginePlugin;
        for (var i = 0; i < this._numMeshes; i++) {
            var impostor = this._impostors[i];
            if (!impostor) {
                continue;
            }
            if (impostor.isDisposed) {
                this.hideImpostor(this._impostors[i--]);
            }
            else {
                if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__["PhysicsImpostor"].MeshImpostor) {
                    continue;
                }
                var mesh = this._meshes[i];
                if (mesh && plugin) {
                    plugin.syncMeshWithImpostor(mesh, impostor);
                }
            }
        }
    };
    /**
     * Renders a specified physic impostor
     * @param impostor defines the impostor to render
     * @param targetMesh defines the mesh represented by the impostor
     * @returns the new debug mesh used to render the impostor
     */
    PhysicsViewer.prototype.showImpostor = function (impostor, targetMesh) {
        if (!this._scene) {
            return null;
        }
        for (var i = 0; i < this._numMeshes; i++) {
            if (this._impostors[i] == impostor) {
                return null;
            }
        }
        var debugMesh = this._getDebugMesh(impostor, targetMesh);
        if (debugMesh) {
            this._impostors[this._numMeshes] = impostor;
            this._meshes[this._numMeshes] = debugMesh;
            if (this._numMeshes === 0) {
                this._renderFunction = this._updateDebugMeshes.bind(this);
                this._scene.registerBeforeRender(this._renderFunction);
            }
            this._numMeshes++;
        }
        return debugMesh;
    };
    /**
     * Hides a specified physic impostor
     * @param impostor defines the impostor to hide
     */
    PhysicsViewer.prototype.hideImpostor = function (impostor) {
        if (!impostor || !this._scene || !this._utilityLayer) {
            return;
        }
        var removed = false;
        var utilityLayerScene = this._utilityLayer.utilityLayerScene;
        for (var i = 0; i < this._numMeshes; i++) {
            if (this._impostors[i] == impostor) {
                var mesh = this._meshes[i];
                if (!mesh) {
                    continue;
                }
                utilityLayerScene.removeMesh(mesh);
                mesh.dispose();
                var index = this._debugMeshMeshes.indexOf(mesh);
                if (index > -1) {
                    this._debugMeshMeshes.splice(index, 1);
                }
                this._numMeshes--;
                if (this._numMeshes > 0) {
                    this._meshes[i] = this._meshes[this._numMeshes];
                    this._impostors[i] = this._impostors[this._numMeshes];
                    this._meshes[this._numMeshes] = null;
                    this._impostors[this._numMeshes] = null;
                }
                else {
                    this._meshes[0] = null;
                    this._impostors[0] = null;
                }
                removed = true;
                break;
            }
        }
        if (removed && this._numMeshes === 0) {
            this._scene.unregisterBeforeRender(this._renderFunction);
        }
    };
    PhysicsViewer.prototype._getDebugMaterial = function (scene) {
        if (!this._debugMaterial) {
            this._debugMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__["StandardMaterial"]('', scene);
            this._debugMaterial.wireframe = true;
            this._debugMaterial.emissiveColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].White();
            this._debugMaterial.disableLighting = true;
        }
        return this._debugMaterial;
    };
    PhysicsViewer.prototype._getDebugBoxMesh = function (scene) {
        if (!this._debugBoxMesh) {
            this._debugBoxMesh = _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_1__["BoxBuilder"].CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene);
            this._debugBoxMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].Identity();
            this._debugBoxMesh.material = this._getDebugMaterial(scene);
            this._debugBoxMesh.setEnabled(false);
        }
        return this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
    };
    PhysicsViewer.prototype._getDebugSphereMesh = function (scene) {
        if (!this._debugSphereMesh) {
            this._debugSphereMesh = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_2__["SphereBuilder"].CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene);
            this._debugSphereMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].Identity();
            this._debugSphereMesh.material = this._getDebugMaterial(scene);
            this._debugSphereMesh.setEnabled(false);
        }
        return this._debugSphereMesh.createInstance('physicsBodyBoxViewInstance');
    };
    PhysicsViewer.prototype._getDebugCylinderMesh = function (scene) {
        if (!this._debugCylinderMesh) {
            this._debugCylinderMesh = _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_9__["CylinderBuilder"].CreateCylinder('physicsBodyCylinderViewMesh', { diameterTop: 1, diameterBottom: 1, height: 1 }, scene);
            this._debugCylinderMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].Identity();
            this._debugCylinderMesh.material = this._getDebugMaterial(scene);
            this._debugCylinderMesh.setEnabled(false);
        }
        return this._debugCylinderMesh.createInstance('physicsBodyBoxViewInstance');
    };
    PhysicsViewer.prototype._getDebugMeshMesh = function (mesh, scene) {
        var wireframeOver = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"](mesh.name, scene, null, mesh);
        wireframeOver.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        wireframeOver.setParent(mesh);
        wireframeOver.material = this._getDebugMaterial(scene);
        this._debugMeshMeshes.push(wireframeOver);
        return wireframeOver;
    };
    PhysicsViewer.prototype._getDebugMesh = function (impostor, targetMesh) {
        var _this = this;
        if (!this._utilityLayer) {
            return null;
        }
        // Only create child impostor debug meshes when evaluating the parent
        if (targetMesh && targetMesh.parent && targetMesh.parent.physicsImpostor) {
            return null;
        }
        var mesh = null;
        var utilityLayerScene = this._utilityLayer.utilityLayerScene;
        switch (impostor.type) {
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__["PhysicsImpostor"].BoxImpostor:
                mesh = this._getDebugBoxMesh(utilityLayerScene);
                impostor.getBoxSizeToRef(mesh.scaling);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__["PhysicsImpostor"].SphereImpostor:
                mesh = this._getDebugSphereMesh(utilityLayerScene);
                var radius = impostor.getRadius();
                mesh.scaling.x = radius * 2;
                mesh.scaling.y = radius * 2;
                mesh.scaling.z = radius * 2;
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__["PhysicsImpostor"].MeshImpostor:
                if (targetMesh) {
                    mesh = this._getDebugMeshMesh(targetMesh, utilityLayerScene);
                }
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__["PhysicsImpostor"].NoImpostor:
                if (targetMesh) {
                    // Handle compound impostors
                    var childMeshes = targetMesh.getChildMeshes().filter(function (c) { return c.physicsImpostor ? 1 : 0; });
                    childMeshes.forEach(function (m) {
                        var a = _this._getDebugBoxMesh(utilityLayerScene);
                        a.parent = m;
                    });
                }
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_7__["PhysicsImpostor"].CylinderImpostor:
                mesh = this._getDebugCylinderMesh(utilityLayerScene);
                var bi = impostor.object.getBoundingInfo();
                mesh.scaling.x = bi.boundingBox.maximum.x - bi.boundingBox.minimum.x;
                mesh.scaling.y = bi.boundingBox.maximum.y - bi.boundingBox.minimum.y;
                mesh.scaling.z = bi.boundingBox.maximum.z - bi.boundingBox.minimum.z;
                break;
        }
        return mesh;
    };
    /** Releases all resources */
    PhysicsViewer.prototype.dispose = function () {
        var count = this._numMeshes;
        for (var index = 0; index < count; index++) {
            this.hideImpostor(this._impostors[0]);
        }
        if (this._debugBoxMesh) {
            this._debugBoxMesh.dispose();
        }
        if (this._debugSphereMesh) {
            this._debugSphereMesh.dispose();
        }
        if (this._debugCylinderMesh) {
            this._debugCylinderMesh.dispose();
        }
        if (this._debugMaterial) {
            this._debugMaterial.dispose();
        }
        this._impostors.length = 0;
        this._scene = null;
        this._physicsEnginePlugin = null;
        if (this._utilityLayer) {
            this._utilityLayer.dispose();
            this._utilityLayer = null;
        }
    };
    return PhysicsViewer;
}());



/***/ }),

/***/ "./Debug/rayHelper.ts":
/*!****************************!*\
  !*** ./Debug/rayHelper.ts ***!
  \****************************/
/*! exports provided: RayHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RayHelper", function() { return RayHelper; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/Builders/linesBuilder */ "./Meshes/Builders/linesBuilder.ts");



/**
 * As raycast might be hard to debug, the RayHelper can help rendering the different rays
 * in order to better appreciate the issue one might have.
 * @see http://doc.babylonjs.com/babylon101/raycasts#debugging
 */
var RayHelper = /** @class */ (function () {
    /**
     * Instantiate a new ray helper.
     * As raycast might be hard to debug, the RayHelper can help rendering the different rays
     * in order to better appreciate the issue one might have.
     * @see http://doc.babylonjs.com/babylon101/raycasts#debugging
     * @param ray Defines the ray we are currently tryin to visualize
     */
    function RayHelper(ray) {
        this.ray = ray;
    }
    /**
     * Helper function to create a colored helper in a scene in one line.
     * @param ray Defines the ray we are currently tryin to visualize
     * @param scene Defines the scene the ray is used in
     * @param color Defines the color we want to see the ray in
     * @returns The newly created ray helper.
     */
    RayHelper.CreateAndShow = function (ray, scene, color) {
        var helper = new RayHelper(ray);
        helper.show(scene, color);
        return helper;
    };
    /**
     * Shows the ray we are willing to debug.
     * @param scene Defines the scene the ray needs to be rendered in
     * @param color Defines the color the ray needs to be rendered in
     */
    RayHelper.prototype.show = function (scene, color) {
        if (!this._renderFunction && this.ray) {
            var ray = this.ray;
            this._renderFunction = this._render.bind(this);
            this._scene = scene;
            this._renderPoints = [ray.origin, ray.origin.add(ray.direction.scale(ray.length))];
            this._renderLine = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateLines("ray", this._renderPoints, scene, true);
            if (this._renderFunction) {
                this._scene.registerBeforeRender(this._renderFunction);
            }
        }
        if (color && this._renderLine) {
            this._renderLine.color.copyFrom(color);
        }
    };
    /**
     * Hides the ray we are debugging.
     */
    RayHelper.prototype.hide = function () {
        if (this._renderFunction && this._scene) {
            this._scene.unregisterBeforeRender(this._renderFunction);
            this._scene = null;
            this._renderFunction = null;
            if (this._renderLine) {
                this._renderLine.dispose();
                this._renderLine = null;
            }
            this._renderPoints = [];
        }
    };
    RayHelper.prototype._render = function () {
        var ray = this.ray;
        if (!ray) {
            return;
        }
        var point = this._renderPoints[1];
        var len = Math.min(ray.length, 1000000);
        point.copyFrom(ray.direction);
        point.scaleInPlace(len);
        point.addInPlace(ray.origin);
        _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateLines("ray", this._renderPoints, this._scene, true, this._renderLine);
    };
    /**
     * Attach a ray helper to a mesh so that we can easily see its orientation for instance or information like its normals.
     * @param mesh Defines the mesh we want the helper attached to
     * @param meshSpaceDirection Defines the direction of the Ray in mesh space (local space of the mesh node)
     * @param meshSpaceOrigin Defines the origin of the Ray in mesh space (local space of the mesh node)
     * @param length Defines the length of the ray
     */
    RayHelper.prototype.attachToMesh = function (mesh, meshSpaceDirection, meshSpaceOrigin, length) {
        this._attachedToMesh = mesh;
        var ray = this.ray;
        if (!ray) {
            return;
        }
        if (!ray.direction) {
            ray.direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        }
        if (!ray.origin) {
            ray.origin = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        }
        if (length) {
            ray.length = length;
        }
        if (!meshSpaceOrigin) {
            meshSpaceOrigin = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        }
        if (!meshSpaceDirection) {
            // -1 so that this will work with Mesh.lookAt
            meshSpaceDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, -1);
        }
        if (!this._meshSpaceDirection) {
            this._meshSpaceDirection = meshSpaceDirection.clone();
            this._meshSpaceOrigin = meshSpaceOrigin.clone();
        }
        else {
            this._meshSpaceDirection.copyFrom(meshSpaceDirection);
            this._meshSpaceOrigin.copyFrom(meshSpaceOrigin);
        }
        if (!this._updateToMeshFunction) {
            this._updateToMeshFunction = this._updateToMesh.bind(this);
            this._attachedToMesh.getScene().registerBeforeRender(this._updateToMeshFunction);
        }
        this._updateToMesh();
    };
    /**
     * Detach the ray helper from the mesh it has previously been attached to.
     */
    RayHelper.prototype.detachFromMesh = function () {
        if (this._attachedToMesh) {
            if (this._updateToMeshFunction) {
                this._attachedToMesh.getScene().unregisterBeforeRender(this._updateToMeshFunction);
            }
            this._attachedToMesh = null;
            this._updateToMeshFunction = null;
        }
    };
    RayHelper.prototype._updateToMesh = function () {
        var ray = this.ray;
        if (!this._attachedToMesh || !ray) {
            return;
        }
        if (this._attachedToMesh._isDisposed) {
            this.detachFromMesh();
            return;
        }
        this._attachedToMesh.getDirectionToRef(this._meshSpaceDirection, ray.direction);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this._meshSpaceOrigin, this._attachedToMesh.getWorldMatrix(), ray.origin);
    };
    /**
     * Dispose the helper and release its associated resources.
     */
    RayHelper.prototype.dispose = function () {
        this.hide();
        this.detachFromMesh();
        this.ray = null;
    };
    return RayHelper;
}());



/***/ }),

/***/ "./Debug/skeletonViewer.ts":
/*!*********************************!*\
  !*** ./Debug/skeletonViewer.ts ***!
  \*********************************/
/*! exports provided: SkeletonViewer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SkeletonViewer", function() { return SkeletonViewer; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/Builders/linesBuilder */ "./Meshes/Builders/linesBuilder.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");




/**
     * Class used to render a debug view of a given skeleton
     * @see http://www.babylonjs-playground.com/#1BZJVJ#8
     */
var SkeletonViewer = /** @class */ (function () {
    /**
     * Creates a new SkeletonViewer
     * @param skeleton defines the skeleton to render
     * @param mesh defines the mesh attached to the skeleton
     * @param scene defines the hosting scene
     * @param autoUpdateBonesMatrices defines a boolean indicating if bones matrices must be forced to update before rendering (true by default)
     * @param renderingGroupId defines the rendering group id to use with the viewer
     */
    function SkeletonViewer(
    /** defines the skeleton to render */
    skeleton,
    /** defines the mesh attached to the skeleton */
    mesh, scene,
    /** defines a boolean indicating if bones matrices must be forced to update before rendering (true by default)  */
    autoUpdateBonesMatrices,
    /** defines the rendering group id to use with the viewer */
    renderingGroupId) {
        if (autoUpdateBonesMatrices === void 0) { autoUpdateBonesMatrices = true; }
        if (renderingGroupId === void 0) { renderingGroupId = 1; }
        this.skeleton = skeleton;
        this.mesh = mesh;
        this.autoUpdateBonesMatrices = autoUpdateBonesMatrices;
        this.renderingGroupId = renderingGroupId;
        /** Gets or sets the color used to render the skeleton */
        this.color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].White();
        this._debugLines = new Array();
        this._isEnabled = false;
        this._scene = scene;
        this._utilityLayer = new _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_3__["UtilityLayerRenderer"](this._scene, false);
        this._utilityLayer.pickUtilitySceneFirst = false;
        this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = true;
        this.update();
        this._renderFunction = this.update.bind(this);
    }
    Object.defineProperty(SkeletonViewer.prototype, "debugMesh", {
        /**
         * Returns the mesh used to render the bones
         */
        get: function () {
            return this._debugMesh;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SkeletonViewer.prototype, "isEnabled", {
        get: function () {
            return this._isEnabled;
        },
        /** Gets or sets a boolean indicating if the viewer is enabled */
        set: function (value) {
            if (this._isEnabled === value) {
                return;
            }
            this._isEnabled = value;
            if (value) {
                this._scene.registerBeforeRender(this._renderFunction);
            }
            else {
                this._scene.unregisterBeforeRender(this._renderFunction);
            }
        },
        enumerable: true,
        configurable: true
    });
    SkeletonViewer.prototype._getBonePosition = function (position, bone, meshMat, x, y, z) {
        if (x === void 0) { x = 0; }
        if (y === void 0) { y = 0; }
        if (z === void 0) { z = 0; }
        var tmat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
        var parentBone = bone.getParent();
        tmat.copyFrom(bone.getLocalMatrix());
        if (x !== 0 || y !== 0 || z !== 0) {
            var tmat2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[1];
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].IdentityToRef(tmat2);
            tmat2.setTranslationFromFloats(x, y, z);
            tmat2.multiplyToRef(tmat, tmat);
        }
        if (parentBone) {
            tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
        }
        tmat.multiplyToRef(meshMat, tmat);
        position.x = tmat.m[12];
        position.y = tmat.m[13];
        position.z = tmat.m[14];
    };
    SkeletonViewer.prototype._getLinesForBonesWithLength = function (bones, meshMat) {
        var len = bones.length;
        var mesh = this.mesh._effectiveMesh;
        var meshPos = mesh.position;
        for (var i = 0; i < len; i++) {
            var bone = bones[i];
            var points = this._debugLines[i];
            if (!points) {
                points = [_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero()];
                this._debugLines[i] = points;
            }
            this._getBonePosition(points[0], bone, meshMat);
            this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
            points[0].subtractInPlace(meshPos);
            points[1].subtractInPlace(meshPos);
        }
    };
    SkeletonViewer.prototype._getLinesForBonesNoLength = function (bones, meshMat) {
        var len = bones.length;
        var boneNum = 0;
        var mesh = this.mesh._effectiveMesh;
        var meshPos = mesh.position;
        for (var i = len - 1; i >= 0; i--) {
            var childBone = bones[i];
            var parentBone = childBone.getParent();
            if (!parentBone) {
                continue;
            }
            var points = this._debugLines[boneNum];
            if (!points) {
                points = [_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero()];
                this._debugLines[boneNum] = points;
            }
            childBone.getAbsolutePositionToRef(mesh, points[0]);
            parentBone.getAbsolutePositionToRef(mesh, points[1]);
            points[0].subtractInPlace(meshPos);
            points[1].subtractInPlace(meshPos);
            boneNum++;
        }
    };
    /** Update the viewer to sync with current skeleton state */
    SkeletonViewer.prototype.update = function () {
        if (!this._utilityLayer) {
            return;
        }
        if (this.autoUpdateBonesMatrices) {
            this.skeleton.computeAbsoluteTransforms();
        }
        var mesh = this.mesh._effectiveMesh;
        if (this.skeleton.bones[0].length === undefined) {
            this._getLinesForBonesNoLength(this.skeleton.bones, mesh.getWorldMatrix());
        }
        else {
            this._getLinesForBonesWithLength(this.skeleton.bones, mesh.getWorldMatrix());
        }
        var targetScene = this._utilityLayer.utilityLayerScene;
        if (!this._debugMesh) {
            this._debugMesh = _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_2__["LinesBuilder"].CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: null }, targetScene);
            this._debugMesh.renderingGroupId = this.renderingGroupId;
        }
        else {
            _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_2__["LinesBuilder"].CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, targetScene);
        }
        this._debugMesh.position.copyFrom(this.mesh.position);
        this._debugMesh.color = this.color;
    };
    /** Release associated resources */
    SkeletonViewer.prototype.dispose = function () {
        this.isEnabled = false;
        if (this._debugMesh) {
            this.isEnabled = false;
            this._debugMesh.dispose();
            this._debugMesh = null;
        }
        if (this._utilityLayer) {
            this._utilityLayer.dispose();
            this._utilityLayer = null;
        }
    };
    return SkeletonViewer;
}());



/***/ }),

/***/ "./Engines/Extensions/engine.cubeTexture.ts":
/*!**************************************************!*\
  !*** ./Engines/Extensions/engine.cubeTexture.ts ***!
  \**************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_fileTools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/fileTools */ "./Misc/fileTools.ts");





_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype._createDepthStencilCubeTexture = function (size, options) {
    var internalTexture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_UNKNOWN);
    internalTexture.isCube = true;
    if (this.webGLVersion === 1) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Depth cube texture is not supported by WebGL 1.");
        return internalTexture;
    }
    var internalOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ bilinearFiltering: false, comparisonFunction: 0, generateStencil: false }, options);
    var gl = this._gl;
    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, internalTexture, true);
    this._setupDepthStencilTexture(internalTexture, size, internalOptions.generateStencil, internalOptions.bilinearFiltering, internalOptions.comparisonFunction);
    // Create the depth/stencil buffer
    for (var face = 0; face < 6; face++) {
        if (internalOptions.generateStencil) {
            gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.DEPTH24_STENCIL8, size, size, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
        }
        else {
            gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, gl.DEPTH_COMPONENT24, size, size, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
        }
    }
    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
    return internalTexture;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype._partialLoadFile = function (url, index, loadedFiles, onfinish, onErrorCallBack) {
    if (onErrorCallBack === void 0) { onErrorCallBack = null; }
    var onload = function (data) {
        loadedFiles[index] = data;
        loadedFiles._internalCount++;
        if (loadedFiles._internalCount === 6) {
            onfinish(loadedFiles);
        }
    };
    var onerror = function (request, exception) {
        if (onErrorCallBack && request) {
            onErrorCallBack(request.status + " " + request.statusText, exception);
        }
    };
    this._loadFile(url, onload, undefined, undefined, true, onerror);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype._cascadeLoadFiles = function (scene, onfinish, files, onError) {
    if (onError === void 0) { onError = null; }
    var loadedFiles = [];
    loadedFiles._internalCount = 0;
    for (var index = 0; index < 6; index++) {
        this._partialLoadFile(files[index], index, loadedFiles, onfinish, onError);
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype._cascadeLoadImgs = function (scene, onfinish, files, onError) {
    if (onError === void 0) { onError = null; }
    var loadedImages = [];
    loadedImages._internalCount = 0;
    for (var index = 0; index < 6; index++) {
        this._partialLoadImg(files[index], index, loadedImages, scene, onfinish, onError);
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype._partialLoadImg = function (url, index, loadedImages, scene, onfinish, onErrorCallBack) {
    if (onErrorCallBack === void 0) { onErrorCallBack = null; }
    var img;
    var onload = function () {
        loadedImages[index] = img;
        loadedImages._internalCount++;
        if (scene) {
            scene._removePendingData(img);
        }
        if (loadedImages._internalCount === 6) {
            onfinish(loadedImages);
        }
    };
    var onerror = function (message, exception) {
        if (scene) {
            scene._removePendingData(img);
        }
        if (onErrorCallBack) {
            onErrorCallBack(message, exception);
        }
    };
    img = _Misc_fileTools__WEBPACK_IMPORTED_MODULE_4__["FileTools"].LoadImage(url, onload, onerror, scene ? scene.offlineProvider : null);
    if (scene) {
        scene._addPendingData(img);
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype.createCubeTexture = function (rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback, excludeLoaders) {
    var _this = this;
    if (onLoad === void 0) { onLoad = null; }
    if (onError === void 0) { onError = null; }
    if (forcedExtension === void 0) { forcedExtension = null; }
    if (createPolynomials === void 0) { createPolynomials = false; }
    if (lodScale === void 0) { lodScale = 0; }
    if (lodOffset === void 0) { lodOffset = 0; }
    if (fallback === void 0) { fallback = null; }
    if (excludeLoaders === void 0) { excludeLoaders = []; }
    var gl = this._gl;
    var texture = fallback ? fallback : new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_CUBE);
    texture.isCube = true;
    texture.url = rootUrl;
    texture.generateMipMaps = !noMipmap;
    texture._lodGenerationScale = lodScale;
    texture._lodGenerationOffset = lodOffset;
    if (!this._doNotHandleContextLost) {
        texture._extension = forcedExtension;
        texture._files = files;
    }
    var lastDot = rootUrl.lastIndexOf('.');
    var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
    var loader = null;
    for (var _i = 0, _a = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._TextureLoaders; _i < _a.length; _i++) {
        var availableLoader = _a[_i];
        if (excludeLoaders.indexOf(availableLoader) === -1 && availableLoader.canLoad(extension, this._textureFormatInUse, fallback, false, false)) {
            loader = availableLoader;
            break;
        }
    }
    var onInternalError = function (request, exception) {
        if (loader) {
            var fallbackUrl = loader.getFallbackTextureUrl(texture.url, _this._textureFormatInUse);
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Warn(loader.constructor.name + " failed when trying to load " + texture.url + ", falling back to the next supported loader");
            if (fallbackUrl) {
                excludeLoaders.push(loader);
                _this.createCubeTexture(fallbackUrl, scene, files, noMipmap, onLoad, onError, format, extension, createPolynomials, lodScale, lodOffset, texture, excludeLoaders);
                return;
            }
        }
        if (onError && request) {
            onError(request.status + " " + request.statusText, exception);
        }
    };
    if (loader) {
        rootUrl = loader.transformUrl(rootUrl, this._textureFormatInUse);
        var onloaddata = function (data) {
            _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
            loader.loadCubeData(data, texture, createPolynomials, onLoad, onError);
        };
        if (files && files.length === 6) {
            if (loader.supportCascades) {
                this._cascadeLoadFiles(scene, onloaddata, files, onError);
            }
            else {
                if (onError) {
                    onError("Textures type does not support cascades.");
                }
                else {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Warn("Texture loader does not support cascades.");
                }
            }
        }
        else {
            this._loadFile(rootUrl, onloaddata, undefined, undefined, true, onInternalError);
        }
    }
    else {
        if (!files) {
            throw new Error("Cannot load cubemap because files were not defined");
        }
        this._cascadeLoadImgs(scene, function (imgs) {
            var width = _this.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].GetExponentOfTwo(imgs[0].width, _this._caps.maxCubemapTextureSize) : imgs[0].width;
            var height = width;
            _this._prepareWorkingCanvas();
            if (!_this._workingCanvas || !_this._workingContext) {
                return;
            }
            _this._workingCanvas.width = width;
            _this._workingCanvas.height = height;
            var faces = [
                gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
                gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
            ];
            _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
            _this._unpackFlipY(false);
            var internalFormat = format ? _this._getInternalFormat(format) : _this._gl.RGBA;
            for (var index = 0; index < faces.length; index++) {
                if (imgs[index].width !== width || imgs[index].height !== height) {
                    _this._workingContext.drawImage(imgs[index], 0, 0, imgs[index].width, imgs[index].height, 0, 0, width, height);
                    gl.texImage2D(faces[index], 0, internalFormat, internalFormat, gl.UNSIGNED_BYTE, _this._workingCanvas);
                }
                else {
                    gl.texImage2D(faces[index], 0, internalFormat, internalFormat, gl.UNSIGNED_BYTE, imgs[index]);
                }
            }
            if (!noMipmap) {
                gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
            }
            _this._setCubeMapTextureParams(!noMipmap);
            texture.width = width;
            texture.height = height;
            texture.isReady = true;
            if (format) {
                texture.format = format;
            }
            texture.onLoadedObservable.notifyObservers(texture);
            texture.onLoadedObservable.clear();
            if (onLoad) {
                onLoad();
            }
        }, files, onError);
    }
    this._internalTexturesCache.push(texture);
    return texture;
};


/***/ }),

/***/ "./Engines/Extensions/engine.multiRender.ts":
/*!**************************************************!*\
  !*** ./Engines/Extensions/engine.multiRender.ts ***!
  \**************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");



_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.unBindMultiColorAttachmentFramebuffer = function (textures, disableGenerateMipMaps, onBeforeUnbind) {
    if (disableGenerateMipMaps === void 0) { disableGenerateMipMaps = false; }
    this._currentRenderTarget = null;
    // If MSAA, we need to bitblt back to main texture
    var gl = this._gl;
    if (textures[0]._MSAAFramebuffer) {
        gl.bindFramebuffer(gl.READ_FRAMEBUFFER, textures[0]._MSAAFramebuffer);
        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, textures[0]._framebuffer);
        var attachments = textures[0]._attachments;
        if (!attachments) {
            attachments = new Array(textures.length);
            textures[0]._attachments = attachments;
        }
        for (var i = 0; i < textures.length; i++) {
            var texture = textures[i];
            for (var j = 0; j < attachments.length; j++) {
                attachments[j] = gl.NONE;
            }
            attachments[i] = gl[this.webGLVersion > 1 ? "COLOR_ATTACHMENT" + i : "COLOR_ATTACHMENT" + i + "_WEBGL"];
            gl.readBuffer(attachments[i]);
            gl.drawBuffers(attachments);
            gl.blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width, texture.height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
        }
        for (var i = 0; i < attachments.length; i++) {
            attachments[i] = gl[this.webGLVersion > 1 ? "COLOR_ATTACHMENT" + i : "COLOR_ATTACHMENT" + i + "_WEBGL"];
        }
        gl.drawBuffers(attachments);
    }
    for (var i = 0; i < textures.length; i++) {
        var texture = textures[i];
        if (texture.generateMipMaps && !disableGenerateMipMaps && !texture.isCube) {
            this._bindTextureDirectly(gl.TEXTURE_2D, texture);
            gl.generateMipmap(gl.TEXTURE_2D);
            this._bindTextureDirectly(gl.TEXTURE_2D, null);
        }
    }
    if (onBeforeUnbind) {
        if (textures[0]._MSAAFramebuffer) {
            // Bind the correct framebuffer
            this._bindUnboundFramebuffer(textures[0]._framebuffer);
        }
        onBeforeUnbind();
    }
    this._bindUnboundFramebuffer(null);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createMultipleRenderTarget = function (size, options) {
    var generateMipMaps = false;
    var generateDepthBuffer = true;
    var generateStencilBuffer = false;
    var generateDepthTexture = false;
    var textureCount = 1;
    var defaultType = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_UNSIGNED_INT;
    var defaultSamplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURE_TRILINEAR_SAMPLINGMODE;
    var types = new Array();
    var samplingModes = new Array();
    if (options !== undefined) {
        generateMipMaps = options.generateMipMaps === undefined ? false : options.generateMipMaps;
        generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
        generateStencilBuffer = options.generateStencilBuffer === undefined ? false : options.generateStencilBuffer;
        generateDepthTexture = options.generateDepthTexture === undefined ? false : options.generateDepthTexture;
        textureCount = options.textureCount || 1;
        if (options.types) {
            types = options.types;
        }
        if (options.samplingModes) {
            samplingModes = options.samplingModes;
        }
    }
    var gl = this._gl;
    // Create the framebuffer
    var framebuffer = gl.createFramebuffer();
    this._bindUnboundFramebuffer(framebuffer);
    var width = size.width || size;
    var height = size.height || size;
    var textures = [];
    var attachments = [];
    var depthStencilBuffer = this._setupFramebufferDepthAttachments(generateStencilBuffer, generateDepthBuffer, width, height);
    for (var i = 0; i < textureCount; i++) {
        var samplingMode = samplingModes[i] || defaultSamplingMode;
        var type = types[i] || defaultType;
        if (type === _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {
            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE
            samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE;
        }
        else if (type === _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {
            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
            samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE;
        }
        var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
        if (type === _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_FLOAT && !this._caps.textureFloat) {
            type = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_UNSIGNED_INT;
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type");
        }
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"].DATASOURCE_MULTIRENDERTARGET);
        var attachment = gl[this.webGLVersion > 1 ? "COLOR_ATTACHMENT" + i : "COLOR_ATTACHMENT" + i + "_WEBGL"];
        textures.push(texture);
        attachments.push(attachment);
        gl.activeTexture(gl["TEXTURE" + i]);
        gl.bindTexture(gl.TEXTURE_2D, texture._webGLTexture);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filters.mag);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filters.min);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texImage2D(gl.TEXTURE_2D, 0, this._getRGBABufferInternalSizedFormat(type), width, height, 0, gl.RGBA, this._getWebGLTextureType(type), null);
        gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, attachment, gl.TEXTURE_2D, texture._webGLTexture, 0);
        if (generateMipMaps) {
            this._gl.generateMipmap(this._gl.TEXTURE_2D);
        }
        // Unbind
        this._bindTextureDirectly(gl.TEXTURE_2D, null);
        texture._framebuffer = framebuffer;
        texture._depthStencilBuffer = depthStencilBuffer;
        texture.baseWidth = width;
        texture.baseHeight = height;
        texture.width = width;
        texture.height = height;
        texture.isReady = true;
        texture.samples = 1;
        texture.generateMipMaps = generateMipMaps;
        texture.samplingMode = samplingMode;
        texture.type = type;
        texture._generateDepthBuffer = generateDepthBuffer;
        texture._generateStencilBuffer = generateStencilBuffer;
        texture._attachments = attachments;
        this._internalTexturesCache.push(texture);
    }
    if (generateDepthTexture && this._caps.depthTextureExtension) {
        // Depth texture
        var depthTexture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"].DATASOURCE_MULTIRENDERTARGET);
        gl.activeTexture(gl.TEXTURE0);
        gl.bindTexture(gl.TEXTURE_2D, depthTexture._webGLTexture);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texImage2D(gl.TEXTURE_2D, 0, this.webGLVersion < 2 ? gl.DEPTH_COMPONENT : gl.DEPTH_COMPONENT16, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture._webGLTexture, 0);
        depthTexture._framebuffer = framebuffer;
        depthTexture.baseWidth = width;
        depthTexture.baseHeight = height;
        depthTexture.width = width;
        depthTexture.height = height;
        depthTexture.isReady = true;
        depthTexture.samples = 1;
        depthTexture.generateMipMaps = generateMipMaps;
        depthTexture.samplingMode = gl.NEAREST;
        depthTexture._generateDepthBuffer = generateDepthBuffer;
        depthTexture._generateStencilBuffer = generateStencilBuffer;
        textures.push(depthTexture);
        this._internalTexturesCache.push(depthTexture);
    }
    gl.drawBuffers(attachments);
    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    this._bindUnboundFramebuffer(null);
    this.resetTextureCache();
    return textures;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.updateMultipleRenderTargetTextureSampleCount = function (textures, samples) {
    if (this.webGLVersion < 2 || !textures || textures.length == 0) {
        return 1;
    }
    if (textures[0].samples === samples) {
        return samples;
    }
    var gl = this._gl;
    samples = Math.min(samples, this.getCaps().maxMSAASamples);
    // Dispose previous render buffers
    if (textures[0]._depthStencilBuffer) {
        gl.deleteRenderbuffer(textures[0]._depthStencilBuffer);
        textures[0]._depthStencilBuffer = null;
    }
    if (textures[0]._MSAAFramebuffer) {
        gl.deleteFramebuffer(textures[0]._MSAAFramebuffer);
        textures[0]._MSAAFramebuffer = null;
    }
    for (var i = 0; i < textures.length; i++) {
        if (textures[i]._MSAARenderBuffer) {
            gl.deleteRenderbuffer(textures[i]._MSAARenderBuffer);
            textures[i]._MSAARenderBuffer = null;
        }
    }
    if (samples > 1) {
        var framebuffer = gl.createFramebuffer();
        if (!framebuffer) {
            throw new Error("Unable to create multi sampled framebuffer");
        }
        this._bindUnboundFramebuffer(framebuffer);
        var depthStencilBuffer = this._setupFramebufferDepthAttachments(textures[0]._generateStencilBuffer, textures[0]._generateDepthBuffer, textures[0].width, textures[0].height, samples);
        var attachments = [];
        for (var i = 0; i < textures.length; i++) {
            var texture = textures[i];
            var attachment = gl[this.webGLVersion > 1 ? "COLOR_ATTACHMENT" + i : "COLOR_ATTACHMENT" + i + "_WEBGL"];
            var colorRenderbuffer = gl.createRenderbuffer();
            if (!colorRenderbuffer) {
                throw new Error("Unable to create multi sampled framebuffer");
            }
            gl.bindRenderbuffer(gl.RENDERBUFFER, colorRenderbuffer);
            gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, this._getRGBAMultiSampleBufferFormat(texture.type), texture.width, texture.height);
            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, colorRenderbuffer);
            texture._MSAAFramebuffer = framebuffer;
            texture._MSAARenderBuffer = colorRenderbuffer;
            texture.samples = samples;
            texture._depthStencilBuffer = depthStencilBuffer;
            gl.bindRenderbuffer(gl.RENDERBUFFER, null);
            attachments.push(attachment);
        }
        gl.drawBuffers(attachments);
    }
    else {
        this._bindUnboundFramebuffer(textures[0]._framebuffer);
    }
    this._bindUnboundFramebuffer(null);
    return samples;
};


/***/ }),

/***/ "./Engines/Extensions/engine.multiview.ts":
/*!************************************************!*\
  !*** ./Engines/Extensions/engine.multiview.ts ***!
  \************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../scene */ "./scene.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Materials/uniformBuffer */ "./Materials/uniformBuffer.ts");
/* harmony import */ var _Materials_Textures_MultiviewRenderTarget__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Materials/Textures/MultiviewRenderTarget */ "./Materials/Textures/MultiviewRenderTarget.ts");
/* harmony import */ var _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Maths/math.frustum */ "./Maths/math.frustum.ts");








_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype.createMultiviewRenderTargetTexture = function (width, height) {
    var gl = this._gl;
    if (!this.getCaps().multiview) {
        throw "Multiview is not supported";
    }
    var internalTexture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_3__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_3__["InternalTexture"].DATASOURCE_UNKNOWN, true);
    internalTexture.width = width;
    internalTexture.height = height;
    internalTexture._framebuffer = gl.createFramebuffer();
    internalTexture._colorTextureArray = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D_ARRAY, internalTexture._colorTextureArray);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, 2);
    internalTexture._depthStencilTextureArray = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D_ARRAY, internalTexture._depthStencilTextureArray);
    gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.DEPTH32F_STENCIL8, width, height, 2);
    internalTexture.isReady = true;
    return internalTexture;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype.bindMultiviewFramebuffer = function (multiviewTexture) {
    var gl = this._gl;
    var ext = this.getCaps().multiview;
    this.bindFramebuffer(multiviewTexture, undefined, undefined, undefined, true);
    gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, multiviewTexture._framebuffer);
    if (multiviewTexture._colorTextureArray && multiviewTexture._depthStencilTextureArray) {
        ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, multiviewTexture._colorTextureArray, 0, 0, 2);
        ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, multiviewTexture._depthStencilTextureArray, 0, 0, 2);
    }
    else {
        throw "Invalid multiview frame buffer";
    }
};
_Cameras_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].prototype._useMultiviewToSingleView = false;
_Cameras_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].prototype._multiviewTexture = null;
_Cameras_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].prototype._resizeOrCreateMultiviewTexture = function (width, height) {
    if (!this._multiviewTexture) {
        this._multiviewTexture = new _Materials_Textures_MultiviewRenderTarget__WEBPACK_IMPORTED_MODULE_6__["MultiviewRenderTarget"](this.getScene(), { width: width, height: height });
    }
    else if (this._multiviewTexture.getRenderWidth() != width || this._multiviewTexture.getRenderHeight() != height) {
        this._multiviewTexture.dispose();
        this._multiviewTexture = new _Materials_Textures_MultiviewRenderTarget__WEBPACK_IMPORTED_MODULE_6__["MultiviewRenderTarget"](this.getScene(), { width: width, height: height });
    }
};
_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype._transformMatrixR = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Zero();
_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype._multiviewSceneUbo = null;
_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype._createMultiviewUbo = function () {
    this._multiviewSceneUbo = new _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_5__["UniformBuffer"](this.getEngine(), undefined, true);
    this._multiviewSceneUbo.addUniform("viewProjection", 16);
    this._multiviewSceneUbo.addUniform("viewProjectionR", 16);
    this._multiviewSceneUbo.addUniform("view", 16);
};
_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype._updateMultiviewUbo = function (viewR, projectionR) {
    if (viewR && projectionR) {
        viewR.multiplyToRef(projectionR, this._transformMatrixR);
    }
    if (viewR && projectionR) {
        viewR.multiplyToRef(projectionR, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Matrix[0]);
        _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_7__["Frustum"].GetRightPlaneToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Matrix[0], this._frustumPlanes[3]); // Replace right plane by second camera right plane
    }
    if (this._multiviewSceneUbo) {
        this._multiviewSceneUbo.updateMatrix("viewProjection", this.getTransformMatrix());
        this._multiviewSceneUbo.updateMatrix("viewProjectionR", this._transformMatrixR);
        this._multiviewSceneUbo.updateMatrix("view", this._viewMatrix);
        this._multiviewSceneUbo.update();
    }
};
_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype._renderMultiviewToSingleView = function (camera) {
    // Multiview is only able to be displayed directly for API's such as webXR
    // This displays a multiview image by rendering to the multiview image and then
    // copying the result into the sub cameras instead of rendering them and proceeding as normal from there
    // Render to a multiview texture
    camera._resizeOrCreateMultiviewTexture((camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.width > 0) ? camera._rigPostProcess.width / 2 : this.getEngine().getRenderWidth(true) / 2, (camera._rigPostProcess && camera._rigPostProcess && camera._rigPostProcess.height > 0) ? camera._rigPostProcess.height : this.getEngine().getRenderHeight(true));
    if (!this._multiviewSceneUbo) {
        this._createMultiviewUbo();
    }
    camera.outputRenderTarget = camera._multiviewTexture;
    this._renderForCamera(camera);
    camera.outputRenderTarget = null;
    // Consume the multiview texture through a shader for each eye
    for (var index = 0; index < camera._rigCameras.length; index++) {
        var engine = this.getEngine();
        this._activeCamera = camera._rigCameras[index];
        engine.setViewport(this._activeCamera.viewport);
        if (this.postProcessManager) {
            this.postProcessManager._prepareFrame();
            this.postProcessManager._finalizeFrame(this._activeCamera.isIntermediate);
        }
    }
};


/***/ }),

/***/ "./Engines/Extensions/engine.occlusionQuery.ts":
/*!*****************************************************!*\
  !*** ./Engines/Extensions/engine.occlusionQuery.ts ***!
  \*****************************************************/
/*! exports provided: _OcclusionDataStorage */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_OcclusionDataStorage", function() { return _OcclusionDataStorage; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Instrumentation_timeToken__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Instrumentation/timeToken */ "./Instrumentation/timeToken.ts");



/** @hidden */
var _OcclusionDataStorage = /** @class */ (function () {
    function _OcclusionDataStorage() {
        /** @hidden */
        this.occlusionInternalRetryCounter = 0;
        /** @hidden */
        this.isOcclusionQueryInProgress = false;
        /** @hidden */
        this.isOccluded = false;
        /** @hidden */
        this.occlusionRetryCount = -1;
        /** @hidden */
        this.occlusionType = _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].OCCLUSION_TYPE_NONE;
        /** @hidden */
        this.occlusionQueryAlgorithmType = _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE;
    }
    return _OcclusionDataStorage;
}());

_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createQuery = function () {
    return this._gl.createQuery();
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.deleteQuery = function (query) {
    this._gl.deleteQuery(query);
    return this;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.isQueryResultAvailable = function (query) {
    return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT_AVAILABLE);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.getQueryResult = function (query) {
    return this._gl.getQueryParameter(query, this._gl.QUERY_RESULT);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.beginOcclusionQuery = function (algorithmType, query) {
    var glAlgorithm = this._getGlAlgorithmType(algorithmType);
    this._gl.beginQuery(glAlgorithm, query);
    return this;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.endOcclusionQuery = function (algorithmType) {
    var glAlgorithm = this._getGlAlgorithmType(algorithmType);
    this._gl.endQuery(glAlgorithm);
    return this;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._createTimeQuery = function () {
    var timerQuery = this.getCaps().timerQuery;
    if (timerQuery.createQueryEXT) {
        return timerQuery.createQueryEXT();
    }
    return this.createQuery();
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._deleteTimeQuery = function (query) {
    var timerQuery = this.getCaps().timerQuery;
    if (timerQuery.deleteQueryEXT) {
        timerQuery.deleteQueryEXT(query);
        return;
    }
    this.deleteQuery(query);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._getTimeQueryResult = function (query) {
    var timerQuery = this.getCaps().timerQuery;
    if (timerQuery.getQueryObjectEXT) {
        return timerQuery.getQueryObjectEXT(query, timerQuery.QUERY_RESULT_EXT);
    }
    return this.getQueryResult(query);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._getTimeQueryAvailability = function (query) {
    var timerQuery = this.getCaps().timerQuery;
    if (timerQuery.getQueryObjectEXT) {
        return timerQuery.getQueryObjectEXT(query, timerQuery.QUERY_RESULT_AVAILABLE_EXT);
    }
    return this.isQueryResultAvailable(query);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.startTimeQuery = function () {
    var caps = this.getCaps();
    var timerQuery = caps.timerQuery;
    if (!timerQuery) {
        return null;
    }
    var token = new _Instrumentation_timeToken__WEBPACK_IMPORTED_MODULE_2__["_TimeToken"]();
    this._gl.getParameter(timerQuery.GPU_DISJOINT_EXT);
    if (caps.canUseTimestampForTimerQuery) {
        token._startTimeQuery = this._createTimeQuery();
        timerQuery.queryCounterEXT(token._startTimeQuery, timerQuery.TIMESTAMP_EXT);
    }
    else {
        if (this._currentNonTimestampToken) {
            return this._currentNonTimestampToken;
        }
        token._timeElapsedQuery = this._createTimeQuery();
        if (timerQuery.beginQueryEXT) {
            timerQuery.beginQueryEXT(timerQuery.TIME_ELAPSED_EXT, token._timeElapsedQuery);
        }
        else {
            this._gl.beginQuery(timerQuery.TIME_ELAPSED_EXT, token._timeElapsedQuery);
        }
        this._currentNonTimestampToken = token;
    }
    return token;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.endTimeQuery = function (token) {
    var caps = this.getCaps();
    var timerQuery = caps.timerQuery;
    if (!timerQuery || !token) {
        return -1;
    }
    if (caps.canUseTimestampForTimerQuery) {
        if (!token._startTimeQuery) {
            return -1;
        }
        if (!token._endTimeQuery) {
            token._endTimeQuery = this._createTimeQuery();
            timerQuery.queryCounterEXT(token._endTimeQuery, timerQuery.TIMESTAMP_EXT);
        }
    }
    else if (!token._timeElapsedQueryEnded) {
        if (!token._timeElapsedQuery) {
            return -1;
        }
        if (timerQuery.endQueryEXT) {
            timerQuery.endQueryEXT(timerQuery.TIME_ELAPSED_EXT);
        }
        else {
            this._gl.endQuery(timerQuery.TIME_ELAPSED_EXT);
        }
        token._timeElapsedQueryEnded = true;
    }
    var disjoint = this._gl.getParameter(timerQuery.GPU_DISJOINT_EXT);
    var available = false;
    if (token._endTimeQuery) {
        available = this._getTimeQueryAvailability(token._endTimeQuery);
    }
    else if (token._timeElapsedQuery) {
        available = this._getTimeQueryAvailability(token._timeElapsedQuery);
    }
    if (available && !disjoint) {
        var result = 0;
        if (caps.canUseTimestampForTimerQuery) {
            if (!token._startTimeQuery || !token._endTimeQuery) {
                return -1;
            }
            var timeStart = this._getTimeQueryResult(token._startTimeQuery);
            var timeEnd = this._getTimeQueryResult(token._endTimeQuery);
            result = timeEnd - timeStart;
            this._deleteTimeQuery(token._startTimeQuery);
            this._deleteTimeQuery(token._endTimeQuery);
            token._startTimeQuery = null;
            token._endTimeQuery = null;
        }
        else {
            if (!token._timeElapsedQuery) {
                return -1;
            }
            result = this._getTimeQueryResult(token._timeElapsedQuery);
            this._deleteTimeQuery(token._timeElapsedQuery);
            token._timeElapsedQuery = null;
            token._timeElapsedQueryEnded = false;
            this._currentNonTimestampToken = null;
        }
        return result;
    }
    return -1;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._getGlAlgorithmType = function (algorithmType) {
    return algorithmType === _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE ? this._gl.ANY_SAMPLES_PASSED_CONSERVATIVE : this._gl.ANY_SAMPLES_PASSED;
};
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "isOcclusionQueryInProgress", {
    get: function () {
        return this._occlusionDataStorage.isOcclusionQueryInProgress;
    },
    enumerable: false,
    configurable: true
});
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "_occlusionDataStorage", {
    get: function () {
        if (!this.__occlusionDataStorage) {
            this.__occlusionDataStorage = new _OcclusionDataStorage();
        }
        return this.__occlusionDataStorage;
    },
    enumerable: false,
    configurable: true
});
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "isOccluded", {
    get: function () {
        return this._occlusionDataStorage.isOccluded;
    },
    set: function (value) {
        this._occlusionDataStorage.isOccluded = value;
    },
    enumerable: true,
    configurable: true
});
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "occlusionQueryAlgorithmType", {
    get: function () {
        return this._occlusionDataStorage.occlusionQueryAlgorithmType;
    },
    set: function (value) {
        this._occlusionDataStorage.occlusionQueryAlgorithmType = value;
    },
    enumerable: true,
    configurable: true
});
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "occlusionType", {
    get: function () {
        return this._occlusionDataStorage.occlusionType;
    },
    set: function (value) {
        this._occlusionDataStorage.occlusionType = value;
    },
    enumerable: true,
    configurable: true
});
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "occlusionRetryCount", {
    get: function () {
        return this._occlusionDataStorage.occlusionRetryCount;
    },
    set: function (value) {
        this._occlusionDataStorage.occlusionRetryCount = value;
    },
    enumerable: true,
    configurable: true
});
// We also need to update AbstractMesh as there is a portion of the code there
_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype._checkOcclusionQuery = function () {
    var dataStorage = this._occlusionDataStorage;
    if (dataStorage.occlusionType === _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].OCCLUSION_TYPE_NONE) {
        dataStorage.isOccluded = false;
        return false;
    }
    var engine = this.getEngine();
    if (engine.webGLVersion < 2) {
        dataStorage.isOccluded = false;
        return false;
    }
    if (!engine.isQueryResultAvailable) { // Occlusion query where not referenced
        dataStorage.isOccluded = false;
        return false;
    }
    if (this.isOcclusionQueryInProgress && this._occlusionQuery) {
        var isOcclusionQueryAvailable = engine.isQueryResultAvailable(this._occlusionQuery);
        if (isOcclusionQueryAvailable) {
            var occlusionQueryResult = engine.getQueryResult(this._occlusionQuery);
            dataStorage.isOcclusionQueryInProgress = false;
            dataStorage.occlusionInternalRetryCounter = 0;
            dataStorage.isOccluded = occlusionQueryResult === 1 ? false : true;
        }
        else {
            dataStorage.occlusionInternalRetryCounter++;
            if (dataStorage.occlusionRetryCount !== -1 && dataStorage.occlusionInternalRetryCounter > dataStorage.occlusionRetryCount) {
                dataStorage.isOcclusionQueryInProgress = false;
                dataStorage.occlusionInternalRetryCounter = 0;
                // if optimistic set isOccluded to false regardless of the status of isOccluded. (Render in the current render loop)
                // if strict continue the last state of the object.
                dataStorage.isOccluded = dataStorage.occlusionType === _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].OCCLUSION_TYPE_OPTIMISTIC ? false : dataStorage.isOccluded;
            }
            else {
                return false;
            }
        }
    }
    var scene = this.getScene();
    if (scene.getBoundingBoxRenderer) {
        var occlusionBoundingBoxRenderer = scene.getBoundingBoxRenderer();
        if (!this._occlusionQuery) {
            this._occlusionQuery = engine.createQuery();
        }
        engine.beginOcclusionQuery(dataStorage.occlusionQueryAlgorithmType, this._occlusionQuery);
        occlusionBoundingBoxRenderer.renderOcclusionBoundingBox(this);
        engine.endOcclusionQuery(dataStorage.occlusionQueryAlgorithmType);
        this._occlusionDataStorage.isOcclusionQueryInProgress = true;
    }
    return dataStorage.isOccluded;
};


/***/ }),

/***/ "./Engines/Extensions/engine.rawTexture.ts":
/*!*************************************************!*\
  !*** ./Engines/Extensions/engine.rawTexture.ts ***!
  \*************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");




_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.updateRawTexture = function (texture, data, format, invertY, compression, type) {
    if (compression === void 0) { compression = null; }
    if (type === void 0) { type = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_UNSIGNED_INT; }
    if (!texture) {
        return;
    }
    // Babylon's internalSizedFomat but gl's texImage2D internalFormat
    var internalSizedFomat = this._getRGBABufferInternalSizedFormat(type, format);
    // Babylon's internalFormat but gl's texImage2D format
    var internalFormat = this._getInternalFormat(format);
    var textureType = this._getWebGLTextureType(type);
    this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
    this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
    if (!this._doNotHandleContextLost) {
        texture._bufferView = data;
        texture.format = format;
        texture.type = type;
        texture.invertY = invertY;
        texture._compression = compression;
    }
    if (texture.width % 4 !== 0) {
        this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
    }
    if (compression && data) {
        this._gl.compressedTexImage2D(this._gl.TEXTURE_2D, 0, this.getCaps().s3tc[compression], texture.width, texture.height, 0, data);
    }
    else {
        this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, data);
    }
    if (texture.generateMipMaps) {
        this._gl.generateMipmap(this._gl.TEXTURE_2D);
    }
    this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
    //  this.resetTextureCache();
    texture.isReady = true;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createRawTexture = function (data, width, height, format, generateMipMaps, invertY, samplingMode, compression, type) {
    if (compression === void 0) { compression = null; }
    if (type === void 0) { type = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_UNSIGNED_INT; }
    var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"].DATASOURCE_RAW);
    texture.baseWidth = width;
    texture.baseHeight = height;
    texture.width = width;
    texture.height = height;
    texture.format = format;
    texture.generateMipMaps = generateMipMaps;
    texture.samplingMode = samplingMode;
    texture.invertY = invertY;
    texture._compression = compression;
    texture.type = type;
    if (!this._doNotHandleContextLost) {
        texture._bufferView = data;
    }
    this.updateRawTexture(texture, data, format, invertY, compression, type);
    this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
    // Filters
    var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
    this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
    this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);
    if (generateMipMaps) {
        this._gl.generateMipmap(this._gl.TEXTURE_2D);
    }
    this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
    this._internalTexturesCache.push(texture);
    return texture;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createRawCubeTexture = function (data, size, format, type, generateMipMaps, invertY, samplingMode, compression) {
    if (compression === void 0) { compression = null; }
    var gl = this._gl;
    var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"].DATASOURCE_CUBERAW);
    texture.isCube = true;
    texture.format = format;
    texture.type = type;
    if (!this._doNotHandleContextLost) {
        texture._bufferViewArray = data;
    }
    var textureType = this._getWebGLTextureType(type);
    var internalFormat = this._getInternalFormat(format);
    if (internalFormat === gl.RGB) {
        internalFormat = gl.RGBA;
    }
    // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable
    if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
        generateMipMaps = false;
        samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
    }
    else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
        generateMipMaps = false;
        samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
    }
    else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {
        generateMipMaps = false;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Render to float textures is not supported. Mipmap generation forced to false.");
    }
    else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {
        generateMipMaps = false;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Render to half float textures is not supported. Mipmap generation forced to false.");
    }
    var width = size;
    var height = width;
    texture.width = width;
    texture.height = height;
    // Double check on POT to generate Mips.
    var isPot = !this.needPOTTextures || (_Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].IsExponentOfTwo(texture.width) && _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].IsExponentOfTwo(texture.height));
    if (!isPot) {
        generateMipMaps = false;
    }
    // Upload data if needed. The texture won't be ready until then.
    if (data) {
        this.updateRawCubeTexture(texture, data, format, type, invertY, compression);
    }
    this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);
    // Filters
    if (data && generateMipMaps) {
        this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
    }
    var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
    texture.generateMipMaps = generateMipMaps;
    return texture;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.updateRawCubeTexture = function (texture, data, format, type, invertY, compression, level) {
    if (compression === void 0) { compression = null; }
    if (level === void 0) { level = 0; }
    texture._bufferViewArray = data;
    texture.format = format;
    texture.type = type;
    texture.invertY = invertY;
    texture._compression = compression;
    var gl = this._gl;
    var textureType = this._getWebGLTextureType(type);
    var internalFormat = this._getInternalFormat(format);
    var internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);
    var needConversion = false;
    if (internalFormat === gl.RGB) {
        internalFormat = gl.RGBA;
        needConversion = true;
    }
    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
    this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
    if (texture.width % 4 !== 0) {
        gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
    }
    // Data are known to be in +X +Y +Z -X -Y -Z
    for (var faceIndex = 0; faceIndex < 6; faceIndex++) {
        var faceData = data[faceIndex];
        if (compression) {
            gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, (this.getCaps().s3tc)[compression], texture.width, texture.height, 0, faceData);
        }
        else {
            if (needConversion) {
                faceData = this._convertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);
            }
            gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, faceData);
        }
    }
    var isPot = !this.needPOTTextures || (_Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].IsExponentOfTwo(texture.width) && _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].IsExponentOfTwo(texture.height));
    if (isPot && texture.generateMipMaps && level === 0) {
        this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
    }
    this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
    // this.resetTextureCache();
    texture.isReady = true;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createRawCubeTextureFromUrl = function (url, scene, size, format, type, noMipmap, callback, mipmapGenerator, onLoad, onError, samplingMode, invertY) {
    var _this = this;
    if (onLoad === void 0) { onLoad = null; }
    if (onError === void 0) { onError = null; }
    if (samplingMode === void 0) { samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
    if (invertY === void 0) { invertY = false; }
    var gl = this._gl;
    var texture = this.createRawCubeTexture(null, size, format, type, !noMipmap, invertY, samplingMode);
    scene._addPendingData(texture);
    texture.url = url;
    this._internalTexturesCache.push(texture);
    var onerror = function (request, exception) {
        scene._removePendingData(texture);
        if (onError && request) {
            onError(request.status + " " + request.statusText, exception);
        }
    };
    var internalCallback = function (data) {
        var width = texture.width;
        var faceDataArrays = callback(data);
        if (!faceDataArrays) {
            return;
        }
        if (mipmapGenerator) {
            var textureType = _this._getWebGLTextureType(type);
            var internalFormat = _this._getInternalFormat(format);
            var internalSizedFomat = _this._getRGBABufferInternalSizedFormat(type);
            var needConversion = false;
            if (internalFormat === gl.RGB) {
                internalFormat = gl.RGBA;
                needConversion = true;
            }
            _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
            _this._unpackFlipY(false);
            var mipData = mipmapGenerator(faceDataArrays);
            for (var level = 0; level < mipData.length; level++) {
                var mipSize = width >> level;
                for (var faceIndex = 0; faceIndex < 6; faceIndex++) {
                    var mipFaceData = mipData[level][faceIndex];
                    if (needConversion) {
                        mipFaceData = _this._convertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);
                    }
                    gl.texImage2D(faceIndex, level, internalSizedFomat, mipSize, mipSize, 0, internalFormat, textureType, mipFaceData);
                }
            }
            _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
        }
        else {
            _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
        }
        texture.isReady = true;
        // this.resetTextureCache();
        scene._removePendingData(texture);
        if (onLoad) {
            onLoad();
        }
    };
    this._loadFile(url, function (data) {
        internalCallback(data);
    }, undefined, scene.offlineProvider, true, onerror);
    return texture;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createRawTexture3D = function (data, width, height, depth, format, generateMipMaps, invertY, samplingMode, compression, textureType) {
    if (compression === void 0) { compression = null; }
    if (textureType === void 0) { textureType = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_UNSIGNED_INT; }
    var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_1__["InternalTexture"].DATASOURCE_RAW3D);
    texture.baseWidth = width;
    texture.baseHeight = height;
    texture.baseDepth = depth;
    texture.width = width;
    texture.height = height;
    texture.depth = depth;
    texture.format = format;
    texture.type = textureType;
    texture.generateMipMaps = generateMipMaps;
    texture.samplingMode = samplingMode;
    texture.is3D = true;
    if (!this._doNotHandleContextLost) {
        texture._bufferView = data;
    }
    this.updateRawTexture3D(texture, data, format, invertY, compression, textureType);
    this._bindTextureDirectly(this._gl.TEXTURE_3D, texture, true);
    // Filters
    var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
    this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
    this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, filters.min);
    if (generateMipMaps) {
        this._gl.generateMipmap(this._gl.TEXTURE_3D);
    }
    this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
    this._internalTexturesCache.push(texture);
    return texture;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.updateRawTexture3D = function (texture, data, format, invertY, compression, textureType) {
    if (compression === void 0) { compression = null; }
    if (textureType === void 0) { textureType = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].TEXTURETYPE_UNSIGNED_INT; }
    var internalType = this._getWebGLTextureType(textureType);
    var internalFormat = this._getInternalFormat(format);
    var internalSizedFomat = this._getRGBABufferInternalSizedFormat(textureType, format);
    this._bindTextureDirectly(this._gl.TEXTURE_3D, texture, true);
    this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
    if (!this._doNotHandleContextLost) {
        texture._bufferView = data;
        texture.format = format;
        texture.invertY = invertY;
        texture._compression = compression;
    }
    if (texture.width % 4 !== 0) {
        this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
    }
    if (compression && data) {
        this._gl.compressedTexImage3D(this._gl.TEXTURE_3D, 0, this.getCaps().s3tc[compression], texture.width, texture.height, texture.depth, 0, data);
    }
    else {
        this._gl.texImage3D(this._gl.TEXTURE_3D, 0, internalSizedFomat, texture.width, texture.height, texture.depth, 0, internalFormat, internalType, data);
    }
    if (texture.generateMipMaps) {
        this._gl.generateMipmap(this._gl.TEXTURE_3D);
    }
    this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
    // this.resetTextureCache();
    texture.isReady = true;
};


/***/ }),

/***/ "./Engines/Extensions/engine.renderTarget.ts":
/*!***************************************************!*\
  !*** ./Engines/Extensions/engine.renderTarget.ts ***!
  \***************************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");




_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].prototype.createRenderTargetCubeTexture = function (size, options) {
    var fullOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ generateMipMaps: true, generateDepthBuffer: true, generateStencilBuffer: false, type: _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_UNSIGNED_INT, samplingMode: _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_TRILINEAR_SAMPLINGMODE, format: _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTUREFORMAT_RGBA }, options);
    fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && fullOptions.generateStencilBuffer;
    if (fullOptions.type === _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {
        // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE
        fullOptions.samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE;
    }
    else if (fullOptions.type === _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {
        // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
        fullOptions.samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE;
    }
    var gl = this._gl;
    var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_RENDERTARGET);
    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
    var filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps);
    if (fullOptions.type === _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_FLOAT && !this._caps.textureFloat) {
        fullOptions.type = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_UNSIGNED_INT;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Warn("Float textures are not supported. Cube render target forced to TEXTURETYPE_UNESIGNED_BYTE type");
    }
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    for (var face = 0; face < 6; face++) {
        gl.texImage2D((gl.TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format), size, size, 0, this._getInternalFormat(fullOptions.format), this._getWebGLTextureType(fullOptions.type), null);
    }
    // Create the framebuffer
    var framebuffer = gl.createFramebuffer();
    this._bindUnboundFramebuffer(framebuffer);
    texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(fullOptions.generateStencilBuffer, fullOptions.generateDepthBuffer, size, size);
    // MipMaps
    if (fullOptions.generateMipMaps) {
        gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
    }
    // Unbind
    this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
    this._bindUnboundFramebuffer(null);
    texture._framebuffer = framebuffer;
    texture.width = size;
    texture.height = size;
    texture.isReady = true;
    texture.isCube = true;
    texture.samples = 1;
    texture.generateMipMaps = fullOptions.generateMipMaps;
    texture.samplingMode = fullOptions.samplingMode;
    texture.type = fullOptions.type;
    texture.format = fullOptions.format;
    texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
    texture._generateStencilBuffer = fullOptions.generateStencilBuffer;
    this._internalTexturesCache.push(texture);
    return texture;
};


/***/ }),

/***/ "./Engines/Extensions/engine.transformFeedback.ts":
/*!********************************************************!*\
  !*** ./Engines/Extensions/engine.transformFeedback.ts ***!
  \********************************************************/
/*! exports provided: _forceTransformFeedbackToBundle */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_forceTransformFeedbackToBundle", function() { return _forceTransformFeedbackToBundle; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");

/** @hidden */
var _forceTransformFeedbackToBundle = true;
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.createTransformFeedback = function () {
    return this._gl.createTransformFeedback();
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.deleteTransformFeedback = function (value) {
    this._gl.deleteTransformFeedback(value);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.bindTransformFeedback = function (value) {
    this._gl.bindTransformFeedback(this._gl.TRANSFORM_FEEDBACK, value);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.beginTransformFeedback = function (usePoints) {
    if (usePoints === void 0) { usePoints = true; }
    this._gl.beginTransformFeedback(usePoints ? this._gl.POINTS : this._gl.TRIANGLES);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.endTransformFeedback = function () {
    this._gl.endTransformFeedback();
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.setTranformFeedbackVaryings = function (program, value) {
    this._gl.transformFeedbackVaryings(program, value, this._gl.INTERLEAVED_ATTRIBS);
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.bindTransformFeedbackBuffer = function (value) {
    this._gl.bindBufferBase(this._gl.TRANSFORM_FEEDBACK_BUFFER, 0, value ? value.underlyingResource : null);
};


/***/ }),

/***/ "./Engines/Extensions/engine.webVR.ts":
/*!********************************************!*\
  !*** ./Engines/Extensions/engine.webVR.ts ***!
  \********************************************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Maths_math_size__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.size */ "./Maths/math.size.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_domManagement__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/domManagement */ "./Misc/domManagement.ts");





Object.defineProperty(_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype, "isInVRExclusivePointerMode", {
    get: function () {
        return this._vrExclusivePointerMode;
    },
    enumerable: true,
    configurable: true
});
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._prepareVRComponent = function () {
    this._vrSupported = false;
    this._vrExclusivePointerMode = false;
    this.onVRDisplayChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
    this.onVRRequestPresentComplete = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
    this.onVRRequestPresentStart = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.isVRDevicePresent = function () {
    return !!this._vrDisplay;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.getVRDevice = function () {
    return this._vrDisplay;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.initWebVR = function () {
    this.initWebVRAsync();
    return this.onVRDisplayChangedObservable;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.initWebVRAsync = function () {
    var _this = this;
    var notifyObservers = function () {
        var eventArgs = {
            vrDisplay: _this._vrDisplay,
            vrSupported: _this._vrSupported
        };
        _this.onVRDisplayChangedObservable.notifyObservers(eventArgs);
        _this._webVRInitPromise = new Promise(function (res) { res(eventArgs); });
    };
    if (!this._onVrDisplayConnect) {
        this._onVrDisplayConnect = function (event) {
            _this._vrDisplay = event.display;
            notifyObservers();
        };
        this._onVrDisplayDisconnect = function () {
            _this._vrDisplay.cancelAnimationFrame(_this._frameHandler);
            _this._vrDisplay = undefined;
            _this._frameHandler = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].QueueNewFrame(_this._bindedRenderFunction);
            notifyObservers();
        };
        this._onVrDisplayPresentChange = function () {
            _this._vrExclusivePointerMode = _this._vrDisplay && _this._vrDisplay.isPresenting;
        };
        var hostWindow = this.getHostWindow();
        hostWindow.addEventListener('vrdisplayconnect', this._onVrDisplayConnect);
        hostWindow.addEventListener('vrdisplaydisconnect', this._onVrDisplayDisconnect);
        hostWindow.addEventListener('vrdisplaypresentchange', this._onVrDisplayPresentChange);
    }
    this._webVRInitPromise = this._webVRInitPromise || this._getVRDisplaysAsync();
    this._webVRInitPromise.then(notifyObservers);
    return this._webVRInitPromise;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._getVRDisplaysAsync = function () {
    var _this = this;
    return new Promise(function (res) {
        if (navigator.getVRDisplays) {
            navigator.getVRDisplays().then(function (devices) {
                _this._vrSupported = true;
                // note that devices may actually be an empty array. This is fine;
                // we expect this._vrDisplay to be undefined in this case.
                _this._vrDisplay = devices[0];
                res({
                    vrDisplay: _this._vrDisplay,
                    vrSupported: _this._vrSupported
                });
            });
        }
        else {
            _this._vrDisplay = undefined;
            _this._vrSupported = false;
            res({
                vrDisplay: _this._vrDisplay,
                vrSupported: _this._vrSupported
            });
        }
    });
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.enableVR = function () {
    var _this = this;
    if (this._vrDisplay && !this._vrDisplay.isPresenting) {
        var onResolved = function () {
            _this.onVRRequestPresentComplete.notifyObservers(true);
            _this._onVRFullScreenTriggered();
        };
        var onRejected = function () {
            _this.onVRRequestPresentComplete.notifyObservers(false);
        };
        this.onVRRequestPresentStart.notifyObservers(this);
        this._vrDisplay.requestPresent([{ source: this.getRenderingCanvas() }]).then(onResolved).catch(onRejected);
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._onVRFullScreenTriggered = function () {
    if (this._vrDisplay && this._vrDisplay.isPresenting) {
        //get the old size before we change
        this._oldSize = new _Maths_math_size__WEBPACK_IMPORTED_MODULE_1__["Size"](this.getRenderWidth(), this.getRenderHeight());
        this._oldHardwareScaleFactor = this.getHardwareScalingLevel();
        //get the width and height, change the render size
        var leftEye = this._vrDisplay.getEyeParameters('left');
        this.setHardwareScalingLevel(1);
        this.setSize(leftEye.renderWidth * 2, leftEye.renderHeight);
    }
    else {
        this.setHardwareScalingLevel(this._oldHardwareScaleFactor);
        this.setSize(this._oldSize.width, this._oldSize.height);
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.disableVR = function () {
    var _this = this;
    if (this._vrDisplay && this._vrDisplay.isPresenting) {
        this._vrDisplay.exitPresent()
            .then(function () { return _this._onVRFullScreenTriggered(); })
            .catch(function () { return _this._onVRFullScreenTriggered(); });
    }
    if (_Misc_domManagement__WEBPACK_IMPORTED_MODULE_4__["DomManagement"].IsWindowObjectExist()) {
        window.removeEventListener('vrdisplaypointerrestricted', this._onVRDisplayPointerRestricted);
        window.removeEventListener('vrdisplaypointerunrestricted', this._onVRDisplayPointerUnrestricted);
        if (this._onVrDisplayConnect) {
            window.removeEventListener('vrdisplayconnect', this._onVrDisplayConnect);
            if (this._onVrDisplayDisconnect) {
                window.removeEventListener('vrdisplaydisconnect', this._onVrDisplayDisconnect);
            }
            if (this._onVrDisplayPresentChange) {
                window.removeEventListener('vrdisplaypresentchange', this._onVrDisplayPresentChange);
            }
            this._onVrDisplayConnect = null;
            this._onVrDisplayDisconnect = null;
        }
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._connectVREvents = function (canvas, document) {
    this._onVRDisplayPointerRestricted = function () {
        if (canvas) {
            canvas.requestPointerLock();
        }
    };
    this._onVRDisplayPointerUnrestricted = function () {
        if (!document.exitPointerLock) {
            return;
        }
        document.exitPointerLock();
    };
    if (_Misc_domManagement__WEBPACK_IMPORTED_MODULE_4__["DomManagement"].IsWindowObjectExist()) {
        var hostWindow = this.getHostWindow();
        hostWindow.addEventListener('vrdisplaypointerrestricted', this._onVRDisplayPointerRestricted, false);
        hostWindow.addEventListener('vrdisplaypointerunrestricted', this._onVRDisplayPointerUnrestricted, false);
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._submitVRFrame = function () {
    // Submit frame to the vr device, if enabled
    if (this._vrDisplay && this._vrDisplay.isPresenting) {
        // TODO: We should only submit the frame if we read frameData successfully.
        try {
            this._vrDisplay.submitFrame();
        }
        catch (e) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].Warn("webVR submitFrame has had an unexpected failure: " + e);
        }
    }
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.isVRPresenting = function () {
    return this._vrDisplay && this._vrDisplay.isPresenting;
};
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype._requestVRFrame = function () {
    this._frameHandler = _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].QueueNewFrame(this._bindedRenderFunction, this._vrDisplay);
};


/***/ }),

/***/ "./Engines/Extensions/index.ts":
/*!*************************************!*\
  !*** ./Engines/Extensions/index.ts ***!
  \*************************************/
/*! exports provided: _OcclusionDataStorage, _forceTransformFeedbackToBundle */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _engine_occlusionQuery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./engine.occlusionQuery */ "./Engines/Extensions/engine.occlusionQuery.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_OcclusionDataStorage", function() { return _engine_occlusionQuery__WEBPACK_IMPORTED_MODULE_0__["_OcclusionDataStorage"]; });

/* harmony import */ var _engine_transformFeedback__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine.transformFeedback */ "./Engines/Extensions/engine.transformFeedback.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceTransformFeedbackToBundle", function() { return _engine_transformFeedback__WEBPACK_IMPORTED_MODULE_1__["_forceTransformFeedbackToBundle"]; });





/***/ }),

/***/ "./Engines/Native/nativeShaderProcessor.ts":
/*!*************************************************!*\
  !*** ./Engines/Native/nativeShaderProcessor.ts ***!
  \*************************************************/
/*! exports provided: NativeShaderProcessor */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NativeShaderProcessor", function() { return NativeShaderProcessor; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _WebGL_webGL2ShaderProcessors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../WebGL/webGL2ShaderProcessors */ "./Engines/WebGL/webGL2ShaderProcessors.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
var _a;



// These numbers must match the values for bgfx::Attrib::Enum
var attributeLocations = (_a = {},
    _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind] = 0,
    _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind] = 1,
    _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].TangentKind] = 2,
    _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind] = 4,
    _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].MatricesIndicesKind] = 8,
    _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].MatricesWeightsKind] = 9,
    _a);
// Must match bgfx::Attrib::TexCoord0
var firstGenericAttributeLocation = 10;
// Must match bgfx::Attrib::TexCoord7
var lastGenericAttributeLocation = 17;
/** @hidden */
var NativeShaderProcessor = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NativeShaderProcessor, _super);
    function NativeShaderProcessor() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    NativeShaderProcessor.prototype.lineProcessor = function (line) {
        for (var _i = 0, _a = this._replacements; _i < _a.length; _i++) {
            var replacement = _a[_i];
            line = line.replace(replacement.searchValue, replacement.replaceValue);
        }
        return line;
    };
    NativeShaderProcessor.prototype.attributeProcessor = function (attribute) {
        var match = attribute.match(/attribute\s+[^\s]+\s+([^\s]+)\s*(?:\[.+\])?\s*;/);
        var name = match[1];
        var location = attributeLocations[name];
        if (location === undefined) {
            location = this._genericAttributeLocation++;
            if (location > lastGenericAttributeLocation) {
                throw new Error("Exceeded maximum custom attributes");
            }
        }
        return "layout(location=" + location + ") " + _super.prototype.attributeProcessor.call(this, attribute);
    };
    NativeShaderProcessor.prototype.varyingProcessor = function (varying, isFragment) {
        var location;
        if (isFragment) {
            location = this._varyingLocationMap[varying];
        }
        else {
            location = this._varyingLocationCount++;
            this._varyingLocationMap[varying] = location;
        }
        return "layout(location=" + location + ") " + _super.prototype.varyingProcessor.call(this, varying, isFragment);
    };
    NativeShaderProcessor.prototype.uniformProcessor = function (uniform) {
        var match = uniform.match(/uniform\s+([^\s]+)\s+([^\s]+)\s*(?:\[.+\])?\s*;/);
        var type = match[1];
        var name = match[2];
        switch (type) {
            case "sampler2D":
            case "samplerCube": {
                var suffix = type.substr(7);
                var binding = this._textureCount++;
                this._replacements.push({ searchValue: new RegExp("\\b" + name + "\\b"), replaceValue: "sampler" + suffix + "(" + name + "Texture, " + name + ")" });
                return "layout(binding=" + binding + ") uniform texture" + suffix + " " + name + "Texture;\nlayout(binding=" + binding + ") uniform sampler " + name + ";";
            }
        }
        this._uniforms.push(uniform);
        return this._uniforms.length === 1 ? "<UNIFORM>" : "";
    };
    NativeShaderProcessor.prototype.preProcessor = function (code, defines, isFragment) {
        this._genericAttributeLocation = firstGenericAttributeLocation;
        if (!isFragment) {
            this._varyingLocationCount = 0;
            this._varyingLocationMap = {};
        }
        this._replacements = [];
        this._textureCount = 0;
        this._uniforms = [];
        return code;
    };
    NativeShaderProcessor.prototype.postProcessor = function (code, defines, isFragment) {
        code = _super.prototype.postProcessor.call(this, code, defines, isFragment);
        code = code.replace("<UNIFORM>", "uniform Frame {\n" + this._uniforms.join("\n") + "\n};");
        code = code.replace("out vec4 glFragColor", "layout(location=0) out vec4 glFragColor");
        return code;
    };
    return NativeShaderProcessor;
}(_WebGL_webGL2ShaderProcessors__WEBPACK_IMPORTED_MODULE_1__["WebGL2ShaderProcessor"]));



/***/ }),

/***/ "./Engines/Processors/Expressions/Operators/shaderDefineAndOperator.ts":
/*!*****************************************************************************!*\
  !*** ./Engines/Processors/Expressions/Operators/shaderDefineAndOperator.ts ***!
  \*****************************************************************************/
/*! exports provided: ShaderDefineAndOperator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderDefineAndOperator", function() { return ShaderDefineAndOperator; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shaderDefineExpression */ "./Engines/Processors/Expressions/shaderDefineExpression.ts");


/** @hidden */
var ShaderDefineAndOperator = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderDefineAndOperator, _super);
    function ShaderDefineAndOperator() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    ShaderDefineAndOperator.prototype.isTrue = function (preprocessors) {
        return this.leftOperand.isTrue(preprocessors) && this.rightOperand.isTrue(preprocessors);
    };
    return ShaderDefineAndOperator;
}(_shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__["ShaderDefineExpression"]));



/***/ }),

/***/ "./Engines/Processors/Expressions/Operators/shaderDefineArithmeticOperator.ts":
/*!************************************************************************************!*\
  !*** ./Engines/Processors/Expressions/Operators/shaderDefineArithmeticOperator.ts ***!
  \************************************************************************************/
/*! exports provided: ShaderDefineArithmeticOperator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderDefineArithmeticOperator", function() { return ShaderDefineArithmeticOperator; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shaderDefineExpression */ "./Engines/Processors/Expressions/shaderDefineExpression.ts");


/** @hidden */
var ShaderDefineArithmeticOperator = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderDefineArithmeticOperator, _super);
    function ShaderDefineArithmeticOperator(define, operand, testValue) {
        var _this = _super.call(this) || this;
        _this.define = define;
        _this.operand = operand;
        _this.testValue = testValue;
        return _this;
    }
    ShaderDefineArithmeticOperator.prototype.isTrue = function (preprocessors) {
        var value = preprocessors[this.define];
        if (value === undefined) {
            return false;
        }
        var condition = false;
        var left = parseInt(value);
        var right = parseInt(this.testValue);
        switch (this.operand) {
            case ">":
                condition = left > right;
                break;
            case "<":
                condition = left < right;
                break;
            case "<=":
                condition = left <= right;
                break;
            case ">=":
                condition = left >= right;
                break;
            case "==":
                condition = left === right;
                break;
        }
        return condition;
    };
    return ShaderDefineArithmeticOperator;
}(_shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__["ShaderDefineExpression"]));



/***/ }),

/***/ "./Engines/Processors/Expressions/Operators/shaderDefineIsDefinedOperator.ts":
/*!***********************************************************************************!*\
  !*** ./Engines/Processors/Expressions/Operators/shaderDefineIsDefinedOperator.ts ***!
  \***********************************************************************************/
/*! exports provided: ShaderDefineIsDefinedOperator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderDefineIsDefinedOperator", function() { return ShaderDefineIsDefinedOperator; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shaderDefineExpression */ "./Engines/Processors/Expressions/shaderDefineExpression.ts");


/** @hidden */
var ShaderDefineIsDefinedOperator = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderDefineIsDefinedOperator, _super);
    function ShaderDefineIsDefinedOperator(define, not) {
        if (not === void 0) { not = false; }
        var _this = _super.call(this) || this;
        _this.define = define;
        _this.not = not;
        return _this;
    }
    ShaderDefineIsDefinedOperator.prototype.isTrue = function (preprocessors) {
        var condition = preprocessors[this.define] !== undefined;
        if (this.not) {
            condition = !condition;
        }
        return condition;
    };
    return ShaderDefineIsDefinedOperator;
}(_shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__["ShaderDefineExpression"]));



/***/ }),

/***/ "./Engines/Processors/Expressions/Operators/shaderDefineOrOperator.ts":
/*!****************************************************************************!*\
  !*** ./Engines/Processors/Expressions/Operators/shaderDefineOrOperator.ts ***!
  \****************************************************************************/
/*! exports provided: ShaderDefineOrOperator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderDefineOrOperator", function() { return ShaderDefineOrOperator; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shaderDefineExpression */ "./Engines/Processors/Expressions/shaderDefineExpression.ts");


/** @hidden */
var ShaderDefineOrOperator = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderDefineOrOperator, _super);
    function ShaderDefineOrOperator() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    ShaderDefineOrOperator.prototype.isTrue = function (preprocessors) {
        return this.leftOperand.isTrue(preprocessors) || this.rightOperand.isTrue(preprocessors);
    };
    return ShaderDefineOrOperator;
}(_shaderDefineExpression__WEBPACK_IMPORTED_MODULE_1__["ShaderDefineExpression"]));



/***/ }),

/***/ "./Engines/Processors/Expressions/shaderDefineExpression.ts":
/*!******************************************************************!*\
  !*** ./Engines/Processors/Expressions/shaderDefineExpression.ts ***!
  \******************************************************************/
/*! exports provided: ShaderDefineExpression */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderDefineExpression", function() { return ShaderDefineExpression; });
/** @hidden */
var ShaderDefineExpression = /** @class */ (function () {
    function ShaderDefineExpression() {
    }
    ShaderDefineExpression.prototype.isTrue = function (preprocessors) {
        return true;
    };
    return ShaderDefineExpression;
}());



/***/ }),

/***/ "./Engines/Processors/shaderCodeConditionNode.ts":
/*!*******************************************************!*\
  !*** ./Engines/Processors/shaderCodeConditionNode.ts ***!
  \*******************************************************/
/*! exports provided: ShaderCodeConditionNode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderCodeConditionNode", function() { return ShaderCodeConditionNode; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _shaderCodeNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shaderCodeNode */ "./Engines/Processors/shaderCodeNode.ts");


/** @hidden */
var ShaderCodeConditionNode = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderCodeConditionNode, _super);
    function ShaderCodeConditionNode() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    ShaderCodeConditionNode.prototype.process = function (preprocessors, options) {
        for (var index = 0; index < this.children.length; index++) {
            var node = this.children[index];
            if (node.isValid(preprocessors)) {
                return node.process(preprocessors, options);
            }
        }
        return "";
    };
    return ShaderCodeConditionNode;
}(_shaderCodeNode__WEBPACK_IMPORTED_MODULE_1__["ShaderCodeNode"]));



/***/ }),

/***/ "./Engines/Processors/shaderCodeCursor.ts":
/*!************************************************!*\
  !*** ./Engines/Processors/shaderCodeCursor.ts ***!
  \************************************************/
/*! exports provided: ShaderCodeCursor */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderCodeCursor", function() { return ShaderCodeCursor; });
/** @hidden */
var ShaderCodeCursor = /** @class */ (function () {
    function ShaderCodeCursor() {
    }
    Object.defineProperty(ShaderCodeCursor.prototype, "currentLine", {
        get: function () {
            return this._lines[this.lineIndex];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShaderCodeCursor.prototype, "canRead", {
        get: function () {
            return this.lineIndex < this._lines.length - 1;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShaderCodeCursor.prototype, "lines", {
        set: function (value) {
            this._lines = [];
            for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
                var line = value_1[_i];
                // Prevent removing line break in macros.
                if (line[0] === "#") {
                    this._lines.push(line);
                    continue;
                }
                var split = line.split(";");
                for (var index = 0; index < split.length; index++) {
                    var subLine = split[index];
                    subLine = subLine.trim();
                    if (!subLine) {
                        continue;
                    }
                    this._lines.push(subLine + (index !== split.length - 1 ? ";" : ""));
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    return ShaderCodeCursor;
}());



/***/ }),

/***/ "./Engines/Processors/shaderCodeNode.ts":
/*!**********************************************!*\
  !*** ./Engines/Processors/shaderCodeNode.ts ***!
  \**********************************************/
/*! exports provided: ShaderCodeNode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderCodeNode", function() { return ShaderCodeNode; });
/* harmony import */ var _Misc_stringTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/stringTools */ "./Misc/stringTools.ts");

/** @hidden */
var ShaderCodeNode = /** @class */ (function () {
    function ShaderCodeNode() {
        this.children = [];
    }
    ShaderCodeNode.prototype.isValid = function (preprocessors) {
        return true;
    };
    ShaderCodeNode.prototype.process = function (preprocessors, options) {
        var result = "";
        if (this.line) {
            var value = this.line;
            var processor = options.processor;
            if (processor) {
                // This must be done before other replacements to avoid mistakenly changing something that was already changed.
                if (processor.lineProcessor) {
                    value = processor.lineProcessor(value, options.isFragment, options.processingContext);
                }
                if (processor.attributeProcessor && _Misc_stringTools__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(this.line, "attribute")) {
                    value = processor.attributeProcessor(this.line, options.processingContext);
                }
                else if (processor.varyingProcessor && _Misc_stringTools__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(this.line, "varying")) {
                    value = processor.varyingProcessor(this.line, options.isFragment, options.processingContext);
                }
                else if ((processor.uniformProcessor || processor.uniformBufferProcessor) && _Misc_stringTools__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(this.line, "uniform") && !options.lookForClosingBracketForUniformBuffer) {
                    var regex = /uniform\s+(\S+)\s+(\S+)\s*;/;
                    if (regex.test(this.line)) { // uniform
                        if (processor.uniformProcessor) {
                            value = processor.uniformProcessor(this.line, options.isFragment, preprocessors, options.processingContext);
                        }
                    }
                    else { // Uniform buffer
                        if (processor.uniformBufferProcessor) {
                            value = processor.uniformBufferProcessor(this.line, options.isFragment, options.processingContext);
                            options.lookForClosingBracketForUniformBuffer = true;
                        }
                    }
                }
                if (options.lookForClosingBracketForUniformBuffer && this.line.indexOf("}") !== -1) {
                    options.lookForClosingBracketForUniformBuffer = false;
                    if (processor.endOfUniformBufferProcessor) {
                        value = processor.endOfUniformBufferProcessor(this.line, options.isFragment, options.processingContext);
                    }
                }
            }
            result += value + "\r\n";
        }
        this.children.forEach(function (child) {
            result += child.process(preprocessors, options);
        });
        if (this.additionalDefineKey) {
            preprocessors[this.additionalDefineKey] = this.additionalDefineValue || "true";
        }
        return result;
    };
    return ShaderCodeNode;
}());



/***/ }),

/***/ "./Engines/Processors/shaderCodeTestNode.ts":
/*!**************************************************!*\
  !*** ./Engines/Processors/shaderCodeTestNode.ts ***!
  \**************************************************/
/*! exports provided: ShaderCodeTestNode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderCodeTestNode", function() { return ShaderCodeTestNode; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _shaderCodeNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shaderCodeNode */ "./Engines/Processors/shaderCodeNode.ts");


/** @hidden */
var ShaderCodeTestNode = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderCodeTestNode, _super);
    function ShaderCodeTestNode() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    ShaderCodeTestNode.prototype.isValid = function (preprocessors) {
        return this.testExpression.isTrue(preprocessors);
    };
    return ShaderCodeTestNode;
}(_shaderCodeNode__WEBPACK_IMPORTED_MODULE_1__["ShaderCodeNode"]));



/***/ }),

/***/ "./Engines/Processors/shaderProcessor.ts":
/*!***********************************************!*\
  !*** ./Engines/Processors/shaderProcessor.ts ***!
  \***********************************************/
/*! exports provided: ShaderProcessor */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderProcessor", function() { return ShaderProcessor; });
/* harmony import */ var _shaderCodeNode__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shaderCodeNode */ "./Engines/Processors/shaderCodeNode.ts");
/* harmony import */ var _shaderCodeCursor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shaderCodeCursor */ "./Engines/Processors/shaderCodeCursor.ts");
/* harmony import */ var _shaderCodeConditionNode__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shaderCodeConditionNode */ "./Engines/Processors/shaderCodeConditionNode.ts");
/* harmony import */ var _shaderCodeTestNode__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shaderCodeTestNode */ "./Engines/Processors/shaderCodeTestNode.ts");
/* harmony import */ var _Expressions_Operators_shaderDefineIsDefinedOperator__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Expressions/Operators/shaderDefineIsDefinedOperator */ "./Engines/Processors/Expressions/Operators/shaderDefineIsDefinedOperator.ts");
/* harmony import */ var _Expressions_Operators_shaderDefineOrOperator__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Expressions/Operators/shaderDefineOrOperator */ "./Engines/Processors/Expressions/Operators/shaderDefineOrOperator.ts");
/* harmony import */ var _Expressions_Operators_shaderDefineAndOperator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Expressions/Operators/shaderDefineAndOperator */ "./Engines/Processors/Expressions/Operators/shaderDefineAndOperator.ts");
/* harmony import */ var _Expressions_Operators_shaderDefineArithmeticOperator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Expressions/Operators/shaderDefineArithmeticOperator */ "./Engines/Processors/Expressions/Operators/shaderDefineArithmeticOperator.ts");
/* harmony import */ var _Misc_fileTools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Misc/fileTools */ "./Misc/fileTools.ts");









/** @hidden */
var ShaderProcessor = /** @class */ (function () {
    function ShaderProcessor() {
    }
    ShaderProcessor.Process = function (sourceCode, options, callback) {
        var _this = this;
        this._ProcessIncludes(sourceCode, options, function (codeWithIncludes) {
            var migratedCode = _this._ProcessShaderConversion(codeWithIncludes, options);
            callback(migratedCode);
        });
    };
    ShaderProcessor.Finalize = function (vertexCode, fragmentCode, options) {
        if (!options.processor || !options.processor.finalizeShaders) {
            return { vertexCode: vertexCode, fragmentCode: fragmentCode };
        }
        return options.processor.finalizeShaders(vertexCode, fragmentCode, options.processingContext);
    };
    ShaderProcessor._ProcessPrecision = function (source, options) {
        var shouldUseHighPrecisionShader = options.shouldUseHighPrecisionShader;
        if (source.indexOf("precision highp float") === -1) {
            if (!shouldUseHighPrecisionShader) {
                source = "precision mediump float;\n" + source;
            }
            else {
                source = "precision highp float;\n" + source;
            }
        }
        else {
            if (!shouldUseHighPrecisionShader) { // Moving highp to mediump
                source = source.replace("precision highp float", "precision mediump float");
            }
        }
        return source;
    };
    ShaderProcessor._ExtractOperation = function (expression) {
        var regex = /defined\((.+)\)/;
        var match = regex.exec(expression);
        if (match && match.length) {
            return new _Expressions_Operators_shaderDefineIsDefinedOperator__WEBPACK_IMPORTED_MODULE_4__["ShaderDefineIsDefinedOperator"](match[1].trim(), expression[0] === "!");
        }
        var operators = ["==", ">=", "<=", "<", ">"];
        var operator = "";
        var indexOperator = 0;
        for (var _i = 0, operators_1 = operators; _i < operators_1.length; _i++) {
            operator = operators_1[_i];
            indexOperator = expression.indexOf(operator);
            if (indexOperator > -1) {
                break;
            }
        }
        if (indexOperator === -1) {
            return new _Expressions_Operators_shaderDefineIsDefinedOperator__WEBPACK_IMPORTED_MODULE_4__["ShaderDefineIsDefinedOperator"](expression);
        }
        var define = expression.substring(0, indexOperator).trim();
        var value = expression.substring(indexOperator + operator.length).trim();
        return new _Expressions_Operators_shaderDefineArithmeticOperator__WEBPACK_IMPORTED_MODULE_7__["ShaderDefineArithmeticOperator"](define, operator, value);
    };
    ShaderProcessor._BuildSubExpression = function (expression) {
        var indexOr = expression.indexOf("||");
        if (indexOr === -1) {
            var indexAnd = expression.indexOf("&&");
            if (indexAnd > -1) {
                var andOperator = new _Expressions_Operators_shaderDefineAndOperator__WEBPACK_IMPORTED_MODULE_6__["ShaderDefineAndOperator"]();
                var leftPart = expression.substring(0, indexAnd).trim();
                var rightPart = expression.substring(indexAnd + 2).trim();
                andOperator.leftOperand = this._BuildSubExpression(leftPart);
                andOperator.rightOperand = this._BuildSubExpression(rightPart);
                return andOperator;
            }
            else {
                return this._ExtractOperation(expression);
            }
        }
        else {
            var orOperator = new _Expressions_Operators_shaderDefineOrOperator__WEBPACK_IMPORTED_MODULE_5__["ShaderDefineOrOperator"]();
            var leftPart = expression.substring(0, indexOr).trim();
            var rightPart = expression.substring(indexOr + 2).trim();
            orOperator.leftOperand = this._BuildSubExpression(leftPart);
            orOperator.rightOperand = this._BuildSubExpression(rightPart);
            return orOperator;
        }
    };
    ShaderProcessor._BuildExpression = function (line, start) {
        var node = new _shaderCodeTestNode__WEBPACK_IMPORTED_MODULE_3__["ShaderCodeTestNode"]();
        var command = line.substring(0, start);
        var expression = line.substring(start).trim();
        if (command === "#ifdef") {
            node.testExpression = new _Expressions_Operators_shaderDefineIsDefinedOperator__WEBPACK_IMPORTED_MODULE_4__["ShaderDefineIsDefinedOperator"](expression);
        }
        else if (command === "#ifndef") {
            node.testExpression = new _Expressions_Operators_shaderDefineIsDefinedOperator__WEBPACK_IMPORTED_MODULE_4__["ShaderDefineIsDefinedOperator"](expression, true);
        }
        else {
            node.testExpression = this._BuildSubExpression(expression);
        }
        return node;
    };
    ShaderProcessor._MoveCursorWithinIf = function (cursor, rootNode, ifNode) {
        var line = cursor.currentLine;
        while (this._MoveCursor(cursor, ifNode)) {
            line = cursor.currentLine;
            var first5 = line.substring(0, 5).toLowerCase();
            if (first5 === "#else") {
                var elseNode = new _shaderCodeNode__WEBPACK_IMPORTED_MODULE_0__["ShaderCodeNode"]();
                rootNode.children.push(elseNode);
                this._MoveCursor(cursor, elseNode);
                return;
            }
            else if (first5 === "#elif") {
                var elifNode = this._BuildExpression(line, 5);
                rootNode.children.push(elifNode);
                ifNode = elifNode;
            }
        }
    };
    ShaderProcessor._MoveCursor = function (cursor, rootNode) {
        while (cursor.canRead) {
            cursor.lineIndex++;
            var line = cursor.currentLine;
            var keywords = /(#ifdef)|(#else)|(#elif)|(#endif)|(#ifndef)|(#if)/;
            var matches = keywords.exec(line);
            if (matches && matches.length) {
                var keyword = matches[0];
                switch (keyword) {
                    case "#ifdef": {
                        var newRootNode = new _shaderCodeConditionNode__WEBPACK_IMPORTED_MODULE_2__["ShaderCodeConditionNode"]();
                        rootNode.children.push(newRootNode);
                        var ifNode = this._BuildExpression(line, 6);
                        newRootNode.children.push(ifNode);
                        this._MoveCursorWithinIf(cursor, newRootNode, ifNode);
                        break;
                    }
                    case "#else":
                    case "#elif":
                        return true;
                    case "#endif":
                        return false;
                    case "#ifndef": {
                        var newRootNode = new _shaderCodeConditionNode__WEBPACK_IMPORTED_MODULE_2__["ShaderCodeConditionNode"]();
                        rootNode.children.push(newRootNode);
                        var ifNode = this._BuildExpression(line, 7);
                        newRootNode.children.push(ifNode);
                        this._MoveCursorWithinIf(cursor, newRootNode, ifNode);
                        break;
                    }
                    case "#if": {
                        var newRootNode = new _shaderCodeConditionNode__WEBPACK_IMPORTED_MODULE_2__["ShaderCodeConditionNode"]();
                        var ifNode = this._BuildExpression(line, 3);
                        rootNode.children.push(newRootNode);
                        newRootNode.children.push(ifNode);
                        this._MoveCursorWithinIf(cursor, newRootNode, ifNode);
                        break;
                    }
                }
            }
            else {
                var newNode = new _shaderCodeNode__WEBPACK_IMPORTED_MODULE_0__["ShaderCodeNode"]();
                newNode.line = line;
                rootNode.children.push(newNode);
                // Detect additional defines
                if (line[0] === "#" && line[1] === "d") {
                    var split = line.replace(";", "").split(" ");
                    newNode.additionalDefineKey = split[1];
                    if (split.length === 3) {
                        newNode.additionalDefineValue = split[2];
                    }
                }
            }
        }
        return false;
    };
    ShaderProcessor._EvaluatePreProcessors = function (sourceCode, preprocessors, options) {
        var rootNode = new _shaderCodeNode__WEBPACK_IMPORTED_MODULE_0__["ShaderCodeNode"]();
        var cursor = new _shaderCodeCursor__WEBPACK_IMPORTED_MODULE_1__["ShaderCodeCursor"]();
        cursor.lineIndex = -1;
        cursor.lines = sourceCode.split("\n");
        // Decompose (We keep it in 2 steps so it is easier to maintain and perf hit is insignificant)
        this._MoveCursor(cursor, rootNode);
        // Recompose
        return rootNode.process(preprocessors, options);
    };
    ShaderProcessor._PreparePreProcessors = function (options) {
        var defines = options.defines;
        var preprocessors = {};
        for (var _i = 0, defines_1 = defines; _i < defines_1.length; _i++) {
            var define = defines_1[_i];
            var keyValue = define.replace("#define", "").replace(";", "").trim();
            var split = keyValue.split(" ");
            preprocessors[split[0]] = split.length > 1 ? split[1] : "";
        }
        preprocessors["GL_ES"] = "true";
        preprocessors["__VERSION__"] = options.version;
        preprocessors[options.platformName] = "true";
        return preprocessors;
    };
    ShaderProcessor._ProcessShaderConversion = function (sourceCode, options) {
        var preparedSourceCode = this._ProcessPrecision(sourceCode, options);
        if (!options.processor) {
            return preparedSourceCode;
        }
        // Already converted
        if (preparedSourceCode.indexOf("#version 3") !== -1) {
            return preparedSourceCode.replace("#version 300 es", "");
        }
        var defines = options.defines;
        var preprocessors = this._PreparePreProcessors(options);
        // General pre processing
        if (options.processor.preProcessor) {
            preparedSourceCode = options.processor.preProcessor(preparedSourceCode, defines, options.isFragment, options.processingContext);
        }
        preparedSourceCode = this._EvaluatePreProcessors(preparedSourceCode, preprocessors, options);
        // Post processing
        if (options.processor.postProcessor) {
            preparedSourceCode = options.processor.postProcessor(preparedSourceCode, defines, options.isFragment, options.processingContext);
        }
        return preparedSourceCode;
    };
    ShaderProcessor._ProcessIncludes = function (sourceCode, options, callback) {
        var _this = this;
        var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
        var match = regex.exec(sourceCode);
        var returnValue = new String(sourceCode);
        while (match != null) {
            var includeFile = match[1];
            // Uniform declaration
            if (includeFile.indexOf("__decl__") !== -1) {
                includeFile = includeFile.replace(/__decl__/, "");
                if (options.supportsUniformBuffers) {
                    includeFile = includeFile.replace(/Vertex/, "Ubo");
                    includeFile = includeFile.replace(/Fragment/, "Ubo");
                }
                includeFile = includeFile + "Declaration";
            }
            if (options.includesShadersStore[includeFile]) {
                // Substitution
                var includeContent = options.includesShadersStore[includeFile];
                if (match[2]) {
                    var splits = match[3].split(",");
                    for (var index = 0; index < splits.length; index += 2) {
                        var source = new RegExp(splits[index], "g");
                        var dest = splits[index + 1];
                        includeContent = includeContent.replace(source, dest);
                    }
                }
                if (match[4]) {
                    var indexString = match[5];
                    if (indexString.indexOf("..") !== -1) {
                        var indexSplits = indexString.split("..");
                        var minIndex = parseInt(indexSplits[0]);
                        var maxIndex = parseInt(indexSplits[1]);
                        var sourceIncludeContent = includeContent.slice(0);
                        includeContent = "";
                        if (isNaN(maxIndex)) {
                            maxIndex = options.indexParameters[indexSplits[1]];
                        }
                        for (var i = minIndex; i < maxIndex; i++) {
                            if (!options.supportsUniformBuffers) {
                                // Ubo replacement
                                sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                    return p1 + "{X}";
                                });
                            }
                            includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
                        }
                    }
                    else {
                        if (!options.supportsUniformBuffers) {
                            // Ubo replacement
                            includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                return p1 + "{X}";
                            });
                        }
                        includeContent = includeContent.replace(/\{X\}/g, indexString);
                    }
                }
                // Replace
                returnValue = returnValue.replace(match[0], includeContent);
            }
            else {
                var includeShaderUrl = options.shadersRepository + "ShadersInclude/" + includeFile + ".fx";
                _Misc_fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].LoadFile(includeShaderUrl, function (fileContent) {
                    options.includesShadersStore[includeFile] = fileContent;
                    _this._ProcessIncludes(returnValue, options, callback);
                });
                return;
            }
            match = regex.exec(sourceCode);
        }
        callback(returnValue);
    };
    return ShaderProcessor;
}());



/***/ }),

/***/ "./Engines/WebGL/webGL2ShaderProcessors.ts":
/*!*************************************************!*\
  !*** ./Engines/WebGL/webGL2ShaderProcessors.ts ***!
  \*************************************************/
/*! exports provided: WebGL2ShaderProcessor */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGL2ShaderProcessor", function() { return WebGL2ShaderProcessor; });
/** @hidden */
var WebGL2ShaderProcessor = /** @class */ (function () {
    function WebGL2ShaderProcessor() {
    }
    WebGL2ShaderProcessor.prototype.attributeProcessor = function (attribute) {
        return attribute.replace("attribute", "in");
    };
    WebGL2ShaderProcessor.prototype.varyingProcessor = function (varying, isFragment) {
        return varying.replace("varying", isFragment ? "in" : "out");
    };
    WebGL2ShaderProcessor.prototype.postProcessor = function (code, defines, isFragment) {
        var hasDrawBuffersExtension = code.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
        // Remove extensions
        var regex = /#extension.+(GL_OVR_multiview2|GL_OES_standard_derivatives|GL_EXT_shader_texture_lod|GL_EXT_frag_depth|GL_EXT_draw_buffers).+(enable|require)/g;
        code = code.replace(regex, "");
        // Replace instructions
        code = code.replace(/texture2D\s*\(/g, "texture(");
        if (isFragment) {
            code = code.replace(/texture2DLodEXT\s*\(/g, "textureLod(");
            code = code.replace(/textureCubeLodEXT\s*\(/g, "textureLod(");
            code = code.replace(/textureCube\s*\(/g, "texture(");
            code = code.replace(/gl_FragDepthEXT/g, "gl_FragDepth");
            code = code.replace(/gl_FragColor/g, "glFragColor");
            code = code.replace(/gl_FragData/g, "glFragData");
            code = code.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
        }
        else {
            var hasMultiviewExtension = defines.indexOf("#define MULTIVIEW") !== -1;
            if (hasMultiviewExtension) {
                return "#extension GL_OVR_multiview2 : require\nlayout (num_views = 2) in;\n" + code;
            }
        }
        return code;
    };
    return WebGL2ShaderProcessor;
}());



/***/ }),

/***/ "./Engines/WebGL/webGLPipelineContext.ts":
/*!***********************************************!*\
  !*** ./Engines/WebGL/webGLPipelineContext.ts ***!
  \***********************************************/
/*! exports provided: WebGLPipelineContext */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGLPipelineContext", function() { return WebGLPipelineContext; });
/** @hidden */
var WebGLPipelineContext = /** @class */ (function () {
    function WebGLPipelineContext() {
        this._valueCache = {};
    }
    Object.defineProperty(WebGLPipelineContext.prototype, "isAsync", {
        get: function () {
            return this.isParallelCompiled;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebGLPipelineContext.prototype, "isReady", {
        get: function () {
            if (this.program) {
                if (this.isParallelCompiled) {
                    return this.engine._isRenderingStateCompiled(this);
                }
                return true;
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    WebGLPipelineContext.prototype._handlesSpectorRebuildCallback = function (onCompiled) {
        if (onCompiled && this.program) {
            onCompiled(this.program);
        }
    };
    WebGLPipelineContext.prototype._fillEffectInformation = function (effect, uniformBuffersNames, uniformsNames, uniforms, samplerList, samplers, attributesNames, attributes) {
        var engine = this.engine;
        if (engine.supportsUniformBuffers) {
            for (var name in uniformBuffersNames) {
                effect.bindUniformBlock(name, uniformBuffersNames[name]);
            }
        }
        var effectAvailableUniforms = this.engine.getUniforms(this, uniformsNames);
        effectAvailableUniforms.forEach(function (uniform, index) {
            uniforms[uniformsNames[index]] = uniform;
        });
        this._uniforms = uniforms;
        var index;
        for (index = 0; index < samplerList.length; index++) {
            var sampler = effect.getUniform(samplerList[index]);
            if (sampler == null) {
                samplerList.splice(index, 1);
                index--;
            }
        }
        samplerList.forEach(function (name, index) {
            samplers[name] = index;
        });
        attributes.push.apply(attributes, engine.getAttributes(this, attributesNames));
    };
    /**
     * Release all associated resources.
     **/
    WebGLPipelineContext.prototype.dispose = function () {
        this._uniforms = {};
    };
    /** @hidden */
    WebGLPipelineContext.prototype._cacheMatrix = function (uniformName, matrix) {
        var cache = this._valueCache[uniformName];
        var flag = matrix.updateFlag;
        if (cache !== undefined && cache === flag) {
            return false;
        }
        this._valueCache[uniformName] = flag;
        return true;
    };
    /** @hidden */
    WebGLPipelineContext.prototype._cacheFloat2 = function (uniformName, x, y) {
        var cache = this._valueCache[uniformName];
        if (!cache) {
            cache = [x, y];
            this._valueCache[uniformName] = cache;
            return true;
        }
        var changed = false;
        if (cache[0] !== x) {
            cache[0] = x;
            changed = true;
        }
        if (cache[1] !== y) {
            cache[1] = y;
            changed = true;
        }
        return changed;
    };
    /** @hidden */
    WebGLPipelineContext.prototype._cacheFloat3 = function (uniformName, x, y, z) {
        var cache = this._valueCache[uniformName];
        if (!cache) {
            cache = [x, y, z];
            this._valueCache[uniformName] = cache;
            return true;
        }
        var changed = false;
        if (cache[0] !== x) {
            cache[0] = x;
            changed = true;
        }
        if (cache[1] !== y) {
            cache[1] = y;
            changed = true;
        }
        if (cache[2] !== z) {
            cache[2] = z;
            changed = true;
        }
        return changed;
    };
    /** @hidden */
    WebGLPipelineContext.prototype._cacheFloat4 = function (uniformName, x, y, z, w) {
        var cache = this._valueCache[uniformName];
        if (!cache) {
            cache = [x, y, z, w];
            this._valueCache[uniformName] = cache;
            return true;
        }
        var changed = false;
        if (cache[0] !== x) {
            cache[0] = x;
            changed = true;
        }
        if (cache[1] !== y) {
            cache[1] = y;
            changed = true;
        }
        if (cache[2] !== z) {
            cache[2] = z;
            changed = true;
        }
        if (cache[3] !== w) {
            cache[3] = w;
            changed = true;
        }
        return changed;
    };
    /**
     * Sets an interger value on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value Value to be set.
     */
    WebGLPipelineContext.prototype.setInt = function (uniformName, value) {
        var cache = this._valueCache[uniformName];
        if (cache !== undefined && cache === value) {
            return;
        }
        this._valueCache[uniformName] = value;
        this.engine.setInt(this._uniforms[uniformName], value);
    };
    /**
     * Sets an int array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setIntArray = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray(this._uniforms[uniformName], array);
    };
    /**
     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setIntArray2 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray2(this._uniforms[uniformName], array);
    };
    /**
     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setIntArray3 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray3(this._uniforms[uniformName], array);
    };
    /**
     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setIntArray4 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray4(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setFloatArray = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setFloatArray2 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray2(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setFloatArray3 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray3(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setFloatArray4 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray4(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setArray = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setArray2 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray2(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    WebGLPipelineContext.prototype.setArray3 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray3(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGLPipelineContext.prototype.setArray4 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray4(this._uniforms[uniformName], array);
    };
    /**
     * Sets matrices on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrices matrices to be set.
     */
    WebGLPipelineContext.prototype.setMatrices = function (uniformName, matrices) {
        if (!matrices) {
            return;
        }
        this._valueCache[uniformName] = null;
        this.engine.setMatrices(this._uniforms[uniformName], matrices);
    };
    /**
     * Sets matrix on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGLPipelineContext.prototype.setMatrix = function (uniformName, matrix) {
        if (this._cacheMatrix(uniformName, matrix)) {
            this.engine.setMatrices(this._uniforms[uniformName], matrix.toArray());
        }
    };
    /**
     * Sets a 3x3 matrix on a uniform variable. (Speicified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGLPipelineContext.prototype.setMatrix3x3 = function (uniformName, matrix) {
        this._valueCache[uniformName] = null;
        this.engine.setMatrix3x3(this._uniforms[uniformName], matrix);
    };
    /**
     * Sets a 2x2 matrix on a uniform variable. (Speicified as [1,2,3,4] will result in [1,2][3,4] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGLPipelineContext.prototype.setMatrix2x2 = function (uniformName, matrix) {
        this._valueCache[uniformName] = null;
        this.engine.setMatrix2x2(this._uniforms[uniformName], matrix);
    };
    /**
     * Sets a float on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value value to be set.
     * @returns this effect.
     */
    WebGLPipelineContext.prototype.setFloat = function (uniformName, value) {
        var cache = this._valueCache[uniformName];
        if (cache !== undefined && cache === value) {
            return;
        }
        this._valueCache[uniformName] = value;
        this.engine.setFloat(this._uniforms[uniformName], value);
    };
    /**
     * Sets a boolean on a uniform variable.
     * @param uniformName Name of the variable.
     * @param bool value to be set.
     */
    WebGLPipelineContext.prototype.setBool = function (uniformName, bool) {
        var cache = this._valueCache[uniformName];
        if (cache !== undefined && cache === bool) {
            return;
        }
        this._valueCache[uniformName] = bool;
        this.engine.setBool(this._uniforms[uniformName], bool ? 1 : 0);
    };
    /**
     * Sets a Vector2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector2 vector2 to be set.
     */
    WebGLPipelineContext.prototype.setVector2 = function (uniformName, vector2) {
        if (this._cacheFloat2(uniformName, vector2.x, vector2.y)) {
            this.engine.setFloat2(this._uniforms[uniformName], vector2.x, vector2.y);
        }
    };
    /**
     * Sets a float2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float2.
     * @param y Second float in float2.
     */
    WebGLPipelineContext.prototype.setFloat2 = function (uniformName, x, y) {
        if (this._cacheFloat2(uniformName, x, y)) {
            this.engine.setFloat2(this._uniforms[uniformName], x, y);
        }
    };
    /**
     * Sets a Vector3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector3 Value to be set.
     */
    WebGLPipelineContext.prototype.setVector3 = function (uniformName, vector3) {
        if (this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z)) {
            this.engine.setFloat3(this._uniforms[uniformName], vector3.x, vector3.y, vector3.z);
        }
    };
    /**
     * Sets a float3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float3.
     * @param y Second float in float3.
     * @param z Third float in float3.
     */
    WebGLPipelineContext.prototype.setFloat3 = function (uniformName, x, y, z) {
        if (this._cacheFloat3(uniformName, x, y, z)) {
            this.engine.setFloat3(this._uniforms[uniformName], x, y, z);
        }
    };
    /**
     * Sets a Vector4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector4 Value to be set.
     */
    WebGLPipelineContext.prototype.setVector4 = function (uniformName, vector4) {
        if (this._cacheFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w)) {
            this.engine.setFloat4(this._uniforms[uniformName], vector4.x, vector4.y, vector4.z, vector4.w);
        }
    };
    /**
     * Sets a float4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float4.
     * @param y Second float in float4.
     * @param z Third float in float4.
     * @param w Fourth float in float4.
     * @returns this effect.
     */
    WebGLPipelineContext.prototype.setFloat4 = function (uniformName, x, y, z, w) {
        if (this._cacheFloat4(uniformName, x, y, z, w)) {
            this.engine.setFloat4(this._uniforms[uniformName], x, y, z, w);
        }
    };
    /**
     * Sets a Color3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     */
    WebGLPipelineContext.prototype.setColor3 = function (uniformName, color3) {
        if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {
            this.engine.setFloat3(this._uniforms[uniformName], color3.r, color3.g, color3.b);
        }
    };
    /**
     * Sets a Color4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     * @param alpha Alpha value to be set.
     */
    WebGLPipelineContext.prototype.setColor4 = function (uniformName, color3, alpha) {
        if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {
            this.engine.setFloat4(this._uniforms[uniformName], color3.r, color3.g, color3.b, alpha);
        }
    };
    /**
     * Sets a Color4 on a uniform variable
     * @param uniformName defines the name of the variable
     * @param color4 defines the value to be set
     */
    WebGLPipelineContext.prototype.setDirectColor4 = function (uniformName, color4) {
        if (this._cacheFloat4(uniformName, color4.r, color4.g, color4.b, color4.a)) {
            this.engine.setDirectColor4(this._uniforms[uniformName], color4);
        }
    };
    return WebGLPipelineContext;
}());



/***/ }),

/***/ "./Engines/WebGPU/webgpuConstants.ts":
/*!*******************************************!*\
  !*** ./Engines/WebGPU/webgpuConstants.ts ***!
  \*******************************************/
/*! exports provided: WebGPUConstants */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGPUConstants", function() { return WebGPUConstants; });
/** @hidden */
var WebGPUConstants = /** @class */ (function () {
    function WebGPUConstants() {
    }
    WebGPUConstants.GPUCullMode_none = "none";
    WebGPUConstants.GPUCullMode_front = "front";
    WebGPUConstants.GPUCullMode_back = "back";
    WebGPUConstants.GPUFrontFace_ccw = "ccw";
    WebGPUConstants.GPUFrontFace_cw = "cw";
    WebGPUConstants.GPUIndexFormat_uint16 = "uint16";
    WebGPUConstants.GPUIndexFormat_uint32 = "uint32";
    WebGPUConstants.GPULoadOp_load = "load";
    WebGPUConstants.GPUStoreOp_store = "store";
    WebGPUConstants.GPUStoreOp_clear = "clear";
    WebGPUConstants.GPUPrimitiveTopology_pointList = "point-list";
    WebGPUConstants.GPUPrimitiveTopology_lineList = "line-list";
    WebGPUConstants.GPUPrimitiveTopology_lineStrip = "line-strip";
    WebGPUConstants.GPUPrimitiveTopology_triangleList = "triangle-list";
    WebGPUConstants.GPUPrimitiveTopology_triangleStrip = "triangle-strip";
    WebGPUConstants.GPUTextureDimension_1d = "1d";
    WebGPUConstants.GPUTextureDimension_2d = "2d";
    WebGPUConstants.GPUTextureDimension_3d = "3d";
    /* Normal 8 bit formats */
    WebGPUConstants.GPUTextureFormat_r8unorm = "r8unorm";
    WebGPUConstants.GPUTextureFormat_r8snorm = "r8snorm";
    WebGPUConstants.GPUTextureFormat_r8uint = "r8uint";
    WebGPUConstants.GPUTextureFormat_r8sint = "r8sint";
    /* Normal 16 bit formats */
    WebGPUConstants.GPUTextureFormat_r16uint = "r16uint";
    WebGPUConstants.GPUTextureFormat_r16sint = "r16sint";
    WebGPUConstants.GPUTextureFormat_r16float = "r16float";
    WebGPUConstants.GPUTextureFormat_rg8unorm = "rg8unorm";
    WebGPUConstants.GPUTextureFormat_rg8snorm = "rg8snorm";
    WebGPUConstants.GPUTextureFormat_rg8uint = "rg8uint";
    WebGPUConstants.GPUTextureFormat_rg8sint = "rg8sint";
    /* Normal 32 bit formats */
    WebGPUConstants.GPUTextureFormat_r32uint = "r32uint";
    WebGPUConstants.GPUTextureFormat_r32sint = "r32sint";
    WebGPUConstants.GPUTextureFormat_r32float = "r32float";
    WebGPUConstants.GPUTextureFormat_rg16uint = "rg16uint";
    WebGPUConstants.GPUTextureFormat_rg16sint = "rg16sint";
    WebGPUConstants.GPUTextureFormat_rg16float = "rg16float";
    WebGPUConstants.GPUTextureFormat_rgba8unorm = "rgba8unorm";
    WebGPUConstants.GPUTextureFormat_rgba8unormSrgb = "rgba8unorm-srgb";
    WebGPUConstants.GPUTextureFormat_rgba8snorm = "rgba8snorm";
    WebGPUConstants.GPUTextureFormat_rgba8uint = "rgba8uint";
    WebGPUConstants.GPUTextureFormat_rgba8sint = "rgba8sint";
    WebGPUConstants.GPUTextureFormat_bgra8unorm = "bgra8unorm";
    WebGPUConstants.GPUTextureFormat_bgra8unormSrgb = "bgra8unorm-srgb";
    /* Packed 32 bit formats */
    WebGPUConstants.GPUTextureFormat_rgb10a2unorm = "rgb10a2unorm";
    WebGPUConstants.GPUTextureFormat_rg11b10float = "rg11b10float";
    /* Normal 64 bit formats */
    WebGPUConstants.GPUTextureFormat_rg32uint = "rg32uint";
    WebGPUConstants.GPUTextureFormat_rg32sint = "rg32sint";
    WebGPUConstants.GPUTextureFormat_rg32float = "rg32float";
    WebGPUConstants.GPUTextureFormat_rgba16uint = "rgba16uint";
    WebGPUConstants.GPUTextureFormat_rgba16sint = "rgba16sint";
    WebGPUConstants.GPUTextureFormat_rgba16float = "rgba16float";
    /* Normal 128 bit formats */
    WebGPUConstants.GPUTextureFormat_rgba32uint = "rgba32uint";
    WebGPUConstants.GPUTextureFormat_rgba32sint = "rgba32sint";
    WebGPUConstants.GPUTextureFormat_rgba32float = "rgba32float";
    /* Depth and Stencil formats */
    WebGPUConstants.GPUTextureFormat_depth32float = "depth32float";
    WebGPUConstants.GPUTextureFormat_depth24plus = "depth24plus";
    WebGPUConstants.GPUTextureFormat_depth24plusStencil8 = "depth24plus-stencil8";
    WebGPUConstants.GPUTextureViewDimension_1d = "1d";
    WebGPUConstants.GPUTextureViewDimension_2d = "2d";
    WebGPUConstants.GPUTextureViewDimension_2dArray = "2d-array";
    WebGPUConstants.GPUTextureViewDimension_cube = "cube";
    WebGPUConstants.GPUTextureViewDimension_cubeArray = "cube-array";
    WebGPUConstants.GPUTextureViewDimension_3d = "3d";
    WebGPUConstants.GPUPowerPreference_lowPower = "low-power";
    WebGPUConstants.GPUPowerPreference_highPerformance = "high-performance";
    WebGPUConstants.GPUVertexFormat_uchar2 = "uchar2";
    WebGPUConstants.GPUVertexFormat_uchar4 = "uchar4";
    WebGPUConstants.GPUVertexFormat_char2 = "char2";
    WebGPUConstants.GPUVertexFormat_char4 = "char4";
    WebGPUConstants.GPUVertexFormat_uchar2norm = "uchar2norm";
    WebGPUConstants.GPUVertexFormat_uchar4norm = "uchar4norm";
    WebGPUConstants.GPUVertexFormat_char2norm = "char2norm";
    WebGPUConstants.GPUVertexFormat_char4norm = "char4norm";
    WebGPUConstants.GPUVertexFormat_ushort2 = "ushort2";
    WebGPUConstants.GPUVertexFormat_ushort4 = "ushort4";
    WebGPUConstants.GPUVertexFormat_short2 = "short2";
    WebGPUConstants.GPUVertexFormat_short4 = "short4";
    WebGPUConstants.GPUVertexFormat_ushort2norm = "ushort2norm";
    WebGPUConstants.GPUVertexFormat_ushort4norm = "ushort4norm";
    WebGPUConstants.GPUVertexFormat_short2norm = "short2norm";
    WebGPUConstants.GPUVertexFormat_short4norm = "short4norm";
    WebGPUConstants.GPUVertexFormat_half2 = "half2";
    WebGPUConstants.GPUVertexFormat_half4 = "half4";
    WebGPUConstants.GPUVertexFormat_float = "float";
    WebGPUConstants.GPUVertexFormat_float2 = "float2";
    WebGPUConstants.GPUVertexFormat_float3 = "float3";
    WebGPUConstants.GPUVertexFormat_float4 = "float4";
    WebGPUConstants.GPUVertexFormat_uint = "uint";
    WebGPUConstants.GPUVertexFormat_uint2 = "uint2";
    WebGPUConstants.GPUVertexFormat_uint3 = "uint3";
    WebGPUConstants.GPUVertexFormat_uint4 = "uint4";
    WebGPUConstants.GPUVertexFormat_int = "int";
    WebGPUConstants.GPUVertexFormat_int2 = "int2";
    WebGPUConstants.GPUVertexFormat_int3 = "int3";
    WebGPUConstants.GPUVertexFormat_int4 = "int4";
    WebGPUConstants.GPUBufferUsage_NONE = 0;
    WebGPUConstants.GPUBufferUsage_MAP_READ = 1;
    WebGPUConstants.GPUBufferUsage_MAP_WRITE = 2;
    WebGPUConstants.GPUBufferUsage_TRANSFER_SRC = 4;
    WebGPUConstants.GPUBufferUsage_TRANSFER_DST = 8;
    WebGPUConstants.GPUBufferUsage_INDEX = 16;
    WebGPUConstants.GPUBufferUsage_VERTEX = 32;
    WebGPUConstants.GPUBufferUsage_UNIFORM = 64;
    WebGPUConstants.GPUBufferUsage_STORAGE = 128;
    WebGPUConstants.GPUColorWriteBits_NONE = 0;
    WebGPUConstants.GPUColorWriteBits_RED = 1;
    WebGPUConstants.GPUColorWriteBits_GREEN = 2;
    WebGPUConstants.GPUColorWriteBits_BLUE = 4;
    WebGPUConstants.GPUColorWriteBits_ALPHA = 8;
    WebGPUConstants.GPUColorWriteBits_ALL = 15;
    WebGPUConstants.GPUShaderStageBit_NONE = 0;
    WebGPUConstants.GPUShaderStageBit_VERTEX = 1;
    WebGPUConstants.GPUShaderStageBit_FRAGMENT = 2;
    WebGPUConstants.GPUShaderStageBit_COMPUTE = 4;
    WebGPUConstants.GPUTextureAspect_all = "all";
    WebGPUConstants.GPUTextureAspect_depthOnly = "depth-only";
    WebGPUConstants.GPUTextureAspect_stencilOnly = "stencil-only";
    WebGPUConstants.GPUTextureUsage_NONE = 0;
    WebGPUConstants.GPUTextureUsage_COPY_SRC = 1;
    WebGPUConstants.GPUTextureUsage_COPY_DST = 2;
    WebGPUConstants.GPUTextureUsage_SAMPLED = 4;
    WebGPUConstants.GPUTextureUsage_STORAGE = 8;
    WebGPUConstants.GPUTextureUsage_OUTPUT_ATTACHMENT = 16;
    WebGPUConstants.GPUCompareFunction_never = "never";
    WebGPUConstants.GPUCompareFunction_less = "less";
    WebGPUConstants.GPUCompareFunction_equal = "equal";
    WebGPUConstants.GPUCompareFunction_lessEqual = "lessEqual";
    WebGPUConstants.GPUCompareFunction_greater = "greater";
    WebGPUConstants.GPUCompareFunction_notEqual = "notEqual";
    WebGPUConstants.GPUCompareFunction_greaterEqual = "greaterEqual";
    WebGPUConstants.GPUCompareFunction_always = "always";
    WebGPUConstants.GPUBindingType_uniformBuffer = "uniform-buffer";
    WebGPUConstants.GPUBindingType_sampler = "sampler";
    WebGPUConstants.GPUBindingType_sampledTexture = "sampled-texture";
    WebGPUConstants.GPUBindingType_storageBuffer = "storage-buffer";
    WebGPUConstants.GPUInputStepMode_vertex = "vertex";
    WebGPUConstants.GPUInputStepMode_instance = "instance";
    WebGPUConstants.GPUStencilOperation_keep = "keep";
    WebGPUConstants.GPUStencilOperation_zero = "zero";
    WebGPUConstants.GPUStencilOperation_replace = "replace";
    WebGPUConstants.GPUStencilOperation_invert = "invert";
    WebGPUConstants.GPUStencilOperation_incrementClamp = "increment-clamp";
    WebGPUConstants.GPUStencilOperation_decrementClamp = "decrement-clamp";
    WebGPUConstants.GPUStencilOperation_incrementWrap = "increment-wrap";
    WebGPUConstants.GPUStencilOperation_decrementWrap = "decrement-wrap";
    WebGPUConstants.GPUFilterMode_nearest = "nearest";
    WebGPUConstants.GPUFilterMode_linear = "linear";
    WebGPUConstants.GPUAddressMode_clampToEdge = "clamp-to-edge";
    WebGPUConstants.GPUAddressMode_repeat = "repeat";
    WebGPUConstants.GPUAddressMode_mirrorRepeat = "mirror-repeat";
    WebGPUConstants.GPUBlendFactor_zero = "zero";
    WebGPUConstants.GPUBlendFactor_one = "one";
    WebGPUConstants.GPUBlendFactor_srcColor = "src-color";
    WebGPUConstants.GPUBlendFactor_oneMinusSrcColor = "one-minus-src-color";
    WebGPUConstants.GPUBlendFactor_srcAlpha = "src-alpha";
    WebGPUConstants.GPUBlendFactor_oneMinusSrcAlpha = "one-minus-src-alpha";
    WebGPUConstants.GPUBlendFactor_dstColor = "dst-color";
    WebGPUConstants.GPUBlendFactor_oneMinusDstColor = "one-minus-dst-color";
    WebGPUConstants.GPUBlendFactor_dstAlpha = "dst-alpha";
    WebGPUConstants.GPUBlendFactor_oneMinusDstAlpha = "one-minus-dst-alpha";
    WebGPUConstants.GPUBlendFactor_srcAlphaSaturated = "src-alpha-saturated";
    WebGPUConstants.GPUBlendFactor_blendColor = "blend-color";
    WebGPUConstants.GPUBlendFactor_oneMinusBlendColor = "one-minus-blend-color";
    WebGPUConstants.GPUBlendOperation_add = "add";
    WebGPUConstants.GPUBlendOperation_substract = "subtract";
    WebGPUConstants.GPUBlendOperation_reverseSubtract = "reverse-subtract";
    WebGPUConstants.GPUBlendOperation_min = "min";
    WebGPUConstants.GPUBlendOperation_max = "max";
    return WebGPUConstants;
}());



/***/ }),

/***/ "./Engines/WebGPU/webgpuPipelineContext.ts":
/*!*************************************************!*\
  !*** ./Engines/WebGPU/webgpuPipelineContext.ts ***!
  \*************************************************/
/*! exports provided: WebGPUPipelineContext */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGPUPipelineContext", function() { return WebGPUPipelineContext; });
/* harmony import */ var _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/uniformBuffer */ "./Materials/uniformBuffer.ts");

var _uniformSizes = {
    "float": 1,
    "vec2": 2,
    "vec3": 3,
    "vec4": 4,
    "mat2": 4,
    "mat3": 9,
    "mat4": 16
};
/** @hidden */
var WebGPUPipelineContext = /** @class */ (function () {
    function WebGPUPipelineContext(shaderProcessingContext, engine) {
        this.samplers = {};
        if (shaderProcessingContext) {
            this.availableAttributes = shaderProcessingContext.availableAttributes;
            this.availableUBOs = shaderProcessingContext.availableUBOs;
            this.availableSamplers = shaderProcessingContext.availableSamplers;
            this.orderedAttributes = shaderProcessingContext.orderedAttributes;
            this.orderedUBOsAndSamplers = shaderProcessingContext.orderedUBOsAndSamplers;
            this.leftOverUniforms = shaderProcessingContext.leftOverUniforms;
            this.leftOverUniformsByName = {};
        }
    }
    Object.defineProperty(WebGPUPipelineContext.prototype, "isAsync", {
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebGPUPipelineContext.prototype, "isReady", {
        get: function () {
            if (this.stages) {
                return true;
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    WebGPUPipelineContext.prototype._handlesSpectorRebuildCallback = function (onCompiled) {
        // Nothing to do yet for spector.
    };
    WebGPUPipelineContext.prototype._fillEffectInformation = function (effect, uniformBuffersNames, uniformsNames, uniforms, samplerList, samplers, attributesNames, attributes) {
        var engine = this.engine;
        // TODO WEBGPU. Cleanup SEB on this entire function. Should not need anything in here or almost.
        var effectAvailableUniforms = engine.getUniforms(this, uniformsNames);
        effectAvailableUniforms.forEach(function (uniform, index) {
            uniforms[uniformsNames[index]] = uniform;
        });
        // Prevent Memory Leak by reducing the number of string, refer to the string instead of copy.
        effect._fragmentSourceCode = "";
        effect._vertexSourceCode = "";
        // this._fragmentSourceCodeOverride = "";
        // this._vertexSourceCodeOverride = "";
        var foundSamplers = this.availableSamplers;
        var index;
        for (index = 0; index < samplerList.length; index++) {
            var name_1 = samplerList[index];
            var sampler = foundSamplers[samplerList[index]];
            if (sampler == null || sampler == undefined) {
                samplerList.splice(index, 1);
                index--;
            }
            else {
                samplers[name_1] = index;
            }
        }
        attributes.push.apply(attributes, engine.getAttributes(this, attributesNames));
        // Build the uniform layout for the left over uniforms.
        this.buildUniformLayout();
    };
    /**
     * Build the uniform buffer used in the material.
     */
    WebGPUPipelineContext.prototype.buildUniformLayout = function () {
        if (!this.leftOverUniforms.length) {
            return;
        }
        this.uniformBuffer = new _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_0__["UniformBuffer"](this.engine);
        for (var _i = 0, _a = this.leftOverUniforms; _i < _a.length; _i++) {
            var leftOverUniform = _a[_i];
            var size = _uniformSizes[leftOverUniform.type];
            this.uniformBuffer.addUniform(leftOverUniform.name, size, leftOverUniform.length);
            // TODO WEBGPU. Replace with info from uniform buffer class
            this.leftOverUniformsByName[leftOverUniform.name] = leftOverUniform.type;
        }
        this.uniformBuffer.create();
    };
    /**
     * Release all associated resources.
     **/
    WebGPUPipelineContext.prototype.dispose = function () {
        if (this.uniformBuffer) {
            this.uniformBuffer.dispose();
        }
    };
    /**
     * Sets an interger value on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value Value to be set.
     */
    WebGPUPipelineContext.prototype.setInt = function (uniformName, value) {
        throw "setInt not Supported in LeftOver UBO.";
    };
    /**
     * Sets an int array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setIntArray = function (uniformName, array) {
        throw "setIntArray not Supported in LeftOver UBO.";
    };
    /**
     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setIntArray2 = function (uniformName, array) {
        throw "setIntArray2 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setIntArray3 = function (uniformName, array) {
        throw "setIntArray3 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setIntArray4 = function (uniformName, array) {
        throw "setIntArray4 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an float array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setFloatArray = function (uniformName, array) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateFloatArray(uniformName, array);
    };
    /**
     * Sets an float array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setFloatArray2 = function (uniformName, array) {
        throw "setFloatArray2 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an float array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setFloatArray3 = function (uniformName, array) {
        throw "setFloatArray3 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an float array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setFloatArray4 = function (uniformName, array) {
        throw "setFloatArray4 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setArray = function (uniformName, array) {
        throw "setArray not Supported in LeftOver UBO.";
    };
    /**
     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setArray2 = function (uniformName, array) {
        throw "setArray2 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    WebGPUPipelineContext.prototype.setArray3 = function (uniformName, array) {
        throw "setArray3 not Supported in LeftOver UBO.";
    };
    /**
     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    WebGPUPipelineContext.prototype.setArray4 = function (uniformName, array) {
        throw "setArray4 not Supported in LeftOver UBO.";
    };
    /**
     * Sets matrices on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrices matrices to be set.
     */
    WebGPUPipelineContext.prototype.setMatrices = function (uniformName, matrices) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateMatrices(uniformName, matrices);
    };
    /**
     * Sets matrix on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGPUPipelineContext.prototype.setMatrix = function (uniformName, matrix) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateMatrix(uniformName, matrix);
    };
    /**
     * Sets a 3x3 matrix on a uniform variable. (Speicified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGPUPipelineContext.prototype.setMatrix3x3 = function (uniformName, matrix) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateMatrix3x3(uniformName, matrix);
    };
    /**
     * Sets a 2x2 matrix on a uniform variable. (Speicified as [1,2,3,4] will result in [1,2][3,4] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    WebGPUPipelineContext.prototype.setMatrix2x2 = function (uniformName, matrix) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateMatrix2x2(uniformName, matrix);
    };
    /**
     * Sets a float on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value value to be set.
     * @returns this effect.
     */
    WebGPUPipelineContext.prototype.setFloat = function (uniformName, value) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateFloat(uniformName, value);
    };
    /**
     * Sets a boolean on a uniform variable.
     * @param uniformName Name of the variable.
     * @param bool value to be set.
     */
    WebGPUPipelineContext.prototype.setBool = function (uniformName, bool) {
        throw "setBool not Supported in LeftOver UBO.";
    };
    /**
     * Sets a Vector2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector2 vector2 to be set.
     */
    WebGPUPipelineContext.prototype.setVector2 = function (uniformName, vector2) {
        this.setFloat2(uniformName, vector2.x, vector2.y);
    };
    /**
     * Sets a float2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float2.
     * @param y Second float in float2.
     */
    WebGPUPipelineContext.prototype.setFloat2 = function (uniformName, x, y) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateFloat2(uniformName, x, y);
    };
    /**
     * Sets a Vector3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector3 Value to be set.
     */
    WebGPUPipelineContext.prototype.setVector3 = function (uniformName, vector3) {
        this.setFloat3(uniformName, vector3.x, vector3.y, vector3.z);
    };
    /**
     * Sets a float3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float3.
     * @param y Second float in float3.
     * @param z Third float in float3.
     */
    WebGPUPipelineContext.prototype.setFloat3 = function (uniformName, x, y, z) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateFloat3(uniformName, x, y, z);
    };
    /**
     * Sets a Vector4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector4 Value to be set.
     */
    WebGPUPipelineContext.prototype.setVector4 = function (uniformName, vector4) {
        this.setFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w);
    };
    /**
     * Sets a float4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float4.
     * @param y Second float in float4.
     * @param z Third float in float4.
     * @param w Fourth float in float4.
     * @returns this effect.
     */
    WebGPUPipelineContext.prototype.setFloat4 = function (uniformName, x, y, z, w) {
        if (!this.uniformBuffer || !this.leftOverUniformsByName[uniformName]) {
            return;
        }
        this.uniformBuffer.updateFloat4(uniformName, x, y, z, w);
    };
    /**
     * Sets a Color3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     */
    WebGPUPipelineContext.prototype.setColor3 = function (uniformName, color3) {
        this.setFloat3(uniformName, color3.b, color3.g, color3.b);
    };
    /**
     * Sets a Color4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     * @param alpha Alpha value to be set.
     */
    WebGPUPipelineContext.prototype.setColor4 = function (uniformName, color3, alpha) {
        this.setFloat4(uniformName, color3.b, color3.g, color3.b, alpha);
    };
    /**
     * Sets a Color4 on a uniform variable
     * @param uniformName defines the name of the variable
     * @param color4 defines the value to be set
     */
    WebGPUPipelineContext.prototype.setDirectColor4 = function (uniformName, color4) {
        this.setFloat4(uniformName, color4.r, color4.g, color4.b, color4.a);
    };
    return WebGPUPipelineContext;
}());



/***/ }),

/***/ "./Engines/WebGPU/webgpuShaderProcessingContext.ts":
/*!*********************************************************!*\
  !*** ./Engines/WebGPU/webgpuShaderProcessingContext.ts ***!
  \*********************************************************/
/*! exports provided: WebGPUShaderProcessingContext */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGPUShaderProcessingContext", function() { return WebGPUShaderProcessingContext; });
var _maxSets = 4;
var _maxBindingsPerSet = 16;
/**
 * @hidden
 */
var WebGPUShaderProcessingContext = /** @class */ (function () {
    function WebGPUShaderProcessingContext() {
        this.attributeNextLocation = 0;
        this.varyingNextLocation = 0;
        this.freeSetIndex = 2;
        this.freeBindingIndex = 0;
        this.availableVaryings = {};
        this.availableAttributes = {};
        this.availableUBOs = {};
        this.availableSamplers = {};
        this.orderedAttributes = [];
        this.orderedUBOsAndSamplers = [];
        this.leftOverUniforms = [];
    }
    WebGPUShaderProcessingContext.prototype.getNextFreeUBOBinding = function () {
        return this._getNextFreeBinding(1);
    };
    WebGPUShaderProcessingContext.prototype.getNextFreeTextureBinding = function () {
        return this._getNextFreeBinding(2);
    };
    WebGPUShaderProcessingContext.prototype._getNextFreeBinding = function (bindingCount) {
        if (this.freeBindingIndex > _maxBindingsPerSet - bindingCount) {
            this.freeSetIndex++;
            this.freeBindingIndex = 0;
        }
        if (this.freeSetIndex === _maxSets) {
            throw "Too many textures or UBOs have been declared and it is not supprted in WebGPU.";
        }
        var returnValue = {
            setIndex: this.freeSetIndex,
            bindingIndex: this.freeBindingIndex
        };
        this.freeBindingIndex += bindingCount;
        return returnValue;
    };
    return WebGPUShaderProcessingContext;
}());



/***/ }),

/***/ "./Engines/WebGPU/webgpuShaderProcessors.ts":
/*!**************************************************!*\
  !*** ./Engines/WebGPU/webgpuShaderProcessors.ts ***!
  \**************************************************/
/*! exports provided: WebGPUShaderProcessor */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGPUShaderProcessor", function() { return WebGPUShaderProcessor; });
var _knownUBOs = {
    "Scene": { setIndex: 0, bindingIndex: 0 },
    "Light0": { setIndex: 0, bindingIndex: 5 },
    "Light1": { setIndex: 0, bindingIndex: 6 },
    "Light2": { setIndex: 0, bindingIndex: 7 },
    "Light3": { setIndex: 0, bindingIndex: 8 },
    "Material": { setIndex: 1, bindingIndex: 0 },
    "Mesh": { setIndex: 1, bindingIndex: 1 },
};
var _knownSamplers = {
    "environmentBrdfSampler": { setIndex: 0, bindingIndex: 1 },
};
// TODO WEBGPU. sampler3D
var _samplerFunctionByWebGLSamplerType = {
    "textureCube": "samplerCube",
    "texture2D": "sampler2D",
    "sampler2D": "sampler2D",
    "samplerCube": "samplerCube"
};
var _textureTypeByWebGLSamplerType = {
    "textureCube": "textureCube",
    "texture2D": "texture2D",
    "sampler2D": "texture2D",
    "samplerCube": "textureCube"
};
/** @hidden */
var WebGPUShaderProcessor = /** @class */ (function () {
    function WebGPUShaderProcessor() {
    }
    WebGPUShaderProcessor.prototype.varyingProcessor = function (varying, isFragment, processingContext) {
        var webgpuProcessingContext = processingContext;
        var varyingRegex = new RegExp(/\s*varying\s+(\S+)\s+(\S+)\s*;/gm);
        var match = varyingRegex.exec(varying);
        if (match != null) {
            var name_1 = match[2];
            var location_1;
            if (isFragment) {
                location_1 = webgpuProcessingContext.availableVaryings[name_1];
            }
            else {
                location_1 = webgpuProcessingContext.varyingNextLocation++;
                webgpuProcessingContext.availableVaryings[name_1] = location_1;
            }
            varying = varying.replace(match[0], "layout(location = " + location_1 + ") " + (isFragment ? "in" : "out") + " " + match[1] + " " + name_1 + ";");
        }
        return varying;
    };
    WebGPUShaderProcessor.prototype.attributeProcessor = function (attribute, processingContext) {
        var webgpuProcessingContext = processingContext;
        var attribRegex = new RegExp(/\s*attribute\s+(\S+)\s+(\S+)\s*;/gm);
        var match = attribRegex.exec(attribute);
        if (match != null) {
            var name_2 = match[2];
            var location_2 = webgpuProcessingContext.attributeNextLocation++;
            webgpuProcessingContext.availableAttributes[name_2] = location_2;
            webgpuProcessingContext.orderedAttributes[location_2] = name_2;
            attribute = attribute.replace(match[0], "layout(location = " + location_2 + ") in " + match[1] + " " + name_2 + ";");
        }
        return attribute;
    };
    WebGPUShaderProcessor.prototype.uniformProcessor = function (uniform, isFragment, preProcessors, processingContext) {
        var webgpuProcessingContext = processingContext;
        var uniformRegex = new RegExp(/\s*uniform\s+(\S+)\s+(\S+)\s*;/gm);
        var match = uniformRegex.exec(uniform);
        if (match != null) {
            var uniformType = match[1];
            var name_3 = match[2];
            if (uniformType.indexOf("texture") === 0 || uniformType.indexOf("sampler") === 0) {
                var samplerInfo = _knownSamplers[name_3];
                if (!samplerInfo) {
                    samplerInfo = webgpuProcessingContext.availableSamplers[name_3];
                    if (!samplerInfo) {
                        samplerInfo = webgpuProcessingContext.getNextFreeTextureBinding();
                    }
                }
                var setIndex = samplerInfo.setIndex;
                var textureBindingIndex = samplerInfo.bindingIndex;
                var samplerBindingIndex = samplerInfo.bindingIndex + 1;
                var samplerFunction = _samplerFunctionByWebGLSamplerType[uniformType];
                var textureType = _textureTypeByWebGLSamplerType[uniformType];
                // Manage textures and samplers.
                uniform = "layout(set = " + setIndex + ", binding = " + textureBindingIndex + ") uniform " + textureType + " " + name_3 + "Texture;\n                    layout(set = " + setIndex + ", binding = " + samplerBindingIndex + ") uniform sampler " + name_3 + "Sampler;\n                    #define " + name_3 + " " + samplerFunction + "(" + name_3 + "Texture, " + name_3 + "Sampler)";
                webgpuProcessingContext.availableSamplers[name_3] = samplerInfo;
                if (!webgpuProcessingContext.orderedUBOsAndSamplers[setIndex]) {
                    webgpuProcessingContext.orderedUBOsAndSamplers[setIndex] = [];
                }
                webgpuProcessingContext.orderedUBOsAndSamplers[setIndex][textureBindingIndex] = { isSampler: true, name: name_3 };
            }
            else {
                // Check the size of the uniform array in case of array.
                var length_1 = 0;
                var startArray = name_3.indexOf("[");
                var endArray = name_3.indexOf("]");
                if (startArray > 0 && endArray > 0) {
                    var lengthInString = name_3.substring(startArray + 1, endArray);
                    length_1 = +(lengthInString);
                    if (isNaN(length_1)) {
                        length_1 = +(preProcessors[lengthInString]);
                    }
                    name_3 = name_3.substr(0, startArray);
                }
                for (var i = 0; i < webgpuProcessingContext.leftOverUniforms.length; i++) {
                    if (webgpuProcessingContext.leftOverUniforms[i].name === name_3) {
                        return "";
                    }
                }
                webgpuProcessingContext.leftOverUniforms.push({
                    name: name_3,
                    type: uniformType,
                    length: length_1
                });
                uniform = "";
            }
        }
        return uniform;
    };
    WebGPUShaderProcessor.prototype.uniformBufferProcessor = function (uniformBuffer, isFragment, processingContext) {
        var webgpuProcessingContext = processingContext;
        var uboRegex = new RegExp(/uniform\s+(\w+)/gm);
        var match = uboRegex.exec(uniformBuffer);
        if (match != null) {
            var name_4 = match[1];
            var setIndex = void 0;
            var bindingIndex = void 0;
            var knownUBO = _knownUBOs[name_4];
            if (knownUBO) {
                setIndex = knownUBO.setIndex;
                bindingIndex = knownUBO.bindingIndex;
            }
            else {
                if (isFragment) {
                    var availableUBO = webgpuProcessingContext.availableUBOs[name_4];
                    if (availableUBO) {
                        setIndex = availableUBO.setIndex;
                        bindingIndex = availableUBO.bindingIndex;
                    }
                    else {
                        var nextBinding = webgpuProcessingContext.getNextFreeUBOBinding();
                        setIndex = nextBinding.setIndex;
                        bindingIndex = nextBinding.bindingIndex;
                    }
                }
                else {
                    var nextBinding = webgpuProcessingContext.getNextFreeUBOBinding();
                    setIndex = nextBinding.setIndex;
                    bindingIndex = nextBinding.bindingIndex;
                }
            }
            webgpuProcessingContext.availableUBOs[name_4] = { setIndex: setIndex, bindingIndex: bindingIndex };
            if (!webgpuProcessingContext.orderedUBOsAndSamplers[setIndex]) {
                webgpuProcessingContext.orderedUBOsAndSamplers[setIndex] = [];
            }
            webgpuProcessingContext.orderedUBOsAndSamplers[setIndex][bindingIndex] = { isSampler: false, name: name_4 };
            uniformBuffer = uniformBuffer.replace("uniform", "layout(set = " + setIndex + ", binding = " + bindingIndex + ") uniform");
        }
        return uniformBuffer;
    };
    // public endOfUniformBufferProcessor(closingBracketLine: string, isFragment: boolean): string {
    //     console.log("uniformBuffer closingBracketLine ", closingBracketLine);
    //     return closingBracketLine;
    // }
    WebGPUShaderProcessor.prototype.postProcessor = function (code, defines, isFragment, processingContext) {
        var hasDrawBuffersExtension = code.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
        // Remove extensions
        var regex = /#extension.+(GL_OVR_multiview2|GL_OES_standard_derivatives|GL_EXT_shader_texture_lod|GL_EXT_frag_depth|GL_EXT_draw_buffers).+(enable|require)/g;
        code = code.replace(regex, "");
        // Replace instructions
        code = code.replace(/texture2D\s*\(/g, "texture(");
        if (isFragment) {
            code = code.replace(/texture2DLodEXT\s*\(/g, "textureLod(");
            code = code.replace(/textureCubeLodEXT\s*\(/g, "textureLod(");
            code = code.replace(/textureCube\s*\(/g, "texture(");
            code = code.replace(/gl_FragDepthEXT/g, "gl_FragDepth");
            code = code.replace(/gl_FragColor/g, "glFragColor");
            code = code.replace(/gl_FragData/g, "glFragData");
            code = code.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "layout(location = 0) out vec4 glFragColor;\n") + "void main(");
        }
        else {
            var hasMultiviewExtension = defines.indexOf("#define MULTIVIEW") !== -1;
            if (hasMultiviewExtension) {
                return "#extension GL_OVR_multiview2 : require\nlayout (num_views = 2) in;\n" + code;
            }
        }
        // Flip Y.
        // TODO WEBGPU. Triple check this part and wait on Google News for this issue.
        // https://github.com/gpuweb/gpuweb/issues/379
        if (!isFragment) {
            var lastClosingCurly = code.lastIndexOf("}");
            code = code.substring(0, lastClosingCurly);
            code += "gl_Position.y *= -1.; }";
        }
        return code;
    };
    WebGPUShaderProcessor.prototype.finalizeShaders = function (vertexCode, fragmentCode, processingContext) {
        // Builds the leftover UBOs.
        var webgpuProcessingContext = processingContext;
        if (webgpuProcessingContext.leftOverUniforms.length) {
            var name_5 = "LeftOver";
            var availableUBO = webgpuProcessingContext.availableUBOs[name_5];
            if (!availableUBO) {
                availableUBO = webgpuProcessingContext.getNextFreeUBOBinding();
                webgpuProcessingContext.availableUBOs[name_5] = availableUBO;
                if (!webgpuProcessingContext.orderedUBOsAndSamplers[availableUBO.setIndex]) {
                    webgpuProcessingContext.orderedUBOsAndSamplers[availableUBO.setIndex] = [];
                }
                webgpuProcessingContext.orderedUBOsAndSamplers[availableUBO.setIndex][availableUBO.bindingIndex] = { isSampler: false, name: name_5 };
            }
            var ubo = "layout(set = " + availableUBO.setIndex + ", binding = " + availableUBO.bindingIndex + ") uniform " + name_5 + " {\n    ";
            for (var _i = 0, _a = webgpuProcessingContext.leftOverUniforms; _i < _a.length; _i++) {
                var leftOverUniform = _a[_i];
                if (leftOverUniform.length > 0) {
                    ubo += "    " + leftOverUniform.type + " " + leftOverUniform.name + "[" + leftOverUniform.length + "];\n";
                }
                else {
                    ubo += "    " + leftOverUniform.type + " " + leftOverUniform.name + ";\n";
                }
            }
            ubo += "};\n\n";
            // Currently set in both vert and frag but could be optim away if necessary.
            vertexCode = ubo + vertexCode;
            fragmentCode = ubo + fragmentCode;
        }
        return { vertexCode: vertexCode, fragmentCode: fragmentCode };
    };
    return WebGPUShaderProcessor;
}());



/***/ }),

/***/ "./Engines/constants.ts":
/*!******************************!*\
  !*** ./Engines/constants.ts ***!
  \******************************/
/*! exports provided: Constants */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Constants", function() { return Constants; });
/** Defines the cross module used constants to avoid circular dependncies */
var Constants = /** @class */ (function () {
    function Constants() {
    }
    /** Defines that alpha blending is disabled */
    Constants.ALPHA_DISABLE = 0;
    /** Defines that alpha blending to SRC ALPHA * SRC + DEST */
    Constants.ALPHA_ADD = 1;
    /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC ALPHA) * DEST */
    Constants.ALPHA_COMBINE = 2;
    /** Defines that alpha blending to DEST - SRC * DEST */
    Constants.ALPHA_SUBTRACT = 3;
    /** Defines that alpha blending to SRC * DEST */
    Constants.ALPHA_MULTIPLY = 4;
    /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC) * DEST */
    Constants.ALPHA_MAXIMIZED = 5;
    /** Defines that alpha blending to SRC + DEST */
    Constants.ALPHA_ONEONE = 6;
    /** Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST */
    Constants.ALPHA_PREMULTIPLIED = 7;
    /**
     * Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST
     * Alpha will be set to (1 - SRC ALPHA) * DEST ALPHA
     */
    Constants.ALPHA_PREMULTIPLIED_PORTERDUFF = 8;
    /** Defines that alpha blending to CST * SRC + (1 - CST) * DEST */
    Constants.ALPHA_INTERPOLATE = 9;
    /**
     * Defines that alpha blending to SRC + (1 - SRC) * DEST
     * Alpha will be set to SRC ALPHA + (1 - SRC ALPHA) * DEST ALPHA
     */
    Constants.ALPHA_SCREENMODE = 10;
    /** Defines that the ressource is not delayed*/
    Constants.DELAYLOADSTATE_NONE = 0;
    /** Defines that the ressource was successfully delay loaded */
    Constants.DELAYLOADSTATE_LOADED = 1;
    /** Defines that the ressource is currently delay loading */
    Constants.DELAYLOADSTATE_LOADING = 2;
    /** Defines that the ressource is delayed and has not started loading */
    Constants.DELAYLOADSTATE_NOTLOADED = 4;
    // Depht or Stencil test Constants.
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass. i.e. Nothing will be drawn */
    Constants.NEVER = 0x0200;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */
    Constants.ALWAYS = 0x0207;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value */
    Constants.LESS = 0x0201;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value */
    Constants.EQUAL = 0x0202;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value */
    Constants.LEQUAL = 0x0203;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value */
    Constants.GREATER = 0x0204;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value */
    Constants.GEQUAL = 0x0206;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value */
    Constants.NOTEQUAL = 0x0205;
    // Stencil Actions Constants.
    /** Passed to stencilOperation to specify that stencil value must be kept */
    Constants.KEEP = 0x1E00;
    /** Passed to stencilOperation to specify that stencil value must be zero */
    Constants.ZERO = 0x0000;
    /** Passed to stencilOperation to specify that stencil value must be replaced */
    Constants.REPLACE = 0x1E01;
    /** Passed to stencilOperation to specify that stencil value must be incremented */
    Constants.INCR = 0x1E02;
    /** Passed to stencilOperation to specify that stencil value must be decremented */
    Constants.DECR = 0x1E03;
    /** Passed to stencilOperation to specify that stencil value must be inverted */
    Constants.INVERT = 0x150A;
    /** Passed to stencilOperation to specify that stencil value must be incremented with wrapping */
    Constants.INCR_WRAP = 0x8507;
    /** Passed to stencilOperation to specify that stencil value must be decremented with wrapping */
    Constants.DECR_WRAP = 0x8508;
    /** Texture is not repeating outside of 0..1 UVs */
    Constants.TEXTURE_CLAMP_ADDRESSMODE = 0;
    /** Texture is repeating outside of 0..1 UVs */
    Constants.TEXTURE_WRAP_ADDRESSMODE = 1;
    /** Texture is repeating and mirrored */
    Constants.TEXTURE_MIRROR_ADDRESSMODE = 2;
    /** ALPHA */
    Constants.TEXTUREFORMAT_ALPHA = 0;
    /** LUMINANCE */
    Constants.TEXTUREFORMAT_LUMINANCE = 1;
    /** LUMINANCE_ALPHA */
    Constants.TEXTUREFORMAT_LUMINANCE_ALPHA = 2;
    /** RGB */
    Constants.TEXTUREFORMAT_RGB = 4;
    /** RGBA */
    Constants.TEXTUREFORMAT_RGBA = 5;
    /** RED */
    Constants.TEXTUREFORMAT_RED = 6;
    /** RED (2nd reference) */
    Constants.TEXTUREFORMAT_R = 6;
    /** RG */
    Constants.TEXTUREFORMAT_RG = 7;
    /** RED_INTEGER */
    Constants.TEXTUREFORMAT_RED_INTEGER = 8;
    /** RED_INTEGER (2nd reference) */
    Constants.TEXTUREFORMAT_R_INTEGER = 8;
    /** RG_INTEGER */
    Constants.TEXTUREFORMAT_RG_INTEGER = 9;
    /** RGB_INTEGER */
    Constants.TEXTUREFORMAT_RGB_INTEGER = 10;
    /** RGBA_INTEGER */
    Constants.TEXTUREFORMAT_RGBA_INTEGER = 11;
    /** UNSIGNED_BYTE */
    Constants.TEXTURETYPE_UNSIGNED_BYTE = 0;
    /** UNSIGNED_BYTE (2nd reference) */
    Constants.TEXTURETYPE_UNSIGNED_INT = 0;
    /** FLOAT */
    Constants.TEXTURETYPE_FLOAT = 1;
    /** HALF_FLOAT */
    Constants.TEXTURETYPE_HALF_FLOAT = 2;
    /** BYTE */
    Constants.TEXTURETYPE_BYTE = 3;
    /** SHORT */
    Constants.TEXTURETYPE_SHORT = 4;
    /** UNSIGNED_SHORT */
    Constants.TEXTURETYPE_UNSIGNED_SHORT = 5;
    /** INT */
    Constants.TEXTURETYPE_INT = 6;
    /** UNSIGNED_INT */
    Constants.TEXTURETYPE_UNSIGNED_INTEGER = 7;
    /** UNSIGNED_SHORT_4_4_4_4 */
    Constants.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 = 8;
    /** UNSIGNED_SHORT_5_5_5_1 */
    Constants.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 = 9;
    /** UNSIGNED_SHORT_5_6_5 */
    Constants.TEXTURETYPE_UNSIGNED_SHORT_5_6_5 = 10;
    /** UNSIGNED_INT_2_10_10_10_REV */
    Constants.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV = 11;
    /** UNSIGNED_INT_24_8 */
    Constants.TEXTURETYPE_UNSIGNED_INT_24_8 = 12;
    /** UNSIGNED_INT_10F_11F_11F_REV */
    Constants.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV = 13;
    /** UNSIGNED_INT_5_9_9_9_REV */
    Constants.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV = 14;
    /** FLOAT_32_UNSIGNED_INT_24_8_REV */
    Constants.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV = 15;
    /** nearest is mag = nearest and min = nearest and mip = linear */
    Constants.TEXTURE_NEAREST_SAMPLINGMODE = 1;
    /** Bilinear is mag = linear and min = linear and mip = nearest */
    Constants.TEXTURE_BILINEAR_SAMPLINGMODE = 2;
    /** Trilinear is mag = linear and min = linear and mip = linear */
    Constants.TEXTURE_TRILINEAR_SAMPLINGMODE = 3;
    /** nearest is mag = nearest and min = nearest and mip = linear */
    Constants.TEXTURE_NEAREST_NEAREST_MIPLINEAR = 1;
    /** Bilinear is mag = linear and min = linear and mip = nearest */
    Constants.TEXTURE_LINEAR_LINEAR_MIPNEAREST = 2;
    /** Trilinear is mag = linear and min = linear and mip = linear */
    Constants.TEXTURE_LINEAR_LINEAR_MIPLINEAR = 3;
    /** mag = nearest and min = nearest and mip = nearest */
    Constants.TEXTURE_NEAREST_NEAREST_MIPNEAREST = 4;
    /** mag = nearest and min = linear and mip = nearest */
    Constants.TEXTURE_NEAREST_LINEAR_MIPNEAREST = 5;
    /** mag = nearest and min = linear and mip = linear */
    Constants.TEXTURE_NEAREST_LINEAR_MIPLINEAR = 6;
    /** mag = nearest and min = linear and mip = none */
    Constants.TEXTURE_NEAREST_LINEAR = 7;
    /** mag = nearest and min = nearest and mip = none */
    Constants.TEXTURE_NEAREST_NEAREST = 8;
    /** mag = linear and min = nearest and mip = nearest */
    Constants.TEXTURE_LINEAR_NEAREST_MIPNEAREST = 9;
    /** mag = linear and min = nearest and mip = linear */
    Constants.TEXTURE_LINEAR_NEAREST_MIPLINEAR = 10;
    /** mag = linear and min = linear and mip = none */
    Constants.TEXTURE_LINEAR_LINEAR = 11;
    /** mag = linear and min = nearest and mip = none */
    Constants.TEXTURE_LINEAR_NEAREST = 12;
    /** Explicit coordinates mode */
    Constants.TEXTURE_EXPLICIT_MODE = 0;
    /** Spherical coordinates mode */
    Constants.TEXTURE_SPHERICAL_MODE = 1;
    /** Planar coordinates mode */
    Constants.TEXTURE_PLANAR_MODE = 2;
    /** Cubic coordinates mode */
    Constants.TEXTURE_CUBIC_MODE = 3;
    /** Projection coordinates mode */
    Constants.TEXTURE_PROJECTION_MODE = 4;
    /** Skybox coordinates mode */
    Constants.TEXTURE_SKYBOX_MODE = 5;
    /** Inverse Cubic coordinates mode */
    Constants.TEXTURE_INVCUBIC_MODE = 6;
    /** Equirectangular coordinates mode */
    Constants.TEXTURE_EQUIRECTANGULAR_MODE = 7;
    /** Equirectangular Fixed coordinates mode */
    Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MODE = 8;
    /** Equirectangular Fixed Mirrored coordinates mode */
    Constants.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE = 9;
    // Texture rescaling mode
    /** Defines that texture rescaling will use a floor to find the closer power of 2 size */
    Constants.SCALEMODE_FLOOR = 1;
    /** Defines that texture rescaling will look for the nearest power of 2 size */
    Constants.SCALEMODE_NEAREST = 2;
    /** Defines that texture rescaling will use a ceil to find the closer power of 2 size */
    Constants.SCALEMODE_CEILING = 3;
    /**
     * The dirty texture flag value
     */
    Constants.MATERIAL_TextureDirtyFlag = 1;
    /**
     * The dirty light flag value
     */
    Constants.MATERIAL_LightDirtyFlag = 2;
    /**
     * The dirty fresnel flag value
     */
    Constants.MATERIAL_FresnelDirtyFlag = 4;
    /**
     * The dirty attribute flag value
     */
    Constants.MATERIAL_AttributesDirtyFlag = 8;
    /**
     * The dirty misc flag value
     */
    Constants.MATERIAL_MiscDirtyFlag = 16;
    /**
     * The all dirty flag value
     */
    Constants.MATERIAL_AllDirtyFlag = 31;
    /**
     * Returns the triangle fill mode
     */
    Constants.MATERIAL_TriangleFillMode = 0;
    /**
     * Returns the wireframe mode
     */
    Constants.MATERIAL_WireFrameFillMode = 1;
    /**
     * Returns the point fill mode
     */
    Constants.MATERIAL_PointFillMode = 2;
    /**
     * Returns the point list draw mode
     */
    Constants.MATERIAL_PointListDrawMode = 3;
    /**
     * Returns the line list draw mode
     */
    Constants.MATERIAL_LineListDrawMode = 4;
    /**
     * Returns the line loop draw mode
     */
    Constants.MATERIAL_LineLoopDrawMode = 5;
    /**
     * Returns the line strip draw mode
     */
    Constants.MATERIAL_LineStripDrawMode = 6;
    /**
     * Returns the triangle strip draw mode
     */
    Constants.MATERIAL_TriangleStripDrawMode = 7;
    /**
     * Returns the triangle fan draw mode
     */
    Constants.MATERIAL_TriangleFanDrawMode = 8;
    /**
     * Stores the clock-wise side orientation
     */
    Constants.MATERIAL_ClockWiseSideOrientation = 0;
    /**
     * Stores the counter clock-wise side orientation
     */
    Constants.MATERIAL_CounterClockWiseSideOrientation = 1;
    /**
     * Nothing
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_NothingTrigger = 0;
    /**
     * On pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnPickTrigger = 1;
    /**
     * On left pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnLeftPickTrigger = 2;
    /**
     * On right pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnRightPickTrigger = 3;
    /**
     * On center pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnCenterPickTrigger = 4;
    /**
     * On pick down
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnPickDownTrigger = 5;
    /**
     * On double pick
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnDoublePickTrigger = 6;
    /**
     * On pick up
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnPickUpTrigger = 7;
    /**
     * On pick out.
     * This trigger will only be raised if you also declared a OnPickDown
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnPickOutTrigger = 16;
    /**
     * On long press
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnLongPressTrigger = 8;
    /**
     * On pointer over
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnPointerOverTrigger = 9;
    /**
     * On pointer out
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnPointerOutTrigger = 10;
    /**
     * On every frame
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnEveryFrameTrigger = 11;
    /**
     * On intersection enter
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnIntersectionEnterTrigger = 12;
    /**
     * On intersection exit
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnIntersectionExitTrigger = 13;
    /**
     * On key down
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnKeyDownTrigger = 14;
    /**
     * On key up
     * @see http://doc.babylonjs.com/how_to/how_to_use_actions#triggers
     */
    Constants.ACTION_OnKeyUpTrigger = 15;
    /**
     * Billboard mode will only apply to Y axis
     */
    Constants.PARTICLES_BILLBOARDMODE_Y = 2;
    /**
     * Billboard mode will apply to all axes
     */
    Constants.PARTICLES_BILLBOARDMODE_ALL = 7;
    /**
     * Special billboard mode where the particle will be biilboard to the camera but rotated to align with direction
     */
    Constants.PARTICLES_BILLBOARDMODE_STRETCHED = 8;
    /**
     * Gets or sets base Assets URL
     */
    Constants.PARTICLES_BaseAssetsUrl = "https://assets.babylonjs.com/particles";
    /** Default culling strategy : this is an exclusion test and it's the more accurate.
     *  Test order :
     *  Is the bounding sphere outside the frustum ?
     *  If not, are the bounding box vertices outside the frustum ?
     *  It not, then the cullable object is in the frustum.
     */
    Constants.MESHES_CULLINGSTRATEGY_STANDARD = 0;
    /** Culling strategy : Bounding Sphere Only.
     *  This is an exclusion test. It's faster than the standard strategy because the bounding box is not tested.
     *  It's also less accurate than the standard because some not visible objects can still be selected.
     *  Test : is the bounding sphere outside the frustum ?
     *  If not, then the cullable object is in the frustum.
     */
    Constants.MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY = 1;
    /** Culling strategy : Optimistic Inclusion.
     *  This in an inclusion test first, then the standard exclusion test.
     *  This can be faster when a cullable object is expected to be almost always in the camera frustum.
     *  This could also be a little slower than the standard test when the tested object center is not the frustum but one of its bounding box vertex is still inside.
     *  Anyway, it's as accurate as the standard strategy.
     *  Test :
     *  Is the cullable object bounding sphere center in the frustum ?
     *  If not, apply the default culling strategy.
     */
    Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION = 2;
    /** Culling strategy : Optimistic Inclusion then Bounding Sphere Only.
     *  This in an inclusion test first, then the bounding sphere only exclusion test.
     *  This can be the fastest test when a cullable object is expected to be almost always in the camera frustum.
     *  This could also be a little slower than the BoundingSphereOnly strategy when the tested object center is not in the frustum but its bounding sphere still intersects it.
     *  It's less accurate than the standard strategy and as accurate as the BoundingSphereOnly strategy.
     *  Test :
     *  Is the cullable object bounding sphere center in the frustum ?
     *  If not, apply the Bounding Sphere Only strategy. No Bounding Box is tested here.
     */
    Constants.MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY = 3;
    /**
     * No logging while loading
     */
    Constants.SCENELOADER_NO_LOGGING = 0;
    /**
     * Minimal logging while loading
     */
    Constants.SCENELOADER_MINIMAL_LOGGING = 1;
    /**
     * Summary logging while loading
     */
    Constants.SCENELOADER_SUMMARY_LOGGING = 2;
    /**
     * Detailled logging while loading
     */
    Constants.SCENELOADER_DETAILED_LOGGING = 3;
    return Constants;
}());



/***/ }),

/***/ "./Engines/engine.ts":
/*!***************************!*\
  !*** ./Engines/engine.ts ***!
  \***************************/
/*! exports provided: InstancingAttributeInfo, DepthTextureCreationOptions, EngineCapabilities, Engine */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancingAttributeInfo", function() { return InstancingAttributeInfo; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthTextureCreationOptions", function() { return DepthTextureCreationOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EngineCapabilities", function() { return EngineCapabilities; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Engine", function() { return Engine; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_performanceMonitor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/performanceMonitor */ "./Misc/performanceMonitor.ts");
/* harmony import */ var _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/stringDictionary */ "./Misc/stringDictionary.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _States_index__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../States/index */ "./States/index.ts");
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/domManagement */ "./Misc/domManagement.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _engineStore__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Materials/Textures/renderTargetCreationOptions */ "./Materials/Textures/renderTargetCreationOptions.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _WebGL_webGLPipelineContext__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./WebGL/webGLPipelineContext */ "./Engines/WebGL/webGLPipelineContext.ts");
/* harmony import */ var _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Meshes/WebGL/webGLDataBuffer */ "./Meshes/WebGL/webGLDataBuffer.ts");
/* harmony import */ var _WebGL_webGL2ShaderProcessors__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./WebGL/webGL2ShaderProcessors */ "./Engines/WebGL/webGL2ShaderProcessors.ts");
/* harmony import */ var _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Misc/perfCounter */ "./Misc/perfCounter.ts");
/* harmony import */ var _Misc_fileTools__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Misc/fileTools */ "./Misc/fileTools.ts");


















/**
 * Keeps track of all the buffer info used in engine.
 */
var BufferPointer = /** @class */ (function () {
    function BufferPointer() {
    }
    return BufferPointer;
}());
/**
 * Interface for attribute information associated with buffer instanciation
 */
var InstancingAttributeInfo = /** @class */ (function () {
    function InstancingAttributeInfo() {
    }
    return InstancingAttributeInfo;
}());

/**
 * Define options used to create a depth texture
 */
var DepthTextureCreationOptions = /** @class */ (function () {
    function DepthTextureCreationOptions() {
    }
    return DepthTextureCreationOptions;
}());

/**
 * Class used to describe the capabilities of the engine relatively to the current browser
 */
var EngineCapabilities = /** @class */ (function () {
    function EngineCapabilities() {
        /** Max number of texture samples for MSAA */
        this.maxMSAASamples = 1;
    }
    return EngineCapabilities;
}());

/**
 * The engine class is responsible for interfacing with all lower-level APIs such as WebGL and Audio
 */
var Engine = /** @class */ (function () {
    /**
     * Creates a new engine
     * @param canvasOrContext defines the canvas or WebGL context to use for rendering. If you provide a WebGL context, Babylon.js will not hook events on the canvas (like pointers, keyboards, etc...) so no event observables will be available. This is mostly used when Babylon.js is used as a plugin on a system which alreay used the WebGL context
     * @param antialias defines enable antialiasing (default: false)
     * @param options defines further options to be sent to the getContext() function
     * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)
     */
    function Engine(canvasOrContext, antialias, options, adaptToDeviceRatio) {
        var _this = this;
        if (adaptToDeviceRatio === void 0) { adaptToDeviceRatio = false; }
        /**
         * Gets or sets a boolean that indicates if textures must be forced to power of 2 size even if not required
         */
        this.forcePOTTextures = false;
        /**
         * Gets a boolean indicating if the engine is currently rendering in fullscreen mode
         */
        this.isFullscreen = false;
        /**
         * Gets a boolean indicating if the pointer is currently locked
         */
        this.isPointerLock = false;
        /**
         * Gets or sets a boolean indicating if back faces must be culled (true by default)
         */
        this.cullBackFaces = true;
        /**
         * Gets or sets a boolean indicating if the engine must keep rendering even if the window is not in foregroun
         */
        this.renderEvenInBackground = true;
        /**
         * Gets or sets a boolean indicating that cache can be kept between frames
         */
        this.preventCacheWipeBetweenFrames = false;
        /**
         * Gets or sets a boolean to enable/disable IndexedDB support and avoid XHR on .manifest
         **/
        this.enableOfflineSupport = false;
        /**
         * Gets or sets a boolean to enable/disable checking manifest if IndexedDB support is enabled (js will always consider the database is up to date)
         **/
        this.disableManifestCheck = false;
        /**
         * Gets the list of created scenes
         */
        this.scenes = new Array();
        /**
         * Event raised when a new scene is created
         */
        this.onNewSceneAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Gets the list of created postprocesses
         */
        this.postProcesses = new Array();
        /** Gets or sets a boolean indicating if the engine should validate programs after compilation */
        this.validateShaderPrograms = false;
        // Observables
        /**
         * Observable event triggered each time the rendering canvas is resized
         */
        this.onResizeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable event triggered each time the canvas loses focus
         */
        this.onCanvasBlurObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable event triggered each time the canvas gains focus
         */
        this.onCanvasFocusObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable event triggered each time the canvas receives pointerout event
         */
        this.onCanvasPointerOutObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable event triggered before each texture is initialized
         */
        this.onBeforeTextureInitObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        // Uniform buffers list
        /**
         * Gets or sets a boolean indicating that uniform buffers must be disabled even if they are supported
         */
        this.disableUniformBuffers = false;
        /** @hidden */
        this._uniformBuffers = new Array();
        // Observables
        /**
         * Observable raised when the engine begins a new frame
         */
        this.onBeginFrameObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * If set, will be used to request the next animation frame for the render loop
         */
        this.customAnimationFrameRequester = null;
        /**
         * Observable raised when the engine ends the current frame
         */
        this.onEndFrameObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable raised when the engine is about to compile a shader
         */
        this.onBeforeShaderCompilationObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable raised when the engine has jsut compiled a shader
         */
        this.onAfterShaderCompilationObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._windowIsBackground = false;
        this._webGLVersion = 1.0;
        this._highPrecisionShadersAllowed = true;
        /** @hidden */
        this._badOS = false;
        /** @hidden */
        this._badDesktopOS = false;
        this._colorWrite = true;
        /** @hidden */
        this._drawCalls = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_16__["PerfCounter"]();
        this._renderingQueueLaunched = false;
        this._activeRenderLoops = new Array();
        // Deterministic lockstepMaxSteps
        this._deterministicLockstep = false;
        this._lockstepMaxSteps = 4;
        // Lost context
        /**
         * Observable signaled when a context lost event is raised
         */
        this.onContextLostObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable signaled when a context restored event is raised
         */
        this.onContextRestoredObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._contextWasLost = false;
        /** @hidden */
        this._doNotHandleContextLost = false;
        // FPS
        this._performanceMonitor = new _Misc_performanceMonitor__WEBPACK_IMPORTED_MODULE_2__["PerformanceMonitor"]();
        this._fps = 60;
        this._deltaTime = 0;
        /**
         * Turn this value on if you want to pause FPS computation when in background
         */
        this.disablePerformanceMonitorInBackground = false;
        /**
         * Gets or sets a boolean indicating that vertex array object must be disabled even if they are supported
         */
        this.disableVertexArrayObjects = false;
        // States
        /** @hidden */
        this._depthCullingState = new _States_index__WEBPACK_IMPORTED_MODULE_6__["_DepthCullingState"]();
        /** @hidden */
        this._stencilState = new _States_index__WEBPACK_IMPORTED_MODULE_6__["_StencilState"]();
        /** @hidden */
        this._alphaState = new _States_index__WEBPACK_IMPORTED_MODULE_6__["_AlphaState"]();
        /** @hidden */
        this._alphaMode = Engine.ALPHA_DISABLE;
        // Cache
        /** @hidden */
        this._internalTexturesCache = new Array();
        /** @hidden */
        this._activeChannel = 0;
        this._currentTextureChannel = -1;
        /** @hidden */
        this._boundTexturesCache = {};
        this._compiledEffects = {};
        this._vertexAttribArraysEnabled = [];
        this._uintIndicesCurrentlySet = false;
        this._currentBoundBuffer = new Array();
        /** @hidden */
        this._currentFramebuffer = null;
        this._currentBufferPointers = new Array();
        this._currentInstanceLocations = new Array();
        this._currentInstanceBuffers = new Array();
        this._vaoRecordInProgress = false;
        this._mustWipeVertexAttributes = false;
        this._nextFreeTextureSlots = new Array();
        this._maxSimultaneousTextures = 0;
        this._activeRequests = new Array();
        // Hardware supported Compressed Textures
        this._texturesSupported = new Array();
        /**
         * Defines whether the engine has been created with the premultipliedAlpha option on or not.
         */
        this.premultipliedAlpha = true;
        /** @hidden */
        this._isWebGPU = false;
        this._viewportCached = { x: 0, y: 0, z: 0, w: 0 };
        this._unpackFlipYCached = null;
        /**
         * In case you are sharing the context with other applications, it might
         * be interested to not cache the unpack flip y state to ensure a consistent
         * value would be set.
         */
        this.enableUnpackFlipYCached = true;
        this._boundUniforms = {};
        var canvas = null;
        Engine.Instances.push(this);
        if (!canvasOrContext) {
            return;
        }
        options = options || {};
        if (canvasOrContext.getContext) {
            if (options.premultipliedAlpha === false) {
                this.premultipliedAlpha = false;
            }
            if (antialias != null) {
                options.antialias = antialias;
            }
            if (options.preserveDrawingBuffer === undefined) {
                options.preserveDrawingBuffer = false;
            }
            if (options.stencil === undefined) {
                options.stencil = true;
            }
            if (options.deterministicLockstep === undefined) {
                options.deterministicLockstep = false;
            }
            if (options.lockstepMaxSteps === undefined) {
                options.lockstepMaxSteps = 4;
            }
            if (options.audioEngine === undefined) {
                options.audioEngine = true;
            }
            this._deterministicLockstep = options.deterministicLockstep;
            this._lockstepMaxSteps = options.lockstepMaxSteps;
            this._doNotHandleContextLost = options.doNotHandleContextLost ? true : false;
            // Exceptions
            if (navigator && navigator.userAgent) {
                var ua = navigator.userAgent;
                for (var _i = 0, _a = Engine.ExceptionList; _i < _a.length; _i++) {
                    var exception = _a[_i];
                    var key = exception.key;
                    var targets = exception.targets;
                    var check = new RegExp(key);
                    if (check.test(ua)) {
                        if (exception.capture && exception.captureConstraint) {
                            var capture = exception.capture;
                            var constraint = exception.captureConstraint;
                            var regex = new RegExp(capture);
                            var matches = regex.exec(ua);
                            if (matches && matches.length > 0) {
                                var capturedValue = parseInt(matches[matches.length - 1]);
                                if (capturedValue >= constraint) {
                                    continue;
                                }
                            }
                        }
                        for (var _b = 0, targets_1 = targets; _b < targets_1.length; _b++) {
                            var target = targets_1[_b];
                            switch (target) {
                                case "uniformBuffer":
                                    this.disableUniformBuffers = true;
                                    break;
                                case "vao":
                                    this.disableVertexArrayObjects = true;
                                    break;
                            }
                        }
                    }
                }
            }
            canvas = canvasOrContext;
            // GL
            if (!options.disableWebGL2Support) {
                try {
                    this._gl = (canvas.getContext("webgl2", options) || canvas.getContext("experimental-webgl2", options));
                    if (this._gl) {
                        this._webGLVersion = 2.0;
                        this._shaderPlatformName = "WEBGL2";
                        // Prevent weird browsers to lie :-)
                        if (!this._gl.deleteQuery) {
                            this._webGLVersion = 1.0;
                            this._shaderPlatformName = "WEBGL1";
                        }
                    }
                }
                catch (e) {
                    // Do nothing
                }
            }
            if (!this._gl) {
                if (!canvas) {
                    throw new Error("The provided canvas is null or undefined.");
                }
                try {
                    this._gl = (canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options));
                }
                catch (e) {
                    throw new Error("WebGL not supported");
                }
            }
            if (!this._gl) {
                throw new Error("WebGL not supported");
            }
            this._sharedInit(canvas, !!options.doNotHandleTouchAction, options.audioEngine);
            // Ensures a consistent color space unpacking of textures cross browser.
            this._gl.pixelStorei(this._gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, this._gl.NONE);
            // Context lost
            if (!this._doNotHandleContextLost) {
                this._onContextLost = function (evt) {
                    evt.preventDefault();
                    _this._contextWasLost = true;
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Warn("WebGL context lost.");
                    _this.onContextLostObservable.notifyObservers(_this);
                };
                this._onContextRestored = function () {
                    // Adding a timeout to avoid race condition at browser level
                    setTimeout(function () {
                        // Rebuild gl context
                        _this._initGLContext();
                        // Rebuild effects
                        _this._rebuildEffects();
                        // Rebuild textures
                        _this._rebuildInternalTextures();
                        // Rebuild buffers
                        _this._rebuildBuffers();
                        // Cache
                        _this.wipeCaches(true);
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Warn("WebGL context successfully restored.");
                        _this.onContextRestoredObservable.notifyObservers(_this);
                        _this._contextWasLost = false;
                    }, 0);
                };
                canvas.addEventListener("webglcontextlost", this._onContextLost, false);
                canvas.addEventListener("webglcontextrestored", this._onContextRestored, false);
                options.powerPreference = "high-performance";
            }
        }
        else {
            this._gl = canvasOrContext;
            this._renderingCanvas = this._gl.canvas;
            if (this._gl.renderbufferStorageMultisample) {
                this._webGLVersion = 2.0;
                this._shaderPlatformName = "WEBGL2";
            }
            var attributes = this._gl.getContextAttributes();
            if (attributes) {
                options.stencil = attributes.stencil;
            }
        }
        if (options.useHighPrecisionFloats !== undefined) {
            this._highPrecisionShadersAllowed = options.useHighPrecisionFloats;
        }
        // Viewport
        var devicePixelRatio = _Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__["DomManagement"].IsWindowObjectExist() ? (window.devicePixelRatio || 1.0) : 1.0;
        var limitDeviceRatio = options.limitDeviceRatio || devicePixelRatio;
        this._hardwareScalingLevel = adaptToDeviceRatio ? 1.0 / Math.min(limitDeviceRatio, devicePixelRatio) : 1.0;
        this.resize();
        this._isStencilEnable = options.stencil ? true : false;
        this._initGLContext();
        if (canvas) {
            var anyDoc_1 = document;
            // Fullscreen
            this._onFullscreenChange = function () {
                if (anyDoc_1.fullscreen !== undefined) {
                    _this.isFullscreen = anyDoc_1.fullscreen;
                }
                else if (anyDoc_1.mozFullScreen !== undefined) {
                    _this.isFullscreen = anyDoc_1.mozFullScreen;
                }
                else if (anyDoc_1.webkitIsFullScreen !== undefined) {
                    _this.isFullscreen = anyDoc_1.webkitIsFullScreen;
                }
                else if (anyDoc_1.msIsFullScreen !== undefined) {
                    _this.isFullscreen = anyDoc_1.msIsFullScreen;
                }
                // Pointer lock
                if (_this.isFullscreen && _this._pointerLockRequested && canvas) {
                    Engine._RequestPointerlock(canvas);
                }
            };
            document.addEventListener("fullscreenchange", this._onFullscreenChange, false);
            document.addEventListener("mozfullscreenchange", this._onFullscreenChange, false);
            document.addEventListener("webkitfullscreenchange", this._onFullscreenChange, false);
            document.addEventListener("msfullscreenchange", this._onFullscreenChange, false);
            // Pointer lock
            this._onPointerLockChange = function () {
                _this.isPointerLock = (anyDoc_1.mozPointerLockElement === canvas ||
                    anyDoc_1.webkitPointerLockElement === canvas ||
                    anyDoc_1.msPointerLockElement === canvas ||
                    anyDoc_1.pointerLockElement === canvas);
            };
            document.addEventListener("pointerlockchange", this._onPointerLockChange, false);
            document.addEventListener("mspointerlockchange", this._onPointerLockChange, false);
            document.addEventListener("mozpointerlockchange", this._onPointerLockChange, false);
            document.addEventListener("webkitpointerlockchange", this._onPointerLockChange, false);
            this._connectVREvents(canvas, anyDoc_1);
        }
        // Prepare buffer pointers
        for (var i = 0; i < this._caps.maxVertexAttribs; i++) {
            this._currentBufferPointers[i] = new BufferPointer();
        }
        // Load WebVR Devices
        this._prepareVRComponent();
        if (options.autoEnableWebVR) {
            this.initWebVR();
        }
        // Detect if we are running on a faulty buggy OS.
        this._badOS = /iPad/i.test(navigator.userAgent) || /iPhone/i.test(navigator.userAgent);
        // Detect if we are running on a faulty buggy desktop OS.
        this._badDesktopOS = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
        console.log("Babylon.js v" + Engine.Version + " - " + this.description);
        this.enableOfflineSupport = Engine.OfflineProviderFactory !== undefined;
    }
    Object.defineProperty(Engine, "Instances", {
        /** Gets the list of created engines */
        get: function () {
            return _engineStore__WEBPACK_IMPORTED_MODULE_10__["EngineStore"].Instances;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine, "LastCreatedEngine", {
        /**
         * Gets the latest created engine
         */
        get: function () {
            return _engineStore__WEBPACK_IMPORTED_MODULE_10__["EngineStore"].LastCreatedEngine;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine, "LastCreatedScene", {
        /**
         * Gets the latest created scene
         */
        get: function () {
            return _engineStore__WEBPACK_IMPORTED_MODULE_10__["EngineStore"].LastCreatedScene;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Will flag all materials in all scenes in all engines as dirty to trigger new shader compilation
     * @param flag defines which part of the materials must be marked as dirty
     * @param predicate defines a predicate used to filter which materials should be affected
     */
    Engine.MarkAllMaterialsAsDirty = function (flag, predicate) {
        for (var engineIndex = 0; engineIndex < Engine.Instances.length; engineIndex++) {
            var engine = Engine.Instances[engineIndex];
            for (var sceneIndex = 0; sceneIndex < engine.scenes.length; sceneIndex++) {
                engine.scenes[sceneIndex].markAllMaterialsAsDirty(flag, predicate);
            }
        }
    };
    Object.defineProperty(Engine, "NpmPackage", {
        /**
         * Returns the current npm package of the sdk
         */
        // Not mixed with Version for tooling purpose.
        get: function () {
            return "babylonjs@4.1.0-alpha.17";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine, "Version", {
        /**
         * Returns the current version of the framework
         */
        get: function () {
            return "4.1.0-alpha.17";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "description", {
        /**
         * Returns a string describing the current engine
         */
        get: function () {
            var description = "WebGL" + this.webGLVersion;
            if (this._caps.parallelShaderCompile) {
                description += " - Parallel shader compilation";
            }
            return description;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine, "ShadersRepository", {
        /**
         * Gets or sets the relative url used to load shaders if using the engine in non-minified mode
         */
        get: function () {
            return _Materials_effect__WEBPACK_IMPORTED_MODULE_4__["Effect"].ShadersRepository;
        },
        set: function (value) {
            _Materials_effect__WEBPACK_IMPORTED_MODULE_4__["Effect"].ShadersRepository = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Method called to create the default loading screen.
     * This can be overriden in your own app.
     * @param canvas The rendering canvas element
     * @returns The loading screen
     */
    Engine.DefaultLoadingScreenFactory = function (canvas) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_12__["_DevTools"].WarnImport("LoadingScreen");
    };
    Object.defineProperty(Engine.prototype, "supportsUniformBuffers", {
        /**
         * Gets a boolean indicating that the engine supports uniform buffers
         * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
         */
        get: function () {
            return this.webGLVersion > 1 && !this.disableUniformBuffers;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "_shouldUseHighPrecisionShader", {
        /** @hidden */
        get: function () {
            return this._caps.highPrecisionShaderSupported && this._highPrecisionShadersAllowed;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "needPOTTextures", {
        /**
         * Gets a boolean indicating that only power of 2 textures are supported
         * Please note that you can still use non power of 2 textures but in this case the engine will forcefully convert them
         */
        get: function () {
            return this._webGLVersion < 2 || this.forcePOTTextures;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "doNotHandleContextLost", {
        /**
         * Gets or sets a boolean indicating if resources should be retained to be able to handle context lost events
         * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#handling-webgl-context-lost
         */
        get: function () {
            return this._doNotHandleContextLost;
        },
        set: function (value) {
            this._doNotHandleContextLost = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "performanceMonitor", {
        /**
         * Gets the performance monitor attached to this engine
         * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#engineinstrumentation
         */
        get: function () {
            return this._performanceMonitor;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "texturesSupported", {
        /**
         * Gets the list of texture formats supported
         */
        get: function () {
            return this._texturesSupported;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "textureFormatInUse", {
        /**
         * Gets the list of texture formats in use
         */
        get: function () {
            return this._textureFormatInUse;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "currentViewport", {
        /**
         * Gets the current viewport
         */
        get: function () {
            return this._cachedViewport;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "emptyTexture", {
        /**
         * Gets the default empty texture
         */
        get: function () {
            if (!this._emptyTexture) {
                this._emptyTexture = this.createRawTexture(new Uint8Array(4), 1, 1, Engine.TEXTUREFORMAT_RGBA, false, false, Engine.TEXTURE_NEAREST_SAMPLINGMODE);
            }
            return this._emptyTexture;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "emptyTexture3D", {
        /**
         * Gets the default empty 3D texture
         */
        get: function () {
            if (!this._emptyTexture3D) {
                this._emptyTexture3D = this.createRawTexture3D(new Uint8Array(4), 1, 1, 1, Engine.TEXTUREFORMAT_RGBA, false, false, Engine.TEXTURE_NEAREST_SAMPLINGMODE);
            }
            return this._emptyTexture3D;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "emptyCubeTexture", {
        /**
         * Gets the default empty cube texture
         */
        get: function () {
            if (!this._emptyCubeTexture) {
                var faceData = new Uint8Array(4);
                var cubeData = [faceData, faceData, faceData, faceData, faceData, faceData];
                this._emptyCubeTexture = this.createRawCubeTexture(cubeData, 1, Engine.TEXTUREFORMAT_RGBA, Engine.TEXTURETYPE_UNSIGNED_INT, false, false, Engine.TEXTURE_NEAREST_SAMPLINGMODE);
            }
            return this._emptyCubeTexture;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "isWebGPU", {
        /**
         * Gets a boolean indicating if the engine runs in WebGPU or not.
         */
        get: function () {
            return this._isWebGPU;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "shaderPlatformName", {
        /**
         * Gets the shader platfrom name used by the effects.
         */
        get: function () {
            return this._shaderPlatformName;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Shared initialization across engines types.
     * @param canvas The canvas associated with this instance of the engine.
     * @param doNotHandleTouchAction Defines that engine should ignore modifying touch action attribute and style
     * @param audioEngine Defines if an audio engine should be created by default
     */
    Engine.prototype._sharedInit = function (canvas, doNotHandleTouchAction, audioEngine) {
        var _this = this;
        this._renderingCanvas = canvas;
        this._onCanvasFocus = function () {
            _this.onCanvasFocusObservable.notifyObservers(_this);
        };
        this._onCanvasBlur = function () {
            _this.onCanvasBlurObservable.notifyObservers(_this);
        };
        canvas.addEventListener("focus", this._onCanvasFocus);
        canvas.addEventListener("blur", this._onCanvasBlur);
        this._onBlur = function () {
            if (_this.disablePerformanceMonitorInBackground) {
                _this._performanceMonitor.disable();
            }
            _this._windowIsBackground = true;
        };
        this._onFocus = function () {
            if (_this.disablePerformanceMonitorInBackground) {
                _this._performanceMonitor.enable();
            }
            _this._windowIsBackground = false;
        };
        this._onCanvasPointerOut = function (ev) {
            _this.onCanvasPointerOutObservable.notifyObservers(ev);
        };
        if (_Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__["DomManagement"].IsWindowObjectExist()) {
            var hostWindow = this.getHostWindow();
            hostWindow.addEventListener("blur", this._onBlur);
            hostWindow.addEventListener("focus", this._onFocus);
        }
        canvas.addEventListener("pointerout", this._onCanvasPointerOut);
        if (!doNotHandleTouchAction) {
            this._disableTouchAction();
        }
        // Create Audio Engine if needed.
        if (!Engine.audioEngine && audioEngine && Engine.AudioEngineFactory) {
            Engine.audioEngine = Engine.AudioEngineFactory(this.getRenderingCanvas());
        }
        // Shader processor
        this._shaderProcessor = this._getShaderProcessor();
    };
    /**
     * Gets a shader processor implementation fitting with the current engine type.
     * @returns The shader processor implementation.
     */
    Engine.prototype._getShaderProcessor = function () {
        if (this.webGLVersion > 1) {
            return new _WebGL_webGL2ShaderProcessors__WEBPACK_IMPORTED_MODULE_15__["WebGL2ShaderProcessor"]();
        }
        return null;
    };
    /** @hidden */
    Engine.prototype._getShaderProcessingContext = function () {
        return null;
    };
    // WebVR
    /**
     * Initializes a webVR display and starts listening to display change events
     * The onVRDisplayChangedObservable will be notified upon these changes
     * @returns The onVRDisplayChangedObservable
     */
    Engine.prototype.initWebVR = function () {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_12__["_DevTools"].WarnImport("WebVRCamera");
    };
    /** @hidden */
    Engine.prototype._prepareVRComponent = function () {
        // Do nothing as the engine side effect will overload it
    };
    /** @hidden */
    Engine.prototype._connectVREvents = function (canvas, document) {
        // Do nothing as the engine side effect will overload it
    };
    /** @hidden */
    Engine.prototype._submitVRFrame = function () {
        // Do nothing as the engine side effect will overload it
    };
    /**
     * Call this function to leave webVR mode
     * Will do nothing if webVR is not supported or if there is no webVR device
     * @see http://doc.babylonjs.com/how_to/webvr_camera
     */
    Engine.prototype.disableVR = function () {
        // Do nothing as the engine side effect will overload it
    };
    /**
     * Gets a boolean indicating that the system is in VR mode and is presenting
     * @returns true if VR mode is engaged
     */
    Engine.prototype.isVRPresenting = function () {
        return false;
    };
    /** @hidden */
    Engine.prototype._requestVRFrame = function () {
        // Do nothing as the engine side effect will overload it
    };
    Engine.prototype._disableTouchAction = function () {
        if (!this._renderingCanvas) {
            return;
        }
        this._renderingCanvas.setAttribute("touch-action", "none");
        this._renderingCanvas.style.touchAction = "none";
        this._renderingCanvas.style.msTouchAction = "none";
    };
    Engine.prototype._rebuildInternalTextures = function () {
        var currentState = this._internalTexturesCache.slice(); // Do a copy because the rebuild will add proxies
        for (var _i = 0, currentState_1 = currentState; _i < currentState_1.length; _i++) {
            var internalTexture = currentState_1[_i];
            internalTexture._rebuild();
        }
    };
    Engine.prototype._rebuildEffects = function () {
        for (var key in this._compiledEffects) {
            var effect = this._compiledEffects[key];
            effect._prepareEffect();
        }
        _Materials_effect__WEBPACK_IMPORTED_MODULE_4__["Effect"].ResetCache();
    };
    /**
     * Gets a boolean indicating if all created effects are ready
     * @returns true if all effects are ready
     */
    Engine.prototype.areAllEffectsReady = function () {
        for (var key in this._compiledEffects) {
            var effect = this._compiledEffects[key];
            if (!effect.isReady()) {
                return false;
            }
        }
        return true;
    };
    Engine.prototype._rebuildBuffers = function () {
        // Index / Vertex
        for (var _i = 0, _a = this.scenes; _i < _a.length; _i++) {
            var scene = _a[_i];
            scene.resetCachedMaterial();
            scene._rebuildGeometries();
            scene._rebuildTextures();
        }
        // Uniforms
        for (var _b = 0, _c = this._uniformBuffers; _b < _c.length; _b++) {
            var uniformBuffer = _c[_b];
            uniformBuffer._rebuild();
        }
    };
    Engine.prototype._initGLContext = function () {
        // Caps
        this._caps = new EngineCapabilities();
        this._caps.maxTexturesImageUnits = this._gl.getParameter(this._gl.MAX_TEXTURE_IMAGE_UNITS);
        this._caps.maxCombinedTexturesImageUnits = this._gl.getParameter(this._gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
        this._caps.maxVertexTextureImageUnits = this._gl.getParameter(this._gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
        this._caps.maxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
        this._caps.maxCubemapTextureSize = this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE);
        this._caps.maxRenderTextureSize = this._gl.getParameter(this._gl.MAX_RENDERBUFFER_SIZE);
        this._caps.maxVertexAttribs = this._gl.getParameter(this._gl.MAX_VERTEX_ATTRIBS);
        this._caps.maxVaryingVectors = this._gl.getParameter(this._gl.MAX_VARYING_VECTORS);
        this._caps.maxFragmentUniformVectors = this._gl.getParameter(this._gl.MAX_FRAGMENT_UNIFORM_VECTORS);
        this._caps.maxVertexUniformVectors = this._gl.getParameter(this._gl.MAX_VERTEX_UNIFORM_VECTORS);
        // Infos
        this._glVersion = this._gl.getParameter(this._gl.VERSION);
        var rendererInfo = this._gl.getExtension("WEBGL_debug_renderer_info");
        if (rendererInfo != null) {
            this._glRenderer = this._gl.getParameter(rendererInfo.UNMASKED_RENDERER_WEBGL);
            this._glVendor = this._gl.getParameter(rendererInfo.UNMASKED_VENDOR_WEBGL);
        }
        if (!this._glVendor) {
            this._glVendor = "Unknown vendor";
        }
        if (!this._glRenderer) {
            this._glRenderer = "Unknown renderer";
        }
        // Constants
        this._gl.HALF_FLOAT_OES = 0x8D61; // Half floating-point type (16-bit).
        if (this._gl.RGBA16F !== 0x881A) {
            this._gl.RGBA16F = 0x881A; // RGBA 16-bit floating-point color-renderable internal sized format.
        }
        if (this._gl.RGBA32F !== 0x8814) {
            this._gl.RGBA32F = 0x8814; // RGBA 32-bit floating-point color-renderable internal sized format.
        }
        if (this._gl.DEPTH24_STENCIL8 !== 35056) {
            this._gl.DEPTH24_STENCIL8 = 35056;
        }
        // Extensions
        this._caps.standardDerivatives = this._webGLVersion > 1 || (this._gl.getExtension('OES_standard_derivatives') !== null);
        this._caps.astc = this._gl.getExtension('WEBGL_compressed_texture_astc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_astc');
        this._caps.s3tc = this._gl.getExtension('WEBGL_compressed_texture_s3tc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
        this._caps.pvrtc = this._gl.getExtension('WEBGL_compressed_texture_pvrtc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
        this._caps.etc1 = this._gl.getExtension('WEBGL_compressed_texture_etc1') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc1');
        this._caps.etc2 = this._gl.getExtension('WEBGL_compressed_texture_etc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_etc') ||
            this._gl.getExtension('WEBGL_compressed_texture_es3_0'); // also a requirement of OpenGL ES 3
        this._caps.textureAnisotropicFilterExtension = this._gl.getExtension('EXT_texture_filter_anisotropic') || this._gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') || this._gl.getExtension('MOZ_EXT_texture_filter_anisotropic');
        this._caps.maxAnisotropy = this._caps.textureAnisotropicFilterExtension ? this._gl.getParameter(this._caps.textureAnisotropicFilterExtension.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 0;
        this._caps.uintIndices = this._webGLVersion > 1 || this._gl.getExtension('OES_element_index_uint') !== null;
        this._caps.fragmentDepthSupported = this._webGLVersion > 1 || this._gl.getExtension('EXT_frag_depth') !== null;
        this._caps.highPrecisionShaderSupported = false;
        this._caps.timerQuery = this._gl.getExtension('EXT_disjoint_timer_query_webgl2') || this._gl.getExtension("EXT_disjoint_timer_query");
        if (this._caps.timerQuery) {
            if (this._webGLVersion === 1) {
                this._gl.getQuery = this._caps.timerQuery.getQueryEXT.bind(this._caps.timerQuery);
            }
            this._caps.canUseTimestampForTimerQuery = this._gl.getQuery(this._caps.timerQuery.TIMESTAMP_EXT, this._caps.timerQuery.QUERY_COUNTER_BITS_EXT) > 0;
        }
        // Checks if some of the format renders first to allow the use of webgl inspector.
        this._caps.colorBufferFloat = this._webGLVersion > 1 && this._gl.getExtension('EXT_color_buffer_float');
        this._caps.textureFloat = (this._webGLVersion > 1 || this._gl.getExtension('OES_texture_float')) ? true : false;
        this._caps.textureFloatLinearFiltering = this._caps.textureFloat && this._gl.getExtension('OES_texture_float_linear') ? true : false;
        this._caps.textureFloatRender = this._caps.textureFloat && this._canRenderToFloatFramebuffer() ? true : false;
        this._caps.textureHalfFloat = (this._webGLVersion > 1 || this._gl.getExtension('OES_texture_half_float')) ? true : false;
        this._caps.textureHalfFloatLinearFiltering = (this._webGLVersion > 1 || (this._caps.textureHalfFloat && this._gl.getExtension('OES_texture_half_float_linear'))) ? true : false;
        if (this._webGLVersion > 1) {
            this._gl.HALF_FLOAT_OES = 0x140B;
        }
        this._caps.textureHalfFloatRender = this._caps.textureHalfFloat && this._canRenderToHalfFloatFramebuffer();
        this._caps.textureLOD = (this._webGLVersion > 1 || this._gl.getExtension('EXT_shader_texture_lod')) ? true : false;
        this._caps.multiview = this._gl.getExtension('OVR_multiview2');
        // Draw buffers
        if (this._webGLVersion > 1) {
            this._caps.drawBuffersExtension = true;
            this._caps.maxMSAASamples = this._gl.getParameter(this._gl.MAX_SAMPLES);
        }
        else {
            var drawBuffersExtension = this._gl.getExtension('WEBGL_draw_buffers');
            if (drawBuffersExtension !== null) {
                this._caps.drawBuffersExtension = true;
                this._gl.drawBuffers = drawBuffersExtension.drawBuffersWEBGL.bind(drawBuffersExtension);
                this._gl.DRAW_FRAMEBUFFER = this._gl.FRAMEBUFFER;
                for (var i = 0; i < 16; i++) {
                    this._gl["COLOR_ATTACHMENT" + i + "_WEBGL"] = drawBuffersExtension["COLOR_ATTACHMENT" + i + "_WEBGL"];
                }
            }
            else {
                this._caps.drawBuffersExtension = false;
            }
        }
        // Shader compiler threads
        this._caps.parallelShaderCompile = this._gl.getExtension('KHR_parallel_shader_compile');
        // Depth Texture
        if (this._webGLVersion > 1) {
            this._caps.depthTextureExtension = true;
        }
        else {
            var depthTextureExtension = this._gl.getExtension('WEBGL_depth_texture');
            if (depthTextureExtension != null) {
                this._caps.depthTextureExtension = true;
                this._gl.UNSIGNED_INT_24_8 = depthTextureExtension.UNSIGNED_INT_24_8_WEBGL;
            }
        }
        // Vertex array object
        if (this.disableVertexArrayObjects) {
            this._caps.vertexArrayObject = false;
        }
        else if (this._webGLVersion > 1) {
            this._caps.vertexArrayObject = true;
        }
        else {
            var vertexArrayObjectExtension = this._gl.getExtension('OES_vertex_array_object');
            if (vertexArrayObjectExtension != null) {
                this._caps.vertexArrayObject = true;
                this._gl.createVertexArray = vertexArrayObjectExtension.createVertexArrayOES.bind(vertexArrayObjectExtension);
                this._gl.bindVertexArray = vertexArrayObjectExtension.bindVertexArrayOES.bind(vertexArrayObjectExtension);
                this._gl.deleteVertexArray = vertexArrayObjectExtension.deleteVertexArrayOES.bind(vertexArrayObjectExtension);
            }
            else {
                this._caps.vertexArrayObject = false;
            }
        }
        // Instances count
        if (this._webGLVersion > 1) {
            this._caps.instancedArrays = true;
        }
        else {
            var instanceExtension = this._gl.getExtension('ANGLE_instanced_arrays');
            if (instanceExtension != null) {
                this._caps.instancedArrays = true;
                this._gl.drawArraysInstanced = instanceExtension.drawArraysInstancedANGLE.bind(instanceExtension);
                this._gl.drawElementsInstanced = instanceExtension.drawElementsInstancedANGLE.bind(instanceExtension);
                this._gl.vertexAttribDivisor = instanceExtension.vertexAttribDivisorANGLE.bind(instanceExtension);
            }
            else {
                this._caps.instancedArrays = false;
            }
        }
        // Intelligently add supported compressed formats in order to check for.
        // Check for ASTC support first as it is most powerful and to be very cross platform.
        // Next PVRTC & DXT, which are probably superior to ETC1/2.
        // Likely no hardware which supports both PVR & DXT, so order matters little.
        // ETC2 is newer and handles ETC1 (no alpha capability), so check for first.
        if (this._caps.astc) {
            this.texturesSupported.push('-astc.ktx');
        }
        if (this._caps.s3tc) {
            this.texturesSupported.push('-dxt.ktx');
        }
        if (this._caps.pvrtc) {
            this.texturesSupported.push('-pvrtc.ktx');
        }
        if (this._caps.etc2) {
            this.texturesSupported.push('-etc2.ktx');
        }
        if (this._caps.etc1) {
            this.texturesSupported.push('-etc1.ktx');
        }
        if (this._gl.getShaderPrecisionFormat) {
            var vertex_highp = this._gl.getShaderPrecisionFormat(this._gl.VERTEX_SHADER, this._gl.HIGH_FLOAT);
            var fragment_highp = this._gl.getShaderPrecisionFormat(this._gl.FRAGMENT_SHADER, this._gl.HIGH_FLOAT);
            if (vertex_highp && fragment_highp) {
                this._caps.highPrecisionShaderSupported = vertex_highp.precision !== 0 && fragment_highp.precision !== 0;
            }
        }
        // Depth buffer
        this.setDepthBuffer(true);
        this.setDepthFunctionToLessOrEqual();
        this.setDepthWrite(true);
        // Texture maps
        this._maxSimultaneousTextures = this._caps.maxCombinedTexturesImageUnits;
        for (var slot = 0; slot < this._maxSimultaneousTextures; slot++) {
            this._nextFreeTextureSlots.push(slot);
        }
    };
    Object.defineProperty(Engine.prototype, "webGLVersion", {
        /**
         * Gets version of the current webGL context
         */
        get: function () {
            return this._webGLVersion;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets a string idenfifying the name of the class
     * @returns "Engine" string
     */
    Engine.prototype.getClassName = function () {
        return "Engine";
    };
    Object.defineProperty(Engine.prototype, "isStencilEnable", {
        /**
         * Returns true if the stencil buffer has been enabled through the creation option of the context.
         */
        get: function () {
            return this._isStencilEnable;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    Engine.prototype._prepareWorkingCanvas = function () {
        if (this._workingCanvas) {
            return;
        }
        this._workingCanvas = document.createElement("canvas");
        var context = this._workingCanvas.getContext("2d");
        if (context) {
            this._workingContext = context;
        }
    };
    /**
     * Reset the texture cache to empty state
     */
    Engine.prototype.resetTextureCache = function () {
        for (var key in this._boundTexturesCache) {
            if (!this._boundTexturesCache.hasOwnProperty(key)) {
                continue;
            }
            this._boundTexturesCache[key] = null;
        }
        this._currentTextureChannel = -1;
    };
    /**
     * Gets a boolean indicating that the engine is running in deterministic lock step mode
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     * @returns true if engine is in deterministic lock step mode
     */
    Engine.prototype.isDeterministicLockStep = function () {
        return this._deterministicLockstep;
    };
    /**
     * Gets the max steps when engine is running in deterministic lock step
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     * @returns the max steps
     */
    Engine.prototype.getLockstepMaxSteps = function () {
        return this._lockstepMaxSteps;
    };
    /**
     * Gets an object containing information about the current webGL context
     * @returns an object containing the vender, the renderer and the version of the current webGL context
     */
    Engine.prototype.getGlInfo = function () {
        return {
            vendor: this._glVendor,
            renderer: this._glRenderer,
            version: this._glVersion
        };
    };
    /**
     * Gets current aspect ratio
     * @param viewportOwner defines the camera to use to get the aspect ratio
     * @param useScreen defines if screen size must be used (or the current render target if any)
     * @returns a number defining the aspect ratio
     */
    Engine.prototype.getAspectRatio = function (viewportOwner, useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        var viewport = viewportOwner.viewport;
        return (this.getRenderWidth(useScreen) * viewport.width) / (this.getRenderHeight(useScreen) * viewport.height);
    };
    /**
     * Gets current screen aspect ratio
     * @returns a number defining the aspect ratio
     */
    Engine.prototype.getScreenAspectRatio = function () {
        return (this.getRenderWidth(true)) / (this.getRenderHeight(true));
    };
    /**
     * Gets the current render width
     * @param useScreen defines if screen size must be used (or the current render target if any)
     * @returns a number defining the current render width
     */
    Engine.prototype.getRenderWidth = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.width;
        }
        return this._gl.drawingBufferWidth;
    };
    /**
     * Gets the current render height
     * @param useScreen defines if screen size must be used (or the current render target if any)
     * @returns a number defining the current render height
     */
    Engine.prototype.getRenderHeight = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.height;
        }
        return this._gl.drawingBufferHeight;
    };
    /**
     * Gets the HTML canvas attached with the current webGL context
     * @returns a HTML canvas
     */
    Engine.prototype.getRenderingCanvas = function () {
        return this._renderingCanvas;
    };
    /**
     * Gets host window
     * @returns the host window object
     */
    Engine.prototype.getHostWindow = function () {
        if (this._renderingCanvas && this._renderingCanvas.ownerDocument && this._renderingCanvas.ownerDocument.defaultView) {
            return this._renderingCanvas.ownerDocument.defaultView;
        }
        return window;
    };
    /**
     * Gets host document
     * @returns the host document object
     */
    Engine.prototype.getHostDocument = function () {
        if (this._renderingCanvas && this._renderingCanvas.ownerDocument) {
            return this._renderingCanvas.ownerDocument;
        }
        return document;
    };
    /**
     * Gets the client rect of the HTML canvas attached with the current webGL context
     * @returns a client rectanglee
     */
    Engine.prototype.getRenderingCanvasClientRect = function () {
        if (!this._renderingCanvas) {
            return null;
        }
        return this._renderingCanvas.getBoundingClientRect();
    };
    /**
     * Defines the hardware scaling level.
     * By default the hardware scaling level is computed from the window device ratio.
     * if level = 1 then the engine will render at the exact resolution of the canvas. If level = 0.5 then the engine will render at twice the size of the canvas.
     * @param level defines the level to use
     */
    Engine.prototype.setHardwareScalingLevel = function (level) {
        this._hardwareScalingLevel = level;
        this.resize();
    };
    /**
     * Gets the current hardware scaling level.
     * By default the hardware scaling level is computed from the window device ratio.
     * if level = 1 then the engine will render at the exact resolution of the canvas. If level = 0.5 then the engine will render at twice the size of the canvas.
     * @returns a number indicating the current hardware scaling level
     */
    Engine.prototype.getHardwareScalingLevel = function () {
        return this._hardwareScalingLevel;
    };
    /**
     * Gets the list of loaded textures
     * @returns an array containing all loaded textures
     */
    Engine.prototype.getLoadedTexturesCache = function () {
        return this._internalTexturesCache;
    };
    /**
     * Gets the object containing all engine capabilities
     * @returns the EngineCapabilities object
     */
    Engine.prototype.getCaps = function () {
        return this._caps;
    };
    /**
     * Gets the current depth function
     * @returns a number defining the depth function
     */
    Engine.prototype.getDepthFunction = function () {
        return this._depthCullingState.depthFunc;
    };
    /**
     * Sets the current depth function
     * @param depthFunc defines the function to use
     */
    Engine.prototype.setDepthFunction = function (depthFunc) {
        this._depthCullingState.depthFunc = depthFunc;
    };
    /**
     * Sets the current depth function to GREATER
     */
    Engine.prototype.setDepthFunctionToGreater = function () {
        this._depthCullingState.depthFunc = this._gl.GREATER;
    };
    /**
     * Sets the current depth function to GEQUAL
     */
    Engine.prototype.setDepthFunctionToGreaterOrEqual = function () {
        this._depthCullingState.depthFunc = this._gl.GEQUAL;
    };
    /**
     * Sets the current depth function to LESS
     */
    Engine.prototype.setDepthFunctionToLess = function () {
        this._depthCullingState.depthFunc = this._gl.LESS;
    };
    /**
     * Caches the the state of the stencil buffer
     */
    Engine.prototype.cacheStencilState = function () {
        this._cachedStencilBuffer = this.getStencilBuffer();
        this._cachedStencilFunction = this.getStencilFunction();
        this._cachedStencilMask = this.getStencilMask();
        this._cachedStencilOperationPass = this.getStencilOperationPass();
        this._cachedStencilOperationFail = this.getStencilOperationFail();
        this._cachedStencilOperationDepthFail = this.getStencilOperationDepthFail();
        this._cachedStencilReference = this.getStencilFunctionReference();
    };
    /**
     * Restores the state of the stencil buffer
     */
    Engine.prototype.restoreStencilState = function () {
        this.setStencilFunction(this._cachedStencilFunction);
        this.setStencilMask(this._cachedStencilMask);
        this.setStencilBuffer(this._cachedStencilBuffer);
        this.setStencilOperationPass(this._cachedStencilOperationPass);
        this.setStencilOperationFail(this._cachedStencilOperationFail);
        this.setStencilOperationDepthFail(this._cachedStencilOperationDepthFail);
        this.setStencilFunctionReference(this._cachedStencilReference);
    };
    /**
     * Sets the current depth function to LEQUAL
     */
    Engine.prototype.setDepthFunctionToLessOrEqual = function () {
        this._depthCullingState.depthFunc = this._gl.LEQUAL;
    };
    /**
     * Gets a boolean indicating if stencil buffer is enabled
     * @returns the current stencil buffer state
     */
    Engine.prototype.getStencilBuffer = function () {
        return this._stencilState.stencilTest;
    };
    /**
     * Enable or disable the stencil buffer
     * @param enable defines if the stencil buffer must be enabled or disabled
     */
    Engine.prototype.setStencilBuffer = function (enable) {
        this._stencilState.stencilTest = enable;
    };
    /**
     * Gets the current stencil mask
     * @returns a number defining the new stencil mask to use
     */
    Engine.prototype.getStencilMask = function () {
        return this._stencilState.stencilMask;
    };
    /**
     * Sets the current stencil mask
     * @param mask defines the new stencil mask to use
     */
    Engine.prototype.setStencilMask = function (mask) {
        this._stencilState.stencilMask = mask;
    };
    /**
     * Gets the current stencil function
     * @returns a number defining the stencil function to use
     */
    Engine.prototype.getStencilFunction = function () {
        return this._stencilState.stencilFunc;
    };
    /**
     * Gets the current stencil reference value
     * @returns a number defining the stencil reference value to use
     */
    Engine.prototype.getStencilFunctionReference = function () {
        return this._stencilState.stencilFuncRef;
    };
    /**
     * Gets the current stencil mask
     * @returns a number defining the stencil mask to use
     */
    Engine.prototype.getStencilFunctionMask = function () {
        return this._stencilState.stencilFuncMask;
    };
    /**
     * Sets the current stencil function
     * @param stencilFunc defines the new stencil function to use
     */
    Engine.prototype.setStencilFunction = function (stencilFunc) {
        this._stencilState.stencilFunc = stencilFunc;
    };
    /**
     * Sets the current stencil reference
     * @param reference defines the new stencil reference to use
     */
    Engine.prototype.setStencilFunctionReference = function (reference) {
        this._stencilState.stencilFuncRef = reference;
    };
    /**
     * Sets the current stencil mask
     * @param mask defines the new stencil mask to use
     */
    Engine.prototype.setStencilFunctionMask = function (mask) {
        this._stencilState.stencilFuncMask = mask;
    };
    /**
     * Gets the current stencil operation when stencil fails
     * @returns a number defining stencil operation to use when stencil fails
     */
    Engine.prototype.getStencilOperationFail = function () {
        return this._stencilState.stencilOpStencilFail;
    };
    /**
     * Gets the current stencil operation when depth fails
     * @returns a number defining stencil operation to use when depth fails
     */
    Engine.prototype.getStencilOperationDepthFail = function () {
        return this._stencilState.stencilOpDepthFail;
    };
    /**
     * Gets the current stencil operation when stencil passes
     * @returns a number defining stencil operation to use when stencil passes
     */
    Engine.prototype.getStencilOperationPass = function () {
        return this._stencilState.stencilOpStencilDepthPass;
    };
    /**
     * Sets the stencil operation to use when stencil fails
     * @param operation defines the stencil operation to use when stencil fails
     */
    Engine.prototype.setStencilOperationFail = function (operation) {
        this._stencilState.stencilOpStencilFail = operation;
    };
    /**
     * Sets the stencil operation to use when depth fails
     * @param operation defines the stencil operation to use when depth fails
     */
    Engine.prototype.setStencilOperationDepthFail = function (operation) {
        this._stencilState.stencilOpDepthFail = operation;
    };
    /**
     * Sets the stencil operation to use when stencil passes
     * @param operation defines the stencil operation to use when stencil passes
     */
    Engine.prototype.setStencilOperationPass = function (operation) {
        this._stencilState.stencilOpStencilDepthPass = operation;
    };
    /**
     * Sets a boolean indicating if the dithering state is enabled or disabled
     * @param value defines the dithering state
     */
    Engine.prototype.setDitheringState = function (value) {
        if (value) {
            this._gl.enable(this._gl.DITHER);
        }
        else {
            this._gl.disable(this._gl.DITHER);
        }
    };
    /**
     * Sets a boolean indicating if the rasterizer state is enabled or disabled
     * @param value defines the rasterizer state
     */
    Engine.prototype.setRasterizerState = function (value) {
        if (value) {
            this._gl.disable(this._gl.RASTERIZER_DISCARD);
        }
        else {
            this._gl.enable(this._gl.RASTERIZER_DISCARD);
        }
    };
    /**
     * stop executing a render loop function and remove it from the execution array
     * @param renderFunction defines the function to be removed. If not provided all functions will be removed.
     */
    Engine.prototype.stopRenderLoop = function (renderFunction) {
        if (!renderFunction) {
            this._activeRenderLoops = [];
            return;
        }
        var index = this._activeRenderLoops.indexOf(renderFunction);
        if (index >= 0) {
            this._activeRenderLoops.splice(index, 1);
        }
    };
    /** @hidden */
    Engine.prototype._renderLoop = function () {
        if (!this._contextWasLost) {
            var shouldRender = true;
            if (!this.renderEvenInBackground && this._windowIsBackground) {
                shouldRender = false;
            }
            if (shouldRender) {
                // Start new frame
                this.beginFrame();
                for (var index = 0; index < this._activeRenderLoops.length; index++) {
                    var renderFunction = this._activeRenderLoops[index];
                    renderFunction();
                }
                // Present
                this.endFrame();
            }
        }
        if (this._activeRenderLoops.length > 0) {
            // Register new frame
            if (this.customAnimationFrameRequester) {
                this.customAnimationFrameRequester.requestID = this._queueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
                this._frameHandler = this.customAnimationFrameRequester.requestID;
            }
            else if (this.isVRPresenting()) {
                this._requestVRFrame();
            }
            else {
                this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
            }
        }
        else {
            this._renderingQueueLaunched = false;
        }
    };
    /**
     * Can be used to override the current requestAnimationFrame requester.
     * @hidden
     */
    Engine.prototype._queueNewFrame = function (bindedRenderFunction, requester) {
        return Engine.QueueNewFrame(bindedRenderFunction, requester);
    };
    /**
     * Register and execute a render loop. The engine can have more than one render function
     * @param renderFunction defines the function to continuously execute
     */
    Engine.prototype.runRenderLoop = function (renderFunction) {
        if (this._activeRenderLoops.indexOf(renderFunction) !== -1) {
            return;
        }
        this._activeRenderLoops.push(renderFunction);
        if (!this._renderingQueueLaunched) {
            this._renderingQueueLaunched = true;
            this._bindedRenderFunction = this._renderLoop.bind(this);
            this._frameHandler = this._queueNewFrame(this._bindedRenderFunction, this.getHostWindow());
        }
    };
    /**
     * Toggle full screen mode
     * @param requestPointerLock defines if a pointer lock should be requested from the user
     */
    Engine.prototype.switchFullscreen = function (requestPointerLock) {
        if (this.isFullscreen) {
            this.exitFullscreen();
        }
        else {
            this.enterFullscreen(requestPointerLock);
        }
    };
    /**
     * Enters full screen mode
     * @param requestPointerLock defines if a pointer lock should be requested from the user
     */
    Engine.prototype.enterFullscreen = function (requestPointerLock) {
        if (!this.isFullscreen) {
            this._pointerLockRequested = requestPointerLock;
            if (this._renderingCanvas) {
                Engine._RequestFullscreen(this._renderingCanvas);
            }
        }
    };
    /**
     * Exits full screen mode
     */
    Engine.prototype.exitFullscreen = function () {
        if (this.isFullscreen) {
            Engine._ExitFullscreen();
        }
    };
    /**
     * Enters Pointerlock mode
     */
    Engine.prototype.enterPointerlock = function () {
        if (this._renderingCanvas) {
            Engine._RequestPointerlock(this._renderingCanvas);
        }
    };
    /**
     * Exits Pointerlock mode
     */
    Engine.prototype.exitPointerlock = function () {
        Engine._ExitPointerlock();
    };
    /**
     * Clear the current render buffer or the current render target (if any is set up)
     * @param color defines the color to use
     * @param backBuffer defines if the back buffer must be cleared
     * @param depth defines if the depth buffer must be cleared
     * @param stencil defines if the stencil buffer must be cleared
     */
    Engine.prototype.clear = function (color, backBuffer, depth, stencil) {
        if (stencil === void 0) { stencil = false; }
        this.applyStates();
        var mode = 0;
        if (backBuffer && color) {
            this._gl.clearColor(color.r, color.g, color.b, color.a !== undefined ? color.a : 1.0);
            mode |= this._gl.COLOR_BUFFER_BIT;
        }
        if (depth) {
            this._gl.clearDepth(1.0);
            mode |= this._gl.DEPTH_BUFFER_BIT;
        }
        if (stencil) {
            this._gl.clearStencil(0);
            mode |= this._gl.STENCIL_BUFFER_BIT;
        }
        this._gl.clear(mode);
    };
    /**
     * Executes a scissor clear (ie. a clear on a specific portion of the screen)
     * @param x defines the x-coordinate of the top left corner of the clear rectangle
     * @param y defines the y-coordinate of the corner of the clear rectangle
     * @param width defines the width of the clear rectangle
     * @param height defines the height of the clear rectangle
     * @param clearColor defines the clear color
     */
    Engine.prototype.scissorClear = function (x, y, width, height, clearColor) {
        this.enableScissor(x, y, width, height);
        this.clear(clearColor, true, true, true);
        this.disableScissor();
    };
    /**
     * Enable scissor test on a specific rectangle (ie. render will only be executed on a specific portion of the screen)
     * @param x defines the x-coordinate of the top left corner of the clear rectangle
     * @param y defines the y-coordinate of the corner of the clear rectangle
     * @param width defines the width of the clear rectangle
     * @param height defines the height of the clear rectangle
     */
    Engine.prototype.enableScissor = function (x, y, width, height) {
        var gl = this._gl;
        // Change state
        gl.enable(gl.SCISSOR_TEST);
        gl.scissor(x, y, width, height);
    };
    /**
     * Disable previously set scissor test rectangle
     */
    Engine.prototype.disableScissor = function () {
        var gl = this._gl;
        gl.disable(gl.SCISSOR_TEST);
    };
    /** @hidden */
    Engine.prototype._viewport = function (x, y, width, height) {
        if (x !== this._viewportCached.x ||
            y !== this._viewportCached.y ||
            width !== this._viewportCached.z ||
            height !== this._viewportCached.w) {
            this._viewportCached.x = x;
            this._viewportCached.y = y;
            this._viewportCached.z = width;
            this._viewportCached.w = height;
            this._gl.viewport(x, y, width, height);
        }
    };
    /**
     * Set the WebGL's viewport
     * @param viewport defines the viewport element to be used
     * @param requiredWidth defines the width required for rendering. If not provided the rendering canvas' width is used
     * @param requiredHeight defines the height required for rendering. If not provided the rendering canvas' height is used
     */
    Engine.prototype.setViewport = function (viewport, requiredWidth, requiredHeight) {
        var width = requiredWidth || this.getRenderWidth();
        var height = requiredHeight || this.getRenderHeight();
        var x = viewport.x || 0;
        var y = viewport.y || 0;
        this._cachedViewport = viewport;
        this._viewport(x * width, y * height, width * viewport.width, height * viewport.height);
    };
    /**
     * Directly set the WebGL Viewport
     * @param x defines the x coordinate of the viewport (in screen space)
     * @param y defines the y coordinate of the viewport (in screen space)
     * @param width defines the width of the viewport (in screen space)
     * @param height defines the height of the viewport (in screen space)
     * @return the current viewport Object (if any) that is being replaced by this call. You can restore this viewport later on to go back to the original state
     */
    Engine.prototype.setDirectViewport = function (x, y, width, height) {
        var currentViewport = this._cachedViewport;
        this._cachedViewport = null;
        this._viewport(x, y, width, height);
        return currentViewport;
    };
    /**
     * Begin a new frame
     */
    Engine.prototype.beginFrame = function () {
        this.onBeginFrameObservable.notifyObservers(this);
        this._measureFps();
    };
    /**
     * Enf the current frame
     */
    Engine.prototype.endFrame = function () {
        // Force a flush in case we are using a bad OS.
        if (this._badOS) {
            this.flushFramebuffer();
        }
        this._submitVRFrame();
        this.onEndFrameObservable.notifyObservers(this);
    };
    /**
     * Resize the view according to the canvas' size
     */
    Engine.prototype.resize = function () {
        // We're not resizing the size of the canvas while in VR mode & presenting
        if (!this.isVRPresenting()) {
            var width = this._renderingCanvas ? this._renderingCanvas.clientWidth : window.innerWidth;
            var height = this._renderingCanvas ? this._renderingCanvas.clientHeight : window.innerHeight;
            this.setSize(width / this._hardwareScalingLevel, height / this._hardwareScalingLevel);
        }
    };
    /**
     * Force a specific size of the canvas
     * @param width defines the new canvas' width
     * @param height defines the new canvas' height
     */
    Engine.prototype.setSize = function (width, height) {
        if (!this._renderingCanvas) {
            return;
        }
        width = width | 0;
        height = height | 0;
        if (this._renderingCanvas.width === width && this._renderingCanvas.height === height) {
            return;
        }
        this._renderingCanvas.width = width;
        this._renderingCanvas.height = height;
        for (var index = 0; index < this.scenes.length; index++) {
            var scene = this.scenes[index];
            for (var camIndex = 0; camIndex < scene.cameras.length; camIndex++) {
                var cam = scene.cameras[camIndex];
                cam._currentRenderId = 0;
            }
        }
        if (this.onResizeObservable.hasObservers) {
            this.onResizeObservable.notifyObservers(this);
        }
    };
    /**
     * Binds the frame buffer to the specified texture.
     * @param texture The texture to render to or null for the default canvas
     * @param faceIndex The face of the texture to render to in case of cube texture
     * @param requiredWidth The width of the target to render to
     * @param requiredHeight The height of the target to render to
     * @param forceFullscreenViewport Forces the viewport to be the entire texture/screen if true
     * @param depthStencilTexture The depth stencil texture to use to render
     * @param lodLevel defines le lod level to bind to the frame buffer
     */
    Engine.prototype.bindFramebuffer = function (texture, faceIndex, requiredWidth, requiredHeight, forceFullscreenViewport, depthStencilTexture, lodLevel) {
        if (lodLevel === void 0) { lodLevel = 0; }
        if (this._currentRenderTarget) {
            this.unBindFramebuffer(this._currentRenderTarget);
        }
        this._currentRenderTarget = texture;
        this._bindUnboundFramebuffer(texture._MSAAFramebuffer ? texture._MSAAFramebuffer : texture._framebuffer);
        var gl = this._gl;
        if (texture.isCube) {
            if (faceIndex === undefined) {
                faceIndex = 0;
            }
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._webGLTexture, lodLevel);
            if (depthStencilTexture) {
                if (depthStencilTexture._generateStencilBuffer) {
                    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, depthStencilTexture._webGLTexture, lodLevel);
                }
                else {
                    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, depthStencilTexture._webGLTexture, lodLevel);
                }
            }
        }
        if (this._cachedViewport && !forceFullscreenViewport) {
            this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);
        }
        else {
            if (!requiredWidth) {
                requiredWidth = texture.width;
                if (lodLevel) {
                    requiredWidth = requiredWidth / Math.pow(2, lodLevel);
                }
            }
            if (!requiredHeight) {
                requiredHeight = texture.height;
                if (lodLevel) {
                    requiredHeight = requiredHeight / Math.pow(2, lodLevel);
                }
            }
            this._viewport(0, 0, requiredWidth, requiredHeight);
        }
        this.wipeCaches();
    };
    /** @hidden */
    Engine.prototype._bindUnboundFramebuffer = function (framebuffer) {
        if (this._currentFramebuffer !== framebuffer) {
            this._gl.bindFramebuffer(this._gl.FRAMEBUFFER, framebuffer);
            this._currentFramebuffer = framebuffer;
        }
    };
    /**
     * Unbind the current render target texture from the webGL context
     * @param texture defines the render target texture to unbind
     * @param disableGenerateMipMaps defines a boolean indicating that mipmaps must not be generated
     * @param onBeforeUnbind defines a function which will be called before the effective unbind
     */
    Engine.prototype.unBindFramebuffer = function (texture, disableGenerateMipMaps, onBeforeUnbind) {
        if (disableGenerateMipMaps === void 0) { disableGenerateMipMaps = false; }
        this._currentRenderTarget = null;
        // If MSAA, we need to bitblt back to main texture
        var gl = this._gl;
        if (texture._MSAAFramebuffer) {
            gl.bindFramebuffer(gl.READ_FRAMEBUFFER, texture._MSAAFramebuffer);
            gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, texture._framebuffer);
            gl.blitFramebuffer(0, 0, texture.width, texture.height, 0, 0, texture.width, texture.height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
        }
        if (texture.generateMipMaps && !disableGenerateMipMaps && !texture.isCube) {
            this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);
            gl.generateMipmap(gl.TEXTURE_2D);
            this._bindTextureDirectly(gl.TEXTURE_2D, null);
        }
        if (onBeforeUnbind) {
            if (texture._MSAAFramebuffer) {
                // Bind the correct framebuffer
                this._bindUnboundFramebuffer(texture._framebuffer);
            }
            onBeforeUnbind();
        }
        this._bindUnboundFramebuffer(null);
    };
    /**
     * Force the mipmap generation for the given render target texture
     * @param texture defines the render target texture to use
     */
    Engine.prototype.generateMipMapsForCubemap = function (texture) {
        if (texture.generateMipMaps) {
            var gl = this._gl;
            this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
            gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
            this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
        }
    };
    /**
     * Force a webGL flush (ie. a flush of all waiting webGL commands)
     */
    Engine.prototype.flushFramebuffer = function () {
        this._gl.flush();
    };
    /**
     * Unbind the current render target and bind the default framebuffer
     */
    Engine.prototype.restoreDefaultFramebuffer = function () {
        if (this._currentRenderTarget) {
            this.unBindFramebuffer(this._currentRenderTarget);
        }
        else {
            this._bindUnboundFramebuffer(null);
        }
        if (this._cachedViewport) {
            this.setViewport(this._cachedViewport);
        }
        this.wipeCaches();
    };
    // UBOs
    /**
     * Create an uniform buffer
     * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
     * @param elements defines the content of the uniform buffer
     * @returns the webGL uniform buffer
     */
    Engine.prototype.createUniformBuffer = function (elements) {
        var ubo = this._gl.createBuffer();
        if (!ubo) {
            throw new Error("Unable to create uniform buffer");
        }
        var result = new _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__["WebGLDataBuffer"](ubo);
        this.bindUniformBuffer(result);
        if (elements instanceof Float32Array) {
            this._gl.bufferData(this._gl.UNIFORM_BUFFER, elements, this._gl.STATIC_DRAW);
        }
        else {
            this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(elements), this._gl.STATIC_DRAW);
        }
        this.bindUniformBuffer(null);
        result.references = 1;
        return result;
    };
    /**
     * Create a dynamic uniform buffer
     * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
     * @param elements defines the content of the uniform buffer
     * @returns the webGL uniform buffer
     */
    Engine.prototype.createDynamicUniformBuffer = function (elements) {
        var ubo = this._gl.createBuffer();
        if (!ubo) {
            throw new Error("Unable to create dynamic uniform buffer");
        }
        var result = new _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__["WebGLDataBuffer"](ubo);
        this.bindUniformBuffer(result);
        if (elements instanceof Float32Array) {
            this._gl.bufferData(this._gl.UNIFORM_BUFFER, elements, this._gl.DYNAMIC_DRAW);
        }
        else {
            this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(elements), this._gl.DYNAMIC_DRAW);
        }
        this.bindUniformBuffer(null);
        result.references = 1;
        return result;
    };
    /**
     * Update an existing uniform buffer
     * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
     * @param uniformBuffer defines the target uniform buffer
     * @param elements defines the content to update
     * @param offset defines the offset in the uniform buffer where update should start
     * @param count defines the size of the data to update
     */
    Engine.prototype.updateUniformBuffer = function (uniformBuffer, elements, offset, count) {
        this.bindUniformBuffer(uniformBuffer);
        if (offset === undefined) {
            offset = 0;
        }
        if (count === undefined) {
            if (elements instanceof Float32Array) {
                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, elements);
            }
            else {
                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, new Float32Array(elements));
            }
        }
        else {
            if (elements instanceof Float32Array) {
                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, elements.subarray(offset, offset + count));
            }
            else {
                this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, new Float32Array(elements).subarray(offset, offset + count));
            }
        }
        this.bindUniformBuffer(null);
    };
    // VBOs
    Engine.prototype._resetVertexBufferBinding = function () {
        this.bindArrayBuffer(null);
        this._cachedVertexBuffers = null;
    };
    /**
     * Creates a vertex buffer
     * @param data the data for the vertex buffer
     * @returns the new WebGL static buffer
     */
    Engine.prototype.createVertexBuffer = function (data) {
        var vbo = this._gl.createBuffer();
        if (!vbo) {
            throw new Error("Unable to create vertex buffer");
        }
        var dataBuffer = new _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__["WebGLDataBuffer"](vbo);
        this.bindArrayBuffer(dataBuffer);
        if (data instanceof Array) {
            this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.STATIC_DRAW);
        }
        else {
            this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.STATIC_DRAW);
        }
        this._resetVertexBufferBinding();
        dataBuffer.references = 1;
        return dataBuffer;
    };
    /**
     * Creates a dynamic vertex buffer
     * @param data the data for the dynamic vertex buffer
     * @returns the new WebGL dynamic buffer
     */
    Engine.prototype.createDynamicVertexBuffer = function (data) {
        var vbo = this._gl.createBuffer();
        if (!vbo) {
            throw new Error("Unable to create dynamic vertex buffer");
        }
        var result = new _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__["WebGLDataBuffer"](vbo);
        this.bindArrayBuffer(result);
        if (data instanceof Array) {
            this._gl.bufferData(this._gl.ARRAY_BUFFER, new Float32Array(data), this._gl.DYNAMIC_DRAW);
        }
        else {
            this._gl.bufferData(this._gl.ARRAY_BUFFER, data, this._gl.DYNAMIC_DRAW);
        }
        this._resetVertexBufferBinding();
        result.references = 1;
        return result;
    };
    /**
     * Update a dynamic index buffer
     * @param indexBuffer defines the target index buffer
     * @param indices defines the data to update
     * @param offset defines the offset in the target index buffer where update should start
     */
    Engine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
        if (offset === void 0) { offset = 0; }
        // Force cache update
        this._currentBoundBuffer[this._gl.ELEMENT_ARRAY_BUFFER] = null;
        this.bindIndexBuffer(indexBuffer);
        var arrayBuffer;
        if (indices instanceof Uint16Array || indices instanceof Uint32Array) {
            arrayBuffer = indices;
        }
        else {
            arrayBuffer = indexBuffer.is32Bits ? new Uint32Array(indices) : new Uint16Array(indices);
        }
        this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, arrayBuffer, this._gl.DYNAMIC_DRAW);
        this._resetIndexBufferBinding();
    };
    /**
     * Updates a dynamic vertex buffer.
     * @param vertexBuffer the vertex buffer to update
     * @param data the data used to update the vertex buffer
     * @param byteOffset the byte offset of the data
     * @param byteLength the byte length of the data
     */
    Engine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, data, byteOffset, byteLength) {
        this.bindArrayBuffer(vertexBuffer);
        if (byteOffset === undefined) {
            byteOffset = 0;
        }
        if (byteLength === undefined) {
            if (data instanceof Array) {
                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, new Float32Array(data));
            }
            else {
                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, byteOffset, data);
            }
        }
        else {
            if (data instanceof Array) {
                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, new Float32Array(data).subarray(byteOffset, byteOffset + byteLength));
            }
            else {
                if (data instanceof ArrayBuffer) {
                    data = new Uint8Array(data, byteOffset, byteLength);
                }
                else {
                    data = new Uint8Array(data.buffer, data.byteOffset + byteOffset, byteLength);
                }
                this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
            }
        }
        this._resetVertexBufferBinding();
    };
    Engine.prototype._resetIndexBufferBinding = function () {
        this.bindIndexBuffer(null);
        this._cachedIndexBuffer = null;
    };
    /**
     * Creates a new index buffer
     * @param indices defines the content of the index buffer
     * @param updatable defines if the index buffer must be updatable
     * @returns a new webGL buffer
     */
    Engine.prototype.createIndexBuffer = function (indices, updatable) {
        var vbo = this._gl.createBuffer();
        var dataBuffer = new _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__["WebGLDataBuffer"](vbo);
        if (!vbo) {
            throw new Error("Unable to create index buffer");
        }
        this.bindIndexBuffer(dataBuffer);
        var data = this._normalizeIndexData(indices);
        this._gl.bufferData(this._gl.ELEMENT_ARRAY_BUFFER, data, updatable ? this._gl.DYNAMIC_DRAW : this._gl.STATIC_DRAW);
        this._resetIndexBufferBinding();
        dataBuffer.references = 1;
        dataBuffer.is32Bits = (data.BYTES_PER_ELEMENT === 4);
        return dataBuffer;
    };
    Engine.prototype._normalizeIndexData = function (indices) {
        if (indices instanceof Uint16Array) {
            return indices;
        }
        // Check 32 bit support
        if (this._caps.uintIndices) {
            if (indices instanceof Uint32Array) {
                return indices;
            }
            else {
                // number[] or Int32Array, check if 32 bit is necessary
                for (var index = 0; index < indices.length; index++) {
                    if (indices[index] >= 65535) {
                        return new Uint32Array(indices);
                    }
                }
                return new Uint16Array(indices);
            }
        }
        // No 32 bit support, force conversion to 16 bit (values greater 16 bit are lost)
        return new Uint16Array(indices);
    };
    /**
     * Bind a webGL buffer to the webGL context
     * @param buffer defines the buffer to bind
     */
    Engine.prototype.bindArrayBuffer = function (buffer) {
        if (!this._vaoRecordInProgress) {
            this._unbindVertexArrayObject();
        }
        this.bindBuffer(buffer, this._gl.ARRAY_BUFFER);
    };
    /**
     * Bind an uniform buffer to the current webGL context
     * @param buffer defines the buffer to bind
     */
    Engine.prototype.bindUniformBuffer = function (buffer) {
        this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer ? buffer.underlyingResource : null);
    };
    /**
     * Bind a buffer to the current webGL context at a given location
     * @param buffer defines the buffer to bind
     * @param location defines the index where to bind the buffer
     * @param name Name of the uniform variable to bind
     */
    Engine.prototype.bindUniformBufferBase = function (buffer, location, name) {
        this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer ? buffer.underlyingResource : null);
    };
    /**
     * Bind a specific block at a given index in a specific shader program
     * @param pipelineContext defines the pipeline context to use
     * @param blockName defines the block name
     * @param index defines the index where to bind the block
     */
    Engine.prototype.bindUniformBlock = function (pipelineContext, blockName, index) {
        var program = pipelineContext.program;
        var uniformLocation = this._gl.getUniformBlockIndex(program, blockName);
        this._gl.uniformBlockBinding(program, uniformLocation, index);
    };
    Engine.prototype.bindIndexBuffer = function (buffer) {
        if (!this._vaoRecordInProgress) {
            this._unbindVertexArrayObject();
        }
        this.bindBuffer(buffer, this._gl.ELEMENT_ARRAY_BUFFER);
    };
    Engine.prototype.bindBuffer = function (buffer, target) {
        if (this._vaoRecordInProgress || this._currentBoundBuffer[target] !== buffer) {
            this._gl.bindBuffer(target, buffer ? buffer.underlyingResource : null);
            this._currentBoundBuffer[target] = buffer;
        }
    };
    /**
     * update the bound buffer with the given data
     * @param data defines the data to update
     */
    Engine.prototype.updateArrayBuffer = function (data) {
        this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
    };
    Engine.prototype._vertexAttribPointer = function (buffer, indx, size, type, normalized, stride, offset) {
        var pointer = this._currentBufferPointers[indx];
        var changed = false;
        if (!pointer.active) {
            changed = true;
            pointer.active = true;
            pointer.index = indx;
            pointer.size = size;
            pointer.type = type;
            pointer.normalized = normalized;
            pointer.stride = stride;
            pointer.offset = offset;
            pointer.buffer = buffer;
        }
        else {
            if (pointer.buffer !== buffer) {
                pointer.buffer = buffer;
                changed = true;
            }
            if (pointer.size !== size) {
                pointer.size = size;
                changed = true;
            }
            if (pointer.type !== type) {
                pointer.type = type;
                changed = true;
            }
            if (pointer.normalized !== normalized) {
                pointer.normalized = normalized;
                changed = true;
            }
            if (pointer.stride !== stride) {
                pointer.stride = stride;
                changed = true;
            }
            if (pointer.offset !== offset) {
                pointer.offset = offset;
                changed = true;
            }
        }
        if (changed || this._vaoRecordInProgress) {
            this.bindArrayBuffer(buffer);
            this._gl.vertexAttribPointer(indx, size, type, normalized, stride, offset);
        }
    };
    Engine.prototype._bindIndexBufferWithCache = function (indexBuffer) {
        if (indexBuffer == null) {
            return;
        }
        if (this._cachedIndexBuffer !== indexBuffer) {
            this._cachedIndexBuffer = indexBuffer;
            this.bindIndexBuffer(indexBuffer);
            this._uintIndicesCurrentlySet = indexBuffer.is32Bits;
        }
    };
    Engine.prototype._bindVertexBuffersAttributes = function (vertexBuffers, effect) {
        var attributes = effect.getAttributesNames();
        if (!this._vaoRecordInProgress) {
            this._unbindVertexArrayObject();
        }
        this.unbindAllAttributes();
        for (var index = 0; index < attributes.length; index++) {
            var order = effect.getAttributeLocation(index);
            if (order >= 0) {
                var vertexBuffer = vertexBuffers[attributes[index]];
                if (!vertexBuffer) {
                    continue;
                }
                this._gl.enableVertexAttribArray(order);
                if (!this._vaoRecordInProgress) {
                    this._vertexAttribArraysEnabled[order] = true;
                }
                var buffer = vertexBuffer.getBuffer();
                if (buffer) {
                    this._vertexAttribPointer(buffer, order, vertexBuffer.getSize(), vertexBuffer.type, vertexBuffer.normalized, vertexBuffer.byteStride, vertexBuffer.byteOffset);
                    if (vertexBuffer.getIsInstanced()) {
                        this._gl.vertexAttribDivisor(order, vertexBuffer.getInstanceDivisor());
                        if (!this._vaoRecordInProgress) {
                            this._currentInstanceLocations.push(order);
                            this._currentInstanceBuffers.push(buffer);
                        }
                    }
                }
            }
        }
    };
    /**
     * Records a vertex array object
     * @see http://doc.babylonjs.com/features/webgl2#vertex-array-objects
     * @param vertexBuffers defines the list of vertex buffers to store
     * @param indexBuffer defines the index buffer to store
     * @param effect defines the effect to store
     * @returns the new vertex array object
     */
    Engine.prototype.recordVertexArrayObject = function (vertexBuffers, indexBuffer, effect) {
        var vao = this._gl.createVertexArray();
        this._vaoRecordInProgress = true;
        this._gl.bindVertexArray(vao);
        this._mustWipeVertexAttributes = true;
        this._bindVertexBuffersAttributes(vertexBuffers, effect);
        this.bindIndexBuffer(indexBuffer);
        this._vaoRecordInProgress = false;
        this._gl.bindVertexArray(null);
        return vao;
    };
    /**
     * Bind a specific vertex array object
     * @see http://doc.babylonjs.com/features/webgl2#vertex-array-objects
     * @param vertexArrayObject defines the vertex array object to bind
     * @param indexBuffer defines the index buffer to bind
     */
    Engine.prototype.bindVertexArrayObject = function (vertexArrayObject, indexBuffer) {
        if (this._cachedVertexArrayObject !== vertexArrayObject) {
            this._cachedVertexArrayObject = vertexArrayObject;
            this._gl.bindVertexArray(vertexArrayObject);
            this._cachedVertexBuffers = null;
            this._cachedIndexBuffer = null;
            this._uintIndicesCurrentlySet = indexBuffer != null && indexBuffer.is32Bits;
            this._mustWipeVertexAttributes = true;
        }
    };
    /**
     * Bind webGl buffers directly to the webGL context
     * @param vertexBuffer defines the vertex buffer to bind
     * @param indexBuffer defines the index buffer to bind
     * @param vertexDeclaration defines the vertex declaration to use with the vertex buffer
     * @param vertexStrideSize defines the vertex stride of the vertex buffer
     * @param effect defines the effect associated with the vertex buffer
     */
    Engine.prototype.bindBuffersDirectly = function (vertexBuffer, indexBuffer, vertexDeclaration, vertexStrideSize, effect) {
        if (this._cachedVertexBuffers !== vertexBuffer || this._cachedEffectForVertexBuffers !== effect) {
            this._cachedVertexBuffers = vertexBuffer;
            this._cachedEffectForVertexBuffers = effect;
            var attributesCount = effect.getAttributesCount();
            this._unbindVertexArrayObject();
            this.unbindAllAttributes();
            var offset = 0;
            for (var index = 0; index < attributesCount; index++) {
                if (index < vertexDeclaration.length) {
                    var order = effect.getAttributeLocation(index);
                    if (order >= 0) {
                        this._gl.enableVertexAttribArray(order);
                        this._vertexAttribArraysEnabled[order] = true;
                        this._vertexAttribPointer(vertexBuffer, order, vertexDeclaration[index], this._gl.FLOAT, false, vertexStrideSize, offset);
                    }
                    offset += vertexDeclaration[index] * 4;
                }
            }
        }
        this._bindIndexBufferWithCache(indexBuffer);
    };
    Engine.prototype._unbindVertexArrayObject = function () {
        if (!this._cachedVertexArrayObject) {
            return;
        }
        this._cachedVertexArrayObject = null;
        this._gl.bindVertexArray(null);
    };
    /**
     * Bind a list of vertex buffers to the webGL context
     * @param vertexBuffers defines the list of vertex buffers to bind
     * @param indexBuffer defines the index buffer to bind
     * @param effect defines the effect associated with the vertex buffers
     */
    Engine.prototype.bindBuffers = function (vertexBuffers, indexBuffer, effect) {
        if (this._cachedVertexBuffers !== vertexBuffers || this._cachedEffectForVertexBuffers !== effect) {
            this._cachedVertexBuffers = vertexBuffers;
            this._cachedEffectForVertexBuffers = effect;
            this._bindVertexBuffersAttributes(vertexBuffers, effect);
        }
        this._bindIndexBufferWithCache(indexBuffer);
    };
    /**
     * Unbind all instance attributes
     */
    Engine.prototype.unbindInstanceAttributes = function () {
        var boundBuffer;
        for (var i = 0, ul = this._currentInstanceLocations.length; i < ul; i++) {
            var instancesBuffer = this._currentInstanceBuffers[i];
            if (boundBuffer != instancesBuffer && instancesBuffer.references) {
                boundBuffer = instancesBuffer;
                this.bindArrayBuffer(instancesBuffer);
            }
            var offsetLocation = this._currentInstanceLocations[i];
            this._gl.vertexAttribDivisor(offsetLocation, 0);
        }
        this._currentInstanceBuffers.length = 0;
        this._currentInstanceLocations.length = 0;
    };
    /**
     * Release and free the memory of a vertex array object
     * @param vao defines the vertex array object to delete
     */
    Engine.prototype.releaseVertexArrayObject = function (vao) {
        this._gl.deleteVertexArray(vao);
    };
    /** @hidden */
    Engine.prototype._releaseBuffer = function (buffer) {
        buffer.references--;
        if (buffer.references === 0) {
            this._deleteBuffer(buffer);
            return true;
        }
        return false;
    };
    Engine.prototype._deleteBuffer = function (buffer) {
        this._gl.deleteBuffer(buffer.underlyingResource);
    };
    /**
     * Creates a webGL buffer to use with instanciation
     * @param capacity defines the size of the buffer
     * @returns the webGL buffer
     */
    Engine.prototype.createInstancesBuffer = function (capacity) {
        var buffer = this._gl.createBuffer();
        if (!buffer) {
            throw new Error("Unable to create instance buffer");
        }
        var result = new _Meshes_WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_14__["WebGLDataBuffer"](buffer);
        result.capacity = capacity;
        this.bindArrayBuffer(result);
        this._gl.bufferData(this._gl.ARRAY_BUFFER, capacity, this._gl.DYNAMIC_DRAW);
        return result;
    };
    /**
     * Delete a webGL buffer used with instanciation
     * @param buffer defines the webGL buffer to delete
     */
    Engine.prototype.deleteInstancesBuffer = function (buffer) {
        this._gl.deleteBuffer(buffer);
    };
    /**
     * Update the content of a webGL buffer used with instanciation and bind it to the webGL context
     * @param instancesBuffer defines the webGL buffer to update and bind
     * @param data defines the data to store in the buffer
     * @param offsetLocations defines the offsets or attributes information used to determine where data must be stored in the buffer
     */
    Engine.prototype.updateAndBindInstancesBuffer = function (instancesBuffer, data, offsetLocations) {
        this.bindArrayBuffer(instancesBuffer);
        if (data) {
            this._gl.bufferSubData(this._gl.ARRAY_BUFFER, 0, data);
        }
        if (offsetLocations[0].index !== undefined) {
            var stride = 0;
            for (var i = 0; i < offsetLocations.length; i++) {
                var ai = offsetLocations[i];
                stride += ai.attributeSize * 4;
            }
            for (var i = 0; i < offsetLocations.length; i++) {
                var ai = offsetLocations[i];
                if (!this._vertexAttribArraysEnabled[ai.index]) {
                    this._gl.enableVertexAttribArray(ai.index);
                    this._vertexAttribArraysEnabled[ai.index] = true;
                }
                this._vertexAttribPointer(instancesBuffer, ai.index, ai.attributeSize, ai.attribyteType || this._gl.FLOAT, ai.normalized || false, stride, ai.offset);
                this._gl.vertexAttribDivisor(ai.index, 1);
                this._currentInstanceLocations.push(ai.index);
                this._currentInstanceBuffers.push(instancesBuffer);
            }
        }
        else {
            for (var index = 0; index < 4; index++) {
                var offsetLocation = offsetLocations[index];
                if (!this._vertexAttribArraysEnabled[offsetLocation]) {
                    this._gl.enableVertexAttribArray(offsetLocation);
                    this._vertexAttribArraysEnabled[offsetLocation] = true;
                }
                this._vertexAttribPointer(instancesBuffer, offsetLocation, 4, this._gl.FLOAT, false, 64, index * 16);
                this._gl.vertexAttribDivisor(offsetLocation, 1);
                this._currentInstanceLocations.push(offsetLocation);
                this._currentInstanceBuffers.push(instancesBuffer);
            }
        }
    };
    /**
     * Apply all cached states (depth, culling, stencil and alpha)
     */
    Engine.prototype.applyStates = function () {
        this._depthCullingState.apply(this._gl);
        this._stencilState.apply(this._gl);
        this._alphaState.apply(this._gl);
    };
    /**
     * Send a draw order
     * @param useTriangles defines if triangles must be used to draw (else wireframe will be used)
     * @param indexStart defines the starting index
     * @param indexCount defines the number of index to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    Engine.prototype.draw = function (useTriangles, indexStart, indexCount, instancesCount) {
        this.drawElementsType(useTriangles ? _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleFillMode : _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_WireFrameFillMode, indexStart, indexCount, instancesCount);
    };
    /**
     * Draw a list of points
     * @param verticesStart defines the index of first vertex to draw
     * @param verticesCount defines the count of vertices to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    Engine.prototype.drawPointClouds = function (verticesStart, verticesCount, instancesCount) {
        this.drawArraysType(_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_PointFillMode, verticesStart, verticesCount, instancesCount);
    };
    /**
     * Draw a list of unindexed primitives
     * @param useTriangles defines if triangles must be used to draw (else wireframe will be used)
     * @param verticesStart defines the index of first vertex to draw
     * @param verticesCount defines the count of vertices to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    Engine.prototype.drawUnIndexed = function (useTriangles, verticesStart, verticesCount, instancesCount) {
        this.drawArraysType(useTriangles ? _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleFillMode : _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_WireFrameFillMode, verticesStart, verticesCount, instancesCount);
    };
    /**
     * Draw a list of indexed primitives
     * @param fillMode defines the primitive to use
     * @param indexStart defines the starting index
     * @param indexCount defines the number of index to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    Engine.prototype.drawElementsType = function (fillMode, indexStart, indexCount, instancesCount) {
        // Apply states
        this.applyStates();
        this._drawCalls.addCount(1, false);
        // Render
        var drawMode = this._drawMode(fillMode);
        var indexFormat = this._uintIndicesCurrentlySet ? this._gl.UNSIGNED_INT : this._gl.UNSIGNED_SHORT;
        var mult = this._uintIndicesCurrentlySet ? 4 : 2;
        if (instancesCount) {
            this._gl.drawElementsInstanced(drawMode, indexCount, indexFormat, indexStart * mult, instancesCount);
        }
        else {
            this._gl.drawElements(drawMode, indexCount, indexFormat, indexStart * mult);
        }
    };
    /**
     * Draw a list of unindexed primitives
     * @param fillMode defines the primitive to use
     * @param verticesStart defines the index of first vertex to draw
     * @param verticesCount defines the count of vertices to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    Engine.prototype.drawArraysType = function (fillMode, verticesStart, verticesCount, instancesCount) {
        // Apply states
        this.applyStates();
        this._drawCalls.addCount(1, false);
        var drawMode = this._drawMode(fillMode);
        if (instancesCount) {
            this._gl.drawArraysInstanced(drawMode, verticesStart, verticesCount, instancesCount);
        }
        else {
            this._gl.drawArrays(drawMode, verticesStart, verticesCount);
        }
    };
    Engine.prototype._drawMode = function (fillMode) {
        switch (fillMode) {
            // Triangle views
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleFillMode:
                return this._gl.TRIANGLES;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_PointFillMode:
                return this._gl.POINTS;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_WireFrameFillMode:
                return this._gl.LINES;
            // Draw modes
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_PointListDrawMode:
                return this._gl.POINTS;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LineListDrawMode:
                return this._gl.LINES;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LineLoopDrawMode:
                return this._gl.LINE_LOOP;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LineStripDrawMode:
                return this._gl.LINE_STRIP;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleStripDrawMode:
                return this._gl.TRIANGLE_STRIP;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleFanDrawMode:
                return this._gl.TRIANGLE_FAN;
            default:
                return this._gl.TRIANGLES;
        }
    };
    // Shaders
    /** @hidden */
    Engine.prototype._releaseEffect = function (effect) {
        if (this._compiledEffects[effect._key]) {
            delete this._compiledEffects[effect._key];
            this._deletePipelineContext(effect.getPipelineContext());
        }
    };
    /** @hidden */
    Engine.prototype._deletePipelineContext = function (pipelineContext) {
        var webGLPipelineContext = pipelineContext;
        if (webGLPipelineContext && webGLPipelineContext.program) {
            webGLPipelineContext.program.__SPECTOR_rebuildProgram = null;
            if (webGLPipelineContext.transformFeedback) {
                this.deleteTransformFeedback(webGLPipelineContext.transformFeedback);
                webGLPipelineContext.transformFeedback = null;
            }
            this._gl.deleteProgram(webGLPipelineContext.program);
        }
    };
    /**
     * Create a new effect (used to store vertex/fragment shaders)
     * @param baseName defines the base name of the effect (The name of file without .fragment.fx or .vertex.fx)
     * @param attributesNamesOrOptions defines either a list of attribute names or an EffectCreationOptions object
     * @param uniformsNamesOrEngine defines either a list of uniform names or the engine to use
     * @param samplers defines an array of string used to represent textures
     * @param defines defines the string containing the defines to use to compile the shaders
     * @param fallbacks defines the list of potential fallbacks to use if shader conmpilation fails
     * @param onCompiled defines a function to call when the effect creation is successful
     * @param onError defines a function to call when the effect creation has failed
     * @param indexParameters defines an object containing the index values to use to compile shaders (like the maximum number of simultaneous lights)
     * @returns the new Effect
     */
    Engine.prototype.createEffect = function (baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, defines, fallbacks, onCompiled, onError, indexParameters) {
        var vertex = baseName.vertexElement || baseName.vertex || baseName;
        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
        var name = vertex + "+" + fragment + "@" + (defines ? defines : attributesNamesOrOptions.defines);
        if (this._compiledEffects[name]) {
            var compiledEffect = this._compiledEffects[name];
            if (onCompiled && compiledEffect.isReady()) {
                onCompiled(compiledEffect);
            }
            return compiledEffect;
        }
        var effect = new _Materials_effect__WEBPACK_IMPORTED_MODULE_4__["Effect"](baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters, name);
        this._compiledEffects[name] = effect;
        return effect;
    };
    Engine._concatenateShader = function (source, defines, shaderVersion) {
        if (shaderVersion === void 0) { shaderVersion = ""; }
        return shaderVersion + (defines ? defines + "\n" : "") + source;
    };
    Engine.prototype._compileShader = function (source, type, defines, shaderVersion) {
        return this._compileRawShader(Engine._concatenateShader(source, defines, shaderVersion), type);
    };
    Engine.prototype._compileRawShader = function (source, type) {
        var gl = this._gl;
        var shader = gl.createShader(type === "vertex" ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER);
        if (!shader) {
            throw new Error("Something went wrong while compile the shader.");
        }
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        return shader;
    };
    /**
     * Directly creates a webGL program
     * @param pipelineContext  defines the pipeline context to attach to
     * @param vertexCode defines the vertex shader code to use
     * @param fragmentCode defines the fragment shader code to use
     * @param context defines the webGL context to use (if not set, the current one will be used)
     * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
     * @returns the new webGL program
     */
    Engine.prototype.createRawShaderProgram = function (pipelineContext, vertexCode, fragmentCode, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        context = context || this._gl;
        var vertexShader = this._compileRawShader(vertexCode, "vertex");
        var fragmentShader = this._compileRawShader(fragmentCode, "fragment");
        return this._createShaderProgram(pipelineContext, vertexShader, fragmentShader, context, transformFeedbackVaryings);
    };
    /**
     * Creates a webGL program
     * @param pipelineContext  defines the pipeline context to attach to
     * @param vertexCode  defines the vertex shader code to use
     * @param fragmentCode defines the fragment shader code to use
     * @param defines defines the string containing the defines to use to compile the shaders
     * @param context defines the webGL context to use (if not set, the current one will be used)
     * @param transformFeedbackVaryings defines the list of transform feedback varyings to use
     * @returns the new webGL program
     */
    Engine.prototype.createShaderProgram = function (pipelineContext, vertexCode, fragmentCode, defines, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        context = context || this._gl;
        this.onBeforeShaderCompilationObservable.notifyObservers(this);
        var shaderVersion = (this._webGLVersion > 1) ? "#version 300 es\n#define WEBGL2 \n" : "";
        var vertexShader = this._compileShader(vertexCode, "vertex", defines, shaderVersion);
        var fragmentShader = this._compileShader(fragmentCode, "fragment", defines, shaderVersion);
        var program = this._createShaderProgram(pipelineContext, vertexShader, fragmentShader, context, transformFeedbackVaryings);
        this.onAfterShaderCompilationObservable.notifyObservers(this);
        return program;
    };
    /**
     * Creates a new pipeline context
     * @param shaderProcessingContext defines the shader processing context used during the processing if available
     * @returns the new pipeline
     */
    Engine.prototype.createPipelineContext = function (shaderProcessingContext) {
        var pipelineContext = new _WebGL_webGLPipelineContext__WEBPACK_IMPORTED_MODULE_13__["WebGLPipelineContext"]();
        pipelineContext.engine = this;
        if (this._caps.parallelShaderCompile) {
            pipelineContext.isParallelCompiled = true;
        }
        return pipelineContext;
    };
    Engine.prototype._createShaderProgram = function (pipelineContext, vertexShader, fragmentShader, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        var shaderProgram = context.createProgram();
        pipelineContext.program = shaderProgram;
        if (!shaderProgram) {
            throw new Error("Unable to create program");
        }
        context.attachShader(shaderProgram, vertexShader);
        context.attachShader(shaderProgram, fragmentShader);
        if (this.webGLVersion > 1 && transformFeedbackVaryings) {
            var transformFeedback = this.createTransformFeedback();
            this.bindTransformFeedback(transformFeedback);
            this.setTranformFeedbackVaryings(shaderProgram, transformFeedbackVaryings);
            pipelineContext.transformFeedback = transformFeedback;
        }
        context.linkProgram(shaderProgram);
        if (this.webGLVersion > 1 && transformFeedbackVaryings) {
            this.bindTransformFeedback(null);
        }
        pipelineContext.context = context;
        pipelineContext.vertexShader = vertexShader;
        pipelineContext.fragmentShader = fragmentShader;
        if (!pipelineContext.isParallelCompiled) {
            this._finalizePipelineContext(pipelineContext);
        }
        return shaderProgram;
    };
    Engine.prototype._finalizePipelineContext = function (pipelineContext) {
        var context = pipelineContext.context;
        var vertexShader = pipelineContext.vertexShader;
        var fragmentShader = pipelineContext.fragmentShader;
        var program = pipelineContext.program;
        var linked = context.getProgramParameter(program, context.LINK_STATUS);
        if (!linked) { // Get more info
            // Vertex
            if (!this._gl.getShaderParameter(vertexShader, this._gl.COMPILE_STATUS)) {
                var log = this._gl.getShaderInfoLog(vertexShader);
                if (log) {
                    throw new Error("VERTEX SHADER " + log);
                }
            }
            // Fragment
            if (!this._gl.getShaderParameter(fragmentShader, this._gl.COMPILE_STATUS)) {
                var log = this._gl.getShaderInfoLog(fragmentShader);
                if (log) {
                    throw new Error("FRAGMENT SHADER " + log);
                }
            }
            var error = context.getProgramInfoLog(program);
            if (error) {
                throw new Error(error);
            }
        }
        if (this.validateShaderPrograms) {
            context.validateProgram(program);
            var validated = context.getProgramParameter(program, context.VALIDATE_STATUS);
            if (!validated) {
                var error = context.getProgramInfoLog(program);
                if (error) {
                    throw new Error(error);
                }
            }
        }
        context.deleteShader(vertexShader);
        context.deleteShader(fragmentShader);
        pipelineContext.vertexShader = undefined;
        pipelineContext.fragmentShader = undefined;
        if (pipelineContext.onCompiled) {
            pipelineContext.onCompiled();
            pipelineContext.onCompiled = undefined;
        }
    };
    /** @hidden */
    Engine.prototype._preparePipelineContext = function (pipelineContext, vertexSourceCode, fragmentSourceCode, createAsRaw, rebuildRebind, defines, transformFeedbackVaryings, key) {
        var webGLRenderingState = pipelineContext;
        if (createAsRaw) {
            webGLRenderingState.program = this.createRawShaderProgram(webGLRenderingState, vertexSourceCode, fragmentSourceCode, undefined, transformFeedbackVaryings);
        }
        else {
            webGLRenderingState.program = this.createShaderProgram(webGLRenderingState, vertexSourceCode, fragmentSourceCode, defines, undefined, transformFeedbackVaryings);
        }
        webGLRenderingState.program.__SPECTOR_rebuildProgram = rebuildRebind;
    };
    /** @hidden */
    Engine.prototype._isRenderingStateCompiled = function (pipelineContext) {
        var webGLPipelineContext = pipelineContext;
        if (this._gl.getProgramParameter(webGLPipelineContext.program, this._caps.parallelShaderCompile.COMPLETION_STATUS_KHR)) {
            this._finalizePipelineContext(webGLPipelineContext);
            return true;
        }
        return false;
    };
    /** @hidden */
    Engine.prototype._executeWhenRenderingStateIsCompiled = function (pipelineContext, action) {
        var webGLPipelineContext = pipelineContext;
        if (!webGLPipelineContext.isParallelCompiled) {
            action();
            return;
        }
        webGLPipelineContext.onCompiled = action;
    };
    /**
     * Gets the list of webGL uniform locations associated with a specific program based on a list of uniform names
     * @param pipelineContext defines the pipeline context to use
     * @param uniformsNames defines the list of uniform names
     * @returns an array of webGL uniform locations
     */
    Engine.prototype.getUniforms = function (pipelineContext, uniformsNames) {
        var results = new Array();
        var webGLPipelineContext = pipelineContext;
        for (var index = 0; index < uniformsNames.length; index++) {
            results.push(this._gl.getUniformLocation(webGLPipelineContext.program, uniformsNames[index]));
        }
        return results;
    };
    /**
     * Gets the lsit of active attributes for a given webGL program
     * @param pipelineContext defines the pipeline context to use
     * @param attributesNames defines the list of attribute names to get
     * @returns an array of indices indicating the offset of each attribute
     */
    Engine.prototype.getAttributes = function (pipelineContext, attributesNames) {
        var results = [];
        var webGLPipelineContext = pipelineContext;
        for (var index = 0; index < attributesNames.length; index++) {
            try {
                results.push(this._gl.getAttribLocation(webGLPipelineContext.program, attributesNames[index]));
            }
            catch (e) {
                results.push(-1);
            }
        }
        return results;
    };
    /**
     * Activates an effect, mkaing it the current one (ie. the one used for rendering)
     * @param effect defines the effect to activate
     */
    Engine.prototype.enableEffect = function (effect) {
        if (!effect || effect === this._currentEffect) {
            return;
        }
        // Use program
        this.bindSamplers(effect);
        this._currentEffect = effect;
        if (effect.onBind) {
            effect.onBind(effect);
        }
        if (effect._onBindObservable) {
            effect._onBindObservable.notifyObservers(effect);
        }
    };
    /**
     * Set the value of an uniform to an array of int32
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of int32 to store
     */
    Engine.prototype.setIntArray = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._gl.uniform1iv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of int32 (stored as vec2)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of int32 to store
     */
    Engine.prototype.setIntArray2 = function (uniform, array) {
        if (!uniform || array.length % 2 !== 0) {
            return;
        }
        this._gl.uniform2iv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of int32 (stored as vec3)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of int32 to store
     */
    Engine.prototype.setIntArray3 = function (uniform, array) {
        if (!uniform || array.length % 3 !== 0) {
            return;
        }
        this._gl.uniform3iv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of int32 (stored as vec4)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of int32 to store
     */
    Engine.prototype.setIntArray4 = function (uniform, array) {
        if (!uniform || array.length % 4 !== 0) {
            return;
        }
        this._gl.uniform4iv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of float32
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of float32 to store
     */
    Engine.prototype.setFloatArray = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._gl.uniform1fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of float32 (stored as vec2)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of float32 to store
     */
    Engine.prototype.setFloatArray2 = function (uniform, array) {
        if (!uniform || array.length % 2 !== 0) {
            return;
        }
        this._gl.uniform2fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of float32 (stored as vec3)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of float32 to store
     */
    Engine.prototype.setFloatArray3 = function (uniform, array) {
        if (!uniform || array.length % 3 !== 0) {
            return;
        }
        this._gl.uniform3fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of float32 (stored as vec4)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of float32 to store
     */
    Engine.prototype.setFloatArray4 = function (uniform, array) {
        if (!uniform || array.length % 4 !== 0) {
            return;
        }
        this._gl.uniform4fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of number
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of number to store
     */
    Engine.prototype.setArray = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._gl.uniform1fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of number (stored as vec2)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of number to store
     */
    Engine.prototype.setArray2 = function (uniform, array) {
        if (!uniform || array.length % 2 !== 0) {
            return;
        }
        this._gl.uniform2fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of number (stored as vec3)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of number to store
     */
    Engine.prototype.setArray3 = function (uniform, array) {
        if (!uniform || array.length % 3 !== 0) {
            return;
        }
        this._gl.uniform3fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of number (stored as vec4)
     * @param uniform defines the webGL uniform location where to store the value
     * @param array defines the array of number to store
     */
    Engine.prototype.setArray4 = function (uniform, array) {
        if (!uniform || array.length % 4 !== 0) {
            return;
        }
        this._gl.uniform4fv(uniform, array);
    };
    /**
     * Set the value of an uniform to an array of float32 (stored as matrices)
     * @param uniform defines the webGL uniform location where to store the value
     * @param matrices defines the array of float32 to store
     */
    Engine.prototype.setMatrices = function (uniform, matrices) {
        if (!uniform) {
            return;
        }
        this._gl.uniformMatrix4fv(uniform, false, matrices);
    };
    /**
     * Set the value of an uniform to a matrix (3x3)
     * @param uniform defines the webGL uniform location where to store the value
     * @param matrix defines the Float32Array representing the 3x3 matrix to store
     */
    Engine.prototype.setMatrix3x3 = function (uniform, matrix) {
        if (!uniform) {
            return;
        }
        this._gl.uniformMatrix3fv(uniform, false, matrix);
    };
    /**
     * Set the value of an uniform to a matrix (2x2)
     * @param uniform defines the webGL uniform location where to store the value
     * @param matrix defines the Float32Array representing the 2x2 matrix to store
     */
    Engine.prototype.setMatrix2x2 = function (uniform, matrix) {
        if (!uniform) {
            return;
        }
        this._gl.uniformMatrix2fv(uniform, false, matrix);
    };
    /**
     * Set the value of an uniform to a number (int)
     * @param uniform defines the webGL uniform location where to store the value
     * @param value defines the int number to store
     */
    Engine.prototype.setInt = function (uniform, value) {
        if (!uniform) {
            return;
        }
        this._gl.uniform1i(uniform, value);
    };
    /**
     * Set the value of an uniform to a number (float)
     * @param uniform defines the webGL uniform location where to store the value
     * @param value defines the float number to store
     */
    Engine.prototype.setFloat = function (uniform, value) {
        if (!uniform) {
            return;
        }
        this._gl.uniform1f(uniform, value);
    };
    /**
     * Set the value of an uniform to a vec2
     * @param uniform defines the webGL uniform location where to store the value
     * @param x defines the 1st component of the value
     * @param y defines the 2nd component of the value
     */
    Engine.prototype.setFloat2 = function (uniform, x, y) {
        if (!uniform) {
            return;
        }
        this._gl.uniform2f(uniform, x, y);
    };
    /**
     * Set the value of an uniform to a vec3
     * @param uniform defines the webGL uniform location where to store the value
     * @param x defines the 1st component of the value
     * @param y defines the 2nd component of the value
     * @param z defines the 3rd component of the value
     */
    Engine.prototype.setFloat3 = function (uniform, x, y, z) {
        if (!uniform) {
            return;
        }
        this._gl.uniform3f(uniform, x, y, z);
    };
    /**
     * Set the value of an uniform to a boolean
     * @param uniform defines the webGL uniform location where to store the value
     * @param bool defines the boolean to store
     */
    Engine.prototype.setBool = function (uniform, bool) {
        if (!uniform) {
            return;
        }
        this._gl.uniform1i(uniform, bool);
    };
    /**
     * Set the value of an uniform to a vec4
     * @param uniform defines the webGL uniform location where to store the value
     * @param x defines the 1st component of the value
     * @param y defines the 2nd component of the value
     * @param z defines the 3rd component of the value
     * @param w defines the 4th component of the value
     */
    Engine.prototype.setFloat4 = function (uniform, x, y, z, w) {
        if (!uniform) {
            return;
        }
        this._gl.uniform4f(uniform, x, y, z, w);
    };
    /**
     * Sets a Color4 on a uniform variable
     * @param uniform defines the uniform location
     * @param color4 defines the value to be set
     */
    Engine.prototype.setDirectColor4 = function (uniform, color4) {
        if (!uniform) {
            return;
        }
        this._gl.uniform4f(uniform, color4.r, color4.g, color4.b, color4.a);
    };
    // States
    /**
     * Set various states to the webGL context
     * @param culling defines backface culling state
     * @param zOffset defines the value to apply to zOffset (0 by default)
     * @param force defines if states must be applied even if cache is up to date
     * @param reverseSide defines if culling must be reversed (CCW instead of CW and CW instead of CCW)
     */
    Engine.prototype.setState = function (culling, zOffset, force, reverseSide) {
        if (zOffset === void 0) { zOffset = 0; }
        if (reverseSide === void 0) { reverseSide = false; }
        // Culling
        if (this._depthCullingState.cull !== culling || force) {
            this._depthCullingState.cull = culling;
        }
        // Cull face
        var cullFace = this.cullBackFaces ? this._gl.BACK : this._gl.FRONT;
        if (this._depthCullingState.cullFace !== cullFace || force) {
            this._depthCullingState.cullFace = cullFace;
        }
        // Z offset
        this.setZOffset(zOffset);
        // Front face
        var frontFace = reverseSide ? this._gl.CW : this._gl.CCW;
        if (this._depthCullingState.frontFace !== frontFace || force) {
            this._depthCullingState.frontFace = frontFace;
        }
    };
    /**
     * Set the z offset to apply to current rendering
     * @param value defines the offset to apply
     */
    Engine.prototype.setZOffset = function (value) {
        this._depthCullingState.zOffset = value;
    };
    /**
     * Gets the current value of the zOffset
     * @returns the current zOffset state
     */
    Engine.prototype.getZOffset = function () {
        return this._depthCullingState.zOffset;
    };
    /**
     * Enable or disable depth buffering
     * @param enable defines the state to set
     */
    Engine.prototype.setDepthBuffer = function (enable) {
        this._depthCullingState.depthTest = enable;
    };
    /**
     * Gets a boolean indicating if depth writing is enabled
     * @returns the current depth writing state
     */
    Engine.prototype.getDepthWrite = function () {
        return this._depthCullingState.depthMask;
    };
    /**
     * Enable or disable depth writing
     * @param enable defines the state to set
     */
    Engine.prototype.setDepthWrite = function (enable) {
        this._depthCullingState.depthMask = enable;
    };
    /**
     * Enable or disable color writing
     * @param enable defines the state to set
     */
    Engine.prototype.setColorWrite = function (enable) {
        this._gl.colorMask(enable, enable, enable, enable);
        this._colorWrite = enable;
    };
    /**
     * Gets a boolean indicating if color writing is enabled
     * @returns the current color writing state
     */
    Engine.prototype.getColorWrite = function () {
        return this._colorWrite;
    };
    /**
     * Sets alpha constants used by some alpha blending modes
     * @param r defines the red component
     * @param g defines the green component
     * @param b defines the blue component
     * @param a defines the alpha component
     */
    Engine.prototype.setAlphaConstants = function (r, g, b, a) {
        this._alphaState.setAlphaBlendConstants(r, g, b, a);
    };
    /**
     * Sets the current alpha mode
     * @param mode defines the mode to use (one of the Engine.ALPHA_XXX)
     * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)
     * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
     */
    Engine.prototype.setAlphaMode = function (mode, noDepthWriteChange) {
        if (noDepthWriteChange === void 0) { noDepthWriteChange = false; }
        if (this._alphaMode === mode) {
            return;
        }
        switch (mode) {
            case Engine.ALPHA_DISABLE:
                this._alphaState.alphaBlend = false;
                break;
            case Engine.ALPHA_PREMULTIPLIED:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_PREMULTIPLIED_PORTERDUFF:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_COMBINE:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_ONEONE:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE, this._gl.ZERO, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_ADD:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.SRC_ALPHA, this._gl.ONE, this._gl.ZERO, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_SUBTRACT:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.ZERO, this._gl.ONE_MINUS_SRC_COLOR, this._gl.ONE, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_MULTIPLY:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.DST_COLOR, this._gl.ZERO, this._gl.ONE, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_MAXIMIZED:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_COLOR, this._gl.ONE, this._gl.ONE);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_INTERPOLATE:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.CONSTANT_COLOR, this._gl.ONE_MINUS_CONSTANT_COLOR, this._gl.CONSTANT_ALPHA, this._gl.ONE_MINUS_CONSTANT_ALPHA);
                this._alphaState.alphaBlend = true;
                break;
            case Engine.ALPHA_SCREENMODE:
                this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_COLOR, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
                this._alphaState.alphaBlend = true;
                break;
        }
        if (!noDepthWriteChange) {
            this.setDepthWrite(mode === Engine.ALPHA_DISABLE);
        }
        this._alphaMode = mode;
    };
    /**
     * Gets the current alpha mode
     * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
     * @returns the current alpha mode
     */
    Engine.prototype.getAlphaMode = function () {
        return this._alphaMode;
    };
    // Textures
    /**
     * Clears the list of texture accessible through engine.
     * This can help preventing texture load conflict due to name collision.
     */
    Engine.prototype.clearInternalTexturesCache = function () {
        this._internalTexturesCache = [];
    };
    /**
     * Force the entire cache to be cleared
     * You should not have to use this function unless your engine needs to share the webGL context with another engine
     * @param bruteForce defines a boolean to force clearing ALL caches (including stencil, detoh and alpha states)
     */
    Engine.prototype.wipeCaches = function (bruteForce) {
        if (this.preventCacheWipeBetweenFrames && !bruteForce) {
            return;
        }
        this._currentEffect = null;
        this._viewportCached.x = 0;
        this._viewportCached.y = 0;
        this._viewportCached.z = 0;
        this._viewportCached.w = 0;
        if (bruteForce) {
            this.resetTextureCache();
            this._currentProgram = null;
            this._stencilState.reset();
            this._depthCullingState.reset();
            this.setDepthFunctionToLessOrEqual();
            this._alphaState.reset();
            this._unpackFlipYCached = null;
        }
        this._resetVertexBufferBinding();
        this._cachedIndexBuffer = null;
        this._cachedEffectForVertexBuffers = null;
        this._unbindVertexArrayObject();
        this.bindIndexBuffer(null);
    };
    /**
     * Set the compressed texture format to use, based on the formats you have, and the formats
     * supported by the hardware / browser.
     *
     * Khronos Texture Container (.ktx) files are used to support this.  This format has the
     * advantage of being specifically designed for OpenGL.  Header elements directly correspond
     * to API arguments needed to compressed textures.  This puts the burden on the container
     * generator to house the arcane code for determining these for current & future formats.
     *
     * for description see https://www.khronos.org/opengles/sdk/tools/KTX/
     * for file layout see https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
     *
     * Note: The result of this call is not taken into account when a texture is base64.
     *
     * @param formatsAvailable defines the list of those format families you have created
     * on your server.  Syntax: '-' + format family + '.ktx'.  (Case and order do not matter.)
     *
     * Current families are astc, dxt, pvrtc, etc2, & etc1.
     * @returns The extension selected.
     */
    Engine.prototype.setTextureFormatToUse = function (formatsAvailable) {
        for (var i = 0, len1 = this.texturesSupported.length; i < len1; i++) {
            for (var j = 0, len2 = formatsAvailable.length; j < len2; j++) {
                if (this._texturesSupported[i] === formatsAvailable[j].toLowerCase()) {
                    return this._textureFormatInUse = this._texturesSupported[i];
                }
            }
        }
        // actively set format to nothing, to allow this to be called more than once
        // and possibly fail the 2nd time
        this._textureFormatInUse = null;
        return null;
    };
    /** @hidden */
    Engine.prototype._getSamplingParameters = function (samplingMode, generateMipMaps) {
        var gl = this._gl;
        var magFilter = gl.NEAREST;
        var minFilter = gl.NEAREST;
        switch (samplingMode) {
            case Engine.TEXTURE_BILINEAR_SAMPLINGMODE:
                magFilter = gl.LINEAR;
                if (generateMipMaps) {
                    minFilter = gl.LINEAR_MIPMAP_NEAREST;
                }
                else {
                    minFilter = gl.LINEAR;
                }
                break;
            case Engine.TEXTURE_TRILINEAR_SAMPLINGMODE:
                magFilter = gl.LINEAR;
                if (generateMipMaps) {
                    minFilter = gl.LINEAR_MIPMAP_LINEAR;
                }
                else {
                    minFilter = gl.LINEAR;
                }
                break;
            case Engine.TEXTURE_NEAREST_SAMPLINGMODE:
                magFilter = gl.NEAREST;
                if (generateMipMaps) {
                    minFilter = gl.NEAREST_MIPMAP_LINEAR;
                }
                else {
                    minFilter = gl.NEAREST;
                }
                break;
            case Engine.TEXTURE_NEAREST_NEAREST_MIPNEAREST:
                magFilter = gl.NEAREST;
                if (generateMipMaps) {
                    minFilter = gl.NEAREST_MIPMAP_NEAREST;
                }
                else {
                    minFilter = gl.NEAREST;
                }
                break;
            case Engine.TEXTURE_NEAREST_LINEAR_MIPNEAREST:
                magFilter = gl.NEAREST;
                if (generateMipMaps) {
                    minFilter = gl.LINEAR_MIPMAP_NEAREST;
                }
                else {
                    minFilter = gl.LINEAR;
                }
                break;
            case Engine.TEXTURE_NEAREST_LINEAR_MIPLINEAR:
                magFilter = gl.NEAREST;
                if (generateMipMaps) {
                    minFilter = gl.LINEAR_MIPMAP_LINEAR;
                }
                else {
                    minFilter = gl.LINEAR;
                }
                break;
            case Engine.TEXTURE_NEAREST_LINEAR:
                magFilter = gl.NEAREST;
                minFilter = gl.LINEAR;
                break;
            case Engine.TEXTURE_NEAREST_NEAREST:
                magFilter = gl.NEAREST;
                minFilter = gl.NEAREST;
                break;
            case Engine.TEXTURE_LINEAR_NEAREST_MIPNEAREST:
                magFilter = gl.LINEAR;
                if (generateMipMaps) {
                    minFilter = gl.NEAREST_MIPMAP_NEAREST;
                }
                else {
                    minFilter = gl.NEAREST;
                }
                break;
            case Engine.TEXTURE_LINEAR_NEAREST_MIPLINEAR:
                magFilter = gl.LINEAR;
                if (generateMipMaps) {
                    minFilter = gl.NEAREST_MIPMAP_LINEAR;
                }
                else {
                    minFilter = gl.NEAREST;
                }
                break;
            case Engine.TEXTURE_LINEAR_LINEAR:
                magFilter = gl.LINEAR;
                minFilter = gl.LINEAR;
                break;
            case Engine.TEXTURE_LINEAR_NEAREST:
                magFilter = gl.LINEAR;
                minFilter = gl.NEAREST;
                break;
        }
        return {
            min: minFilter,
            mag: magFilter
        };
    };
    /** @hidden */
    Engine.prototype._createTexture = function () {
        var texture = this._gl.createTexture();
        if (!texture) {
            throw new Error("Unable to create texture");
        }
        return texture;
    };
    /**
     * Usually called from Texture.ts.
     * Passed information to create a WebGLTexture
     * @param urlArg defines a value which contains one of the following:
     * * A conventional http URL, e.g. 'http://...' or 'file://...'
     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)
     * @param scene needed for loading to the correct scene
     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)
     * @param onLoad optional callback to be called upon successful completion
     * @param onError optional callback to be called upon failure
     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob
     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
     * @param forcedExtension defines the extension to use to pick the right loader
     * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
     * @returns a InternalTexture for assignment back into BABYLON.Texture
     */
    Engine.prototype.createTexture = function (urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, fallback, format, forcedExtension, excludeLoaders) {
        var _this = this;
        if (samplingMode === void 0) { samplingMode = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (buffer === void 0) { buffer = null; }
        if (fallback === void 0) { fallback = null; }
        if (format === void 0) { format = null; }
        if (forcedExtension === void 0) { forcedExtension = null; }
        if (excludeLoaders === void 0) { excludeLoaders = []; }
        var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
        var fromData = url.substr(0, 5) === "data:";
        var fromBlob = url.substr(0, 5) === "blob:";
        var isBase64 = fromData && url.indexOf(";base64,") !== -1;
        var texture = fallback ? fallback : new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"].DATASOURCE_URL);
        // establish the file extension, if possible
        var lastDot = url.lastIndexOf('.');
        var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? url.substring(lastDot).toLowerCase() : "");
        var loader = null;
        for (var _i = 0, _a = Engine._TextureLoaders; _i < _a.length; _i++) {
            var availableLoader = _a[_i];
            if (excludeLoaders.indexOf(availableLoader) === -1 && availableLoader.canLoad(extension, this._textureFormatInUse, fallback, isBase64, buffer ? true : false)) {
                loader = availableLoader;
                break;
            }
        }
        if (loader) {
            url = loader.transformUrl(url, this._textureFormatInUse);
        }
        if (scene) {
            scene._addPendingData(texture);
        }
        texture.url = url;
        texture.generateMipMaps = !noMipmap;
        texture.samplingMode = samplingMode;
        texture.invertY = invertY;
        if (!this._doNotHandleContextLost) {
            // Keep a link to the buffer only if we plan to handle context lost
            texture._buffer = buffer;
        }
        var onLoadObserver = null;
        if (onLoad && !fallback) {
            onLoadObserver = texture.onLoadedObservable.add(onLoad);
        }
        if (!fallback) {
            this._internalTexturesCache.push(texture);
        }
        var onInternalError = function (message, exception) {
            if (scene) {
                scene._removePendingData(texture);
            }
            var customFallback = false;
            if (loader) {
                var fallbackUrl = loader.getFallbackTextureUrl(url, _this._textureFormatInUse);
                if (fallbackUrl) {
                    // Add Back
                    customFallback = true;
                    excludeLoaders.push(loader);
                    _this.createTexture(urlArg, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
                    return;
                }
            }
            if (!customFallback) {
                if (onLoadObserver) {
                    texture.onLoadedObservable.remove(onLoadObserver);
                }
                if (_engineStore__WEBPACK_IMPORTED_MODULE_10__["EngineStore"].UseFallbackTexture) {
                    _this.createTexture(_engineStore__WEBPACK_IMPORTED_MODULE_10__["EngineStore"].FallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
                    return;
                }
            }
            if (onError) {
                onError(message || "Unknown error", exception);
            }
        };
        // processing for non-image formats
        if (loader) {
            var callback = function (data) {
                loader.loadData(data, texture, function (width, height, loadMipmap, isCompressed, done, loadFailed) {
                    if (loadFailed) {
                        onInternalError("TextureLoader failed to load data");
                    }
                    else {
                        _this._prepareWebGLTexture(texture, scene, width, height, texture.invertY, !loadMipmap, isCompressed, function () {
                            done();
                            return false;
                        }, samplingMode);
                    }
                });
            };
            if (!buffer) {
                this._loadFile(url, callback, undefined, scene ? scene.offlineProvider : undefined, true, function (request, exception) {
                    onInternalError("Unable to load " + (request ? request.responseURL : url, exception));
                });
            }
            else {
                //callback(buffer as ArrayBuffer);
                if (buffer instanceof ArrayBuffer) {
                    callback(buffer);
                }
                else {
                    if (onError) {
                        onError("Unable to load: only ArrayBuffer supported here", null);
                    }
                }
            }
        }
        else {
            var onload = function (img) {
                if (fromBlob && !_this._doNotHandleContextLost) {
                    // We need to store the image if we need to rebuild the texture
                    // in case of a webgl context lost
                    texture._buffer = img;
                }
                _this._prepareWebGLTexture(texture, scene, img.width, img.height, texture.invertY, noMipmap, false, function (potWidth, potHeight, continuationCallback) {
                    var gl = _this._gl;
                    var isPot = (img.width === potWidth && img.height === potHeight);
                    var internalFormat = format ? _this._getInternalFormat(format) : ((extension === ".jpg") ? gl.RGB : gl.RGBA);
                    if (isPot) {
                        gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, internalFormat, gl.UNSIGNED_BYTE, img);
                        return false;
                    }
                    var maxTextureSize = _this._caps.maxTextureSize;
                    if (img.width > maxTextureSize || img.height > maxTextureSize || Engine._RescalePostProcessFactory === null) {
                        _this._prepareWorkingCanvas();
                        if (!_this._workingCanvas || !_this._workingContext) {
                            return false;
                        }
                        _this._workingCanvas.width = potWidth;
                        _this._workingCanvas.height = potHeight;
                        _this._workingContext.drawImage(img, 0, 0, img.width, img.height, 0, 0, potWidth, potHeight);
                        gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, internalFormat, gl.UNSIGNED_BYTE, _this._workingCanvas);
                        texture.width = potWidth;
                        texture.height = potHeight;
                        return false;
                    }
                    else {
                        // Using shaders when possible to rescale because canvas.drawImage is lossy
                        var source_1 = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"](_this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"].DATASOURCE_TEMP);
                        _this._bindTextureDirectly(gl.TEXTURE_2D, source_1, true);
                        gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, internalFormat, gl.UNSIGNED_BYTE, img);
                        _this._rescaleTexture(source_1, texture, scene, internalFormat, function () {
                            _this._releaseTexture(source_1);
                            _this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);
                            continuationCallback();
                        });
                    }
                    return true;
                }, samplingMode);
            };
            if (!fromData || isBase64) {
                if (buffer instanceof HTMLImageElement) {
                    onload(buffer);
                }
                else {
                    _Misc_fileTools__WEBPACK_IMPORTED_MODULE_17__["FileTools"].LoadImage(url, onload, onInternalError, scene ? scene.offlineProvider : null);
                }
            }
            else if (typeof buffer === "string" || buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer) || buffer instanceof Blob) {
                _Misc_fileTools__WEBPACK_IMPORTED_MODULE_17__["FileTools"].LoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null);
            }
            else {
                onload(buffer);
            }
        }
        return texture;
    };
    /**
     * @hidden
     * Rescales a texture
     * @param source input texutre
     * @param destination destination texture
     * @param scene scene to use to render the resize
     * @param internalFormat format to use when resizing
     * @param onComplete callback to be called when resize has completed
     */
    Engine.prototype._rescaleTexture = function (source, destination, scene, internalFormat, onComplete) {
        var _this = this;
        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, this._gl.LINEAR);
        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, this._gl.LINEAR);
        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._gl.CLAMP_TO_EDGE);
        this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._gl.CLAMP_TO_EDGE);
        var rtt = this.createRenderTargetTexture({
            width: destination.width,
            height: destination.height,
        }, {
            generateMipMaps: false,
            type: Engine.TEXTURETYPE_UNSIGNED_INT,
            samplingMode: Engine.TEXTURE_BILINEAR_SAMPLINGMODE,
            generateDepthBuffer: false,
            generateStencilBuffer: false
        });
        if (!this._rescalePostProcess && Engine._RescalePostProcessFactory) {
            this._rescalePostProcess = Engine._RescalePostProcessFactory(this);
        }
        this._rescalePostProcess.getEffect().executeWhenCompiled(function () {
            _this._rescalePostProcess.onApply = function (effect) {
                effect._bindTexture("textureSampler", source);
            };
            var hostingScene = scene;
            if (!hostingScene) {
                hostingScene = _this.scenes[_this.scenes.length - 1];
            }
            hostingScene.postProcessManager.directRender([_this._rescalePostProcess], rtt, true);
            _this._bindTextureDirectly(_this._gl.TEXTURE_2D, destination, true);
            _this._gl.copyTexImage2D(_this._gl.TEXTURE_2D, 0, internalFormat, 0, 0, destination.width, destination.height, 0);
            _this.unBindFramebuffer(rtt);
            _this._releaseTexture(rtt);
            if (onComplete) {
                onComplete();
            }
        });
    };
    /**
     * Creates a raw texture
     * @param data defines the data to store in the texture
     * @param width defines the width of the texture
     * @param height defines the height of the texture
     * @param format defines the format of the data
     * @param generateMipMaps defines if the engine should generate the mip levels
     * @param invertY defines if data must be stored with Y axis inverted
     * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
     * @param compression defines the compression used (null by default)
     * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
     * @returns the raw texture inside an InternalTexture
     */
    Engine.prototype.createRawTexture = function (data, width, height, format, generateMipMaps, invertY, samplingMode, compression, type) {
        if (compression === void 0) { compression = null; }
        if (type === void 0) { type = Engine.TEXTURETYPE_UNSIGNED_INT; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_12__["_DevTools"].WarnImport("Engine.RawTexture");
    };
    /** @hidden */
    Engine.prototype._unpackFlipY = function (value) {
        if (this._unpackFlipYCached !== value) {
            this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, value ? 1 : 0);
            if (this.enableUnpackFlipYCached) {
                this._unpackFlipYCached = value;
            }
        }
    };
    /** @hidden */
    Engine.prototype._getUnpackAlignement = function () {
        return this._gl.getParameter(this._gl.UNPACK_ALIGNMENT);
    };
    /**
     * Creates a dynamic texture
     * @param width defines the width of the texture
     * @param height defines the height of the texture
     * @param generateMipMaps defines if the engine should generate the mip levels
     * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
     * @returns the dynamic texture inside an InternalTexture
     */
    Engine.prototype.createDynamicTexture = function (width, height, generateMipMaps, samplingMode) {
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"].DATASOURCE_DYNAMIC);
        texture.baseWidth = width;
        texture.baseHeight = height;
        if (generateMipMaps) {
            width = this.needPOTTextures ? Engine.GetExponentOfTwo(width, this._caps.maxTextureSize) : width;
            height = this.needPOTTextures ? Engine.GetExponentOfTwo(height, this._caps.maxTextureSize) : height;
        }
        //  this.resetTextureCache();
        texture.width = width;
        texture.height = height;
        texture.isReady = false;
        texture.generateMipMaps = generateMipMaps;
        texture.samplingMode = samplingMode;
        this.updateTextureSamplingMode(samplingMode, texture);
        this._internalTexturesCache.push(texture);
        return texture;
    };
    /**
     * Update the sampling mode of a given texture
     * @param samplingMode defines the required sampling mode
     * @param texture defines the texture to update
     */
    Engine.prototype.updateTextureSamplingMode = function (samplingMode, texture) {
        var filters = this._getSamplingParameters(samplingMode, texture.generateMipMaps);
        if (texture.isCube) {
            this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);
            this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MIN_FILTER, filters.min);
            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
        }
        else if (texture.is3D) {
            this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);
            this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, filters.min);
            this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
        }
        else {
            this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag, texture);
            this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);
            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
        }
        texture.samplingMode = samplingMode;
    };
    /**
     * Update the content of a dynamic texture
     * @param texture defines the texture to update
     * @param canvas defines the canvas containing the source
     * @param invertY defines if data must be stored with Y axis inverted
     * @param premulAlpha defines if alpha is stored as premultiplied
     * @param format defines the format of the data
     * @param forceBindTexture if the texture should be forced to be bound eg. after a graphics context loss (Default: false)
     */
    Engine.prototype.updateDynamicTexture = function (texture, canvas, invertY, premulAlpha, format, forceBindTexture) {
        if (premulAlpha === void 0) { premulAlpha = false; }
        if (forceBindTexture === void 0) { forceBindTexture = false; }
        if (!texture) {
            return;
        }
        this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true, forceBindTexture);
        this._unpackFlipY(invertY);
        if (premulAlpha) {
            this._gl.pixelStorei(this._gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
        }
        var internalFormat = format ? this._getInternalFormat(format) : this._gl.RGBA;
        this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, internalFormat, this._gl.UNSIGNED_BYTE, canvas);
        if (texture.generateMipMaps) {
            this._gl.generateMipmap(this._gl.TEXTURE_2D);
        }
        this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
        if (premulAlpha) {
            this._gl.pixelStorei(this._gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
        }
        texture.isReady = true;
    };
    /**
     * Update a video texture
     * @param texture defines the texture to update
     * @param video defines the video element to use
     * @param invertY defines if data must be stored with Y axis inverted
     */
    Engine.prototype.updateVideoTexture = function (texture, video, invertY) {
        if (!texture || texture._isDisabled) {
            return;
        }
        var wasPreviouslyBound = this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
        this._unpackFlipY(!invertY); // Video are upside down by default
        try {
            // Testing video texture support
            if (this._videoTextureSupported === undefined) {
                this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
                if (this._gl.getError() !== 0) {
                    this._videoTextureSupported = false;
                }
                else {
                    this._videoTextureSupported = true;
                }
            }
            // Copy video through the current working canvas if video texture is not supported
            if (!this._videoTextureSupported) {
                if (!texture._workingCanvas) {
                    texture._workingCanvas = document.createElement("canvas");
                    var context = texture._workingCanvas.getContext("2d");
                    if (!context) {
                        throw new Error("Unable to get 2d context");
                    }
                    texture._workingContext = context;
                    texture._workingCanvas.width = texture.width;
                    texture._workingCanvas.height = texture.height;
                }
                texture._workingContext.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, texture.width, texture.height);
                this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, texture._workingCanvas);
            }
            else {
                this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
            }
            if (texture.generateMipMaps) {
                this._gl.generateMipmap(this._gl.TEXTURE_2D);
            }
            if (!wasPreviouslyBound) {
                this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
            }
            //    this.resetTextureCache();
            texture.isReady = true;
        }
        catch (ex) {
            // Something unexpected
            // Let's disable the texture
            texture._isDisabled = true;
        }
    };
    /**
     * Updates a depth texture Comparison Mode and Function.
     * If the comparison Function is equal to 0, the mode will be set to none.
     * Otherwise, this only works in webgl 2 and requires a shadow sampler in the shader.
     * @param texture The texture to set the comparison function for
     * @param comparisonFunction The comparison function to set, 0 if no comparison required
     */
    Engine.prototype.updateTextureComparisonFunction = function (texture, comparisonFunction) {
        if (this.webGLVersion === 1) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Error("WebGL 1 does not support texture comparison.");
            return;
        }
        var gl = this._gl;
        if (texture.isCube) {
            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);
            if (comparisonFunction === 0) {
                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, Engine.LEQUAL);
                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.NONE);
            }
            else {
                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);
                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
            }
            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
        }
        else {
            this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
            if (comparisonFunction === 0) {
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, Engine.LEQUAL);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.NONE);
            }
            else {
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
            }
            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
        }
        texture._comparisonFunction = comparisonFunction;
    };
    /** @hidden */
    Engine.prototype._setupDepthStencilTexture = function (internalTexture, size, generateStencil, bilinearFiltering, comparisonFunction) {
        var width = size.width || size;
        var height = size.height || size;
        internalTexture.baseWidth = width;
        internalTexture.baseHeight = height;
        internalTexture.width = width;
        internalTexture.height = height;
        internalTexture.isReady = true;
        internalTexture.samples = 1;
        internalTexture.generateMipMaps = false;
        internalTexture._generateDepthBuffer = true;
        internalTexture._generateStencilBuffer = generateStencil;
        internalTexture.samplingMode = bilinearFiltering ? Engine.TEXTURE_BILINEAR_SAMPLINGMODE : Engine.TEXTURE_NEAREST_SAMPLINGMODE;
        internalTexture.type = Engine.TEXTURETYPE_UNSIGNED_INT;
        internalTexture._comparisonFunction = comparisonFunction;
        var gl = this._gl;
        var target = internalTexture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;
        var samplingParameters = this._getSamplingParameters(internalTexture.samplingMode, false);
        gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, samplingParameters.mag);
        gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, samplingParameters.min);
        gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        if (comparisonFunction === 0) {
            gl.texParameteri(target, gl.TEXTURE_COMPARE_FUNC, Engine.LEQUAL);
            gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.NONE);
        }
        else {
            gl.texParameteri(target, gl.TEXTURE_COMPARE_FUNC, comparisonFunction);
            gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
        }
    };
    /**
     * Creates a depth stencil texture.
     * This is only available in WebGL 2 or with the depth texture extension available.
     * @param size The size of face edge in the texture.
     * @param options The options defining the texture.
     * @returns The texture
     */
    Engine.prototype.createDepthStencilTexture = function (size, options) {
        if (options.isCube) {
            var width = size.width || size;
            return this._createDepthStencilCubeTexture(width, options);
        }
        else {
            return this._createDepthStencilTexture(size, options);
        }
    };
    /**
     * Creates a depth stencil texture.
     * This is only available in WebGL 2 or with the depth texture extension available.
     * @param size The size of face edge in the texture.
     * @param options The options defining the texture.
     * @returns The texture
     */
    Engine.prototype._createDepthStencilTexture = function (size, options) {
        var internalTexture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"].DATASOURCE_DEPTHTEXTURE);
        if (!this._caps.depthTextureExtension) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Error("Depth texture is not supported by your browser or hardware.");
            return internalTexture;
        }
        var internalOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ bilinearFiltering: false, comparisonFunction: 0, generateStencil: false }, options);
        var gl = this._gl;
        this._bindTextureDirectly(gl.TEXTURE_2D, internalTexture, true);
        this._setupDepthStencilTexture(internalTexture, size, internalOptions.generateStencil, internalOptions.bilinearFiltering, internalOptions.comparisonFunction);
        if (this.webGLVersion > 1) {
            if (internalOptions.generateStencil) {
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH24_STENCIL8, internalTexture.width, internalTexture.height, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
            }
            else {
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT24, internalTexture.width, internalTexture.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
            }
        }
        else {
            if (internalOptions.generateStencil) {
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_STENCIL, internalTexture.width, internalTexture.height, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null);
            }
            else {
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, internalTexture.width, internalTexture.height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, null);
            }
        }
        this._bindTextureDirectly(gl.TEXTURE_2D, null);
        return internalTexture;
    };
    /**
     * Sets the frame buffer Depth / Stencil attachement of the render target to the defined depth stencil texture.
     * @param renderTarget The render target to set the frame buffer for
     */
    Engine.prototype.setFrameBufferDepthStencilTexture = function (renderTarget) {
        // Create the framebuffer
        var internalTexture = renderTarget.getInternalTexture();
        if (!internalTexture || !internalTexture._framebuffer || !renderTarget.depthStencilTexture) {
            return;
        }
        var gl = this._gl;
        var depthStencilTexture = renderTarget.depthStencilTexture;
        this._bindUnboundFramebuffer(internalTexture._framebuffer);
        if (depthStencilTexture.isCube) {
            if (depthStencilTexture._generateStencilBuffer) {
                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X, depthStencilTexture._webGLTexture, 0);
            }
            else {
                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_CUBE_MAP_POSITIVE_X, depthStencilTexture._webGLTexture, 0);
            }
        }
        else {
            if (depthStencilTexture._generateStencilBuffer) {
                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTexture._webGLTexture, 0);
            }
            else {
                gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTexture._webGLTexture, 0);
            }
        }
        this._bindUnboundFramebuffer(null);
    };
    /**
     * Creates a new render target texture
     * @param size defines the size of the texture
     * @param options defines the options used to create the texture
     * @returns a new render target texture stored in an InternalTexture
     */
    Engine.prototype.createRenderTargetTexture = function (size, options) {
        var fullOptions = new _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_11__["RenderTargetCreationOptions"]();
        if (options !== undefined && typeof options === "object") {
            fullOptions.generateMipMaps = options.generateMipMaps;
            fullOptions.generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
            fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && options.generateStencilBuffer;
            fullOptions.type = options.type === undefined ? Engine.TEXTURETYPE_UNSIGNED_INT : options.type;
            fullOptions.samplingMode = options.samplingMode === undefined ? Engine.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;
            fullOptions.format = options.format === undefined ? Engine.TEXTUREFORMAT_RGBA : options.format;
        }
        else {
            fullOptions.generateMipMaps = options;
            fullOptions.generateDepthBuffer = true;
            fullOptions.generateStencilBuffer = false;
            fullOptions.type = Engine.TEXTURETYPE_UNSIGNED_INT;
            fullOptions.samplingMode = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE;
            fullOptions.format = Engine.TEXTUREFORMAT_RGBA;
        }
        if (fullOptions.type === Engine.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) {
            // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE
            fullOptions.samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
        }
        else if (fullOptions.type === Engine.TEXTURETYPE_HALF_FLOAT && !this._caps.textureHalfFloatLinearFiltering) {
            // if floating point linear (HALF_FLOAT) then force to NEAREST_SAMPLINGMODE
            fullOptions.samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
        }
        var gl = this._gl;
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_5__["InternalTexture"].DATASOURCE_RENDERTARGET);
        this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);
        var width = size.width || size;
        var height = size.height || size;
        var filters = this._getSamplingParameters(fullOptions.samplingMode, fullOptions.generateMipMaps ? true : false);
        if (fullOptions.type === Engine.TEXTURETYPE_FLOAT && !this._caps.textureFloat) {
            fullOptions.type = Engine.TEXTURETYPE_UNSIGNED_INT;
            _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Warn("Float textures are not supported. Render target forced to TEXTURETYPE_UNSIGNED_BYTE type");
        }
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filters.mag);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filters.min);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texImage2D(gl.TEXTURE_2D, 0, this._getRGBABufferInternalSizedFormat(fullOptions.type, fullOptions.format), width, height, 0, this._getInternalFormat(fullOptions.format), this._getWebGLTextureType(fullOptions.type), null);
        // Create the framebuffer
        var currentFrameBuffer = this._currentFramebuffer;
        var framebuffer = gl.createFramebuffer();
        this._bindUnboundFramebuffer(framebuffer);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._webGLTexture, 0);
        texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(fullOptions.generateStencilBuffer ? true : false, fullOptions.generateDepthBuffer, width, height);
        if (fullOptions.generateMipMaps) {
            this._gl.generateMipmap(this._gl.TEXTURE_2D);
        }
        // Unbind
        this._bindTextureDirectly(gl.TEXTURE_2D, null);
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        this._bindUnboundFramebuffer(currentFrameBuffer);
        texture._framebuffer = framebuffer;
        texture.baseWidth = width;
        texture.baseHeight = height;
        texture.width = width;
        texture.height = height;
        texture.isReady = true;
        texture.samples = 1;
        texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;
        texture.samplingMode = fullOptions.samplingMode;
        texture.type = fullOptions.type;
        texture.format = fullOptions.format;
        texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
        texture._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;
        // this.resetTextureCache();
        this._internalTexturesCache.push(texture);
        return texture;
    };
    /** @hidden */
    Engine.prototype._setupFramebufferDepthAttachments = function (generateStencilBuffer, generateDepthBuffer, width, height, samples) {
        if (samples === void 0) { samples = 1; }
        var depthStencilBuffer = null;
        var gl = this._gl;
        // Create the depth/stencil buffer
        if (generateStencilBuffer) {
            depthStencilBuffer = gl.createRenderbuffer();
            gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
            if (samples > 1) {
                gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.DEPTH24_STENCIL8, width, height);
            }
            else {
                gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
            }
            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
        }
        else if (generateDepthBuffer) {
            depthStencilBuffer = gl.createRenderbuffer();
            gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
            if (samples > 1) {
                gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.DEPTH_COMPONENT16, width, height);
            }
            else {
                gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
            }
            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
        }
        return depthStencilBuffer;
    };
    /**
     * Updates the sample count of a render target texture
     * @see http://doc.babylonjs.com/features/webgl2#multisample-render-targets
     * @param texture defines the texture to update
     * @param samples defines the sample count to set
     * @returns the effective sample count (could be 0 if multisample render targets are not supported)
     */
    Engine.prototype.updateRenderTargetTextureSampleCount = function (texture, samples) {
        if (this.webGLVersion < 2 || !texture) {
            return 1;
        }
        if (texture.samples === samples) {
            return samples;
        }
        var gl = this._gl;
        samples = Math.min(samples, this.getCaps().maxMSAASamples);
        // Dispose previous render buffers
        if (texture._depthStencilBuffer) {
            gl.deleteRenderbuffer(texture._depthStencilBuffer);
            texture._depthStencilBuffer = null;
        }
        if (texture._MSAAFramebuffer) {
            gl.deleteFramebuffer(texture._MSAAFramebuffer);
            texture._MSAAFramebuffer = null;
        }
        if (texture._MSAARenderBuffer) {
            gl.deleteRenderbuffer(texture._MSAARenderBuffer);
            texture._MSAARenderBuffer = null;
        }
        if (samples > 1) {
            var framebuffer = gl.createFramebuffer();
            if (!framebuffer) {
                throw new Error("Unable to create multi sampled framebuffer");
            }
            texture._MSAAFramebuffer = framebuffer;
            this._bindUnboundFramebuffer(texture._MSAAFramebuffer);
            var colorRenderbuffer = gl.createRenderbuffer();
            if (!colorRenderbuffer) {
                throw new Error("Unable to create multi sampled framebuffer");
            }
            gl.bindRenderbuffer(gl.RENDERBUFFER, colorRenderbuffer);
            gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, this._getRGBAMultiSampleBufferFormat(texture.type), texture.width, texture.height);
            gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRenderbuffer);
            texture._MSAARenderBuffer = colorRenderbuffer;
        }
        else {
            this._bindUnboundFramebuffer(texture._framebuffer);
        }
        texture.samples = samples;
        texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(texture._generateStencilBuffer, texture._generateDepthBuffer, texture.width, texture.height, samples);
        gl.bindRenderbuffer(gl.RENDERBUFFER, null);
        this._bindUnboundFramebuffer(null);
        return samples;
    };
    /** @hidden */
    Engine.prototype._uploadCompressedDataToTextureDirectly = function (texture, internalFormat, width, height, data, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        var gl = this._gl;
        var target = gl.TEXTURE_2D;
        if (texture.isCube) {
            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;
        }
        this._gl.compressedTexImage2D(target, lod, internalFormat, width, height, 0, data);
    };
    /** @hidden */
    Engine.prototype._uploadDataToTextureDirectly = function (texture, imageData, faceIndex, lod, babylonInternalFormat, useTextureWidthAndHeight) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        if (useTextureWidthAndHeight === void 0) { useTextureWidthAndHeight = false; }
        var gl = this._gl;
        var textureType = this._getWebGLTextureType(texture.type);
        var format = this._getInternalFormat(texture.format);
        var internalFormat = babylonInternalFormat === undefined ? this._getRGBABufferInternalSizedFormat(texture.type, format) : this._getInternalFormat(babylonInternalFormat);
        this._unpackFlipY(texture.invertY);
        var target = gl.TEXTURE_2D;
        if (texture.isCube) {
            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;
        }
        var lodMaxWidth = Math.round(Math.log(texture.width) * Math.LOG2E);
        var lodMaxHeight = Math.round(Math.log(texture.height) * Math.LOG2E);
        var width = useTextureWidthAndHeight ? texture.width : Math.pow(2, Math.max(lodMaxWidth - lod, 0));
        var height = useTextureWidthAndHeight ? texture.height : Math.pow(2, Math.max(lodMaxHeight - lod, 0));
        gl.texImage2D(target, lod, internalFormat, width, height, 0, format, textureType, imageData);
    };
    /** @hidden */
    Engine.prototype._uploadArrayBufferViewToTexture = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        var gl = this._gl;
        var bindTarget = texture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;
        this._bindTextureDirectly(bindTarget, texture, true);
        this._uploadDataToTextureDirectly(texture, imageData, faceIndex, lod);
        this._bindTextureDirectly(bindTarget, null, true);
    };
    /** @hidden */
    Engine.prototype._uploadImageToTexture = function (texture, image, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        var gl = this._gl;
        var textureType = this._getWebGLTextureType(texture.type);
        var format = this._getInternalFormat(texture.format);
        var internalFormat = this._getRGBABufferInternalSizedFormat(texture.type, format);
        var bindTarget = texture.isCube ? gl.TEXTURE_CUBE_MAP : gl.TEXTURE_2D;
        this._bindTextureDirectly(bindTarget, texture, true);
        this._unpackFlipY(texture.invertY);
        var target = gl.TEXTURE_2D;
        if (texture.isCube) {
            target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;
        }
        gl.texImage2D(target, lod, internalFormat, format, textureType, image);
        this._bindTextureDirectly(bindTarget, null, true);
    };
    /**
     * @hidden
     */
    Engine.prototype._setCubeMapTextureParams = function (loadMipmap) {
        var gl = this._gl;
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, loadMipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
    };
    /**
     * Creates a new raw cube texture
     * @param data defines the array of data to use to create each face
     * @param size defines the size of the textures
     * @param format defines the format of the data
     * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
     * @param generateMipMaps  defines if the engine should generate the mip levels
     * @param invertY defines if data must be stored with Y axis inverted
     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
     * @param compression defines the compression used (null by default)
     * @returns the cube texture as an InternalTexture
     */
    Engine.prototype.createRawCubeTexture = function (data, size, format, type, generateMipMaps, invertY, samplingMode, compression) {
        if (compression === void 0) { compression = null; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_12__["_DevTools"].WarnImport("Engine.RawTexture");
    };
    /**
     * Creates a new raw 3D texture
     * @param data defines the data used to create the texture
     * @param width defines the width of the texture
     * @param height defines the height of the texture
     * @param depth defines the depth of the texture
     * @param format defines the format of the texture
     * @param generateMipMaps defines if the engine must generate mip levels
     * @param invertY defines if data must be stored with Y axis inverted
     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
     * @param compression defines the compressed used (can be null)
     * @param textureType defines the compressed used (can be null)
     * @returns a new raw 3D texture (stored in an InternalTexture)
     */
    Engine.prototype.createRawTexture3D = function (data, width, height, depth, format, generateMipMaps, invertY, samplingMode, compression, textureType) {
        if (compression === void 0) { compression = null; }
        if (textureType === void 0) { textureType = Engine.TEXTURETYPE_UNSIGNED_INT; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_12__["_DevTools"].WarnImport("Engine.RawTexture");
    };
    Engine.prototype._prepareWebGLTextureContinuation = function (texture, scene, noMipmap, isCompressed, samplingMode) {
        var gl = this._gl;
        if (!gl) {
            return;
        }
        var filters = this._getSamplingParameters(samplingMode, !noMipmap);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filters.mag);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filters.min);
        if (!noMipmap && !isCompressed) {
            gl.generateMipmap(gl.TEXTURE_2D);
        }
        this._bindTextureDirectly(gl.TEXTURE_2D, null);
        // this.resetTextureCache();
        if (scene) {
            scene._removePendingData(texture);
        }
        texture.onLoadedObservable.notifyObservers(texture);
        texture.onLoadedObservable.clear();
    };
    Engine.prototype._prepareWebGLTexture = function (texture, scene, width, height, invertY, noMipmap, isCompressed, processFunction, samplingMode) {
        var _this = this;
        if (samplingMode === void 0) { samplingMode = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE; }
        var maxTextureSize = this.getCaps().maxTextureSize;
        var potWidth = Math.min(maxTextureSize, this.needPOTTextures ? Engine.GetExponentOfTwo(width, maxTextureSize) : width);
        var potHeight = Math.min(maxTextureSize, this.needPOTTextures ? Engine.GetExponentOfTwo(height, maxTextureSize) : height);
        var gl = this._gl;
        if (!gl) {
            return;
        }
        if (!texture._webGLTexture) {
            //  this.resetTextureCache();
            if (scene) {
                scene._removePendingData(texture);
            }
            return;
        }
        this._bindTextureDirectly(gl.TEXTURE_2D, texture, true);
        this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
        texture.baseWidth = width;
        texture.baseHeight = height;
        texture.width = potWidth;
        texture.height = potHeight;
        texture.isReady = true;
        if (processFunction(potWidth, potHeight, function () {
            _this._prepareWebGLTextureContinuation(texture, scene, noMipmap, isCompressed, samplingMode);
        })) {
            // Returning as texture needs extra async steps
            return;
        }
        this._prepareWebGLTextureContinuation(texture, scene, noMipmap, isCompressed, samplingMode);
    };
    /** @hidden */
    Engine.prototype._convertRGBtoRGBATextureData = function (rgbData, width, height, textureType) {
        // Create new RGBA data container.
        var rgbaData;
        if (textureType === Engine.TEXTURETYPE_FLOAT) {
            rgbaData = new Float32Array(width * height * 4);
        }
        else {
            rgbaData = new Uint32Array(width * height * 4);
        }
        // Convert each pixel.
        for (var x = 0; x < width; x++) {
            for (var y = 0; y < height; y++) {
                var index = (y * width + x) * 3;
                var newIndex = (y * width + x) * 4;
                // Map Old Value to new value.
                rgbaData[newIndex + 0] = rgbData[index + 0];
                rgbaData[newIndex + 1] = rgbData[index + 1];
                rgbaData[newIndex + 2] = rgbData[index + 2];
                // Add fully opaque alpha channel.
                rgbaData[newIndex + 3] = 1;
            }
        }
        return rgbaData;
    };
    /** @hidden */
    Engine.prototype._releaseFramebufferObjects = function (texture) {
        var gl = this._gl;
        if (texture._framebuffer) {
            gl.deleteFramebuffer(texture._framebuffer);
            texture._framebuffer = null;
        }
        if (texture._depthStencilBuffer) {
            gl.deleteRenderbuffer(texture._depthStencilBuffer);
            texture._depthStencilBuffer = null;
        }
        if (texture._MSAAFramebuffer) {
            gl.deleteFramebuffer(texture._MSAAFramebuffer);
            texture._MSAAFramebuffer = null;
        }
        if (texture._MSAARenderBuffer) {
            gl.deleteRenderbuffer(texture._MSAARenderBuffer);
            texture._MSAARenderBuffer = null;
        }
    };
    /** @hidden */
    Engine.prototype._releaseTexture = function (texture) {
        this._releaseFramebufferObjects(texture);
        this._deleteTexture(texture._webGLTexture);
        // Unbind channels
        this.unbindAllTextures();
        var index = this._internalTexturesCache.indexOf(texture);
        if (index !== -1) {
            this._internalTexturesCache.splice(index, 1);
        }
        // Integrated fixed lod samplers.
        if (texture._lodTextureHigh) {
            texture._lodTextureHigh.dispose();
        }
        if (texture._lodTextureMid) {
            texture._lodTextureMid.dispose();
        }
        if (texture._lodTextureLow) {
            texture._lodTextureLow.dispose();
        }
        // Integrated irradiance map.
        if (texture._irradianceTexture) {
            texture._irradianceTexture.dispose();
        }
        // Set output texture of post process to null if the texture has been released/disposed
        this.scenes.forEach(function (scene) {
            scene.postProcesses.forEach(function (postProcess) {
                if (postProcess._outputTexture == texture) {
                    postProcess._outputTexture = null;
                }
            });
            scene.cameras.forEach(function (camera) {
                camera._postProcesses.forEach(function (postProcess) {
                    if (postProcess) {
                        if (postProcess._outputTexture == texture) {
                            postProcess._outputTexture = null;
                        }
                    }
                });
            });
        });
    };
    Engine.prototype._deleteTexture = function (texture) {
        this._gl.deleteTexture(texture);
    };
    Engine.prototype._setProgram = function (program) {
        if (this._currentProgram !== program) {
            this._gl.useProgram(program);
            this._currentProgram = program;
        }
    };
    /**
     * Binds an effect to the webGL context
     * @param effect defines the effect to bind
     */
    Engine.prototype.bindSamplers = function (effect) {
        var webGLPipelineContext = effect.getPipelineContext();
        this._setProgram(webGLPipelineContext.program);
        var samplers = effect.getSamplers();
        for (var index = 0; index < samplers.length; index++) {
            var uniform = effect.getUniform(samplers[index]);
            if (uniform) {
                this._boundUniforms[index] = uniform;
            }
        }
        this._currentEffect = null;
    };
    Engine.prototype._activateCurrentTexture = function () {
        if (this._currentTextureChannel !== this._activeChannel) {
            this._gl.activeTexture(this._gl.TEXTURE0 + this._activeChannel);
            this._currentTextureChannel = this._activeChannel;
        }
    };
    /** @hidden */
    Engine.prototype._bindTextureDirectly = function (target, texture, forTextureDataUpdate, force) {
        if (forTextureDataUpdate === void 0) { forTextureDataUpdate = false; }
        if (force === void 0) { force = false; }
        var wasPreviouslyBound = false;
        var isTextureForRendering = texture && texture._associatedChannel > -1;
        if (forTextureDataUpdate && isTextureForRendering) {
            this._activeChannel = texture._associatedChannel;
        }
        var currentTextureBound = this._boundTexturesCache[this._activeChannel];
        if (currentTextureBound !== texture || force) {
            this._activateCurrentTexture();
            if (texture && texture.isMultiview) {
                this._gl.bindTexture(target, texture ? texture._colorTextureArray : null);
            }
            else {
                this._gl.bindTexture(target, texture ? texture._webGLTexture : null);
            }
            this._boundTexturesCache[this._activeChannel] = texture;
            if (texture) {
                texture._associatedChannel = this._activeChannel;
            }
        }
        else if (forTextureDataUpdate) {
            wasPreviouslyBound = true;
            this._activateCurrentTexture();
        }
        if (isTextureForRendering && !forTextureDataUpdate) {
            this._bindSamplerUniformToChannel(texture._associatedChannel, this._activeChannel);
        }
        return wasPreviouslyBound;
    };
    /** @hidden */
    Engine.prototype._bindTexture = function (channel, texture) {
        if (channel === undefined) {
            return;
        }
        if (texture) {
            texture._associatedChannel = channel;
        }
        this._activeChannel = channel;
        this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
    };
    /**
     * Sets a texture to the webGL context from a postprocess
     * @param channel defines the channel to use
     * @param postProcess defines the source postprocess
     */
    Engine.prototype.setTextureFromPostProcess = function (channel, postProcess) {
        this._bindTexture(channel, postProcess ? postProcess._textures.data[postProcess._currentRenderTextureInd] : null);
    };
    /**
     * Binds the output of the passed in post process to the texture channel specified
     * @param channel The channel the texture should be bound to
     * @param postProcess The post process which's output should be bound
     */
    Engine.prototype.setTextureFromPostProcessOutput = function (channel, postProcess) {
        this._bindTexture(channel, postProcess ? postProcess._outputTexture : null);
    };
    /**
     * Unbind all textures from the webGL context
     */
    Engine.prototype.unbindAllTextures = function () {
        for (var channel = 0; channel < this._maxSimultaneousTextures; channel++) {
            this._activeChannel = channel;
            this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
            this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
            if (this.webGLVersion > 1) {
                this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
            }
        }
    };
    /**
     * Sets a texture to the according uniform.
     * @param channel The texture channel
     * @param uniform The uniform to set
     * @param texture The texture to apply
     * @param name The name of the uniform in the effect
     */
    Engine.prototype.setTexture = function (channel, uniform, texture, name) {
        if (channel === undefined) {
            return;
        }
        if (uniform) {
            this._boundUniforms[channel] = uniform;
        }
        this._setTexture(channel, texture);
    };
    /**
     * Sets a depth stencil texture from a render target to the according uniform.
     * @param channel The texture channel
     * @param uniform The uniform to set
     * @param texture The render target texture containing the depth stencil texture to apply
     */
    Engine.prototype.setDepthStencilTexture = function (channel, uniform, texture) {
        if (channel === undefined) {
            return;
        }
        if (uniform) {
            this._boundUniforms[channel] = uniform;
        }
        if (!texture || !texture.depthStencilTexture) {
            this._setTexture(channel, null);
        }
        else {
            this._setTexture(channel, texture, false, true);
        }
    };
    Engine.prototype._bindSamplerUniformToChannel = function (sourceSlot, destination) {
        var uniform = this._boundUniforms[sourceSlot];
        if (!uniform || uniform._currentState === destination) {
            return;
        }
        this._gl.uniform1i(uniform, destination);
        uniform._currentState = destination;
    };
    Engine.prototype._getTextureWrapMode = function (mode) {
        switch (mode) {
            case Engine.TEXTURE_WRAP_ADDRESSMODE:
                return this._gl.REPEAT;
            case Engine.TEXTURE_CLAMP_ADDRESSMODE:
                return this._gl.CLAMP_TO_EDGE;
            case Engine.TEXTURE_MIRROR_ADDRESSMODE:
                return this._gl.MIRRORED_REPEAT;
        }
        return this._gl.REPEAT;
    };
    Engine.prototype._setTexture = function (channel, texture, isPartOfTextureArray, depthStencilTexture) {
        if (isPartOfTextureArray === void 0) { isPartOfTextureArray = false; }
        if (depthStencilTexture === void 0) { depthStencilTexture = false; }
        // Not ready?
        if (!texture) {
            if (this._boundTexturesCache[channel] != null) {
                this._activeChannel = channel;
                this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
                this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
                if (this.webGLVersion > 1) {
                    this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
                }
            }
            return false;
        }
        // Video
        if (texture.video) {
            this._activeChannel = channel;
            texture.update();
        }
        else if (texture.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) { // Delay loading
            texture.delayLoad();
            return false;
        }
        var internalTexture;
        if (depthStencilTexture) {
            internalTexture = texture.depthStencilTexture;
        }
        else if (texture.isReady()) {
            internalTexture = texture.getInternalTexture();
        }
        else if (texture.isCube) {
            internalTexture = this.emptyCubeTexture;
        }
        else if (texture.is3D) {
            internalTexture = this.emptyTexture3D;
        }
        else {
            internalTexture = this.emptyTexture;
        }
        if (!isPartOfTextureArray && internalTexture) {
            internalTexture._associatedChannel = channel;
        }
        var needToBind = true;
        if (this._boundTexturesCache[channel] === internalTexture) {
            if (!isPartOfTextureArray) {
                this._bindSamplerUniformToChannel(internalTexture._associatedChannel, channel);
            }
            needToBind = false;
        }
        this._activeChannel = channel;
        if (internalTexture && internalTexture.isMultiview) {
            if (needToBind) {
                this._bindTextureDirectly(this._gl.TEXTURE_2D_ARRAY, internalTexture, isPartOfTextureArray);
            }
        }
        else if (internalTexture && internalTexture.is3D) {
            if (needToBind) {
                this._bindTextureDirectly(this._gl.TEXTURE_3D, internalTexture, isPartOfTextureArray);
            }
            if (internalTexture && internalTexture._cachedWrapU !== texture.wrapU) {
                internalTexture._cachedWrapU = texture.wrapU;
                this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_S, this._getTextureWrapMode(texture.wrapU), internalTexture);
            }
            if (internalTexture && internalTexture._cachedWrapV !== texture.wrapV) {
                internalTexture._cachedWrapV = texture.wrapV;
                this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_T, this._getTextureWrapMode(texture.wrapV), internalTexture);
            }
            if (internalTexture && internalTexture._cachedWrapR !== texture.wrapR) {
                internalTexture._cachedWrapR = texture.wrapR;
                this._setTextureParameterInteger(this._gl.TEXTURE_3D, this._gl.TEXTURE_WRAP_R, this._getTextureWrapMode(texture.wrapR), internalTexture);
            }
            this._setAnisotropicLevel(this._gl.TEXTURE_3D, texture);
        }
        else if (internalTexture && internalTexture.isCube) {
            if (needToBind) {
                this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, internalTexture, isPartOfTextureArray);
            }
            if (internalTexture._cachedCoordinatesMode !== texture.coordinatesMode) {
                internalTexture._cachedCoordinatesMode = texture.coordinatesMode;
                // CUBIC_MODE and SKYBOX_MODE both require CLAMP_TO_EDGE.  All other modes use REPEAT.
                var textureWrapMode = (texture.coordinatesMode !== Engine.TEXTURE_CUBIC_MODE && texture.coordinatesMode !== Engine.TEXTURE_SKYBOX_MODE) ? this._gl.REPEAT : this._gl.CLAMP_TO_EDGE;
                this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_WRAP_S, textureWrapMode, internalTexture);
                this._setTextureParameterInteger(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_WRAP_T, textureWrapMode);
            }
            this._setAnisotropicLevel(this._gl.TEXTURE_CUBE_MAP, texture);
        }
        else {
            if (needToBind) {
                this._bindTextureDirectly(this._gl.TEXTURE_2D, internalTexture, isPartOfTextureArray);
            }
            if (internalTexture && internalTexture._cachedWrapU !== texture.wrapU) {
                internalTexture._cachedWrapU = texture.wrapU;
                this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_S, this._getTextureWrapMode(texture.wrapU), internalTexture);
            }
            if (internalTexture && internalTexture._cachedWrapV !== texture.wrapV) {
                internalTexture._cachedWrapV = texture.wrapV;
                this._setTextureParameterInteger(this._gl.TEXTURE_2D, this._gl.TEXTURE_WRAP_T, this._getTextureWrapMode(texture.wrapV), internalTexture);
            }
            this._setAnisotropicLevel(this._gl.TEXTURE_2D, texture);
        }
        return true;
    };
    /**
     * Sets an array of texture to the webGL context
     * @param channel defines the channel where the texture array must be set
     * @param uniform defines the associated uniform location
     * @param textures defines the array of textures to bind
     */
    Engine.prototype.setTextureArray = function (channel, uniform, textures) {
        if (channel === undefined || !uniform) {
            return;
        }
        if (!this._textureUnits || this._textureUnits.length !== textures.length) {
            this._textureUnits = new Int32Array(textures.length);
        }
        for (var i = 0; i < textures.length; i++) {
            var texture = textures[i].getInternalTexture();
            if (texture) {
                this._textureUnits[i] = channel + i;
                texture._associatedChannel = channel + i;
            }
            else {
                this._textureUnits[i] = -1;
            }
        }
        this._gl.uniform1iv(uniform, this._textureUnits);
        for (var index = 0; index < textures.length; index++) {
            this._setTexture(this._textureUnits[index], textures[index], true);
        }
    };
    /** @hidden */
    Engine.prototype._setAnisotropicLevel = function (target, texture) {
        var internalTexture = texture.getInternalTexture();
        if (!internalTexture) {
            return;
        }
        var anisotropicFilterExtension = this._caps.textureAnisotropicFilterExtension;
        var value = texture.anisotropicFilteringLevel;
        if (internalTexture.samplingMode !== Engine.TEXTURE_LINEAR_LINEAR_MIPNEAREST
            && internalTexture.samplingMode !== Engine.TEXTURE_LINEAR_LINEAR_MIPLINEAR
            && internalTexture.samplingMode !== Engine.TEXTURE_LINEAR_LINEAR) {
            value = 1; // Forcing the anisotropic to 1 because else webgl will force filters to linear
        }
        if (anisotropicFilterExtension && internalTexture._cachedAnisotropicFilteringLevel !== value) {
            this._setTextureParameterFloat(target, anisotropicFilterExtension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(value, this._caps.maxAnisotropy), internalTexture);
            internalTexture._cachedAnisotropicFilteringLevel = value;
        }
    };
    Engine.prototype._setTextureParameterFloat = function (target, parameter, value, texture) {
        this._bindTextureDirectly(target, texture, true, true);
        this._gl.texParameterf(target, parameter, value);
    };
    Engine.prototype._setTextureParameterInteger = function (target, parameter, value, texture) {
        if (texture) {
            this._bindTextureDirectly(target, texture, true, true);
        }
        this._gl.texParameteri(target, parameter, value);
    };
    /**
     * Reads pixels from the current frame buffer. Please note that this function can be slow
     * @param x defines the x coordinate of the rectangle where pixels must be read
     * @param y defines the y coordinate of the rectangle where pixels must be read
     * @param width defines the width of the rectangle where pixels must be read
     * @param height defines the height of the rectangle where pixels must be read
     * @returns a Uint8Array containing RGBA colors
     */
    Engine.prototype.readPixels = function (x, y, width, height) {
        var data = new Uint8Array(height * width * 4);
        this._gl.readPixels(x, y, width, height, this._gl.RGBA, this._gl.UNSIGNED_BYTE, data);
        return data;
    };
    /**
     * Add an externaly attached data from its key.
     * This method call will fail and return false, if such key already exists.
     * If you don't care and just want to get the data no matter what, use the more convenient getOrAddExternalDataWithFactory() method.
     * @param key the unique key that identifies the data
     * @param data the data object to associate to the key for this Engine instance
     * @return true if no such key were already present and the data was added successfully, false otherwise
     */
    Engine.prototype.addExternalData = function (key, data) {
        if (!this._externalData) {
            this._externalData = new _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_3__["StringDictionary"]();
        }
        return this._externalData.add(key, data);
    };
    /**
     * Get an externaly attached data from its key
     * @param key the unique key that identifies the data
     * @return the associated data, if present (can be null), or undefined if not present
     */
    Engine.prototype.getExternalData = function (key) {
        if (!this._externalData) {
            this._externalData = new _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_3__["StringDictionary"]();
        }
        return this._externalData.get(key);
    };
    /**
     * Get an externaly attached data from its key, create it using a factory if it's not already present
     * @param key the unique key that identifies the data
     * @param factory the factory that will be called to create the instance if and only if it doesn't exists
     * @return the associated data, can be null if the factory returned null.
     */
    Engine.prototype.getOrAddExternalDataWithFactory = function (key, factory) {
        if (!this._externalData) {
            this._externalData = new _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_3__["StringDictionary"]();
        }
        return this._externalData.getOrAddWithFactory(key, factory);
    };
    /**
     * Remove an externaly attached data from the Engine instance
     * @param key the unique key that identifies the data
     * @return true if the data was successfully removed, false if it doesn't exist
     */
    Engine.prototype.removeExternalData = function (key) {
        if (!this._externalData) {
            this._externalData = new _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_3__["StringDictionary"]();
        }
        return this._externalData.remove(key);
    };
    /**
     * Unbind all vertex attributes from the webGL context
     */
    Engine.prototype.unbindAllAttributes = function () {
        if (this._mustWipeVertexAttributes) {
            this._mustWipeVertexAttributes = false;
            for (var i = 0; i < this._caps.maxVertexAttribs; i++) {
                this._gl.disableVertexAttribArray(i);
                this._vertexAttribArraysEnabled[i] = false;
                this._currentBufferPointers[i].active = false;
            }
            return;
        }
        for (var i = 0, ul = this._vertexAttribArraysEnabled.length; i < ul; i++) {
            if (i >= this._caps.maxVertexAttribs || !this._vertexAttribArraysEnabled[i]) {
                continue;
            }
            this._gl.disableVertexAttribArray(i);
            this._vertexAttribArraysEnabled[i] = false;
            this._currentBufferPointers[i].active = false;
        }
    };
    /**
     * Force the engine to release all cached effects. This means that next effect compilation will have to be done completely even if a similar effect was already compiled
     */
    Engine.prototype.releaseEffects = function () {
        for (var name in this._compiledEffects) {
            var webGLPipelineContext = this._compiledEffects[name].getPipelineContext();
            this._deletePipelineContext(webGLPipelineContext);
        }
        this._compiledEffects = {};
    };
    /**
     * Dispose and release all associated resources
     */
    Engine.prototype.dispose = function () {
        this.hideLoadingUI();
        this.stopRenderLoop();
        this.onNewSceneAddedObservable.clear();
        // Release postProcesses
        while (this.postProcesses.length) {
            this.postProcesses[0].dispose();
        }
        // Empty texture
        if (this._emptyTexture) {
            this._releaseTexture(this._emptyTexture);
            this._emptyTexture = null;
        }
        if (this._emptyCubeTexture) {
            this._releaseTexture(this._emptyCubeTexture);
            this._emptyCubeTexture = null;
        }
        // Rescale PP
        if (this._rescalePostProcess) {
            this._rescalePostProcess.dispose();
        }
        // Release scenes
        while (this.scenes.length) {
            this.scenes[0].dispose();
        }
        // Release audio engine
        if (Engine.Instances.length === 1 && Engine.audioEngine) {
            Engine.audioEngine.dispose();
        }
        // Release effects
        this.releaseEffects();
        // Unbind
        this.unbindAllAttributes();
        this._boundUniforms = [];
        if (this._dummyFramebuffer) {
            this._gl.deleteFramebuffer(this._dummyFramebuffer);
        }
        //WebVR
        this.disableVR();
        // Events
        if (_Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__["DomManagement"].IsWindowObjectExist()) {
            window.removeEventListener("blur", this._onBlur);
            window.removeEventListener("focus", this._onFocus);
            if (this._renderingCanvas) {
                this._renderingCanvas.removeEventListener("focus", this._onCanvasFocus);
                this._renderingCanvas.removeEventListener("blur", this._onCanvasBlur);
                this._renderingCanvas.removeEventListener("pointerout", this._onCanvasPointerOut);
                if (!this._doNotHandleContextLost) {
                    this._renderingCanvas.removeEventListener("webglcontextlost", this._onContextLost);
                    this._renderingCanvas.removeEventListener("webglcontextrestored", this._onContextRestored);
                }
            }
            document.removeEventListener("fullscreenchange", this._onFullscreenChange);
            document.removeEventListener("mozfullscreenchange", this._onFullscreenChange);
            document.removeEventListener("webkitfullscreenchange", this._onFullscreenChange);
            document.removeEventListener("msfullscreenchange", this._onFullscreenChange);
            document.removeEventListener("pointerlockchange", this._onPointerLockChange);
            document.removeEventListener("mspointerlockchange", this._onPointerLockChange);
            document.removeEventListener("mozpointerlockchange", this._onPointerLockChange);
            document.removeEventListener("webkitpointerlockchange", this._onPointerLockChange);
        }
        // Remove from Instances
        var index = Engine.Instances.indexOf(this);
        if (index >= 0) {
            Engine.Instances.splice(index, 1);
        }
        this._workingCanvas = null;
        this._workingContext = null;
        this._currentBufferPointers = [];
        this._renderingCanvas = null;
        this._currentProgram = null;
        this._bindedRenderFunction = null;
        this.onResizeObservable.clear();
        this.onCanvasBlurObservable.clear();
        this.onCanvasFocusObservable.clear();
        this.onCanvasPointerOutObservable.clear();
        this.onBeginFrameObservable.clear();
        this.onEndFrameObservable.clear();
        _Materials_effect__WEBPACK_IMPORTED_MODULE_4__["Effect"].ResetCache();
        // Abort active requests
        for (var _i = 0, _a = this._activeRequests; _i < _a.length; _i++) {
            var request = _a[_i];
            request.abort();
        }
    };
    // Loading screen
    /**
     * Display the loading screen
     * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
     */
    Engine.prototype.displayLoadingUI = function () {
        if (!_Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__["DomManagement"].IsWindowObjectExist()) {
            return;
        }
        var loadingScreen = this.loadingScreen;
        if (loadingScreen) {
            loadingScreen.displayLoadingUI();
        }
    };
    /**
     * Hide the loading screen
     * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
     */
    Engine.prototype.hideLoadingUI = function () {
        if (!_Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__["DomManagement"].IsWindowObjectExist()) {
            return;
        }
        var loadingScreen = this._loadingScreen;
        if (loadingScreen) {
            loadingScreen.hideLoadingUI();
        }
    };
    Object.defineProperty(Engine.prototype, "loadingScreen", {
        /**
         * Gets the current loading screen object
         * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
         */
        get: function () {
            if (!this._loadingScreen && this._renderingCanvas) {
                this._loadingScreen = Engine.DefaultLoadingScreenFactory(this._renderingCanvas);
            }
            return this._loadingScreen;
        },
        /**
         * Sets the current loading screen object
         * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
         */
        set: function (loadingScreen) {
            this._loadingScreen = loadingScreen;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "loadingUIText", {
        /**
         * Sets the current loading screen text
         * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
         */
        set: function (text) {
            this.loadingScreen.loadingUIText = text;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Engine.prototype, "loadingUIBackgroundColor", {
        /**
         * Sets the current loading screen background color
         * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
         */
        set: function (color) {
            this.loadingScreen.loadingUIBackgroundColor = color;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attach a new callback raised when context lost event is fired
     * @param callback defines the callback to call
     */
    Engine.prototype.attachContextLostEvent = function (callback) {
        if (this._renderingCanvas) {
            this._renderingCanvas.addEventListener("webglcontextlost", callback, false);
        }
    };
    /**
     * Attach a new callback raised when context restored event is fired
     * @param callback defines the callback to call
     */
    Engine.prototype.attachContextRestoredEvent = function (callback) {
        if (this._renderingCanvas) {
            this._renderingCanvas.addEventListener("webglcontextrestored", callback, false);
        }
    };
    /**
     * Gets the source code of the vertex shader associated with a specific webGL program
     * @param program defines the program to use
     * @returns a string containing the source code of the vertex shader associated with the program
     */
    Engine.prototype.getVertexShaderSource = function (program) {
        var shaders = this._gl.getAttachedShaders(program);
        if (!shaders) {
            return null;
        }
        return this._gl.getShaderSource(shaders[0]);
    };
    /**
     * Gets the source code of the fragment shader associated with a specific webGL program
     * @param program defines the program to use
     * @returns a string containing the source code of the fragment shader associated with the program
     */
    Engine.prototype.getFragmentShaderSource = function (program) {
        var shaders = this._gl.getAttachedShaders(program);
        if (!shaders) {
            return null;
        }
        return this._gl.getShaderSource(shaders[1]);
    };
    /**
     * Get the current error code of the webGL context
     * @returns the error code
     * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getError
     */
    Engine.prototype.getError = function () {
        return this._gl.getError();
    };
    // FPS
    /**
     * Gets the current framerate
     * @returns a number representing the framerate
     */
    Engine.prototype.getFps = function () {
        return this._fps;
    };
    /**
     * Gets the time spent between current and previous frame
     * @returns a number representing the delta time in ms
     */
    Engine.prototype.getDeltaTime = function () {
        return this._deltaTime;
    };
    Engine.prototype._measureFps = function () {
        this._performanceMonitor.sampleFrame();
        this._fps = this._performanceMonitor.averageFPS;
        this._deltaTime = this._performanceMonitor.instantaneousFrameTime || 0;
    };
    /** @hidden */
    Engine.prototype._readTexturePixels = function (texture, width, height, faceIndex, level, buffer) {
        if (faceIndex === void 0) { faceIndex = -1; }
        if (level === void 0) { level = 0; }
        if (buffer === void 0) { buffer = null; }
        var gl = this._gl;
        if (!this._dummyFramebuffer) {
            var dummy = gl.createFramebuffer();
            if (!dummy) {
                throw new Error("Unable to create dummy framebuffer");
            }
            this._dummyFramebuffer = dummy;
        }
        gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);
        if (faceIndex > -1) {
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._webGLTexture, level);
        }
        else {
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._webGLTexture, level);
        }
        var readType = (texture.type !== undefined) ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;
        switch (readType) {
            case gl.UNSIGNED_BYTE:
                if (!buffer) {
                    buffer = new Uint8Array(4 * width * height);
                }
                readType = gl.UNSIGNED_BYTE;
                break;
            default:
                if (!buffer) {
                    buffer = new Float32Array(4 * width * height);
                }
                readType = gl.FLOAT;
                break;
        }
        gl.readPixels(0, 0, width, height, gl.RGBA, readType, buffer);
        gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer);
        return buffer;
    };
    Engine.prototype._canRenderToFloatFramebuffer = function () {
        if (this._webGLVersion > 1) {
            return this._caps.colorBufferFloat;
        }
        return this._canRenderToFramebuffer(Engine.TEXTURETYPE_FLOAT);
    };
    Engine.prototype._canRenderToHalfFloatFramebuffer = function () {
        if (this._webGLVersion > 1) {
            return this._caps.colorBufferFloat;
        }
        return this._canRenderToFramebuffer(Engine.TEXTURETYPE_HALF_FLOAT);
    };
    // Thank you : http://stackoverflow.com/questions/28827511/webgl-ios-render-to-floating-point-texture
    Engine.prototype._canRenderToFramebuffer = function (type) {
        var gl = this._gl;
        //clear existing errors
        while (gl.getError() !== gl.NO_ERROR) { }
        var successful = true;
        var texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texImage2D(gl.TEXTURE_2D, 0, this._getRGBABufferInternalSizedFormat(type), 1, 1, 0, gl.RGBA, this._getWebGLTextureType(type), null);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        var fb = gl.createFramebuffer();
        gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
        gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
        var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
        successful = successful && (status === gl.FRAMEBUFFER_COMPLETE);
        successful = successful && (gl.getError() === gl.NO_ERROR);
        //try render by clearing frame buffer's color buffer
        if (successful) {
            gl.clear(gl.COLOR_BUFFER_BIT);
            successful = successful && (gl.getError() === gl.NO_ERROR);
        }
        //try reading from frame to ensure render occurs (just creating the FBO is not sufficient to determine if rendering is supported)
        if (successful) {
            //in practice it's sufficient to just read from the backbuffer rather than handle potentially issues reading from the texture
            gl.bindFramebuffer(gl.FRAMEBUFFER, null);
            var readFormat = gl.RGBA;
            var readType = gl.UNSIGNED_BYTE;
            var buffer = new Uint8Array(4);
            gl.readPixels(0, 0, 1, 1, readFormat, readType, buffer);
            successful = successful && (gl.getError() === gl.NO_ERROR);
        }
        //clean up
        gl.deleteTexture(texture);
        gl.deleteFramebuffer(fb);
        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
        //clear accumulated errors
        while (!successful && (gl.getError() !== gl.NO_ERROR)) { }
        return successful;
    };
    /** @hidden */
    Engine.prototype._getWebGLTextureType = function (type) {
        if (this._webGLVersion === 1) {
            switch (type) {
                case Engine.TEXTURETYPE_FLOAT:
                    return this._gl.FLOAT;
                case Engine.TEXTURETYPE_HALF_FLOAT:
                    return this._gl.HALF_FLOAT_OES;
                case Engine.TEXTURETYPE_UNSIGNED_BYTE:
                    return this._gl.UNSIGNED_BYTE;
                case Engine.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:
                    return this._gl.UNSIGNED_SHORT_4_4_4_4;
                case Engine.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:
                    return this._gl.UNSIGNED_SHORT_5_5_5_1;
                case Engine.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:
                    return this._gl.UNSIGNED_SHORT_5_6_5;
            }
            return this._gl.UNSIGNED_BYTE;
        }
        switch (type) {
            case Engine.TEXTURETYPE_BYTE:
                return this._gl.BYTE;
            case Engine.TEXTURETYPE_UNSIGNED_BYTE:
                return this._gl.UNSIGNED_BYTE;
            case Engine.TEXTURETYPE_SHORT:
                return this._gl.SHORT;
            case Engine.TEXTURETYPE_UNSIGNED_SHORT:
                return this._gl.UNSIGNED_SHORT;
            case Engine.TEXTURETYPE_INT:
                return this._gl.INT;
            case Engine.TEXTURETYPE_UNSIGNED_INTEGER: // Refers to UNSIGNED_INT
                return this._gl.UNSIGNED_INT;
            case Engine.TEXTURETYPE_FLOAT:
                return this._gl.FLOAT;
            case Engine.TEXTURETYPE_HALF_FLOAT:
                return this._gl.HALF_FLOAT;
            case Engine.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:
                return this._gl.UNSIGNED_SHORT_4_4_4_4;
            case Engine.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:
                return this._gl.UNSIGNED_SHORT_5_5_5_1;
            case Engine.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:
                return this._gl.UNSIGNED_SHORT_5_6_5;
            case Engine.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:
                return this._gl.UNSIGNED_INT_2_10_10_10_REV;
            case Engine.TEXTURETYPE_UNSIGNED_INT_24_8:
                return this._gl.UNSIGNED_INT_24_8;
            case Engine.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:
                return this._gl.UNSIGNED_INT_10F_11F_11F_REV;
            case Engine.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:
                return this._gl.UNSIGNED_INT_5_9_9_9_REV;
            case Engine.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV:
                return this._gl.FLOAT_32_UNSIGNED_INT_24_8_REV;
        }
        return this._gl.UNSIGNED_BYTE;
    };
    /** @hidden */
    Engine.prototype._getInternalFormat = function (format) {
        var internalFormat = this._gl.RGBA;
        switch (format) {
            case Engine.TEXTUREFORMAT_ALPHA:
                internalFormat = this._gl.ALPHA;
                break;
            case Engine.TEXTUREFORMAT_LUMINANCE:
                internalFormat = this._gl.LUMINANCE;
                break;
            case Engine.TEXTUREFORMAT_LUMINANCE_ALPHA:
                internalFormat = this._gl.LUMINANCE_ALPHA;
                break;
            case Engine.TEXTUREFORMAT_RED:
                internalFormat = this._gl.RED;
                break;
            case Engine.TEXTUREFORMAT_RG:
                internalFormat = this._gl.RG;
                break;
            case Engine.TEXTUREFORMAT_RGB:
                internalFormat = this._gl.RGB;
                break;
            case Engine.TEXTUREFORMAT_RGBA:
                internalFormat = this._gl.RGBA;
                break;
        }
        if (this._webGLVersion > 1) {
            switch (format) {
                case Engine.TEXTUREFORMAT_RED_INTEGER:
                    internalFormat = this._gl.RED_INTEGER;
                    break;
                case Engine.TEXTUREFORMAT_RG_INTEGER:
                    internalFormat = this._gl.RG_INTEGER;
                    break;
                case Engine.TEXTUREFORMAT_RGB_INTEGER:
                    internalFormat = this._gl.RGB_INTEGER;
                    break;
                case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                    internalFormat = this._gl.RGBA_INTEGER;
                    break;
            }
        }
        return internalFormat;
    };
    /** @hidden */
    Engine.prototype._getRGBABufferInternalSizedFormat = function (type, format) {
        if (this._webGLVersion === 1) {
            if (format !== undefined) {
                switch (format) {
                    case Engine.TEXTUREFORMAT_ALPHA:
                        return this._gl.ALPHA;
                    case Engine.TEXTUREFORMAT_LUMINANCE:
                        return this._gl.LUMINANCE;
                    case Engine.TEXTUREFORMAT_LUMINANCE_ALPHA:
                        return this._gl.LUMINANCE_ALPHA;
                }
            }
            return this._gl.RGBA;
        }
        switch (type) {
            case Engine.TEXTURETYPE_BYTE:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED:
                        return this._gl.R8_SNORM;
                    case Engine.TEXTUREFORMAT_RG:
                        return this._gl.RG8_SNORM;
                    case Engine.TEXTUREFORMAT_RGB:
                        return this._gl.RGB8_SNORM;
                    case Engine.TEXTUREFORMAT_RED_INTEGER:
                        return this._gl.R8I;
                    case Engine.TEXTUREFORMAT_RG_INTEGER:
                        return this._gl.RG8I;
                    case Engine.TEXTUREFORMAT_RGB_INTEGER:
                        return this._gl.RGB8I;
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGBA8I;
                    default:
                        return this._gl.RGBA8_SNORM;
                }
            case Engine.TEXTURETYPE_UNSIGNED_BYTE:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED:
                        return this._gl.R8;
                    case Engine.TEXTUREFORMAT_RG:
                        return this._gl.RG8;
                    case Engine.TEXTUREFORMAT_RGB:
                        return this._gl.RGB8; // By default. Other possibilities are RGB565, SRGB8.
                    case Engine.TEXTUREFORMAT_RGBA:
                        return this._gl.RGBA8; // By default. Other possibilities are RGB5_A1, RGBA4, SRGB8_ALPHA8.
                    case Engine.TEXTUREFORMAT_RED_INTEGER:
                        return this._gl.R8UI;
                    case Engine.TEXTUREFORMAT_RG_INTEGER:
                        return this._gl.RG8UI;
                    case Engine.TEXTUREFORMAT_RGB_INTEGER:
                        return this._gl.RGB8UI;
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGBA8UI;
                    case Engine.TEXTUREFORMAT_ALPHA:
                        return this._gl.ALPHA;
                    case Engine.TEXTUREFORMAT_LUMINANCE:
                        return this._gl.LUMINANCE;
                    case Engine.TEXTUREFORMAT_LUMINANCE_ALPHA:
                        return this._gl.LUMINANCE_ALPHA;
                    default:
                        return this._gl.RGBA8;
                }
            case Engine.TEXTURETYPE_SHORT:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED_INTEGER:
                        return this._gl.R16I;
                    case Engine.TEXTUREFORMAT_RG_INTEGER:
                        return this._gl.RG16I;
                    case Engine.TEXTUREFORMAT_RGB_INTEGER:
                        return this._gl.RGB16I;
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGBA16I;
                    default:
                        return this._gl.RGBA16I;
                }
            case Engine.TEXTURETYPE_UNSIGNED_SHORT:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED_INTEGER:
                        return this._gl.R16UI;
                    case Engine.TEXTUREFORMAT_RG_INTEGER:
                        return this._gl.RG16UI;
                    case Engine.TEXTUREFORMAT_RGB_INTEGER:
                        return this._gl.RGB16UI;
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGBA16UI;
                    default:
                        return this._gl.RGBA16UI;
                }
            case Engine.TEXTURETYPE_INT:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED_INTEGER:
                        return this._gl.R32I;
                    case Engine.TEXTUREFORMAT_RG_INTEGER:
                        return this._gl.RG32I;
                    case Engine.TEXTUREFORMAT_RGB_INTEGER:
                        return this._gl.RGB32I;
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGBA32I;
                    default:
                        return this._gl.RGBA32I;
                }
            case Engine.TEXTURETYPE_UNSIGNED_INTEGER: // Refers to UNSIGNED_INT
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED_INTEGER:
                        return this._gl.R32UI;
                    case Engine.TEXTUREFORMAT_RG_INTEGER:
                        return this._gl.RG32UI;
                    case Engine.TEXTUREFORMAT_RGB_INTEGER:
                        return this._gl.RGB32UI;
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGBA32UI;
                    default:
                        return this._gl.RGBA32UI;
                }
            case Engine.TEXTURETYPE_FLOAT:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED:
                        return this._gl.R32F; // By default. Other possibility is R16F.
                    case Engine.TEXTUREFORMAT_RG:
                        return this._gl.RG32F; // By default. Other possibility is RG16F.
                    case Engine.TEXTUREFORMAT_RGB:
                        return this._gl.RGB32F; // By default. Other possibilities are RGB16F, R11F_G11F_B10F, RGB9_E5.
                    case Engine.TEXTUREFORMAT_RGBA:
                        return this._gl.RGBA32F; // By default. Other possibility is RGBA16F.
                    default:
                        return this._gl.RGBA32F;
                }
            case Engine.TEXTURETYPE_HALF_FLOAT:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RED:
                        return this._gl.R16F;
                    case Engine.TEXTUREFORMAT_RG:
                        return this._gl.RG16F;
                    case Engine.TEXTUREFORMAT_RGB:
                        return this._gl.RGB16F; // By default. Other possibilities are R11F_G11F_B10F, RGB9_E5.
                    case Engine.TEXTUREFORMAT_RGBA:
                        return this._gl.RGBA16F;
                    default:
                        return this._gl.RGBA16F;
                }
            case Engine.TEXTURETYPE_UNSIGNED_SHORT_5_6_5:
                return this._gl.RGB565;
            case Engine.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV:
                return this._gl.R11F_G11F_B10F;
            case Engine.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV:
                return this._gl.RGB9_E5;
            case Engine.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4:
                return this._gl.RGBA4;
            case Engine.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1:
                return this._gl.RGB5_A1;
            case Engine.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV:
                switch (format) {
                    case Engine.TEXTUREFORMAT_RGBA:
                        return this._gl.RGB10_A2; // By default. Other possibility is RGB5_A1.
                    case Engine.TEXTUREFORMAT_RGBA_INTEGER:
                        return this._gl.RGB10_A2UI;
                    default:
                        return this._gl.RGB10_A2;
                }
        }
        return this._gl.RGBA8;
    };
    /** @hidden */
    Engine.prototype._getRGBAMultiSampleBufferFormat = function (type) {
        if (type === Engine.TEXTURETYPE_FLOAT) {
            return this._gl.RGBA32F;
        }
        else if (type === Engine.TEXTURETYPE_HALF_FLOAT) {
            return this._gl.RGBA16F;
        }
        return this._gl.RGBA8;
    };
    /** @hidden */
    Engine.prototype._loadFile = function (url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError) {
        var _this = this;
        var request = _Misc_fileTools__WEBPACK_IMPORTED_MODULE_17__["FileTools"].LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);
        this._activeRequests.push(request);
        request.onCompleteObservable.add(function (request) {
            _this._activeRequests.splice(_this._activeRequests.indexOf(request), 1);
        });
        return request;
    };
    /** @hidden */
    Engine.prototype._loadFileAsync = function (url, offlineProvider, useArrayBuffer) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this._loadFile(url, function (data) {
                resolve(data);
            }, undefined, offlineProvider, useArrayBuffer, function (request, exception) {
                reject(exception);
            });
        });
    };
    /** @hidden */
    Engine.prototype._shouldOnlyUpdateCameras = function () {
        return false;
    };
    // Statics
    /**
     * Gets a boolean indicating if the engine can be instanciated (ie. if a webGL context can be found)
     * @returns true if the engine can be created
     * @ignorenaming
     */
    Engine.isSupported = function () {
        try {
            var tempcanvas = document.createElement("canvas");
            var gl = tempcanvas.getContext("webgl") || tempcanvas.getContext("experimental-webgl");
            return gl != null && !!window.WebGLRenderingContext;
        }
        catch (e) {
            return false;
        }
    };
    /**
     * Find the next highest power of two.
     * @param x Number to start search from.
     * @return Next highest power of two.
     */
    Engine.CeilingPOT = function (x) {
        x--;
        x |= x >> 1;
        x |= x >> 2;
        x |= x >> 4;
        x |= x >> 8;
        x |= x >> 16;
        x++;
        return x;
    };
    /**
     * Find the next lowest power of two.
     * @param x Number to start search from.
     * @return Next lowest power of two.
     */
    Engine.FloorPOT = function (x) {
        x = x | (x >> 1);
        x = x | (x >> 2);
        x = x | (x >> 4);
        x = x | (x >> 8);
        x = x | (x >> 16);
        return x - (x >> 1);
    };
    /**
     * Find the nearest power of two.
     * @param x Number to start search from.
     * @return Next nearest power of two.
     */
    Engine.NearestPOT = function (x) {
        var c = Engine.CeilingPOT(x);
        var f = Engine.FloorPOT(x);
        return (c - x) > (x - f) ? f : c;
    };
    /**
     * Get the closest exponent of two
     * @param value defines the value to approximate
     * @param max defines the maximum value to return
     * @param mode defines how to define the closest value
     * @returns closest exponent of two of the given value
     */
    Engine.GetExponentOfTwo = function (value, max, mode) {
        if (mode === void 0) { mode = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_NEAREST; }
        var pot;
        switch (mode) {
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_FLOOR:
                pot = Engine.FloorPOT(value);
                break;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_NEAREST:
                pot = Engine.NearestPOT(value);
                break;
            case _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_CEILING:
            default:
                pot = Engine.CeilingPOT(value);
                break;
        }
        return Math.min(pot, max);
    };
    /**
     * Queue a new function into the requested animation frame pool (ie. this function will be executed byt the browser for the next frame)
     * @param func - the function to be called
     * @param requester - the object that will request the next frame. Falls back to window.
     * @returns frame number
     */
    Engine.QueueNewFrame = function (func, requester) {
        if (!_Misc_domManagement__WEBPACK_IMPORTED_MODULE_8__["DomManagement"].IsWindowObjectExist()) {
            return setTimeout(func, 16);
        }
        if (!requester) {
            requester = window;
        }
        if (requester.requestAnimationFrame) {
            return requester.requestAnimationFrame(func);
        }
        else if (requester.msRequestAnimationFrame) {
            return requester.msRequestAnimationFrame(func);
        }
        else if (requester.webkitRequestAnimationFrame) {
            return requester.webkitRequestAnimationFrame(func);
        }
        else if (requester.mozRequestAnimationFrame) {
            return requester.mozRequestAnimationFrame(func);
        }
        else if (requester.oRequestAnimationFrame) {
            return requester.oRequestAnimationFrame(func);
        }
        else {
            return window.setTimeout(func, 16);
        }
    };
    /**
     * Ask the browser to promote the current element to pointerlock mode
     * @param element defines the DOM element to promote
     */
    Engine._RequestPointerlock = function (element) {
        element.requestPointerLock = element.requestPointerLock || element.msRequestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
        if (element.requestPointerLock) {
            element.requestPointerLock();
        }
    };
    /**
     * Asks the browser to exit pointerlock mode
     */
    Engine._ExitPointerlock = function () {
        var anyDoc = document;
        document.exitPointerLock = document.exitPointerLock || anyDoc.msExitPointerLock || anyDoc.mozExitPointerLock || anyDoc.webkitExitPointerLock;
        if (document.exitPointerLock) {
            document.exitPointerLock();
        }
    };
    /**
     * Ask the browser to promote the current element to fullscreen rendering mode
     * @param element defines the DOM element to promote
     */
    Engine._RequestFullscreen = function (element) {
        var requestFunction = element.requestFullscreen || element.msRequestFullscreen || element.webkitRequestFullscreen || element.mozRequestFullScreen;
        if (!requestFunction) {
            return;
        }
        requestFunction.call(element);
    };
    /**
     * Asks the browser to exit fullscreen mode
     */
    Engine._ExitFullscreen = function () {
        var anyDoc = document;
        if (document.exitFullscreen) {
            document.exitFullscreen();
        }
        else if (anyDoc.mozCancelFullScreen) {
            anyDoc.mozCancelFullScreen();
        }
        else if (anyDoc.webkitCancelFullScreen) {
            anyDoc.webkitCancelFullScreen();
        }
        else if (anyDoc.msCancelFullScreen) {
            anyDoc.msCancelFullScreen();
        }
    };
    /** Use this array to turn off some WebGL2 features on known buggy browsers version */
    Engine.ExceptionList = [
        { key: "Chrome\/63\.0", capture: "63\\.0\\.3239\\.(\\d+)", captureConstraint: 108, targets: ["uniformBuffer"] },
        { key: "Firefox\/58", capture: null, captureConstraint: null, targets: ["uniformBuffer"] },
        { key: "Firefox\/59", capture: null, captureConstraint: null, targets: ["uniformBuffer"] },
        { key: "Chrome\/72.+?Mobile", capture: null, captureConstraint: null, targets: ["vao"] },
        { key: "Chrome\/73.+?Mobile", capture: null, captureConstraint: null, targets: ["vao"] },
        { key: "Chrome\/74.+?Mobile", capture: null, captureConstraint: null, targets: ["vao"] },
        { key: "Mac OS.+Chrome\/71", capture: null, captureConstraint: null, targets: ["vao"] },
        { key: "Mac OS.+Chrome\/72", capture: null, captureConstraint: null, targets: ["vao"] }
    ];
    /** @hidden */
    Engine._TextureLoaders = [];
    // Const statics
    /** Defines that alpha blending is disabled */
    Engine.ALPHA_DISABLE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_DISABLE;
    /** Defines that alpha blending to SRC ALPHA * SRC + DEST */
    Engine.ALPHA_ADD = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_ADD;
    /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC ALPHA) * DEST */
    Engine.ALPHA_COMBINE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_COMBINE;
    /** Defines that alpha blending to DEST - SRC * DEST */
    Engine.ALPHA_SUBTRACT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_SUBTRACT;
    /** Defines that alpha blending to SRC * DEST */
    Engine.ALPHA_MULTIPLY = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_MULTIPLY;
    /** Defines that alpha blending to SRC ALPHA * SRC + (1 - SRC) * DEST */
    Engine.ALPHA_MAXIMIZED = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_MAXIMIZED;
    /** Defines that alpha blending to SRC + DEST */
    Engine.ALPHA_ONEONE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_ONEONE;
    /** Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST */
    Engine.ALPHA_PREMULTIPLIED = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_PREMULTIPLIED;
    /**
     * Defines that alpha blending to SRC + (1 - SRC ALPHA) * DEST
     * Alpha will be set to (1 - SRC ALPHA) * DEST ALPHA
     */
    Engine.ALPHA_PREMULTIPLIED_PORTERDUFF = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_PREMULTIPLIED_PORTERDUFF;
    /** Defines that alpha blending to CST * SRC + (1 - CST) * DEST */
    Engine.ALPHA_INTERPOLATE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_INTERPOLATE;
    /**
     * Defines that alpha blending to SRC + (1 - SRC) * DEST
     * Alpha will be set to SRC ALPHA + (1 - SRC ALPHA) * DEST ALPHA
     */
    Engine.ALPHA_SCREENMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_SCREENMODE;
    /** Defines that the ressource is not delayed*/
    Engine.DELAYLOADSTATE_NONE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_NONE;
    /** Defines that the ressource was successfully delay loaded */
    Engine.DELAYLOADSTATE_LOADED = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_LOADED;
    /** Defines that the ressource is currently delay loading */
    Engine.DELAYLOADSTATE_LOADING = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_LOADING;
    /** Defines that the ressource is delayed and has not started loading */
    Engine.DELAYLOADSTATE_NOTLOADED = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_NOTLOADED;
    // Depht or Stencil test Constants.
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will never pass. i.e. Nothing will be drawn */
    Engine.NEVER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].NEVER;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */
    Engine.ALWAYS = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALWAYS;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than the stored value */
    Engine.LESS = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].LESS;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is equals to the stored value */
    Engine.EQUAL = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].EQUAL;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is less than or equal to the stored value */
    Engine.LEQUAL = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].LEQUAL;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than the stored value */
    Engine.GREATER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].GREATER;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is greater than or equal to the stored value */
    Engine.GEQUAL = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].GEQUAL;
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will pass if the new depth value is not equal to the stored value */
    Engine.NOTEQUAL = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].NOTEQUAL;
    // Stencil Actions Constants.
    /** Passed to stencilOperation to specify that stencil value must be kept */
    Engine.KEEP = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].KEEP;
    /** Passed to stencilOperation to specify that stencil value must be replaced */
    Engine.REPLACE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].REPLACE;
    /** Passed to stencilOperation to specify that stencil value must be incremented */
    Engine.INCR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].INCR;
    /** Passed to stencilOperation to specify that stencil value must be decremented */
    Engine.DECR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DECR;
    /** Passed to stencilOperation to specify that stencil value must be inverted */
    Engine.INVERT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].INVERT;
    /** Passed to stencilOperation to specify that stencil value must be incremented with wrapping */
    Engine.INCR_WRAP = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].INCR_WRAP;
    /** Passed to stencilOperation to specify that stencil value must be decremented with wrapping */
    Engine.DECR_WRAP = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DECR_WRAP;
    /** Texture is not repeating outside of 0..1 UVs */
    Engine.TEXTURE_CLAMP_ADDRESSMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_CLAMP_ADDRESSMODE;
    /** Texture is repeating outside of 0..1 UVs */
    Engine.TEXTURE_WRAP_ADDRESSMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_WRAP_ADDRESSMODE;
    /** Texture is repeating and mirrored */
    Engine.TEXTURE_MIRROR_ADDRESSMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_MIRROR_ADDRESSMODE;
    /** ALPHA */
    Engine.TEXTUREFORMAT_ALPHA = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_ALPHA;
    /** LUMINANCE */
    Engine.TEXTUREFORMAT_LUMINANCE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_LUMINANCE;
    /** LUMINANCE_ALPHA */
    Engine.TEXTUREFORMAT_LUMINANCE_ALPHA = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_LUMINANCE_ALPHA;
    /** RGB */
    Engine.TEXTUREFORMAT_RGB = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RGB;
    /** RGBA */
    Engine.TEXTUREFORMAT_RGBA = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RGBA;
    /** RED */
    Engine.TEXTUREFORMAT_RED = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RED;
    /** RED (2nd reference) */
    Engine.TEXTUREFORMAT_R = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_R;
    /** RG */
    Engine.TEXTUREFORMAT_RG = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RG;
    /** RED_INTEGER */
    Engine.TEXTUREFORMAT_RED_INTEGER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RED_INTEGER;
    /** RED_INTEGER (2nd reference) */
    Engine.TEXTUREFORMAT_R_INTEGER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_R_INTEGER;
    /** RG_INTEGER */
    Engine.TEXTUREFORMAT_RG_INTEGER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RG_INTEGER;
    /** RGB_INTEGER */
    Engine.TEXTUREFORMAT_RGB_INTEGER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RGB_INTEGER;
    /** RGBA_INTEGER */
    Engine.TEXTUREFORMAT_RGBA_INTEGER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RGBA_INTEGER;
    /** UNSIGNED_BYTE */
    Engine.TEXTURETYPE_UNSIGNED_BYTE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_BYTE;
    /** UNSIGNED_BYTE (2nd reference) */
    Engine.TEXTURETYPE_UNSIGNED_INT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INT;
    /** FLOAT */
    Engine.TEXTURETYPE_FLOAT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_FLOAT;
    /** HALF_FLOAT */
    Engine.TEXTURETYPE_HALF_FLOAT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_HALF_FLOAT;
    /** BYTE */
    Engine.TEXTURETYPE_BYTE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_BYTE;
    /** SHORT */
    Engine.TEXTURETYPE_SHORT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_SHORT;
    /** UNSIGNED_SHORT */
    Engine.TEXTURETYPE_UNSIGNED_SHORT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_SHORT;
    /** INT */
    Engine.TEXTURETYPE_INT = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_INT;
    /** UNSIGNED_INT */
    Engine.TEXTURETYPE_UNSIGNED_INTEGER = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INTEGER;
    /** UNSIGNED_SHORT_4_4_4_4 */
    Engine.TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4 = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_SHORT_4_4_4_4;
    /** UNSIGNED_SHORT_5_5_5_1 */
    Engine.TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1 = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_SHORT_5_5_5_1;
    /** UNSIGNED_SHORT_5_6_5 */
    Engine.TEXTURETYPE_UNSIGNED_SHORT_5_6_5 = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_SHORT_5_6_5;
    /** UNSIGNED_INT_2_10_10_10_REV */
    Engine.TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INT_2_10_10_10_REV;
    /** UNSIGNED_INT_24_8 */
    Engine.TEXTURETYPE_UNSIGNED_INT_24_8 = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INT_24_8;
    /** UNSIGNED_INT_10F_11F_11F_REV */
    Engine.TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV;
    /** UNSIGNED_INT_5_9_9_9_REV */
    Engine.TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INT_5_9_9_9_REV;
    /** FLOAT_32_UNSIGNED_INT_24_8_REV */
    Engine.TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_FLOAT_32_UNSIGNED_INT_24_8_REV;
    /** nearest is mag = nearest and min = nearest and mip = linear */
    Engine.TEXTURE_NEAREST_SAMPLINGMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE;
    /** Bilinear is mag = linear and min = linear and mip = nearest */
    Engine.TEXTURE_BILINEAR_SAMPLINGMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE;
    /** Trilinear is mag = linear and min = linear and mip = linear */
    Engine.TEXTURE_TRILINEAR_SAMPLINGMODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE;
    /** nearest is mag = nearest and min = nearest and mip = linear */
    Engine.TEXTURE_NEAREST_NEAREST_MIPLINEAR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_NEAREST_MIPLINEAR;
    /** Bilinear is mag = linear and min = linear and mip = nearest */
    Engine.TEXTURE_LINEAR_LINEAR_MIPNEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_LINEAR_LINEAR_MIPNEAREST;
    /** Trilinear is mag = linear and min = linear and mip = linear */
    Engine.TEXTURE_LINEAR_LINEAR_MIPLINEAR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_LINEAR_LINEAR_MIPLINEAR;
    /** mag = nearest and min = nearest and mip = nearest */
    Engine.TEXTURE_NEAREST_NEAREST_MIPNEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_NEAREST_MIPNEAREST;
    /** mag = nearest and min = linear and mip = nearest */
    Engine.TEXTURE_NEAREST_LINEAR_MIPNEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_LINEAR_MIPNEAREST;
    /** mag = nearest and min = linear and mip = linear */
    Engine.TEXTURE_NEAREST_LINEAR_MIPLINEAR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_LINEAR_MIPLINEAR;
    /** mag = nearest and min = linear and mip = none */
    Engine.TEXTURE_NEAREST_LINEAR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_LINEAR;
    /** mag = nearest and min = nearest and mip = none */
    Engine.TEXTURE_NEAREST_NEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_NEAREST_NEAREST;
    /** mag = linear and min = nearest and mip = nearest */
    Engine.TEXTURE_LINEAR_NEAREST_MIPNEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_LINEAR_NEAREST_MIPNEAREST;
    /** mag = linear and min = nearest and mip = linear */
    Engine.TEXTURE_LINEAR_NEAREST_MIPLINEAR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_LINEAR_NEAREST_MIPLINEAR;
    /** mag = linear and min = linear and mip = none */
    Engine.TEXTURE_LINEAR_LINEAR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_LINEAR_LINEAR;
    /** mag = linear and min = nearest and mip = none */
    Engine.TEXTURE_LINEAR_NEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_LINEAR_NEAREST;
    /** Explicit coordinates mode */
    Engine.TEXTURE_EXPLICIT_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_EXPLICIT_MODE;
    /** Spherical coordinates mode */
    Engine.TEXTURE_SPHERICAL_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_SPHERICAL_MODE;
    /** Planar coordinates mode */
    Engine.TEXTURE_PLANAR_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_PLANAR_MODE;
    /** Cubic coordinates mode */
    Engine.TEXTURE_CUBIC_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_CUBIC_MODE;
    /** Projection coordinates mode */
    Engine.TEXTURE_PROJECTION_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_PROJECTION_MODE;
    /** Skybox coordinates mode */
    Engine.TEXTURE_SKYBOX_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_SKYBOX_MODE;
    /** Inverse Cubic coordinates mode */
    Engine.TEXTURE_INVCUBIC_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_INVCUBIC_MODE;
    /** Equirectangular coordinates mode */
    Engine.TEXTURE_EQUIRECTANGULAR_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_EQUIRECTANGULAR_MODE;
    /** Equirectangular Fixed coordinates mode */
    Engine.TEXTURE_FIXED_EQUIRECTANGULAR_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_FIXED_EQUIRECTANGULAR_MODE;
    /** Equirectangular Fixed Mirrored coordinates mode */
    Engine.TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE;
    // Texture rescaling mode
    /** Defines that texture rescaling will use a floor to find the closer power of 2 size */
    Engine.SCALEMODE_FLOOR = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_FLOOR;
    /** Defines that texture rescaling will look for the nearest power of 2 size */
    Engine.SCALEMODE_NEAREST = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_NEAREST;
    /** Defines that texture rescaling will use a ceil to find the closer power of 2 size */
    Engine.SCALEMODE_CEILING = _constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCALEMODE_CEILING;
    // Updatable statics so stick with vars here
    /**
     * Gets or sets the epsilon value used by collision engine
     */
    Engine.CollisionsEpsilon = 0.001;
    /**
     * Method called to create the default rescale post process on each engine.
     */
    Engine._RescalePostProcessFactory = null;
    return Engine;
}());



/***/ }),

/***/ "./Engines/engineStore.ts":
/*!********************************!*\
  !*** ./Engines/engineStore.ts ***!
  \********************************/
/*! exports provided: EngineStore */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EngineStore", function() { return EngineStore; });
/**
 * The engine store class is responsible to hold all the instances of Engine and Scene created
 * during the life time of the application.
 */
var EngineStore = /** @class */ (function () {
    function EngineStore() {
    }
    Object.defineProperty(EngineStore, "LastCreatedEngine", {
        /**
         * Gets the latest created engine
         */
        get: function () {
            if (this.Instances.length === 0) {
                return null;
            }
            return this.Instances[this.Instances.length - 1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EngineStore, "LastCreatedScene", {
        /**
         * Gets the latest created scene
         */
        get: function () {
            return this._LastCreatedScene;
        },
        enumerable: true,
        configurable: true
    });
    /** Gets the list of created engines */
    EngineStore.Instances = new Array();
    /** @hidden */
    EngineStore._LastCreatedScene = null;
    /**
     * Gets or sets a global variable indicating if fallback texture must be used when a texture cannot be loaded
     * @ignorenaming
     */
    EngineStore.UseFallbackTexture = true;
    /**
     * Texture content used if a texture cannot loaded
     * @ignorenaming
     */
    EngineStore.FallbackTexture = "";
    return EngineStore;
}());



/***/ }),

/***/ "./Engines/index.ts":
/*!**************************!*\
  !*** ./Engines/index.ts ***!
  \**************************/
/*! exports provided: Constants, InstancingAttributeInfo, DepthTextureCreationOptions, EngineCapabilities, Engine, EngineStore, NullEngineOptions, NullEngine, WebGLPipelineContext, WebGPUConstants, WebGPUEngine, WebGL2ShaderProcessor, NativeEngine, _OcclusionDataStorage, _forceTransformFeedbackToBundle */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants */ "./Engines/constants.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Constants", function() { return _constants__WEBPACK_IMPORTED_MODULE_0__["Constants"]; });

/* harmony import */ var _engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./engine */ "./Engines/engine.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancingAttributeInfo", function() { return _engine__WEBPACK_IMPORTED_MODULE_1__["InstancingAttributeInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthTextureCreationOptions", function() { return _engine__WEBPACK_IMPORTED_MODULE_1__["DepthTextureCreationOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineCapabilities", function() { return _engine__WEBPACK_IMPORTED_MODULE_1__["EngineCapabilities"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Engine", function() { return _engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]; });

/* harmony import */ var _engineStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./engineStore */ "./Engines/engineStore.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineStore", function() { return _engineStore__WEBPACK_IMPORTED_MODULE_2__["EngineStore"]; });

/* harmony import */ var _nullEngine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./nullEngine */ "./Engines/nullEngine.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NullEngineOptions", function() { return _nullEngine__WEBPACK_IMPORTED_MODULE_3__["NullEngineOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NullEngine", function() { return _nullEngine__WEBPACK_IMPORTED_MODULE_3__["NullEngine"]; });

/* harmony import */ var _Extensions_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Extensions/index */ "./Engines/Extensions/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_OcclusionDataStorage", function() { return _Extensions_index__WEBPACK_IMPORTED_MODULE_4__["_OcclusionDataStorage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceTransformFeedbackToBundle", function() { return _Extensions_index__WEBPACK_IMPORTED_MODULE_4__["_forceTransformFeedbackToBundle"]; });

/* harmony import */ var _WebGL_webGLPipelineContext__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./WebGL/webGLPipelineContext */ "./Engines/WebGL/webGLPipelineContext.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGLPipelineContext", function() { return _WebGL_webGLPipelineContext__WEBPACK_IMPORTED_MODULE_5__["WebGLPipelineContext"]; });

/* harmony import */ var _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./WebGPU/webgpuConstants */ "./Engines/WebGPU/webgpuConstants.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUConstants", function() { return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_6__["WebGPUConstants"]; });

/* harmony import */ var _webgpuEngine__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./webgpuEngine */ "./Engines/webgpuEngine.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUEngine", function() { return _webgpuEngine__WEBPACK_IMPORTED_MODULE_7__["WebGPUEngine"]; });

/* harmony import */ var _WebGL_webGL2ShaderProcessors__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./WebGL/webGL2ShaderProcessors */ "./Engines/WebGL/webGL2ShaderProcessors.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGL2ShaderProcessor", function() { return _WebGL_webGL2ShaderProcessors__WEBPACK_IMPORTED_MODULE_8__["WebGL2ShaderProcessor"]; });

/* harmony import */ var _nativeEngine__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./nativeEngine */ "./Engines/nativeEngine.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NativeEngine", function() { return _nativeEngine__WEBPACK_IMPORTED_MODULE_9__["NativeEngine"]; });













/***/ }),

/***/ "./Engines/nativeEngine.ts":
/*!*********************************!*\
  !*** ./Engines/nativeEngine.ts ***!
  \*********************************/
/*! exports provided: NativeEngine */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NativeEngine", function() { return NativeEngine; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Meshes_dataBuffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/dataBuffer */ "./Meshes/dataBuffer.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Misc/environmentTextureTools */ "./Misc/environmentTextureTools.ts");
/* harmony import */ var _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/Textures/renderTargetCreationOptions */ "./Materials/Textures/renderTargetCreationOptions.ts");
/* harmony import */ var _Native_nativeShaderProcessor__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Native/nativeShaderProcessor */ "./Engines/Native/nativeShaderProcessor.ts");









var NativePipelineContext = /** @class */ (function () {
    function NativePipelineContext() {
        // TODO: async should be true?
        this.isAsync = false;
        this.isReady = false;
        this._valueCache = {};
    }
    // TODO: what should this do?
    NativePipelineContext.prototype._handlesSpectorRebuildCallback = function (onCompiled) {
        throw new Error("Not implemented");
    };
    NativePipelineContext.prototype._fillEffectInformation = function (effect, uniformBuffersNames, uniformsNames, uniforms, samplerList, samplers, attributesNames, attributes) {
        var engine = this.engine;
        if (engine.supportsUniformBuffers) {
            for (var name in uniformBuffersNames) {
                effect.bindUniformBlock(name, uniformBuffersNames[name]);
            }
        }
        var effectAvailableUniforms = this.engine.getUniforms(this, uniformsNames);
        effectAvailableUniforms.forEach(function (uniform, index) {
            uniforms[uniformsNames[index]] = uniform;
        });
        this._uniforms = uniforms;
        var index;
        for (index = 0; index < samplerList.length; index++) {
            var sampler = effect.getUniform(samplerList[index]);
            if (sampler == null) {
                samplerList.splice(index, 1);
                index--;
            }
        }
        samplerList.forEach(function (name, index) {
            samplers[name] = index;
        });
        attributes.push.apply(attributes, engine.getAttributes(this, attributesNames));
    };
    /**
     * Release all associated resources.
     **/
    NativePipelineContext.prototype.dispose = function () {
        this._uniforms = {};
    };
    /** @hidden */
    NativePipelineContext.prototype._cacheMatrix = function (uniformName, matrix) {
        var cache = this._valueCache[uniformName];
        var flag = matrix.updateFlag;
        if (cache !== undefined && cache === flag) {
            return false;
        }
        this._valueCache[uniformName] = flag;
        return true;
    };
    /** @hidden */
    NativePipelineContext.prototype._cacheFloat2 = function (uniformName, x, y) {
        var cache = this._valueCache[uniformName];
        if (!cache) {
            cache = [x, y];
            this._valueCache[uniformName] = cache;
            return true;
        }
        var changed = false;
        if (cache[0] !== x) {
            cache[0] = x;
            changed = true;
        }
        if (cache[1] !== y) {
            cache[1] = y;
            changed = true;
        }
        return changed;
    };
    /** @hidden */
    NativePipelineContext.prototype._cacheFloat3 = function (uniformName, x, y, z) {
        var cache = this._valueCache[uniformName];
        if (!cache) {
            cache = [x, y, z];
            this._valueCache[uniformName] = cache;
            return true;
        }
        var changed = false;
        if (cache[0] !== x) {
            cache[0] = x;
            changed = true;
        }
        if (cache[1] !== y) {
            cache[1] = y;
            changed = true;
        }
        if (cache[2] !== z) {
            cache[2] = z;
            changed = true;
        }
        return changed;
    };
    /** @hidden */
    NativePipelineContext.prototype._cacheFloat4 = function (uniformName, x, y, z, w) {
        var cache = this._valueCache[uniformName];
        if (!cache) {
            cache = [x, y, z, w];
            this._valueCache[uniformName] = cache;
            return true;
        }
        var changed = false;
        if (cache[0] !== x) {
            cache[0] = x;
            changed = true;
        }
        if (cache[1] !== y) {
            cache[1] = y;
            changed = true;
        }
        if (cache[2] !== z) {
            cache[2] = z;
            changed = true;
        }
        if (cache[3] !== w) {
            cache[3] = w;
            changed = true;
        }
        return changed;
    };
    /**
     * Sets an interger value on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value Value to be set.
     */
    NativePipelineContext.prototype.setInt = function (uniformName, value) {
        var cache = this._valueCache[uniformName];
        if (cache !== undefined && cache === value) {
            return;
        }
        this._valueCache[uniformName] = value;
        this.engine.setInt(this._uniforms[uniformName], value);
    };
    /**
     * Sets an int array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setIntArray = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray(this._uniforms[uniformName], array);
    };
    /**
     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setIntArray2 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray2(this._uniforms[uniformName], array);
    };
    /**
     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setIntArray3 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray3(this._uniforms[uniformName], array);
    };
    /**
     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setIntArray4 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setIntArray4(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setFloatArray = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setFloatArray2 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray2(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setFloatArray3 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray3(this._uniforms[uniformName], array);
    };
    /**
     * Sets an float array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setFloatArray4 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setFloatArray4(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setArray = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setArray2 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray2(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    NativePipelineContext.prototype.setArray3 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray3(this._uniforms[uniformName], array);
    };
    /**
     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     */
    NativePipelineContext.prototype.setArray4 = function (uniformName, array) {
        this._valueCache[uniformName] = null;
        this.engine.setArray4(this._uniforms[uniformName], array);
    };
    /**
     * Sets matrices on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrices matrices to be set.
     */
    NativePipelineContext.prototype.setMatrices = function (uniformName, matrices) {
        if (!matrices) {
            return;
        }
        this._valueCache[uniformName] = null;
        this.engine.setMatrices(this._uniforms[uniformName], matrices);
    };
    /**
     * Sets matrix on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    NativePipelineContext.prototype.setMatrix = function (uniformName, matrix) {
        if (this._cacheMatrix(uniformName, matrix)) {
            this.engine.setMatrices(this._uniforms[uniformName], matrix.toArray());
        }
    };
    /**
     * Sets a 3x3 matrix on a uniform variable. (Speicified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    NativePipelineContext.prototype.setMatrix3x3 = function (uniformName, matrix) {
        this._valueCache[uniformName] = null;
        this.engine.setMatrix3x3(this._uniforms[uniformName], matrix);
    };
    /**
     * Sets a 2x2 matrix on a uniform variable. (Speicified as [1,2,3,4] will result in [1,2][3,4] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     */
    NativePipelineContext.prototype.setMatrix2x2 = function (uniformName, matrix) {
        this._valueCache[uniformName] = null;
        this.engine.setMatrix2x2(this._uniforms[uniformName], matrix);
    };
    /**
     * Sets a float on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value value to be set.
     * @returns this effect.
     */
    NativePipelineContext.prototype.setFloat = function (uniformName, value) {
        var cache = this._valueCache[uniformName];
        if (cache !== undefined && cache === value) {
            return;
        }
        this._valueCache[uniformName] = value;
        this.engine.setFloat(this._uniforms[uniformName], value);
    };
    /**
     * Sets a boolean on a uniform variable.
     * @param uniformName Name of the variable.
     * @param bool value to be set.
     */
    NativePipelineContext.prototype.setBool = function (uniformName, bool) {
        var cache = this._valueCache[uniformName];
        if (cache !== undefined && cache === bool) {
            return;
        }
        this._valueCache[uniformName] = bool;
        this.engine.setBool(this._uniforms[uniformName], bool ? 1 : 0);
    };
    /**
     * Sets a Vector2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector2 vector2 to be set.
     */
    NativePipelineContext.prototype.setVector2 = function (uniformName, vector2) {
        if (this._cacheFloat2(uniformName, vector2.x, vector2.y)) {
            this.engine.setFloat2(this._uniforms[uniformName], vector2.x, vector2.y);
        }
    };
    /**
     * Sets a float2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float2.
     * @param y Second float in float2.
     */
    NativePipelineContext.prototype.setFloat2 = function (uniformName, x, y) {
        if (this._cacheFloat2(uniformName, x, y)) {
            this.engine.setFloat2(this._uniforms[uniformName], x, y);
        }
    };
    /**
     * Sets a Vector3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector3 Value to be set.
     */
    NativePipelineContext.prototype.setVector3 = function (uniformName, vector3) {
        if (this._cacheFloat3(uniformName, vector3.x, vector3.y, vector3.z)) {
            this.engine.setFloat3(this._uniforms[uniformName], vector3.x, vector3.y, vector3.z);
        }
    };
    /**
     * Sets a float3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float3.
     * @param y Second float in float3.
     * @param z Third float in float3.
     */
    NativePipelineContext.prototype.setFloat3 = function (uniformName, x, y, z) {
        if (this._cacheFloat3(uniformName, x, y, z)) {
            this.engine.setFloat3(this._uniforms[uniformName], x, y, z);
        }
    };
    /**
     * Sets a Vector4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector4 Value to be set.
     */
    NativePipelineContext.prototype.setVector4 = function (uniformName, vector4) {
        if (this._cacheFloat4(uniformName, vector4.x, vector4.y, vector4.z, vector4.w)) {
            this.engine.setFloat4(this._uniforms[uniformName], vector4.x, vector4.y, vector4.z, vector4.w);
        }
    };
    /**
     * Sets a float4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float4.
     * @param y Second float in float4.
     * @param z Third float in float4.
     * @param w Fourth float in float4.
     * @returns this effect.
     */
    NativePipelineContext.prototype.setFloat4 = function (uniformName, x, y, z, w) {
        if (this._cacheFloat4(uniformName, x, y, z, w)) {
            this.engine.setFloat4(this._uniforms[uniformName], x, y, z, w);
        }
    };
    /**
     * Sets a Color3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     */
    NativePipelineContext.prototype.setColor3 = function (uniformName, color3) {
        if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {
            this.engine.setFloat3(this._uniforms[uniformName], color3.r, color3.g, color3.b);
        }
    };
    /**
     * Sets a Color4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     * @param alpha Alpha value to be set.
     */
    NativePipelineContext.prototype.setColor4 = function (uniformName, color3, alpha) {
        if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {
            this.engine.setFloat4(this._uniforms[uniformName], color3.r, color3.g, color3.b, alpha);
        }
    };
    /**
     * Sets a Color4 on a uniform variable
     * @param uniformName defines the name of the variable
     * @param color4 defines the value to be set
     */
    NativePipelineContext.prototype.setDirectColor4 = function (uniformName, color4) {
        if (this._cacheFloat4(uniformName, color4.r, color4.g, color4.b, color4.a)) {
            this.engine.setDirectColor4(this._uniforms[uniformName], color4);
        }
    };
    return NativePipelineContext;
}());
/**
 * Container for accessors for natively-stored mesh data buffers.
 */
var NativeDataBuffer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NativeDataBuffer, _super);
    function NativeDataBuffer() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return NativeDataBuffer;
}(_Meshes_dataBuffer__WEBPACK_IMPORTED_MODULE_4__["DataBuffer"]));
// TODO: change this to match bgfx.
// Must match Filter enum in SpectreEngine.h.
var NativeFilter = /** @class */ (function () {
    function NativeFilter() {
    }
    NativeFilter.POINT = 0;
    NativeFilter.MINPOINT_MAGPOINT_MIPPOINT = NativeFilter.POINT;
    NativeFilter.BILINEAR = 1;
    NativeFilter.MINLINEAR_MAGLINEAR_MIPPOINT = NativeFilter.BILINEAR;
    NativeFilter.TRILINEAR = 2;
    NativeFilter.MINLINEAR_MAGLINEAR_MIPLINEAR = NativeFilter.TRILINEAR;
    NativeFilter.ANISOTROPIC = 3;
    NativeFilter.POINT_COMPARE = 4;
    NativeFilter.TRILINEAR_COMPARE = 5;
    NativeFilter.MINBILINEAR_MAGPOINT = 6;
    NativeFilter.MINLINEAR_MAGPOINT_MIPLINEAR = NativeFilter.MINBILINEAR_MAGPOINT;
    NativeFilter.MINPOINT_MAGPOINT_MIPLINEAR = 7;
    NativeFilter.MINPOINT_MAGLINEAR_MIPPOINT = 8;
    NativeFilter.MINPOINT_MAGLINEAR_MIPLINEAR = 9;
    NativeFilter.MINLINEAR_MAGPOINT_MIPPOINT = 10;
    return NativeFilter;
}());
// TODO: change this to match bgfx.
// Must match AddressMode enum in SpectreEngine.h.
var NativeAddressMode = /** @class */ (function () {
    function NativeAddressMode() {
    }
    NativeAddressMode.WRAP = 0;
    NativeAddressMode.MIRROR = 1;
    NativeAddressMode.CLAMP = 2;
    NativeAddressMode.BORDER = 3;
    NativeAddressMode.MIRROR_ONCE = 4;
    return NativeAddressMode;
}());
/** @hidden */
var NativeEngine = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NativeEngine, _super);
    function NativeEngine() {
        var _this = _super.call(this, null) || this;
        _this._native = nativeEngine;
        _this._webGLVersion = 2;
        _this.disableUniformBuffers = true;
        // TODO: Initialize this more correctly based on the hardware capabilities.
        // Init caps
        _this._caps = new _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["EngineCapabilities"]();
        _this._caps.maxTexturesImageUnits = 16;
        _this._caps.maxVertexTextureImageUnits = 16;
        _this._caps.maxTextureSize = 512;
        _this._caps.maxCubemapTextureSize = 512;
        _this._caps.maxRenderTextureSize = 512;
        _this._caps.maxVertexAttribs = 16;
        _this._caps.maxVaryingVectors = 16;
        _this._caps.maxFragmentUniformVectors = 16;
        _this._caps.maxVertexUniformVectors = 16;
        // Extensions
        _this._caps.standardDerivatives = true;
        _this._caps.astc = null;
        _this._caps.s3tc = null;
        _this._caps.pvrtc = null;
        _this._caps.etc1 = null;
        _this._caps.etc2 = null;
        _this._caps.maxAnisotropy = 16; // TODO: Retrieve this smartly. Currently set to D3D11 maximum allowable value.
        _this._caps.uintIndices = false;
        _this._caps.fragmentDepthSupported = false;
        _this._caps.highPrecisionShaderSupported = true;
        _this._caps.colorBufferFloat = false;
        _this._caps.textureFloat = false;
        _this._caps.textureFloatLinearFiltering = false;
        _this._caps.textureFloatRender = false;
        _this._caps.textureHalfFloat = false;
        _this._caps.textureHalfFloatLinearFiltering = false;
        _this._caps.textureHalfFloatRender = false;
        _this._caps.textureLOD = true;
        _this._caps.drawBuffersExtension = false;
        _this._caps.depthTextureExtension = false;
        _this._caps.vertexArrayObject = true;
        _this._caps.instancedArrays = false;
        _Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].Log("Babylon Native (v" + _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].Version + ") launched");
        // Wrappers
        if (typeof URL === "undefined") {
            window.URL = {
                createObjectURL: function () { },
                revokeObjectURL: function () { }
            };
        }
        if (typeof Blob === "undefined") {
            window.Blob = function () { };
        }
        // Shader processor
        _this._shaderProcessor = new _Native_nativeShaderProcessor__WEBPACK_IMPORTED_MODULE_8__["NativeShaderProcessor"]();
        return _this;
    }
    NativeEngine.prototype.getHardwareScalingLevel = function () {
        return 1.0;
    };
    /**
     * Can be used to override the current requestAnimationFrame requester.
     * @hidden
     */
    NativeEngine.prototype._queueNewFrame = function (bindedRenderFunction, requester) {
        this._native.requestAnimationFrame(bindedRenderFunction);
        return 0;
    };
    NativeEngine.prototype.clear = function (color, backBuffer, depth, stencil) {
        if (stencil === void 0) { stencil = false; }
        this._native.clear(color.r, color.g, color.b, color.a, backBuffer, depth, stencil);
    };
    NativeEngine.prototype.createIndexBuffer = function (indices) {
        var data = this._normalizeIndexData(indices);
        var buffer = new NativeDataBuffer();
        buffer.references = 1;
        buffer.is32Bits = (data.BYTES_PER_ELEMENT === 4);
        buffer.nativeIndexBuffer = this._native.createIndexBuffer(data);
        return buffer;
    };
    NativeEngine.prototype.createVertexBuffer = function (data) {
        var buffer = new NativeDataBuffer();
        buffer.references = 1;
        buffer.nativeVertexBuffer = this._native.createVertexBuffer(ArrayBuffer.isView(data) ? data : new Float32Array(data));
        return buffer;
    };
    NativeEngine.prototype.recordVertexArrayObject = function (vertexBuffers, indexBuffer, effect) {
        var vertexArray = this._native.createVertexArray();
        if (indexBuffer) {
            this._native.recordIndexBuffer(vertexArray, indexBuffer.nativeIndexBuffer);
        }
        var attributes = effect.getAttributesNames();
        for (var index = 0; index < attributes.length; index++) {
            var location_1 = effect.getAttributeLocation(index);
            if (location_1 >= 0) {
                var kind = attributes[index];
                var vertexBuffer = vertexBuffers[kind];
                if (vertexBuffer) {
                    var buffer = vertexBuffer.getBuffer();
                    if (buffer) {
                        this._native.recordVertexBuffer(vertexArray, buffer.nativeVertexBuffer, location_1, vertexBuffer.byteOffset, vertexBuffer.byteStride, vertexBuffer.getSize(), vertexBuffer.type, vertexBuffer.normalized);
                    }
                }
            }
        }
        return vertexArray;
    };
    NativeEngine.prototype.bindVertexArrayObject = function (vertexArray) {
        this._native.bindVertexArray(vertexArray);
    };
    NativeEngine.prototype.releaseVertexArrayObject = function (vertexArray) {
        this._native.deleteVertexArray(vertexArray);
    };
    NativeEngine.prototype.getAttributes = function (pipelineContext, attributesNames) {
        var nativePipelineContext = pipelineContext;
        return this._native.getAttributes(nativePipelineContext.nativeProgram, attributesNames);
    };
    /**
     * Draw a list of indexed primitives
     * @param fillMode defines the primitive to use
     * @param indexStart defines the starting index
     * @param indexCount defines the number of index to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    NativeEngine.prototype.drawElementsType = function (fillMode, indexStart, indexCount, instancesCount) {
        // Apply states
        this._drawCalls.addCount(1, false);
        // TODO: Make this implementation more robust like core Engine version.
        // Render
        //var indexFormat = this._uintIndicesCurrentlySet ? this._gl.UNSIGNED_INT : this._gl.UNSIGNED_SHORT;
        //var mult = this._uintIndicesCurrentlySet ? 4 : 2;
        // if (instancesCount) {
        //     this._gl.drawElementsInstanced(drawMode, indexCount, indexFormat, indexStart * mult, instancesCount);
        // } else {
        this._native.drawIndexed(fillMode, indexStart, indexCount);
        // }
    };
    /**
     * Draw a list of unindexed primitives
     * @param fillMode defines the primitive to use
     * @param verticesStart defines the index of first vertex to draw
     * @param verticesCount defines the count of vertices to draw
     * @param instancesCount defines the number of instances to draw (if instanciation is enabled)
     */
    NativeEngine.prototype.drawArraysType = function (fillMode, verticesStart, verticesCount, instancesCount) {
        // Apply states
        this._drawCalls.addCount(1, false);
        // TODO: Make this implementation more robust like core Engine version.
        // if (instancesCount) {
        //     this._gl.drawArraysInstanced(drawMode, verticesStart, verticesCount, instancesCount);
        // } else {
        this._native.draw(fillMode, verticesStart, verticesCount);
        // }
    };
    NativeEngine.prototype.createPipelineContext = function () {
        return new NativePipelineContext();
    };
    NativeEngine.prototype._preparePipelineContext = function (pipelineContext, vertexSourceCode, fragmentSourceCode, createAsRaw, rebuildRebind, defines, transformFeedbackVaryings) {
        var nativePipelineContext = pipelineContext;
        if (createAsRaw) {
            nativePipelineContext.nativeProgram = this.createRawShaderProgram(pipelineContext, vertexSourceCode, fragmentSourceCode, undefined, transformFeedbackVaryings);
        }
        else {
            nativePipelineContext.nativeProgram = this.createShaderProgram(pipelineContext, vertexSourceCode, fragmentSourceCode, defines, undefined, transformFeedbackVaryings);
        }
    };
    /** @hidden */
    NativeEngine.prototype._isRenderingStateCompiled = function (pipelineContext) {
        // TODO: support async shader compilcation
        return true;
    };
    /** @hidden */
    NativeEngine.prototype._executeWhenRenderingStateIsCompiled = function (pipelineContext, action) {
        // TODO: support async shader compilcation
        action();
    };
    NativeEngine.prototype.createRawShaderProgram = function (pipelineContext, vertexCode, fragmentCode, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        throw new Error("Not Supported");
    };
    NativeEngine.prototype.createShaderProgram = function (pipelineContext, vertexCode, fragmentCode, defines, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        this.onBeforeShaderCompilationObservable.notifyObservers(this);
        var program = this._native.createProgram(_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._concatenateShader(vertexCode, defines), _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._concatenateShader(fragmentCode, defines));
        this.onAfterShaderCompilationObservable.notifyObservers(this);
        return program;
    };
    NativeEngine.prototype._setProgram = function (program) {
        if (this._currentProgram !== program) {
            this._native.setProgram(program);
            this._currentProgram = program;
        }
    };
    NativeEngine.prototype._releaseEffect = function (effect) {
        // TODO
    };
    NativeEngine.prototype._deletePipelineContext = function (pipelineContext) {
        // TODO
    };
    NativeEngine.prototype.getUniforms = function (pipelineContext, uniformsNames) {
        var nativePipelineContext = pipelineContext;
        return this._native.getUniforms(nativePipelineContext.nativeProgram, uniformsNames);
    };
    NativeEngine.prototype.bindUniformBlock = function (pipelineContext, blockName, index) {
        // TODO
        throw new Error("Not Implemented");
    };
    NativeEngine.prototype.bindSamplers = function (effect) {
        var nativePipelineContext = effect.getPipelineContext();
        this._setProgram(nativePipelineContext.nativeProgram);
        // TODO: share this with engine?
        var samplers = effect.getSamplers();
        for (var index = 0; index < samplers.length; index++) {
            var uniform = effect.getUniform(samplers[index]);
            if (uniform) {
                this._boundUniforms[index] = uniform;
            }
        }
        this._currentEffect = null;
    };
    NativeEngine.prototype.setMatrix = function (uniform, matrix) {
        if (!uniform) {
            return;
        }
        this._native.setMatrix(uniform, matrix.toArray());
    };
    NativeEngine.prototype.getRenderWidth = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.width;
        }
        return this._native.getRenderWidth();
    };
    NativeEngine.prototype.getRenderHeight = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.height;
        }
        return this._native.getRenderHeight();
    };
    NativeEngine.prototype.setViewport = function (viewport, requiredWidth, requiredHeight) {
        // TODO: Implement.
        this._cachedViewport = viewport;
    };
    NativeEngine.prototype.setState = function (culling, zOffset, force, reverseSide) {
        if (zOffset === void 0) { zOffset = 0; }
        if (reverseSide === void 0) { reverseSide = false; }
        this._native.setState(culling, zOffset, reverseSide);
    };
    /**
     * Set the z offset to apply to current rendering
     * @param value defines the offset to apply
     */
    NativeEngine.prototype.setZOffset = function (value) {
        this._native.setZOffset(value);
    };
    /**
     * Gets the current value of the zOffset
     * @returns the current zOffset state
     */
    NativeEngine.prototype.getZOffset = function () {
        return this._native.getZOffset();
    };
    /**
     * Enable or disable depth buffering
     * @param enable defines the state to set
     */
    NativeEngine.prototype.setDepthBuffer = function (enable) {
        this._native.setDepthTest(enable);
    };
    /**
     * Gets a boolean indicating if depth writing is enabled
     * @returns the current depth writing state
     */
    NativeEngine.prototype.getDepthWrite = function () {
        return this._native.getDepthWrite();
    };
    /**
     * Enable or disable depth writing
     * @param enable defines the state to set
     */
    NativeEngine.prototype.setDepthWrite = function (enable) {
        this._native.setDepthWrite(enable);
    };
    /**
     * Enable or disable color writing
     * @param enable defines the state to set
     */
    NativeEngine.prototype.setColorWrite = function (enable) {
        this._native.setColorWrite(enable);
        this._colorWrite = enable;
    };
    /**
     * Gets a boolean indicating if color writing is enabled
     * @returns the current color writing state
     */
    NativeEngine.prototype.getColorWrite = function () {
        return this._colorWrite;
    };
    /**
     * Sets alpha constants used by some alpha blending modes
     * @param r defines the red component
     * @param g defines the green component
     * @param b defines the blue component
     * @param a defines the alpha component
     */
    NativeEngine.prototype.setAlphaConstants = function (r, g, b, a) {
        throw new Error("Setting alpha blend constant color not yet implemented.");
    };
    /**
     * Sets the current alpha mode
     * @param mode defines the mode to use (one of the BABYLON.Engine.ALPHA_XXX)
     * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)
     * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
     */
    NativeEngine.prototype.setAlphaMode = function (mode, noDepthWriteChange) {
        if (noDepthWriteChange === void 0) { noDepthWriteChange = false; }
        if (this._alphaMode === mode) {
            return;
        }
        this._native.setBlendMode(mode);
        if (!noDepthWriteChange) {
            this.setDepthWrite(mode === _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].ALPHA_DISABLE);
        }
        this._alphaMode = mode;
    };
    /**
     * Gets the current alpha mode
     * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
     * @returns the current alpha mode
     */
    NativeEngine.prototype.getAlphaMode = function () {
        return this._alphaMode;
    };
    NativeEngine.prototype.setIntArray = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setIntArray(uniform, array);
    };
    NativeEngine.prototype.setIntArray2 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setIntArray2(uniform, array);
    };
    NativeEngine.prototype.setIntArray3 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setIntArray3(uniform, array);
    };
    NativeEngine.prototype.setIntArray4 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setIntArray4(uniform, array);
    };
    NativeEngine.prototype.setFloatArray = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray(uniform, array);
    };
    NativeEngine.prototype.setFloatArray2 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray2(uniform, array);
    };
    NativeEngine.prototype.setFloatArray3 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray3(uniform, array);
    };
    NativeEngine.prototype.setFloatArray4 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray4(uniform, array);
    };
    NativeEngine.prototype.setArray = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray(uniform, array);
    };
    NativeEngine.prototype.setArray2 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray2(uniform, array);
    };
    NativeEngine.prototype.setArray3 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray3(uniform, array);
    };
    NativeEngine.prototype.setArray4 = function (uniform, array) {
        if (!uniform) {
            return;
        }
        this._native.setFloatArray4(uniform, array);
    };
    NativeEngine.prototype.setMatrices = function (uniform, matrices) {
        if (!uniform) {
            return;
        }
        this._native.setMatrices(uniform, matrices);
    };
    NativeEngine.prototype.setMatrix3x3 = function (uniform, matrix) {
        if (!uniform) {
            return;
        }
        this._native.setMatrix3x3(uniform, matrix);
    };
    NativeEngine.prototype.setMatrix2x2 = function (uniform, matrix) {
        if (!uniform) {
            return;
        }
        this._native.setMatrix2x2(uniform, matrix);
    };
    NativeEngine.prototype.setFloat = function (uniform, value) {
        if (!uniform) {
            return;
        }
        this._native.setFloat(uniform, value);
    };
    NativeEngine.prototype.setFloat2 = function (uniform, x, y) {
        if (!uniform) {
            return;
        }
        this._native.setFloat2(uniform, x, y);
    };
    NativeEngine.prototype.setFloat3 = function (uniform, x, y, z) {
        if (!uniform) {
            return;
        }
        this._native.setFloat3(uniform, x, y, z);
    };
    NativeEngine.prototype.setBool = function (uniform, bool) {
        if (!uniform) {
            return;
        }
        this._native.setBool(uniform, bool);
    };
    NativeEngine.prototype.setFloat4 = function (uniform, x, y, z, w) {
        if (!uniform) {
            return;
        }
        this._native.setFloat4(uniform, x, y, z, w);
    };
    NativeEngine.prototype.setColor3 = function (uniform, color3) {
        if (!uniform) {
            return;
        }
        this._native.setFloat3(uniform, color3.r, color3.g, color3.b);
    };
    NativeEngine.prototype.setColor4 = function (uniform, color3, alpha) {
        if (!uniform) {
            return;
        }
        this._native.setFloat4(uniform, color3.r, color3.g, color3.b, alpha);
    };
    NativeEngine.prototype.wipeCaches = function (bruteForce) {
        if (this.preventCacheWipeBetweenFrames) {
            return;
        }
        this.resetTextureCache();
        this._currentEffect = null;
        if (bruteForce) {
            this._currentProgram = null;
            this._stencilState.reset();
            this._depthCullingState.reset();
            this._alphaState.reset();
        }
        this._cachedVertexBuffers = null;
        this._cachedIndexBuffer = null;
        this._cachedEffectForVertexBuffers = null;
    };
    NativeEngine.prototype._createTexture = function () {
        return this._native.createTexture();
    };
    NativeEngine.prototype._deleteTexture = function (texture) {
        this._native.deleteTexture(texture);
    };
    // TODO: Refactor to share more logic with babylon.engine.ts version.
    /**
     * Usually called from BABYLON.Texture.ts.
     * Passed information to create a WebGLTexture
     * @param urlArg defines a value which contains one of the following:
     * * A conventional http URL, e.g. 'http://...' or 'file://...'
     * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
     * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
     * @param invertY when true, image is flipped when loaded.  You probably want true. Ignored for compressed textures.  Must be flipped in the file
     * @param scene needed for loading to the correct scene
     * @param samplingMode mode with should be used sample / access the texture (Default: BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
     * @param onLoad optional callback to be called upon successful completion
     * @param onError optional callback to be called upon failure
     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), or a Blob
     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
     * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
     * @param forcedExtension defines the extension to use to pick the right loader
     * @returns a InternalTexture for assignment back into BABYLON.Texture
     */
    NativeEngine.prototype.createTexture = function (urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, fallback, format, forcedExtension) {
        var _this = this;
        if (samplingMode === void 0) { samplingMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (buffer === void 0) { buffer = null; }
        if (fallback === void 0) { fallback = null; }
        if (format === void 0) { format = null; }
        if (forcedExtension === void 0) { forcedExtension = null; }
        var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
        var fromData = url.substr(0, 5) === "data:";
        var fromBlob = url.substr(0, 5) === "blob:";
        var isBase64 = fromData && url.indexOf("base64") !== -1;
        var texture = fallback ? fallback : new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_URL);
        // establish the file extension, if possible
        var lastDot = url.lastIndexOf('.');
        var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? url.substring(lastDot).toLowerCase() : "");
        // TODO: Add support for compressed texture formats.
        var textureFormatInUse = null;
        var loader = null;
        for (var _i = 0, _a = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._TextureLoaders; _i < _a.length; _i++) {
            var availableLoader = _a[_i];
            if (availableLoader.canLoad(extension, textureFormatInUse, fallback, isBase64, buffer ? true : false)) {
                loader = availableLoader;
                break;
            }
        }
        if (loader) {
            url = loader.transformUrl(url, textureFormatInUse);
        }
        if (scene) {
            scene._addPendingData(texture);
        }
        texture.url = url;
        texture.generateMipMaps = !noMipmap;
        texture.samplingMode = samplingMode;
        texture.invertY = invertY;
        if (!this.doNotHandleContextLost) {
            // Keep a link to the buffer only if we plan to handle context lost
            texture._buffer = buffer;
        }
        var onLoadObserver = null;
        if (onLoad && !fallback) {
            onLoadObserver = texture.onLoadedObservable.add(onLoad);
        }
        if (!fallback) {
            this._internalTexturesCache.push(texture);
        }
        var onInternalError = function (message, exception) {
            if (scene) {
                scene._removePendingData(texture);
            }
            var customFallback = false;
            if (loader) {
                var fallbackUrl = loader.getFallbackTextureUrl(url, textureFormatInUse);
                if (fallbackUrl) {
                    // Add Back
                    customFallback = true;
                    _this.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
                }
            }
            if (!customFallback) {
                if (onLoadObserver) {
                    texture.onLoadedObservable.remove(onLoadObserver);
                }
                if (_Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].UseFallbackTexture) {
                    _this.createTexture(_Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].fallbackTexture, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
                }
            }
            if (onError) {
                onError(message || "Unknown error", exception);
            }
        };
        // processing for non-image formats
        if (loader) {
            throw new Error("Loading textures from IInternalTextureLoader not yet implemented.");
            // var callback = (data: string | ArrayBuffer) => {
            //     loader!.loadData(data as ArrayBuffer, texture, (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => {
            //         this._prepareWebGLTexture(texture, scene, width, height, invertY, !loadMipmap, isCompressed, () => {
            //                 done();
            //                 return false;
            //             },
            //             samplingMode);
            //     });
            // }
            // if (!buffer) {
            //     this._loadFile(url, callback, undefined, scene ? scene.database : undefined, true, (request?: XMLHttpRequest, exception?: any) => {
            //         onInternalError("Unable to load " + (request ? request.responseURL : url, exception));
            //     });
            // } else {
            //     callback(buffer as ArrayBuffer);
            // }
        }
        else {
            var onload = function (data, responseURL) {
                if (typeof (data) === "string") {
                    throw new Error("Loading textures from string data not yet implemented.");
                }
                if (fromBlob && !_this.doNotHandleContextLost) {
                    // We need to store the image if we need to rebuild the texture
                    // in case of a webgl context lost
                    texture._buffer = data;
                }
                var webGLTexture = texture._webGLTexture;
                if (!webGLTexture) {
                    //  this.resetTextureCache();
                    if (scene) {
                        scene._removePendingData(texture);
                    }
                    return;
                }
                _this._native.loadTexture(webGLTexture, data, !noMipmap);
                if (invertY) {
                    throw new Error("Support for textures with inverted Y coordinates not yet implemented.");
                }
                //this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
                texture.baseWidth = _this._native.getTextureWidth(webGLTexture);
                texture.baseHeight = _this._native.getTextureHeight(webGLTexture);
                texture.width = texture.baseWidth;
                texture.height = texture.baseHeight;
                texture.isReady = true;
                var filter = _this._getSamplingFilter(samplingMode);
                _this._native.setTextureSampling(webGLTexture, filter);
                // this.resetTextureCache();
                if (scene) {
                    scene._removePendingData(texture);
                }
                texture.onLoadedObservable.notifyObservers(texture);
                texture.onLoadedObservable.clear();
            };
            if (buffer instanceof ArrayBuffer) {
                onload(buffer);
            }
            else if (ArrayBuffer.isView(buffer)) {
                onload(buffer.buffer);
            }
            else if (buffer instanceof Blob) {
                throw new Error("Loading texture from Blob not yet implemented.");
            }
            else if (!fromData) {
                var onLoadFileError = function (request, exception) {
                    onInternalError("Failed to retrieve " + url + ".", exception);
                };
                _Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].LoadFile(url, onload, undefined, undefined, /*useArrayBuffer*/ true, onLoadFileError);
            }
            else {
                onload(_Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].DecodeBase64(buffer));
            }
        }
        return texture;
    };
    /**
     * Creates a cube texture
     * @param rootUrl defines the url where the files to load is located
     * @param scene defines the current scene
     * @param files defines the list of files to load (1 per face)
     * @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)
     * @param onLoad defines an optional callback raised when the texture is loaded
     * @param onError defines an optional callback raised if there is an issue to load the texture
     * @param format defines the format of the data
     * @param forcedExtension defines the extension to use to pick the right loader
     * @param createPolynomials if a polynomial sphere should be created for the cube texture
     * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
     * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
     * @param fallback defines texture to use while falling back when (compressed) texture file not found.
     * @returns the cube texture as an InternalTexture
     */
    NativeEngine.prototype.createCubeTexture = function (rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback) {
        var _this = this;
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (forcedExtension === void 0) { forcedExtension = null; }
        if (createPolynomials === void 0) { createPolynomials = false; }
        if (lodScale === void 0) { lodScale = 0; }
        if (lodOffset === void 0) { lodOffset = 0; }
        if (fallback === void 0) { fallback = null; }
        var texture = fallback ? fallback : new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_CUBE);
        texture.isCube = true;
        texture.url = rootUrl;
        texture.generateMipMaps = !noMipmap;
        texture._lodGenerationScale = lodScale;
        texture._lodGenerationOffset = lodOffset;
        if (!this._doNotHandleContextLost) {
            texture._extension = forcedExtension;
            texture._files = files;
        }
        var lastDot = rootUrl.lastIndexOf('.');
        var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
        if (extension === ".env") {
            var onloaddata = function (data) {
                data = data;
                var info = _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_6__["EnvironmentTextureTools"].GetEnvInfo(data);
                texture.width = info.width;
                texture.height = info.width;
                _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_6__["EnvironmentTextureTools"].UploadEnvSpherical(texture, info);
                if (info.version !== 1) {
                    throw new Error("Unsupported babylon environment map version \"" + info.version + "\"");
                }
                var specularInfo = info.specular;
                if (!specularInfo) {
                    throw new Error("Nothing else parsed so far");
                }
                texture._lodGenerationScale = specularInfo.lodGenerationScale;
                var imageData = _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_6__["EnvironmentTextureTools"].CreateImageDataArrayBufferViews(data, info);
                texture.format = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTUREFORMAT_RGBA;
                texture.type = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_UNSIGNED_INT;
                texture.generateMipMaps = true;
                texture.getEngine().updateTextureSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].TRILINEAR_SAMPLINGMODE, texture);
                texture._isRGBD = true;
                texture.invertY = true;
                _this._native.loadCubeTexture(texture._webGLTexture, imageData, true);
                texture.isReady = true;
                if (onLoad) {
                    onLoad();
                }
            };
            if (files && files.length === 6) {
                throw new Error("Multi-file loading not yet supported.");
            }
            else {
                var onInternalError = function (request, exception) {
                    if (onError && request) {
                        onError(request.status + " " + request.statusText, exception);
                    }
                };
                this._loadFile(rootUrl, onloaddata, undefined, undefined, true, onInternalError);
            }
        }
        else {
            throw new Error("Cannot load cubemap: non-ENV format not supported.");
        }
        this._internalTexturesCache.push(texture);
        return texture;
    };
    // Returns a NativeFilter.XXXX value.
    NativeEngine.prototype._getSamplingFilter = function (samplingMode) {
        switch (samplingMode) {
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_BILINEAR_SAMPLINGMODE:
                return NativeFilter.MINLINEAR_MAGLINEAR_MIPPOINT;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_TRILINEAR_SAMPLINGMODE:
                return NativeFilter.MINLINEAR_MAGLINEAR_MIPLINEAR;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE:
                return NativeFilter.MINPOINT_MAGPOINT_MIPLINEAR;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_NEAREST_MIPNEAREST:
                return NativeFilter.MINPOINT_MAGPOINT_MIPPOINT;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_LINEAR_MIPNEAREST:
                return NativeFilter.MINLINEAR_MAGPOINT_MIPPOINT;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_LINEAR_MIPLINEAR:
                return NativeFilter.MINLINEAR_MAGPOINT_MIPLINEAR;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_LINEAR:
                return NativeFilter.MINLINEAR_MAGPOINT_MIPLINEAR;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_NEAREST_NEAREST:
                return NativeFilter.MINPOINT_MAGPOINT_MIPPOINT;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_LINEAR_NEAREST_MIPNEAREST:
                return NativeFilter.MINPOINT_MAGLINEAR_MIPPOINT;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_LINEAR_NEAREST_MIPLINEAR:
                return NativeFilter.MINPOINT_MAGLINEAR_MIPLINEAR;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_LINEAR_LINEAR:
                return NativeFilter.MINLINEAR_MAGLINEAR_MIPLINEAR;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_LINEAR_NEAREST:
                return NativeFilter.MINPOINT_MAGLINEAR_MIPLINEAR;
            default:
                throw new Error("Unexpected sampling mode: " + samplingMode + ".");
        }
    };
    NativeEngine.prototype.createRenderTargetTexture = function (size, options) {
        var fullOptions = new _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_7__["RenderTargetCreationOptions"]();
        if (options !== undefined && typeof options === "object") {
            fullOptions.generateMipMaps = options.generateMipMaps;
            fullOptions.generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
            fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && options.generateStencilBuffer;
            fullOptions.type = options.type === undefined ? _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_UNSIGNED_INT : options.type;
            fullOptions.samplingMode = options.samplingMode === undefined ? _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].TRILINEAR_SAMPLINGMODE : options.samplingMode;
        }
        else {
            fullOptions.generateMipMaps = options;
            fullOptions.generateDepthBuffer = true;
            fullOptions.generateStencilBuffer = false;
            fullOptions.type = _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURETYPE_UNSIGNED_INT;
            fullOptions.samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].TRILINEAR_SAMPLINGMODE;
        }
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_RENDERTARGET);
        var width = size.width || size;
        var height = size.height || size;
        texture._depthStencilBuffer = {};
        texture._framebuffer = {};
        texture.baseWidth = width;
        texture.baseHeight = height;
        texture.width = width;
        texture.height = height;
        texture.isReady = true;
        texture.samples = 1;
        texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;
        texture.samplingMode = fullOptions.samplingMode;
        texture.type = fullOptions.type;
        texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
        texture._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;
        this._internalTexturesCache.push(texture);
        return texture;
    };
    NativeEngine.prototype.updateTextureSamplingMode = function (samplingMode, texture) {
        if (texture._webGLTexture) {
            var filter = this._getSamplingFilter(samplingMode);
            this._native.setTextureSampling(texture._webGLTexture, filter);
        }
        texture.samplingMode = samplingMode;
    };
    NativeEngine.prototype.bindFramebuffer = function (texture, faceIndex, requiredWidth, requiredHeight, forceFullscreenViewport) {
        throw new Error("bindFramebuffer not yet implemented.");
    };
    NativeEngine.prototype.unBindFramebuffer = function (texture, disableGenerateMipMaps, onBeforeUnbind) {
        if (disableGenerateMipMaps === void 0) { disableGenerateMipMaps = false; }
        throw new Error("unBindFramebuffer not yet implemented.");
    };
    NativeEngine.prototype.createDynamicVertexBuffer = function (data) {
        throw new Error("createDynamicVertexBuffer not yet implemented.");
    };
    NativeEngine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
        if (offset === void 0) { offset = 0; }
        throw new Error("updateDynamicIndexBuffer not yet implemented.");
    };
    /**
     * Updates a dynamic vertex buffer.
     * @param vertexBuffer the vertex buffer to update
     * @param data the data used to update the vertex buffer
     * @param byteOffset the byte offset of the data (optional)
     * @param byteLength the byte length of the data (optional)
     */
    NativeEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, data, byteOffset, byteLength) {
        throw new Error("updateDynamicVertexBuffer not yet implemented.");
    };
    // TODO: Refactor to share more logic with base Engine implementation.
    NativeEngine.prototype._setTexture = function (channel, texture, isPartOfTextureArray, depthStencilTexture) {
        if (isPartOfTextureArray === void 0) { isPartOfTextureArray = false; }
        if (depthStencilTexture === void 0) { depthStencilTexture = false; }
        var uniform = this._boundUniforms[channel];
        if (!uniform) {
            return false;
        }
        // Not ready?
        if (!texture) {
            if (this._boundTexturesCache[channel] != null) {
                this._activeChannel = channel;
                this._native.setTexture(uniform, null);
            }
            return false;
        }
        // Video
        if (texture.video) {
            this._activeChannel = channel;
            texture.update();
        }
        else if (texture.delayLoadState === _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].DELAYLOADSTATE_NOTLOADED) { // Delay loading
            texture.delayLoad();
            return false;
        }
        var internalTexture;
        if (depthStencilTexture) {
            internalTexture = texture.depthStencilTexture;
        }
        else if (texture.isReady()) {
            internalTexture = texture.getInternalTexture();
        }
        else if (texture.isCube) {
            internalTexture = this.emptyCubeTexture;
        }
        else if (texture.is3D) {
            internalTexture = this.emptyTexture3D;
        }
        else {
            internalTexture = this.emptyTexture;
        }
        this._activeChannel = channel;
        if (!internalTexture ||
            !internalTexture._webGLTexture) {
            return false;
        }
        this._native.setTextureWrapMode(internalTexture._webGLTexture, this._getAddressMode(texture.wrapU), this._getAddressMode(texture.wrapV), this._getAddressMode(texture.wrapR));
        this._updateAnisotropicLevel(texture);
        this._native.setTexture(uniform, internalTexture._webGLTexture);
        return true;
    };
    // TODO: Share more of this logic with the base implementation.
    // TODO: Rename to match naming in base implementation once refactoring allows different parameters.
    NativeEngine.prototype._updateAnisotropicLevel = function (texture) {
        var internalTexture = texture.getInternalTexture();
        var value = texture.anisotropicFilteringLevel;
        if (!internalTexture || !internalTexture._webGLTexture) {
            return;
        }
        if (internalTexture._cachedAnisotropicFilteringLevel !== value) {
            this._native.setTextureAnisotropicLevel(internalTexture._webGLTexture, value);
            internalTexture._cachedAnisotropicFilteringLevel = value;
        }
    };
    // Returns a NativeAddressMode.XXX value.
    NativeEngine.prototype._getAddressMode = function (wrapMode) {
        switch (wrapMode) {
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_WRAP_ADDRESSMODE:
                return NativeAddressMode.WRAP;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_CLAMP_ADDRESSMODE:
                return NativeAddressMode.CLAMP;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"].TEXTURE_MIRROR_ADDRESSMODE:
                return NativeAddressMode.MIRROR;
            default:
                throw new Error("Unexpected wrap mode: " + wrapMode + ".");
        }
    };
    /** @hidden */
    NativeEngine.prototype._bindTexture = function (channel, texture) {
        throw new Error("_bindTexture not implemented.");
    };
    NativeEngine.prototype._deleteBuffer = function (buffer) {
        if (buffer.nativeIndexBuffer) {
            this._native.deleteIndexBuffer(buffer.nativeIndexBuffer);
            delete buffer.nativeIndexBuffer;
        }
        if (buffer.nativeVertexBuffer) {
            this._native.deleteVertexBuffer(buffer.nativeVertexBuffer);
            delete buffer.nativeVertexBuffer;
        }
    };
    NativeEngine.prototype.releaseEffects = function () {
        // TODO
    };
    /** @hidden */
    NativeEngine.prototype._uploadCompressedDataToTextureDirectly = function (texture, internalFormat, width, height, data, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        throw new Error("_uploadCompressedDataToTextureDirectly not implemented.");
    };
    /** @hidden */
    NativeEngine.prototype._uploadDataToTextureDirectly = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        throw new Error("_uploadDataToTextureDirectly not implemented.");
    };
    /** @hidden */
    NativeEngine.prototype._uploadArrayBufferViewToTexture = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        throw new Error("_uploadArrayBufferViewToTexture not implemented.");
    };
    /** @hidden */
    NativeEngine.prototype._uploadImageToTexture = function (texture, image, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
        throw new Error("_uploadArrayBufferViewToTexture not implemented.");
    };
    return NativeEngine;
}(_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]));



/***/ }),

/***/ "./Engines/nullEngine.ts":
/*!*******************************!*\
  !*** ./Engines/nullEngine.ts ***!
  \*******************************/
/*! exports provided: NullEngineOptions, NullEngine */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NullEngineOptions", function() { return NullEngineOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NullEngine", function() { return NullEngine; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Materials/Textures/renderTargetCreationOptions */ "./Materials/Textures/renderTargetCreationOptions.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./constants */ "./Engines/constants.ts");
/* harmony import */ var _Meshes_dataBuffer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/dataBuffer */ "./Meshes/dataBuffer.ts");







/**
 * Options to create the null engine
 */
var NullEngineOptions = /** @class */ (function () {
    function NullEngineOptions() {
        /**
         * Render width (Default: 512)
         */
        this.renderWidth = 512;
        /**
         * Render height (Default: 256)
         */
        this.renderHeight = 256;
        /**
         * Texture size (Default: 512)
         */
        this.textureSize = 512;
        /**
         * If delta time between frames should be constant
         * @see https://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
         */
        this.deterministicLockstep = false;
        /**
         * Maximum about of steps between frames (Default: 4)
         * @see https://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
         */
        this.lockstepMaxSteps = 4;
    }
    return NullEngineOptions;
}());

/**
 * The null engine class provides support for headless version of babylon.js.
 * This can be used in server side scenario or for testing purposes
 */
var NullEngine = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NullEngine, _super);
    function NullEngine(options) {
        if (options === void 0) { options = new NullEngineOptions(); }
        var _this = _super.call(this, null) || this;
        if (options.deterministicLockstep === undefined) {
            options.deterministicLockstep = false;
        }
        if (options.lockstepMaxSteps === undefined) {
            options.lockstepMaxSteps = 4;
        }
        _this._options = options;
        // Init caps
        // We consider we are on a webgl1 capable device
        _this._caps = new _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["EngineCapabilities"]();
        _this._caps.maxTexturesImageUnits = 16;
        _this._caps.maxVertexTextureImageUnits = 16;
        _this._caps.maxTextureSize = 512;
        _this._caps.maxCubemapTextureSize = 512;
        _this._caps.maxRenderTextureSize = 512;
        _this._caps.maxVertexAttribs = 16;
        _this._caps.maxVaryingVectors = 16;
        _this._caps.maxFragmentUniformVectors = 16;
        _this._caps.maxVertexUniformVectors = 16;
        // Extensions
        _this._caps.standardDerivatives = false;
        _this._caps.astc = null;
        _this._caps.s3tc = null;
        _this._caps.pvrtc = null;
        _this._caps.etc1 = null;
        _this._caps.etc2 = null;
        _this._caps.textureAnisotropicFilterExtension = null;
        _this._caps.maxAnisotropy = 0;
        _this._caps.uintIndices = false;
        _this._caps.fragmentDepthSupported = false;
        _this._caps.highPrecisionShaderSupported = true;
        _this._caps.colorBufferFloat = false;
        _this._caps.textureFloat = false;
        _this._caps.textureFloatLinearFiltering = false;
        _this._caps.textureFloatRender = false;
        _this._caps.textureHalfFloat = false;
        _this._caps.textureHalfFloatLinearFiltering = false;
        _this._caps.textureHalfFloatRender = false;
        _this._caps.textureLOD = false;
        _this._caps.drawBuffersExtension = false;
        _this._caps.depthTextureExtension = false;
        _this._caps.vertexArrayObject = false;
        _this._caps.instancedArrays = false;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Log("Babylon.js v" + _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].Version + " - Null engine");
        // Wrappers
        var theCurrentGlobal = (typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : window);
        if (typeof URL === "undefined") {
            theCurrentGlobal.URL = {
                createObjectURL: function () { },
                revokeObjectURL: function () { }
            };
        }
        if (typeof Blob === "undefined") {
            theCurrentGlobal.Blob = function () { };
        }
        return _this;
    }
    /**
     * @see https://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     */
    NullEngine.prototype.isDeterministicLockStep = function () {
        return this._options.deterministicLockstep;
    };
    /** @see https://doc.babylonjs.com/babylon101/animations#deterministic-lockstep */
    NullEngine.prototype.getLockstepMaxSteps = function () {
        return this._options.lockstepMaxSteps;
    };
    /**
     * Sets hardware scaling, used to save performance if needed
     * @see https://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
     */
    NullEngine.prototype.getHardwareScalingLevel = function () {
        return 1.0;
    };
    NullEngine.prototype.createVertexBuffer = function (vertices) {
        var buffer = new _Meshes_dataBuffer__WEBPACK_IMPORTED_MODULE_6__["DataBuffer"]();
        buffer.references = 1;
        return buffer;
    };
    NullEngine.prototype.createIndexBuffer = function (indices) {
        var buffer = new _Meshes_dataBuffer__WEBPACK_IMPORTED_MODULE_6__["DataBuffer"]();
        buffer.references = 1;
        return buffer;
    };
    NullEngine.prototype.clear = function (color, backBuffer, depth, stencil) {
        if (stencil === void 0) { stencil = false; }
    };
    NullEngine.prototype.getRenderWidth = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.width;
        }
        return this._options.renderWidth;
    };
    NullEngine.prototype.getRenderHeight = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.height;
        }
        return this._options.renderHeight;
    };
    NullEngine.prototype.setViewport = function (viewport, requiredWidth, requiredHeight) {
        this._cachedViewport = viewport;
    };
    NullEngine.prototype.createShaderProgram = function (pipelineContext, vertexCode, fragmentCode, defines, context) {
        return {
            __SPECTOR_rebuildProgram: null,
        };
    };
    NullEngine.prototype.getUniforms = function (pipelineContext, uniformsNames) {
        return [];
    };
    NullEngine.prototype.getAttributes = function (pipelineContext, attributesNames) {
        return [];
    };
    NullEngine.prototype.bindSamplers = function (effect) {
        this._currentEffect = null;
    };
    NullEngine.prototype.enableEffect = function (effect) {
        this._currentEffect = effect;
        if (effect.onBind) {
            effect.onBind(effect);
        }
        if (effect._onBindObservable) {
            effect._onBindObservable.notifyObservers(effect);
        }
    };
    NullEngine.prototype.setState = function (culling, zOffset, force, reverseSide) {
        if (zOffset === void 0) { zOffset = 0; }
        if (reverseSide === void 0) { reverseSide = false; }
    };
    NullEngine.prototype.setIntArray = function (uniform, array) {
    };
    NullEngine.prototype.setIntArray2 = function (uniform, array) {
    };
    NullEngine.prototype.setIntArray3 = function (uniform, array) {
    };
    NullEngine.prototype.setIntArray4 = function (uniform, array) {
    };
    NullEngine.prototype.setFloatArray = function (uniform, array) {
    };
    NullEngine.prototype.setFloatArray2 = function (uniform, array) {
    };
    NullEngine.prototype.setFloatArray3 = function (uniform, array) {
    };
    NullEngine.prototype.setFloatArray4 = function (uniform, array) {
    };
    NullEngine.prototype.setArray = function (uniform, array) {
    };
    NullEngine.prototype.setArray2 = function (uniform, array) {
    };
    NullEngine.prototype.setArray3 = function (uniform, array) {
    };
    NullEngine.prototype.setArray4 = function (uniform, array) {
    };
    NullEngine.prototype.setMatrices = function (uniform, matrices) {
    };
    NullEngine.prototype.setMatrix3x3 = function (uniform, matrix) {
    };
    NullEngine.prototype.setMatrix2x2 = function (uniform, matrix) {
    };
    NullEngine.prototype.setFloat = function (uniform, value) {
    };
    NullEngine.prototype.setFloat2 = function (uniform, x, y) {
    };
    NullEngine.prototype.setFloat3 = function (uniform, x, y, z) {
    };
    NullEngine.prototype.setBool = function (uniform, bool) {
    };
    NullEngine.prototype.setFloat4 = function (uniform, x, y, z, w) {
    };
    NullEngine.prototype.setAlphaMode = function (mode, noDepthWriteChange) {
        if (noDepthWriteChange === void 0) { noDepthWriteChange = false; }
        if (this._alphaMode === mode) {
            return;
        }
        this._alphaState.alphaBlend = (mode !== _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].ALPHA_DISABLE);
        if (!noDepthWriteChange) {
            this.setDepthWrite(mode === _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].ALPHA_DISABLE);
        }
        this._alphaMode = mode;
    };
    NullEngine.prototype.bindBuffers = function (vertexBuffers, indexBuffer, effect) {
    };
    NullEngine.prototype.wipeCaches = function (bruteForce) {
        if (this.preventCacheWipeBetweenFrames) {
            return;
        }
        this.resetTextureCache();
        this._currentEffect = null;
        if (bruteForce) {
            this._currentProgram = null;
            this._stencilState.reset();
            this._depthCullingState.reset();
            this._alphaState.reset();
        }
        this._cachedVertexBuffers = null;
        this._cachedIndexBuffer = null;
        this._cachedEffectForVertexBuffers = null;
    };
    NullEngine.prototype.draw = function (useTriangles, indexStart, indexCount, instancesCount) {
    };
    NullEngine.prototype.drawElementsType = function (fillMode, indexStart, indexCount, instancesCount) {
    };
    NullEngine.prototype.drawArraysType = function (fillMode, verticesStart, verticesCount, instancesCount) {
    };
    /** @hidden */
    NullEngine.prototype._createTexture = function () {
        return {};
    };
    /** @hidden */
    NullEngine.prototype._releaseTexture = function (texture) {
    };
    NullEngine.prototype.createTexture = function (urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, fallBack, format) {
        if (samplingMode === void 0) { samplingMode = _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (buffer === void 0) { buffer = null; }
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"].DATASOURCE_URL);
        var url = String(urlArg);
        texture.url = url;
        texture.generateMipMaps = !noMipmap;
        texture.samplingMode = samplingMode;
        texture.invertY = invertY;
        texture.baseWidth = this._options.textureSize;
        texture.baseHeight = this._options.textureSize;
        texture.width = this._options.textureSize;
        texture.height = this._options.textureSize;
        if (format) {
            texture.format = format;
        }
        texture.isReady = true;
        if (onLoad) {
            onLoad();
        }
        this._internalTexturesCache.push(texture);
        return texture;
    };
    NullEngine.prototype.createRenderTargetTexture = function (size, options) {
        var fullOptions = new _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_3__["RenderTargetCreationOptions"]();
        if (options !== undefined && typeof options === "object") {
            fullOptions.generateMipMaps = options.generateMipMaps;
            fullOptions.generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
            fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && options.generateStencilBuffer;
            fullOptions.type = options.type === undefined ? _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_UNSIGNED_INT : options.type;
            fullOptions.samplingMode = options.samplingMode === undefined ? _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;
        }
        else {
            fullOptions.generateMipMaps = options;
            fullOptions.generateDepthBuffer = true;
            fullOptions.generateStencilBuffer = false;
            fullOptions.type = _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_UNSIGNED_INT;
            fullOptions.samplingMode = _constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE;
        }
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"].DATASOURCE_RENDERTARGET);
        var width = size.width || size;
        var height = size.height || size;
        texture._depthStencilBuffer = {};
        texture._framebuffer = {};
        texture.baseWidth = width;
        texture.baseHeight = height;
        texture.width = width;
        texture.height = height;
        texture.isReady = true;
        texture.samples = 1;
        texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;
        texture.samplingMode = fullOptions.samplingMode;
        texture.type = fullOptions.type;
        texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
        texture._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;
        this._internalTexturesCache.push(texture);
        return texture;
    };
    NullEngine.prototype.updateTextureSamplingMode = function (samplingMode, texture) {
        texture.samplingMode = samplingMode;
    };
    NullEngine.prototype.bindFramebuffer = function (texture, faceIndex, requiredWidth, requiredHeight, forceFullscreenViewport) {
        if (this._currentRenderTarget) {
            this.unBindFramebuffer(this._currentRenderTarget);
        }
        this._currentRenderTarget = texture;
        this._currentFramebuffer = texture._MSAAFramebuffer ? texture._MSAAFramebuffer : texture._framebuffer;
        if (this._cachedViewport && !forceFullscreenViewport) {
            this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);
        }
    };
    NullEngine.prototype.unBindFramebuffer = function (texture, disableGenerateMipMaps, onBeforeUnbind) {
        if (disableGenerateMipMaps === void 0) { disableGenerateMipMaps = false; }
        this._currentRenderTarget = null;
        if (onBeforeUnbind) {
            if (texture._MSAAFramebuffer) {
                this._currentFramebuffer = texture._framebuffer;
            }
            onBeforeUnbind();
        }
        this._currentFramebuffer = null;
    };
    NullEngine.prototype.createDynamicVertexBuffer = function (vertices) {
        var buffer = new _Meshes_dataBuffer__WEBPACK_IMPORTED_MODULE_6__["DataBuffer"]();
        buffer.references = 1;
        buffer.capacity = 1;
        return buffer;
    };
    NullEngine.prototype.updateDynamicTexture = function (texture, canvas, invertY, premulAlpha, format) {
        if (premulAlpha === void 0) { premulAlpha = false; }
    };
    NullEngine.prototype.areAllEffectsReady = function () {
        return true;
    };
    /**
     * @hidden
     * Get the current error code of the webGL context
     * @returns the error code
     * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getError
     */
    NullEngine.prototype.getError = function () {
        return 0;
    };
    /** @hidden */
    NullEngine.prototype._getUnpackAlignement = function () {
        return 1;
    };
    /** @hidden */
    NullEngine.prototype._unpackFlipY = function (value) {
    };
    NullEngine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
        if (offset === void 0) { offset = 0; }
    };
    /**
     * Updates a dynamic vertex buffer.
     * @param vertexBuffer the vertex buffer to update
     * @param data the data used to update the vertex buffer
     * @param byteOffset the byte offset of the data (optional)
     * @param byteLength the byte length of the data (optional)
     */
    NullEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, vertices, byteOffset, byteLength) {
    };
    NullEngine.prototype._bindTextureDirectly = function (target, texture) {
        if (this._boundTexturesCache[this._activeChannel] !== texture) {
            this._boundTexturesCache[this._activeChannel] = texture;
            return true;
        }
        return false;
    };
    /** @hidden */
    NullEngine.prototype._bindTexture = function (channel, texture) {
        if (channel < 0) {
            return;
        }
        this._bindTextureDirectly(0, texture);
    };
    NullEngine.prototype._deleteBuffer = function (buffer) {
    };
    NullEngine.prototype.releaseEffects = function () {
    };
    NullEngine.prototype.displayLoadingUI = function () {
    };
    NullEngine.prototype.hideLoadingUI = function () {
    };
    /** @hidden */
    NullEngine.prototype._uploadCompressedDataToTextureDirectly = function (texture, internalFormat, width, height, data, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    /** @hidden */
    NullEngine.prototype._uploadDataToTextureDirectly = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    /** @hidden */
    NullEngine.prototype._uploadArrayBufferViewToTexture = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    /** @hidden */
    NullEngine.prototype._uploadImageToTexture = function (texture, image, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    return NullEngine;
}(_Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"]));


/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/webpack/buildin/global.js */ "../node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./Engines/webgpuEngine.ts":
/*!*********************************!*\
  !*** ./Engines/webgpuEngine.ts ***!
  \*********************************/
/*! exports provided: WebGPUEngine */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGPUEngine", function() { return WebGPUEngine; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math */ "./Maths/math.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Textures/renderTargetCreationOptions */ "./Materials/Textures/renderTargetCreationOptions.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./constants */ "./Engines/constants.ts");
/* harmony import */ var _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./WebGPU/webgpuConstants */ "./Engines/WebGPU/webgpuConstants.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _WebGPU_webgpuPipelineContext__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./WebGPU/webgpuPipelineContext */ "./Engines/WebGPU/webgpuPipelineContext.ts");
/* harmony import */ var _Meshes_WebGPU_webgpuDataBuffer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Meshes/WebGPU/webgpuDataBuffer */ "./Meshes/WebGPU/webgpuDataBuffer.ts");
/* harmony import */ var _WebGPU_webgpuShaderProcessors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./WebGPU/webgpuShaderProcessors */ "./Engines/WebGPU/webgpuShaderProcessors.ts");
/* harmony import */ var _WebGPU_webgpuShaderProcessingContext__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./WebGPU/webgpuShaderProcessingContext */ "./Engines/WebGPU/webgpuShaderProcessingContext.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
















/**
 * The web GPU engine class provides support for WebGPU version of babylon.js.
 */
var WebGPUEngine = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WebGPUEngine, _super);
    /**
     * Create a new instance of the gpu engine.
     * @param canvas Defines the canvas to use to display the result
     * @param options Defines the options passed to the engine to create the GPU context dependencies
     */
    function WebGPUEngine(canvas, options) {
        if (options === void 0) { options = {}; }
        var _this = _super.call(this, null) || this;
        // Page Life cycle and constants
        _this._uploadEncoderDescriptor = { label: "upload" };
        _this._renderEncoderDescriptor = { label: "render" };
        _this._clearDepthValue = 1;
        _this._clearStencilValue = 0;
        _this._defaultSampleCount = 4; // Only supported value for now.
        _this._shaderc = null;
        _this._commandBuffers = [null, null];
        // Frame Buffer Life Cycle (recreated for each render target pass)
        _this._currentRenderPass = null;
        // DrawCall Life Cycle
        // Effect is on the parent class
        // protected _currentEffect: Nullable<Effect> = null;
        _this._currentVertexBuffers = null;
        _this._currentIndexBuffer = null;
        _this.__colorWrite = true;
        _this._uniformsBuffers = {};
        // Caches
        _this._compiledShaders = {};
        // TODO WEBGPU. Texture Management. Temporary...
        _this._decodeCanvas = document.createElement("canvas");
        _this._decodeEngine = new _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"](_this._decodeCanvas, false, {
            alpha: true,
            premultipliedAlpha: false,
        }, false);
        _this._freezeCommands = false;
        _this._frozenCommands = null;
        options.deviceDescriptor = options.deviceDescriptor || {};
        options.swapChainFormat = options.swapChainFormat || _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureFormat_bgra8unorm;
        options.antialiasing = options.antialiasing === undefined ? true : options.antialiasing;
        _this._decodeEngine.getCaps().textureFloat = false;
        _this._decodeEngine.getCaps().textureFloatRender = false;
        _this._decodeEngine.getCaps().textureHalfFloat = false;
        _this._decodeEngine.getCaps().textureHalfFloatRender = false;
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Log("Babylon.js v" + _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].Version + " - WebGPU engine");
        if (!navigator.gpu || GPUBufferUsage.COPY_SRC === undefined) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("WebGPU is not supported by your browser.");
            return _this;
        }
        _this._isWebGPU = true;
        _this._shaderPlatformName = "WEBGPU";
        if (options.deterministicLockstep === undefined) {
            options.deterministicLockstep = false;
        }
        if (options.lockstepMaxSteps === undefined) {
            options.lockstepMaxSteps = 4;
        }
        if (options.audioEngine === undefined) {
            options.audioEngine = true;
        }
        _this._deterministicLockstep = options.deterministicLockstep;
        _this._lockstepMaxSteps = options.lockstepMaxSteps;
        _this._doNotHandleContextLost = true;
        _this._canvas = canvas;
        _this._options = options;
        _this._hardwareScalingLevel = 1;
        _this._mainPassSampleCount = options.antialiasing ? _this._defaultSampleCount : 1;
        _this._sharedInit(canvas, !!options.doNotHandleTouchAction, options.audioEngine);
        return _this;
    }
    Object.defineProperty(WebGPUEngine.prototype, "supportsUniformBuffers", {
        /**
         * Gets a boolean indicating that the engine supports uniform buffers
         * @see http://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
         */
        get: function () {
            return true;
        },
        enumerable: true,
        configurable: true
    });
    //------------------------------------------------------------------------------
    //                              Initialization
    //------------------------------------------------------------------------------
    /**
     * Initializes the WebGPU context and dependencies.
     * @param shadercOptions Defines the ShaderC compiler options if necessary
     * @returns a promise notifying the readiness of the engine.
     */
    WebGPUEngine.prototype.initAsync = function (shadercOptions) {
        var _this = this;
        return this._initShaderc(shadercOptions)
            .then(function (shaderc) {
            _this._shaderc = shaderc;
            return navigator.gpu.requestAdapter(_this._options);
        })
            .then(function (adapter) {
            _this._adapter = adapter;
            return _this._adapter.requestDevice(_this._options.deviceDescriptor);
        })
            .then(function (device) { return _this._device = device; })
            .then(function () {
            _this._initializeLimits();
            _this._initializeContextAndSwapChain();
            // this._initializeMainAttachments();
            // Initialization is in the resize :-)
            _this.resize();
        })
            .catch(function (e) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Can not create WebGPU Device and/or context.");
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error(e);
        });
    };
    WebGPUEngine.prototype._initShaderc = function (shadercOptions) {
        shadercOptions = shadercOptions || {};
        shadercOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, WebGPUEngine._shadercDefaultOptions, shadercOptions);
        if (shadercOptions.shaderc) {
            return Promise.resolve(shadercOptions.shaderc);
        }
        var wasmOptions = {
            wasmBinaryFile: shadercOptions.wasmPath
        };
        if (window.Shaderc) {
            return window.Shaderc(wasmOptions);
        }
        if (shadercOptions.jsPath && shadercOptions.wasmPath) {
            return _Misc_tools__WEBPACK_IMPORTED_MODULE_15__["Tools"].LoadScriptAsync(shadercOptions.jsPath)
                .then(function () {
                return window.Shaderc(wasmOptions);
            });
        }
        return Promise.reject("shaderc is not available.");
    };
    WebGPUEngine.prototype._initializeLimits = function () {
        // Init caps
        // TODO WEBGPU Real Capability check once limits will be working.
        this._caps = new _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["EngineCapabilities"]();
        this._caps.maxTexturesImageUnits = 16;
        this._caps.maxVertexTextureImageUnits = 16;
        this._caps.maxTextureSize = 2048;
        this._caps.maxCubemapTextureSize = 2048;
        this._caps.maxRenderTextureSize = 2048;
        this._caps.maxVertexAttribs = 16;
        this._caps.maxVaryingVectors = 16;
        this._caps.maxFragmentUniformVectors = 1024;
        this._caps.maxVertexUniformVectors = 1024;
        // Extensions
        this._caps.standardDerivatives = true;
        this._caps.astc = null;
        this._caps.s3tc = null;
        this._caps.pvrtc = null;
        this._caps.etc1 = null;
        this._caps.etc2 = null;
        this._caps.textureAnisotropicFilterExtension = null;
        this._caps.maxAnisotropy = 0;
        this._caps.uintIndices = true;
        this._caps.fragmentDepthSupported = false;
        this._caps.highPrecisionShaderSupported = true;
        this._caps.colorBufferFloat = true;
        this._caps.textureFloat = false;
        this._caps.textureFloatLinearFiltering = false;
        this._caps.textureFloatRender = false;
        this._caps.textureHalfFloat = false;
        this._caps.textureHalfFloatLinearFiltering = false;
        this._caps.textureHalfFloatRender = false;
        this._caps.textureLOD = true;
        this._caps.drawBuffersExtension = true;
        this._caps.depthTextureExtension = true;
        this._caps.vertexArrayObject = false;
        this._caps.instancedArrays = true;
        this._caps.parallelShaderCompile = null;
    };
    WebGPUEngine.prototype._initializeContextAndSwapChain = function () {
        this._context = this._canvas.getContext('gpu');
        this._swapChain = this._context.configureSwapChain({
            device: this._device,
            format: this._options.swapChainFormat,
            usage: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_OUTPUT_ATTACHMENT | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_COPY_SRC,
        });
    };
    // Set default values as WebGL with depth and stencil attachment for the broadest Compat.
    WebGPUEngine.prototype._initializeMainAttachments = function () {
        this._mainTextureExtends = {
            width: this.getRenderWidth(),
            height: this.getRenderHeight(),
            depth: 1
        };
        if (this._options.antialiasing) {
            var mainTextureDescriptor = {
                size: this._mainTextureExtends,
                arrayLayerCount: 1,
                mipLevelCount: 1,
                sampleCount: this._mainPassSampleCount,
                dimension: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureDimension_2d,
                format: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureFormat_bgra8unorm,
                usage: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_OUTPUT_ATTACHMENT,
            };
            if (this._mainTexture) {
                this._mainTexture.destroy();
            }
            this._mainTexture = this._device.createTexture(mainTextureDescriptor);
            this._mainColorAttachments = [{
                    attachment: this._mainTexture.createView(),
                    loadValue: new _Maths_math__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 1),
                    loadOp: "clear",
                    clearColor: new _Maths_math__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 1),
                    storeOp: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStoreOp_store
                }];
        }
        else {
            this._mainColorAttachments = [{
                    attachment: this._swapChain.getCurrentTexture().createDefaultView(),
                    loadValue: new _Maths_math__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 1),
                    loadOp: "clear",
                    clearColor: new _Maths_math__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 1),
                    storeOp: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStoreOp_store
                }];
        }
        var depthTextureDescriptor = {
            size: this._mainTextureExtends,
            arrayLayerCount: 1,
            mipLevelCount: 1,
            sampleCount: this._mainPassSampleCount,
            dimension: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureDimension_2d,
            format: "depth32float-stencil8",
            usage: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_OUTPUT_ATTACHMENT
        };
        if (this._depthTexture) {
            this._depthTexture.destroy();
        }
        this._depthTexture = this._device.createTexture(depthTextureDescriptor);
        this._mainDepthAttachment = {
            attachment: this._depthTexture.createDefaultView(),
            depthLoadValue: this._clearDepthValue,
            depthLoadOp: "clear",
            clearDepth: this._clearDepthValue,
            depthStoreOp: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStoreOp_store,
            stencilLoadValue: this._clearStencilValue,
            stencilLoadOp: "clear",
            clearStencil: this._clearStencilValue,
            stencilStoreOp: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStoreOp_store,
        };
    };
    /**
     * Gets a shader processor implementation fitting with the current engine type.
     * @returns The shader processor implementation.
     */
    WebGPUEngine.prototype._getShaderProcessor = function () {
        return new _WebGPU_webgpuShaderProcessors__WEBPACK_IMPORTED_MODULE_13__["WebGPUShaderProcessor"]();
    };
    /** @hidden */
    WebGPUEngine.prototype._getShaderProcessingContext = function () {
        return new _WebGPU_webgpuShaderProcessingContext__WEBPACK_IMPORTED_MODULE_14__["WebGPUShaderProcessingContext"]();
    };
    //------------------------------------------------------------------------------
    //                          Static Pipeline WebGPU States
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.wipeCaches = function (bruteForce) {
        if (this.preventCacheWipeBetweenFrames) {
            return;
        }
        this.resetTextureCache();
        this._currentEffect = null;
        this._currentIndexBuffer = null;
        this._currentVertexBuffers = null;
        if (bruteForce) {
            this._currentProgram = null;
            this._stencilState.reset();
            this._depthCullingState.reset();
            this._alphaState.reset();
        }
        this._cachedVertexBuffers = null;
        this._cachedIndexBuffer = null;
        this._cachedEffectForVertexBuffers = null;
    };
    WebGPUEngine.prototype.setColorWrite = function (enable) {
        this.__colorWrite = enable;
    };
    WebGPUEngine.prototype.getColorWrite = function () {
        return this.__colorWrite;
    };
    //------------------------------------------------------------------------------
    //                              Dynamic WebGPU States
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype._viewport = function (x, y, width, height) {
        // TODO WEBGPU. Cache.
        // if (x !== this._viewportCached.x ||
        //     y !== this._viewportCached.y ||
        //     width !== this._viewportCached.z ||
        //     height !== this._viewportCached.w) {
        //     this._viewportCached.x = x;
        //     this._viewportCached.y = y;
        //     this._viewportCached.z = width;
        //     this._viewportCached.w = height;
        //     this._gl.viewport(x, y, width, height);
        // }
        if (!this._currentRenderPass) {
            this._startMainRenderPass();
        }
        // TODO WEBGPU. Viewport.
        // Use 0 1 like the default webgl values.
        // this._currentRenderPass!.setViewport(x, y, width, height, 0, 1);
    };
    WebGPUEngine.prototype.enableScissor = function (x, y, width, height) {
        if (!this._currentRenderPass) {
            this._startMainRenderPass();
        }
        this._currentRenderPass.setScissorRect(x, y, width, height);
    };
    WebGPUEngine.prototype.disableScissor = function () {
        if (!this._currentRenderPass) {
            this._startMainRenderPass();
        }
        this._currentRenderPass.setScissorRect(0, 0, this.getRenderWidth(), this.getRenderHeight());
    };
    WebGPUEngine.prototype.clear = function (color, backBuffer, depth, stencil) {
        if (stencil === void 0) { stencil = false; }
        // Some PGs are using color3...
        if (color.a === undefined) {
            color.a = 1;
        }
        if (backBuffer) {
            this._mainColorAttachments[0].loadValue = color;
            this._mainColorAttachments[0].loadOp = "clear";
            this._mainColorAttachments[0].clearColor = color;
        } else {
            this._mainColorAttachments[0].loadValue = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPULoadOp_load;
            this._mainColorAttachments[0].loadOp = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPULoadOp_load;
        }
        if (depth) {
            this._mainDepthAttachment.depthLoadValue = this._clearDepthValue;
            this._mainDepthAttachment.depthLoadOp = "clear";
            this._mainDepthAttachment.clearDepth = this._clearDepthValue;
        } else {
            this._mainDepthAttachment.depthLoadValue = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPULoadOp_load;
            this._mainDepthAttachment.depthLoadOp = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPULoadOp_load;
            this._mainDepthAttachment.clearDepth = 0;
        }
        if (stencil) {
            this._mainDepthAttachment.stencilLoadValue = this._clearStencilValue;
            this._mainDepthAttachment.stencilLoadOp = "clear";
            this._mainDepthAttachment.clearStencil = this._clearStencilValue;
        } else {
            this._mainDepthAttachment.stencilLoadValue = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPULoadOp_load;
            this._mainDepthAttachment.stencilLoadOp = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPULoadOp_load;
        }
        this._startMainRenderPass();
    };
    //------------------------------------------------------------------------------
    //                              WebGPU Buffers
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype._createBuffer = function (view, flags) {
        var padding = view.byteLength % 4;
        var verticesBufferDescriptor = {
            size: view.byteLength + padding,
            usage: flags
        };
        var [buffer, arr] = this._device.createBufferMapped(verticesBufferDescriptor);
        var uint8View = new Uint8Array(view.buffer, view.byteOffset);
        var uint8Arr = new Uint8Array(arr);
        for (var i = 0; i < uint8View.length; ++i)
            uint8Arr[i] = uint8View[i];
        buffer.unmap();
        var dataBuffer = new _Meshes_WebGPU_webgpuDataBuffer__WEBPACK_IMPORTED_MODULE_12__["WebGPUDataBuffer"](buffer);
        dataBuffer.references = 1;
        dataBuffer.capacity = view.byteLength;
        return dataBuffer;
    };
    WebGPUEngine.prototype._setSubData = function (dataBuffer, dstByteOffset, src, srcByteOffset, byteLength) {
        if (srcByteOffset === void 0) { srcByteOffset = 0; }
        if (byteLength === void 0) { byteLength = 0; }
        var buffer = dataBuffer.underlyingResource;
        byteLength = byteLength || src.byteLength;
        byteLength = Math.min(byteLength, dataBuffer.capacity - dstByteOffset);
        // TODO WEBGPU. Deprecated soon to be removed... replace by mappedBuffers
        var bufferDescriptor = {
            size: byteLength,
            usage: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_MAP_WRITE | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_SRC
        };
        var [tempBuffer, arr] = this._device.createBufferMapped(bufferDescriptor);
        var uint8Src = new Uint8Array(src.buffer, src.byteOffset);
        var uint8Arr = new Uint8Array(arr);
        for (var i = 0; i < byteLength; ++i)
            uint8Arr[i] = uint8Src[srcByteOffset + i];
        tempBuffer.unmap();
        var commandEncoder = this._device.createCommandEncoder();
        commandEncoder.copyBufferToBuffer(tempBuffer, 0, buffer, dstByteOffset, byteLength);
        var commandBuffer = commandEncoder.finish();
        this._device.getQueue().submit([commandBuffer]);
        tempBuffer.destroy();
    };
    //------------------------------------------------------------------------------
    //                              Vertex/Index Buffers
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.createVertexBuffer = function (data) {
        var view;
        if (data instanceof Array) {
            view = new Float32Array(data);
        }
        else if (data instanceof ArrayBuffer) {
            view = new Uint8Array(data);
        }
        else {
            view = data;
        }
        var dataBuffer = this._createBuffer(view, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_VERTEX | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
        return dataBuffer;
    };
    WebGPUEngine.prototype.createDynamicVertexBuffer = function (data) {
        return this.createVertexBuffer(data);
    };
    WebGPUEngine.prototype.updateDynamicVertexBuffer = function (vertexBuffer, data, byteOffset, byteLength) {
        var dataBuffer = vertexBuffer;
        if (byteOffset === undefined) {
            byteOffset = 0;
        }
        var view;
        if (byteLength === undefined) {
            if (data instanceof Array) {
                view = new Float32Array(data);
            }
            else if (data instanceof ArrayBuffer) {
                view = new Uint8Array(data);
            }
            else {
                view = data;
            }
            byteLength = view.byteLength;
        }
        else {
            if (data instanceof Array) {
                view = new Float32Array(data);
            }
            else if (data instanceof ArrayBuffer) {
                view = new Uint8Array(data);
            }
            else {
                view = data;
            }
        }
        this._setSubData(dataBuffer, byteOffset, view, 0, byteLength);
    };
    WebGPUEngine.prototype.createIndexBuffer = function (data) {
        var is32Bits = true;
        var view;
        if (data instanceof Uint32Array || data instanceof Int32Array) {
            view = data;
        }
        else if (data instanceof Uint16Array) {
            view = data;
            is32Bits = false;
        }
        else {
            if (data.length > 65535) {
                view = new Uint32Array(data);
            }
            else {
                view = new Uint16Array(data);
                is32Bits = false;
            }
        }
        var dataBuffer = this._createBuffer(view, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_INDEX | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
        dataBuffer.is32Bits = is32Bits;
        return dataBuffer;
    };
    WebGPUEngine.prototype.updateDynamicIndexBuffer = function (indexBuffer, indices, offset) {
        if (offset === void 0) { offset = 0; }
        var gpuBuffer = indexBuffer;
        var view;
        if (indices instanceof Uint16Array) {
            if (indexBuffer.is32Bits) {
                view = Uint32Array.from(indices);
            }
            else {
                view = indices;
            }
        }
        else if (indices instanceof Uint32Array) {
            if (indexBuffer.is32Bits) {
                view = indices;
            }
            else {
                view = Uint16Array.from(indices);
            }
        }
        else {
            if (indexBuffer.is32Bits) {
                view = new Uint32Array(indices);
            }
            else {
                view = new Uint16Array(indices);
            }
        }
        this._setSubData(gpuBuffer, offset, view);
    };
    WebGPUEngine.prototype.bindBuffersDirectly = function (vertexBuffer, indexBuffer, vertexDeclaration, vertexStrideSize, effect) {
        throw "Not implemented on WebGPU so far.";
    };
    WebGPUEngine.prototype.updateAndBindInstancesBuffer = function (instancesBuffer, data, offsetLocations) {
        throw "Not implemented on WebGPU so far.";
    };
    WebGPUEngine.prototype.bindBuffers = function (vertexBuffers, indexBuffer, effect) {
        this._currentIndexBuffer = indexBuffer;
        this._currentVertexBuffers = vertexBuffers;
    };
    /** @hidden */
    WebGPUEngine.prototype._releaseBuffer = function (buffer) {
        buffer.references--;
        if (buffer.references === 0) {
            buffer.underlyingResource.destroy();
            return true;
        }
        return false;
    };
    //------------------------------------------------------------------------------
    //                              UBO
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.createUniformBuffer = function (elements) {
        var view;
        if (elements instanceof Array) {
            view = new Float32Array(elements);
        }
        else {
            view = elements;
        }
        var dataBuffer = this._createBuffer(view, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_UNIFORM | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
        return dataBuffer;
    };
    WebGPUEngine.prototype.createDynamicUniformBuffer = function (elements) {
        return this.createUniformBuffer(elements);
    };
    WebGPUEngine.prototype.updateUniformBuffer = function (uniformBuffer, elements, offset, count) {
        if (offset === undefined) {
            offset = 0;
        }
        var dataBuffer = uniformBuffer;
        var view;
        if (count === undefined) {
            if (elements instanceof Float32Array) {
                view = elements;
            }
            else {
                view = new Float32Array(elements);
            }
            count = view.byteLength;
        }
        else {
            if (elements instanceof Float32Array) {
                view = elements;
            }
            else {
                view = new Float32Array(elements);
            }
        }
        this._setSubData(dataBuffer, offset, view, 0, count);
    };
    WebGPUEngine.prototype.bindUniformBufferBase = function (buffer, location, name) {
        this._uniformsBuffers[name] = buffer;
    };
    //------------------------------------------------------------------------------
    //                              Effects
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.createEffect = function (baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, defines, fallbacks, onCompiled, onError, indexParameters) {
        var vertex = baseName.vertexElement || baseName.vertex || baseName;
        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
        var name = vertex + "+" + fragment + "@" + (defines ? defines : attributesNamesOrOptions.defines);
        var shader = this._compiledShaders[name];
        if (shader) {
            return new _Materials_effect__WEBPACK_IMPORTED_MODULE_7__["Effect"](baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters, name, shader.sources);
        }
        else {
            return new _Materials_effect__WEBPACK_IMPORTED_MODULE_7__["Effect"](baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters, name);
        }
    };
    WebGPUEngine.prototype._compileRawShaderToSpirV = function (source, type) {
        var Shaderc = this._shaderc;
        var compiler = new Shaderc.Compiler();
        var opts = new Shaderc.CompileOptions();
        var result = compiler.CompileGlslToSpv(source, type === "fragment" ? Shaderc.shader_kind.fragment :
            type === "vertex" ? Shaderc.shader_kind.vertex :
                type === "compute" ? Shaderc.shader_kind.compute : null, "tempCompilation.glsl", "main", opts);
        var error = result.GetErrorMessage();
        if (error) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error(error);
            throw new Error("Something went wrong while compile the shader.");
        }
        return result.GetBinary().slice();
    };
    WebGPUEngine.prototype._compileShaderToSpirV = function (source, type, defines, shaderVersion) {
        return this._compileRawShaderToSpirV(shaderVersion + (defines ? defines + "\n" : "") + source, type);
    };
    WebGPUEngine.prototype._createPipelineStageDescriptor = function (vertexShader, fragmentShader) {
        return {
            vertexStage: {
                module: this._device.createShaderModule({
                    code: vertexShader,
                }),
                entryPoint: "main",
            },
            fragmentStage: {
                module: this._device.createShaderModule({
                    code: fragmentShader,
                }),
                entryPoint: "main"
            }
        };
    };
    WebGPUEngine.prototype._compileRawPipelineStageDescriptor = function (vertexCode, fragmentCode) {
        var vertexShader = this._compileRawShaderToSpirV(vertexCode, "vertex");
        var fragmentShader = this._compileRawShaderToSpirV(fragmentCode, "fragment");
        return this._createPipelineStageDescriptor(vertexShader, fragmentShader);
    };
    WebGPUEngine.prototype._compilePipelineStageDescriptor = function (vertexCode, fragmentCode, defines) {
        this.onBeforeShaderCompilationObservable.notifyObservers(this);
        var shaderVersion = "#version 450\n";
        var vertexShader = this._compileShaderToSpirV(vertexCode, "vertex", defines, shaderVersion);
        var fragmentShader = this._compileShaderToSpirV(fragmentCode, "fragment", defines, shaderVersion);
        var program = this._createPipelineStageDescriptor(vertexShader, fragmentShader);
        this.onAfterShaderCompilationObservable.notifyObservers(this);
        return program;
    };
    WebGPUEngine.prototype.createRawShaderProgram = function (pipelineContext, vertexCode, fragmentCode, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        throw "Not available on WebGPU";
    };
    WebGPUEngine.prototype.createShaderProgram = function (pipelineContext, vertexCode, fragmentCode, defines, context, transformFeedbackVaryings) {
        if (transformFeedbackVaryings === void 0) { transformFeedbackVaryings = null; }
        throw "Not available on WebGPU";
    };
    WebGPUEngine.prototype.createPipelineContext = function (shaderProcessingContext) {
        var pipelineContext = new _WebGPU_webgpuPipelineContext__WEBPACK_IMPORTED_MODULE_11__["WebGPUPipelineContext"](shaderProcessingContext, this);
        pipelineContext.engine = this;
        return pipelineContext;
    };
    /** @hidden */
    WebGPUEngine.prototype._preparePipelineContext = function (pipelineContext, vertexSourceCode, fragmentSourceCode, createAsRaw, rebuildRebind, defines, transformFeedbackVaryings, key) {
        var webGpuContext = pipelineContext;
        // TODO WEBGPU. Check if caches could be reuse from piepline ???
        var shader = this._compiledShaders[key];
        if (shader) {
            webGpuContext.stages = shader.stages;
            webGpuContext.availableAttributes = shader.availableAttributes;
            webGpuContext.availableUBOs = shader.availableUBOs;
            webGpuContext.availableSamplers = shader.availableSamplers;
            webGpuContext.orderedAttributes = shader.orderedAttributes;
            webGpuContext.orderedUBOsAndSamplers = shader.orderedUBOsAndSamplers;
            webGpuContext.leftOverUniforms = shader.leftOverUniforms;
            webGpuContext.leftOverUniformsByName = shader.leftOverUniformsByName;
            webGpuContext.sources = shader.sources;
        }
        else {
            if (createAsRaw) {
                webGpuContext.stages = this._compileRawPipelineStageDescriptor(vertexSourceCode, fragmentSourceCode);
            }
            else {
                webGpuContext.stages = this._compilePipelineStageDescriptor(vertexSourceCode, fragmentSourceCode, defines);
            }
            this._compiledShaders[key] = {
                stages: webGpuContext.stages,
                availableAttributes: webGpuContext.availableAttributes,
                availableUBOs: webGpuContext.availableUBOs,
                availableSamplers: webGpuContext.availableSamplers,
                orderedAttributes: webGpuContext.orderedAttributes,
                orderedUBOsAndSamplers: webGpuContext.orderedUBOsAndSamplers,
                leftOverUniforms: webGpuContext.leftOverUniforms,
                leftOverUniformsByName: webGpuContext.leftOverUniformsByName,
                sources: {
                    fragment: fragmentSourceCode,
                    vertex: vertexSourceCode
                }
            };
        }
    };
    WebGPUEngine.prototype.getAttributes = function (pipelineContext, attributesNames) {
        var results = new Array(attributesNames.length);
        var gpuPipelineContext = pipelineContext;
        // TODO WEBGPU. Hard coded for WebGPU until an introspection lib is available.
        // Should be done at processing time, not need to double the work in here.
        for (var i = 0; i < attributesNames.length; i++) {
            var attributeName = attributesNames[i];
            var attributeLocation = gpuPipelineContext.availableAttributes[attributeName];
            if (attributeLocation === undefined) {
                continue;
            }
            results[i] = attributeLocation;
        }
        return results;
    };
    WebGPUEngine.prototype.enableEffect = function (effect) {
        this._currentEffect = effect;
        if (effect.onBind) {
            effect.onBind(effect);
        }
        if (effect._onBindObservable) {
            effect._onBindObservable.notifyObservers(effect);
        }
    };
    WebGPUEngine.prototype._releaseEffect = function (effect) {
        // Effect gets garbage collected without explicit destroy in WebGPU.
    };
    /**
     * Force the engine to release all cached effects. This means that next effect compilation will have to be done completely even if a similar effect was already compiled
     */
    WebGPUEngine.prototype.releaseEffects = function () {
        // Effect gets garbage collected without explicit destroy in WebGPU.
    };
    WebGPUEngine.prototype._deletePipelineContext = function (pipelineContext) {
        var webgpuPipelineContext = pipelineContext;
        if (webgpuPipelineContext) {
            pipelineContext.dispose();
        }
    };
    //------------------------------------------------------------------------------
    //                              Textures
    //------------------------------------------------------------------------------
    /** @hidden */
    WebGPUEngine.prototype._createTexture = function () {
        // TODO WEBGPU. This should return the GPUTexture, WebGLTexture might need to be wrapped like the buffers.
        return {};
    };
    /** @hidden */
    WebGPUEngine.prototype._releaseTexture = function (texture) {
        if (texture._webGPUTexture) {
            texture._webGPUTexture.destroy();
        }
    };
    WebGPUEngine.prototype._justTheUpload = function (pixels, gpuTexture, width, height, face, mip) {
        var textureView = {
            texture: gpuTexture,
            origin: {
                x: 0,
                y: 0,
                z: 0
            },
            mipLevel: mip,
            arrayLayer: Math.max(face, 0),
        };
        var textureExtent = {
            width: width,
            height: height,
            depth: 1
        };
        var commandEncoder = this._device.createCommandEncoder({});
        var rowPitch = Math.ceil(width * 4 / 256) * 256;
        var dataBuffer;
        if (rowPitch == width * 4) {
            dataBuffer = this._createBuffer(pixels, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
            var bufferView = {
                buffer: dataBuffer.underlyingResource,
                rowPitch: rowPitch,
                imageHeight: height,
                offset: 0,
            };
            commandEncoder.copyBufferToTexture(bufferView, textureView, textureExtent);
        }
        else {
            var alignedPixels = new Uint8Array(rowPitch * height);
            var pixelsIndex = 0;
            for (var y = 0; y < height; ++y) {
                for (var x = 0; x < width; ++x) {
                    var i = x * 4 + y * rowPitch;
                    alignedPixels[i] = pixels[pixelsIndex];
                    alignedPixels[i + 1] = pixels[pixelsIndex + 1];
                    alignedPixels[i + 2] = pixels[pixelsIndex + 2];
                    alignedPixels[i + 3] = pixels[pixelsIndex + 3];
                    pixelsIndex += 4;
                }
            }
            dataBuffer = this._createBuffer(alignedPixels, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
            var bufferView = {
                buffer: dataBuffer.underlyingResource,
                rowPitch: rowPitch,
                imageHeight: height,
                offset: 0,
            };
            commandEncoder.copyBufferToTexture(bufferView, textureView, textureExtent);
        }
        this._device.getQueue().submit([commandEncoder.finish()]);
        this._releaseBuffer(dataBuffer);
    }
    WebGPUEngine.prototype._uploadMipMapsFromWebglTexture = function (mipMaps, webglEngineTexture, gpuTexture, width, height, face) {
        // Work around the fact that Safari Technology Preview only supports WebGL 1.
        // In WebGL 1, the "mip" argument to _readTexturePixels() must be 0, which means it's impossible to readPixels() a non-0 miplevel of a texture.
        // Therefore, we have to generate our own mipmaps on the CPU here.
        var pixels = this._decodeEngine._readTexturePixels(webglEngineTexture, webglEngineTexture.width, webglEngineTexture.height, face, 0);
        if (pixels instanceof Float32Array) {
            var newPixels_1 = new Uint8ClampedArray(pixels.length);
            pixels.forEach(function (value, index) { return newPixels_1[index] = value * 255; });
            pixels = newPixels_1;
        }
        let originalCanvas = document.createElement("canvas");
        originalCanvas.width = webglEngineTexture.width;
        originalCanvas.height = webglEngineTexture.height;
        let originalContext = originalCanvas.getContext("2d");
        let imageData = new ImageData(new Uint8ClampedArray(pixels), webglEngineTexture.width, webglEngineTexture.width);
        originalContext.putImageData(imageData, 0, 0);

        var faceWidth = width;
        var faceHeight = height;
        var mip = 0;
        do {
            let smallCanvas = document.createElement("canvas");
            smallCanvas.width = faceWidth;
            smallCanvas.height = faceHeight;
            let smallContext = smallCanvas.getContext("2d");
            smallContext.drawImage(originalCanvas, 0, 0, faceWidth, faceHeight);
            let imageData = smallContext.getImageData(0, 0, faceWidth, faceHeight);
            this._justTheUpload(imageData.data, gpuTexture, faceWidth, faceHeight, face, mip);
            if (faceWidth <= 1 && faceHeight <= 1)
                break;
            faceWidth /= 2;
            faceHeight /= 2;
            ++mip;
        } while (true);
    };
    WebGPUEngine.prototype._uploadFromWebglTexture = function (webglEngineTexture, gpuTexture, width, height, face, mip) {
        if (mip === void 0) { mip = 0; }
        var pixels = this._decodeEngine._readTexturePixels(webglEngineTexture, width, height, face, mip);
        if (pixels instanceof Float32Array) {
            var newPixels_1 = new Uint8ClampedArray(pixels.length);
            pixels.forEach(function (value, index) { return newPixels_1[index] = value * 255; });
            pixels = newPixels_1;
        }
        var textureView = {
            texture: gpuTexture,
            origin: {
                x: 0,
                y: 0,
                z: 0
            },
            mipLevel: mip,
            arrayLayer: Math.max(face, 0),
        };
        var textureExtent = {
            width: width,
            height: height,
            depth: 1
        };
        var commandEncoder = this._device.createCommandEncoder({});
        var rowPitch = Math.ceil(width * 4 / 256) * 256;
        var dataBuffer;
        if (rowPitch == width * 4) {
            dataBuffer = this._createBuffer(pixels, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
            var bufferView = {
                buffer: dataBuffer.underlyingResource,
                rowPitch: rowPitch,
                imageHeight: height,
                offset: 0,
            };
            commandEncoder.copyBufferToTexture(bufferView, textureView, textureExtent);
        }
        else {
            var alignedPixels = new Uint8Array(rowPitch * height);
            var pixelsIndex = 0;
            for (var y = 0; y < height; ++y) {
                for (var x = 0; x < width; ++x) {
                    var i = x * 4 + y * rowPitch;
                    alignedPixels[i] = pixels[pixelsIndex];
                    alignedPixels[i + 1] = pixels[pixelsIndex + 1];
                    alignedPixels[i + 2] = pixels[pixelsIndex + 2];
                    alignedPixels[i + 3] = pixels[pixelsIndex + 3];
                    pixelsIndex += 4;
                }
            }
            dataBuffer = this._createBuffer(alignedPixels, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_TRANSFER_DST);
            var bufferView = {
                buffer: dataBuffer.underlyingResource,
                rowPitch: rowPitch,
                imageHeight: height,
                offset: 0,
            };
            commandEncoder.copyBufferToTexture(bufferView, textureView, textureExtent);
        }
        this._device.getQueue().submit([commandEncoder.finish()]);
        this._releaseBuffer(dataBuffer);
    };
    WebGPUEngine.prototype._getSamplerFilterDescriptor = function (internalTexture) {
        var magFilter, minFilter, mipmapFilter;
        switch (internalTexture.samplingMode) {
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_BILINEAR_SAMPLINGMODE:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_TRILINEAR_SAMPLINGMODE:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_NEAREST_SAMPLINGMODE:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_NEAREST_NEAREST_MIPNEAREST:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_NEAREST_LINEAR_MIPNEAREST:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_NEAREST_LINEAR_MIPLINEAR:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_NEAREST_LINEAR:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_NEAREST_NEAREST:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_LINEAR_NEAREST_MIPNEAREST:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_LINEAR_NEAREST_MIPLINEAR:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_LINEAR_LINEAR:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_LINEAR_NEAREST:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_nearest;
                break;
            default:
                magFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                minFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                mipmapFilter = _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFilterMode_linear;
                break;
        }
        return {
            magFilter: magFilter,
            minFilter: minFilter,
            mipmapFilter: mipmapFilter
        };
    };
    WebGPUEngine.prototype._getWrappingMode = function (mode) {
        switch (mode) {
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_WRAP_ADDRESSMODE:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUAddressMode_repeat;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_CLAMP_ADDRESSMODE:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUAddressMode_clampToEdge;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].TEXTURE_MIRROR_ADDRESSMODE:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUAddressMode_mirrorRepeat;
        }
        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUAddressMode_repeat;
    };
    WebGPUEngine.prototype._getSamplerWrappingDescriptor = function (internalTexture) {
        return {
            addressModeU: this._getWrappingMode(internalTexture._cachedWrapU),
            addressModeV: this._getWrappingMode(internalTexture._cachedWrapV),
            addressModeW: this._getWrappingMode(internalTexture._cachedWrapR),
        };
    };
    WebGPUEngine.prototype._getSamplerDescriptor = function (internalTexture) {
        return tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, this._getSamplerFilterDescriptor(internalTexture), this._getSamplerWrappingDescriptor(internalTexture));
    };
    WebGPUEngine.prototype.createTexture = function (urlArg, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer, fallBack, format) {
        var _this = this;
        if (samplingMode === void 0) { samplingMode = _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (buffer === void 0) { buffer = null; }
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"].DATASOURCE_URL);
        var url = String(urlArg);
        // TODO WEBGPU. Find a better way.
        // TODO WEBGPU. this._options.textureSize
        texture.url = url;
        texture.generateMipMaps = !noMipmap;
        texture.samplingMode = samplingMode;
        texture.invertY = invertY;
        if (format) {
            texture.format = format;
        }
        var webglEngineTexture;
        var onLoadInternal = function () {
            texture.isReady = webglEngineTexture.isReady;
            var width = webglEngineTexture.width;
            var height = webglEngineTexture.height;
            texture.width = width;
            texture.height = height;
            texture.baseWidth = width;
            texture.baseHeight = height;
            texture._isRGBD = webglEngineTexture._isRGBD;
            texture._sphericalPolynomial = webglEngineTexture._sphericalPolynomial;
            var mipMaps = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_3__["Scalar"].Log2(Math.max(width, height));
            mipMaps = Math.floor(mipMaps);
            var textureExtent = {
                width: width,
                height: height,
                depth: 1
            };
            var textureDescriptor = {
                dimension: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureDimension_2d,
                format: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureFormat_rgba8unorm,
                arrayLayerCount: 1,
                mipLevelCount: noMipmap ? 1 : mipMaps + 1,
                sampleCount: 1,
                size: textureExtent,
                usage: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_COPY_DST | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_SAMPLED
            };
            var gpuTexture = _this._device.createTexture(textureDescriptor);
            texture._webGPUTexture = gpuTexture;
            if (noMipmap) {
                _this._uploadFromWebglTexture(webglEngineTexture, gpuTexture, width, height, -1);
            }
            else {
                _this._uploadMipMapsFromWebglTexture(mipMaps, webglEngineTexture, gpuTexture, width, height, -1);
            }
            texture._webGPUTextureView = gpuTexture.createDefaultView();
            webglEngineTexture.dispose();
            texture.onLoadedObservable.notifyObservers(texture);
            texture.onLoadedObservable.clear();
            if (onLoad) {
                onLoad();
            }
        };
        webglEngineTexture = this._decodeEngine.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, onLoadInternal, onError, buffer, fallBack, format);
        this._internalTexturesCache.push(texture);
        return texture;
    };
    WebGPUEngine.prototype.createCubeTexture = function (rootUrl, scene, files, noMipmap, onLoad, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback, excludeLoaders) {
        var _this = this;
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (forcedExtension === void 0) { forcedExtension = null; }
        if (createPolynomials === void 0) { createPolynomials = false; }
        if (lodScale === void 0) { lodScale = 0; }
        if (lodOffset === void 0) { lodOffset = 0; }
        if (fallback === void 0) { fallback = null; }
        if (excludeLoaders === void 0) { excludeLoaders = []; }
        var texture = fallback ? fallback : new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"].DATASOURCE_CUBE);
        texture.isCube = true;
        texture.url = rootUrl;
        texture.generateMipMaps = !noMipmap;
        // TODO WEBGPU. Cube Texture Sampling Mode.
        texture.samplingMode = noMipmap ? _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE : _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE;
        texture._lodGenerationScale = lodScale;
        texture._lodGenerationOffset = lodOffset;
        if (!this._doNotHandleContextLost) {
            texture._extension = forcedExtension;
            texture._files = files;
        }
        var webglEngineTexture;
        var onLoadInternal = function () {
            texture.isReady = webglEngineTexture.isReady;
            var width;
            var height;
            if (noMipmap) {
                width = webglEngineTexture.width;
                height = webglEngineTexture.height;
            } else {
                // Work around the fact that Safari Technical Preview branched before SampleLevel() was implemented.
                // https://bugs.webkit.org/show_bug.cgi?id=201385
                var cubeMapTextureCap = 16;
                if (webglEngineTexture.width < cubeMapTextureCap || webglEngineTexture.height < cubeMapTextureCap)
                    alert("Texture too small");
                width = cubeMapTextureCap;
                height = cubeMapTextureCap;
            }
            var depth = 1;
            texture.width = width;
            texture.height = height;
            texture.baseWidth = width;
            texture.baseHeight = height;
            texture.depth = depth;
            texture.baseDepth = depth;
            texture._isRGBD = webglEngineTexture._isRGBD;
            texture._sphericalPolynomial = webglEngineTexture._sphericalPolynomial;
            var mipMaps = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_3__["Scalar"].Log2(width);
            mipMaps = Math.round(mipMaps);
            var textureExtent = {
                width: width,
                height: height,
                depth: depth,
            };
            var textureDescriptor = {
                dimension: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureDimension_2d,
                format: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureFormat_rgba8unorm,
                arrayLayerCount: 1,
                mipLevelCount: noMipmap ? 1 : mipMaps + 1,
                sampleCount: 1,
                size: textureExtent,
                usage: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_COPY_DST | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUTextureUsage_SAMPLED
            };
            var gpuTexture = _this._device.createTexture(textureDescriptor);
            texture._webGPUTexture = gpuTexture;
            var faces = [0];
            for (var _i = 0, faces_1 = faces; _i < faces_1.length; _i++) {
                var face = faces_1[_i];
                if (noMipmap) {
                    _this._uploadFromWebglTexture(webglEngineTexture, gpuTexture, width, height, face);
                }
                else {
                    _this._uploadMipMapsFromWebglTexture(mipMaps, webglEngineTexture, gpuTexture, width, height, face);
                }
            }
            texture._webGPUTextureView = gpuTexture.createDefaultView();
            webglEngineTexture.dispose();
            onLoad && onLoad();
        };
        webglEngineTexture = this._decodeEngine.createCubeTexture(rootUrl, scene, files, noMipmap, onLoadInternal, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset, fallback, excludeLoaders);
        this._internalTexturesCache.push(texture);
        return texture;
    };
    WebGPUEngine.prototype.updateTextureSamplingMode = function (samplingMode, texture) {
        texture.samplingMode = samplingMode;
    };
    WebGPUEngine.prototype.updateDynamicTexture = function (texture, canvas, invertY, premulAlpha, format) {
        if (premulAlpha === void 0) { premulAlpha = false; }
        throw "Unimplemented updateDynamicTexture on WebGPU so far";
    };
    WebGPUEngine.prototype.setTexture = function (channel, _, texture, name) {
        if (this._currentEffect) {
            var pipeline = this._currentEffect._pipelineContext;
            if (!texture) {
                pipeline.samplers[name] = null;
                return;
            }
            var internalTexture = texture.getInternalTexture();
            if (internalTexture) {
                internalTexture._cachedWrapU = texture.wrapU;
                internalTexture._cachedWrapV = texture.wrapV;
                internalTexture._cachedWrapR = texture.wrapR;
            }
            if (pipeline.samplers[name]) {
                pipeline.samplers[name].texture = internalTexture;
            }
            else {
                // TODO WEBGPU. 121 mapping samplers <-> availableSamplers
                var availableSampler = pipeline.availableSamplers[name];
                if (availableSampler) {
                    pipeline.samplers[name] = {
                        setIndex: availableSampler.setIndex,
                        textureBinding: availableSampler.bindingIndex,
                        samplerBinding: availableSampler.bindingIndex + 1,
                        texture: internalTexture
                    };
                }
            }
        }
    };
    WebGPUEngine.prototype.bindSamplers = function (effect) { };
    WebGPUEngine.prototype._bindTextureDirectly = function (target, texture) {
        if (this._boundTexturesCache[this._activeChannel] !== texture) {
            this._boundTexturesCache[this._activeChannel] = texture;
            return true;
        }
        return false;
    };
    /** @hidden */
    WebGPUEngine.prototype._bindTexture = function (channel, texture) {
        if (channel < 0) {
            return;
        }
        this._bindTextureDirectly(0, texture);
    };
    /** @hidden */
    WebGPUEngine.prototype._uploadCompressedDataToTextureDirectly = function (texture, internalFormat, width, height, data, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    /** @hidden */
    WebGPUEngine.prototype._uploadDataToTextureDirectly = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    /** @hidden */
    WebGPUEngine.prototype._uploadArrayBufferViewToTexture = function (texture, imageData, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    /** @hidden */
    WebGPUEngine.prototype._uploadImageToTexture = function (texture, image, faceIndex, lod) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lod === void 0) { lod = 0; }
    };
    //------------------------------------------------------------------------------
    //                              Render Target Textures
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.createRenderTargetTexture = function (size, options) {
        var fullOptions = new _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_5__["RenderTargetCreationOptions"]();
        if (options !== undefined && typeof options === "object") {
            fullOptions.generateMipMaps = options.generateMipMaps;
            fullOptions.generateDepthBuffer = options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
            fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && options.generateStencilBuffer;
            fullOptions.type = options.type === undefined ? _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURETYPE_UNSIGNED_INT : options.type;
            fullOptions.samplingMode = options.samplingMode === undefined ? _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;
        }
        else {
            fullOptions.generateMipMaps = options;
            fullOptions.generateDepthBuffer = true;
            fullOptions.generateStencilBuffer = false;
            fullOptions.type = _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURETYPE_UNSIGNED_INT;
            fullOptions.samplingMode = _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE;
        }
        var texture = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"](this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"].DATASOURCE_RENDERTARGET);
        var width = size.width || size;
        var height = size.height || size;
        texture._depthStencilBuffer = {};
        texture._framebuffer = {};
        texture.baseWidth = width;
        texture.baseHeight = height;
        texture.width = width;
        texture.height = height;
        texture.isReady = true;
        texture.samples = 1;
        texture.generateMipMaps = fullOptions.generateMipMaps ? true : false;
        texture.samplingMode = fullOptions.samplingMode;
        texture.type = fullOptions.type;
        texture._generateDepthBuffer = fullOptions.generateDepthBuffer;
        texture._generateStencilBuffer = fullOptions.generateStencilBuffer ? true : false;
        this._internalTexturesCache.push(texture);
        return texture;
    };
    //------------------------------------------------------------------------------
    //                              Render Commands
    //------------------------------------------------------------------------------
    /**
     * Begin a new frame
     */
    WebGPUEngine.prototype.beginFrame = function () {
        _super.prototype.beginFrame.call(this);
        this._uploadEncoder = this._device.createCommandEncoder(this._uploadEncoderDescriptor);
        this._renderEncoder = this._device.createCommandEncoder(this._renderEncoderDescriptor);
    };
    WebGPUEngine.prototype._shouldOnlyUpdateCameras = function () {
        return this._frozenCommands !== null;
    };
    /**
     * End the current frame
     */
    WebGPUEngine.prototype.endFrame = function () {
        this._endRenderPass();
        if (this._freezeCommands && this._frozenCommands) {
            this._commandBuffers[0] = this._frozenCommands[0];
            this._commandBuffers[1] = this._frozenCommands[1];
        }
        else {
            this._commandBuffers[0] = this._uploadEncoder.finish();
            this._commandBuffers[1] = this._renderEncoder.finish();
        }
        if (this._freezeCommands && !this._frozenCommands) {
            this._frozenCommands = [];
            this._frozenCommands[0] = this._commandBuffers[0];
            this._frozenCommands[1] = this._commandBuffers[1];
        }
        this._device.getQueue().submit(this._commandBuffers);
        _super.prototype.endFrame.call(this);
    };
    /**
     * Freezes the current list of commands to speed up rendering of sub sequent frames.
     */
    WebGPUEngine.prototype.freezeCommands = function () {
        this._freezeCommands = true;
        this._frozenCommands = null;
    };
    /**
     * Freezes the current list of commands to speed up rendering of sub sequent frames.
     */
    WebGPUEngine.prototype.unFreezeCommands = function () {
        this._freezeCommands = false;
        this._frozenCommands = null;
    };
    //------------------------------------------------------------------------------
    //                              Render Pass
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype._startMainRenderPass = function () {
        if (this._currentRenderPass) {
            this._endRenderPass();
        }
        // Resolve in case of MSAA
        if (this._options.antialiasing) {
            this._mainColorAttachments[0].resolveTarget = this._swapChain.getCurrentTexture().createView();
        }
        else {
            this._mainColorAttachments[0].attachment = this._swapChain.getCurrentTexture().createDefaultView();
        }
        this._currentRenderPass = this._renderEncoder.beginRenderPass({
            colorAttachments: this._mainColorAttachments,
            depthStencilAttachment: this._mainDepthAttachment
        });
    };
    WebGPUEngine.prototype._endRenderPass = function () {
        if (this._currentRenderPass) {
            this._currentRenderPass.endPass();
            this._currentRenderPass = null;
        }
    };
    WebGPUEngine.prototype.bindFramebuffer = function (texture, faceIndex, requiredWidth, requiredHeight, forceFullscreenViewport) {
        if (this._currentRenderTarget) {
            this.unBindFramebuffer(this._currentRenderTarget);
        }
        this._currentRenderTarget = texture;
        this._currentFramebuffer = texture._MSAAFramebuffer ? texture._MSAAFramebuffer : texture._framebuffer;
        if (this._cachedViewport && !forceFullscreenViewport) {
            this.setViewport(this._cachedViewport, requiredWidth, requiredHeight);
        }
    };
    WebGPUEngine.prototype.unBindFramebuffer = function (texture, disableGenerateMipMaps, onBeforeUnbind) {
        if (disableGenerateMipMaps === void 0) { disableGenerateMipMaps = false; }
        this._currentRenderTarget = null;
        if (onBeforeUnbind) {
            if (texture._MSAAFramebuffer) {
                this._currentFramebuffer = texture._framebuffer;
            }
            onBeforeUnbind();
        }
        this._currentFramebuffer = null;
    };
    //------------------------------------------------------------------------------
    //                              Render
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype._getTopology = function (fillMode) {
        switch (fillMode) {
            // Triangle views
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_TriangleFillMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_triangleList;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_PointFillMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_pointList;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_WireFrameFillMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_lineList;
            // Draw modes
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_PointListDrawMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_pointList;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_LineListDrawMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_lineList;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_LineLoopDrawMode:
                // return this._gl.LINE_LOOP;
                // TODO WEBGPU. Line Loop Mode Fallback at buffer load time.
                throw "LineLoop is an unsupported fillmode in WebGPU";
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_LineStripDrawMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_lineStrip;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_TriangleStripDrawMode:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_triangleStrip;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].MATERIAL_TriangleFanDrawMode:
                // return this._gl.TRIANGLE_FAN;
                // TODO WEBGPU. Triangle Fan Mode Fallback at buffer load time.
                throw "TriangleFan is an unsupported fillmode in WebGPU";
            default:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUPrimitiveTopology_triangleList;
        }
    };
    WebGPUEngine.prototype._getCompareFunction = function (compareFunction) {
        switch (compareFunction) {
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].ALWAYS:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_always;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].EQUAL:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_equal;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].GREATER:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_greater;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].GEQUAL:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_greaterEqual;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].LESS:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_less;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].LEQUAL:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_lessEqual;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].NEVER:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_never;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].NOTEQUAL:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_notEqual;
            default:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCompareFunction_less;
        }
    };
    WebGPUEngine.prototype._getOpFunction = function (operation, defaultOp) {
        switch (operation) {
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].KEEP:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_keep;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].ZERO:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_zero;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].REPLACE:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_replace;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].INVERT:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_invert;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].INCR:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_incrementClamp;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].DECR:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_decrementClamp;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].INCR_WRAP:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_incrementWrap;
            case _constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].DECR_WRAP:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_decrementWrap;
            default:
                return defaultOp;
        }
    };
    WebGPUEngine.prototype._getDepthStencilStateDescriptor = function () {
        // TODO WEBGPU. Depth State according to the cached state.
        // And the current render pass attachment setup.
        var stencilFrontBack = {
            compare: this._getCompareFunction(this._stencilState.stencilFunc),
            depthFailOp: this._getOpFunction(this._stencilState.stencilOpDepthFail, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_keep),
            failOp: this._getOpFunction(this._stencilState.stencilOpStencilFail, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_keep),
            passOp: this._getOpFunction(this._stencilState.stencilOpStencilDepthPass, _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUStencilOperation_replace)
        };
        return {
            depthWriteEnabled: this.getDepthWrite(),
            depthCompare: this._getCompareFunction(this.getDepthFunction()),
            format: "depth32float-stencil8",
            stencilFront: stencilFrontBack,
            stencilBack: stencilFrontBack,
            stencilReadMask: this._stencilState.stencilFuncMask,
            stencilWriteMask: this._stencilState.stencilMask,
        };
    };
    /**
     * Set various states to the webGL context
     * @param culling defines backface culling state
     * @param zOffset defines the value to apply to zOffset (0 by default)
     * @param force defines if states must be applied even if cache is up to date
     * @param reverseSide defines if culling must be reversed (CCW instead of CW and CW instead of CCW)
     */
    WebGPUEngine.prototype.setState = function (culling, zOffset, force, reverseSide) {
        if (zOffset === void 0) { zOffset = 0; }
        if (reverseSide === void 0) { reverseSide = false; }
        // Culling
        if (this._depthCullingState.cull !== culling || force) {
            this._depthCullingState.cull = culling;
        }
        // Cull face
        // var cullFace = this.cullBackFaces ? this._gl.BACK : this._gl.FRONT;
        var cullFace = this.cullBackFaces ? 1 : 2;
        if (this._depthCullingState.cullFace !== cullFace || force) {
            this._depthCullingState.cullFace = cullFace;
        }
        // Z offset
        this.setZOffset(zOffset);
        // Front face
        // var frontFace = reverseSide ? this._gl.CW : this._gl.CCW;
        var frontFace = reverseSide ? 1 : 2;
        if (this._depthCullingState.frontFace !== frontFace || force) {
            this._depthCullingState.frontFace = frontFace;
        }
    };
    WebGPUEngine.prototype._getFrontFace = function () {
        switch (this._depthCullingState.frontFace) {
            case 1:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFrontFace_cw;
            default:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUFrontFace_ccw;
        }
    };
    WebGPUEngine.prototype._getCullMode = function () {
        if (this._depthCullingState.cull === false) {
            return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCullMode_none;
        }
        if (this._depthCullingState.cullFace === 2) {
            return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCullMode_front;
        }
        else {
            return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUCullMode_back;
        }
    };
    WebGPUEngine.prototype._getRasterizationStateDescriptor = function () {
        return {
            frontFace: this._getFrontFace(),
            cullMode: this._getCullMode(),
            depthBias: this._depthCullingState.zOffset,
        };
    };
    WebGPUEngine.prototype._getWriteMask = function () {
        if (this.__colorWrite) {
            return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUColorWriteBits_ALL;
        }
        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUColorWriteBits_NONE;
    };
    /**
     * Sets the current alpha mode
     * @param mode defines the mode to use (one of the Engine.ALPHA_XXX)
     * @param noDepthWriteChange defines if depth writing state should remains unchanged (false by default)
     * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered
     */
    WebGPUEngine.prototype.setAlphaMode = function (mode, noDepthWriteChange) {
        if (noDepthWriteChange === void 0) { noDepthWriteChange = false; }
        if (this._alphaMode === mode) {
            return;
        }
        switch (mode) {
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_DISABLE:
                this._alphaState.alphaBlend = false;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_PREMULTIPLIED:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(1, 0x0303, 1, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_PREMULTIPLIED_PORTERDUFF:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
                this._alphaState.setAlphaBlendFunctionParameters(1, 0x0303, 1, 0x0303);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_COMBINE:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(0x0302, 0x0303, 1, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_ONEONE:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE, this._gl.ZERO, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(1, 1, 0, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_ADD:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.SRC_ALPHA, this._gl.ONE, this._gl.ZERO, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(0x0302, 1, 0, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_SUBTRACT:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.ZERO, this._gl.ONE_MINUS_SRC_COLOR, this._gl.ONE, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(0, 0x0301, 1, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_MULTIPLY:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.DST_COLOR, this._gl.ZERO, this._gl.ONE, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(0x0306, 0, 1, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_MAXIMIZED:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.SRC_ALPHA, this._gl.ONE_MINUS_SRC_COLOR, this._gl.ONE, this._gl.ONE);
                this._alphaState.setAlphaBlendFunctionParameters(0x0302, 0x0301, 1, 1);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_INTERPOLATE:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.CONSTANT_COLOR, this._gl.ONE_MINUS_CONSTANT_COLOR, this._gl.CONSTANT_ALPHA, this._gl.ONE_MINUS_CONSTANT_ALPHA);
                this._alphaState.setAlphaBlendFunctionParameters(0x8001, 0x8002, 0x8003, 0x8004);
                this._alphaState.alphaBlend = true;
                break;
            case _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_SCREENMODE:
                // this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_COLOR, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
                this._alphaState.setAlphaBlendFunctionParameters(1, 0x0301, 1, 0x0303);
                this._alphaState.alphaBlend = true;
                break;
        }
        if (!noDepthWriteChange) {
            this.setDepthWrite(mode === _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].ALPHA_DISABLE);
        }
        this._alphaMode = mode;
    };
    WebGPUEngine.prototype._getAphaBlendOperation = function (operation) {
        switch (operation) {
            case 0x8006:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendOperation_add;
            case 0x800A:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendOperation_substract;
            case 0x800B:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendOperation_reverseSubtract;
            default:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendOperation_add;
        }
    };
    WebGPUEngine.prototype._getAphaBlendFactor = function (factor) {
        switch (factor) {
            case 0:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_zero;
            case 1:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_one;
            case 0x0300:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_srcColor;
            case 0x0301:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_oneMinusSrcColor;
            case 0x0302:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_srcAlpha;
            case 0x0303:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_oneMinusSrcAlpha;
            case 0x0304:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_dstAlpha;
            case 0x0305:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_oneMinusDstAlpha;
            case 0x0306:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_dstColor;
            case 0x0307:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_oneMinusDstColor;
            case 0x0308:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_srcAlphaSaturated;
            case 0x8001:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_blendColor;
            case 0x8002:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_oneMinusBlendColor;
            case 0x8003:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_blendColor;
            case 0x8004:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_oneMinusBlendColor;
            default:
                return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBlendFactor_one;
        }
    };
    WebGPUEngine.prototype._getAphaBlendState = function () {
        if (!this._alphaState.alphaBlend) {
            return {};
        }
        return {
            srcFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[2]),
            dstFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[3]),
            operation: this._getAphaBlendOperation(this._alphaState._blendEquationParameters[1]),
        };
    };
    WebGPUEngine.prototype._getColorBlendState = function () {
        if (!this._alphaState.alphaBlend) {
            return {};
        }
        return {
            srcFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[0]),
            dstFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[1]),
            operation: this._getAphaBlendOperation(this._alphaState._blendEquationParameters[0]),
        };
    };
    WebGPUEngine.prototype._getColorStateDescriptors = function () {
        // TODO WEBGPU. Manage Multi render target.
        return [{
                format: this._options.swapChainFormat,
                alphaBlend: this._getAphaBlendState(),
                colorBlend: this._getColorBlendState(),
                writeMask: this._getWriteMask(),
            }];
    };
    WebGPUEngine.prototype._getStages = function () {
        var gpuPipeline = this._currentEffect._pipelineContext;
        return gpuPipeline.stages;
    };
    WebGPUEngine.prototype._getVertexInputDescriptorFormat = function (vertexBuffer) {
        var kind = vertexBuffer.getKind();
        var type = vertexBuffer.type;
        var normalized = vertexBuffer.normalized;
        var size = vertexBuffer.getSize();
        switch (type) {
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].BYTE:
                switch (size) {
                    case 2:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_char2norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_char2;
                    case 4:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_char4norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_char4;
                }
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].UNSIGNED_BYTE:
                switch (size) {
                    case 2:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uchar2norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uchar2;
                    case 4:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uchar4norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uchar4;
                }
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].SHORT:
                switch (size) {
                    case 2:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_short2norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_short2;
                    case 4:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_short4norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_short4;
                }
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].UNSIGNED_SHORT:
                switch (size) {
                    case 2:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_ushort2norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_ushort2;
                    case 4:
                        return normalized ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_ushort4norm : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_ushort4;
                }
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].INT:
                switch (size) {
                    case 1:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_int;
                    case 2:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_int2;
                    case 3:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_int3;
                    case 4:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_int4;
                }
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].UNSIGNED_INT:
                switch (size) {
                    case 1:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uint;
                    case 2:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uint2;
                    case 3:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uint3;
                    case 4:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_uint4;
                }
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_10__["VertexBuffer"].FLOAT:
                switch (size) {
                    case 1:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_float;
                    case 2:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_float2;
                    case 3:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_float3;
                    case 4:
                        return _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUVertexFormat_float4;
                }
        }
        throw new Error("Invalid Format '" + kind + "'");
    };
    WebGPUEngine.prototype._getVertexInputDescriptor = function () {
        var descriptors = [];
        var effect = this._currentEffect;
        var attributes = effect.getAttributesNames();
        for (var index = 0; index < attributes.length; index++) {
            var location_1 = effect.getAttributeLocation(index);
            if (location_1 >= 0) {
                var vertexBuffer = this._currentVertexBuffers[attributes[index]];
                if (!vertexBuffer) {
                    continue;
                }
                var positionAttributeDescriptor = {
                    shaderLocation: location_1,
                    offset: 0,
                    format: this._getVertexInputDescriptorFormat(vertexBuffer),
                };
                // TODO WEBGPU. Factorize the one with the same underlying buffer.
                var vertexBufferDescriptor = {
                    stride: vertexBuffer.byteStride,
                    stepMode: vertexBuffer.getIsInstanced() ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUInputStepMode_instance : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUInputStepMode_vertex,
                    attributeSet: [positionAttributeDescriptor]
                };
                descriptors.push(vertexBufferDescriptor);
            }
        }
        if (!this._currentIndexBuffer) {
            return {
                indexFormat: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUIndexFormat_uint32,
                vertexBuffers: descriptors
            };
        }
        var inputStateDescriptor = {
            indexFormat: this._currentIndexBuffer.is32Bits ? _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUIndexFormat_uint32 : _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUIndexFormat_uint16,
            vertexBuffers: descriptors
        };
        return inputStateDescriptor;
    };
    WebGPUEngine.prototype._getPipelineLayout = function () {
        var bindGroupLayouts = [];
        var webgpuPipelineContext = this._currentEffect._pipelineContext;
        for (var i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
            var setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
            if (setDefinition === undefined) {
                var bindings_1 = [];
                var uniformsBindGroupLayout = this._device.createBindGroupLayout({
                    bindings: bindings_1,
                });
                bindGroupLayouts[i] = uniformsBindGroupLayout;
                continue;
            }
            var bindings = [];
            for (var j = 0; j < setDefinition.length; j++) {
                var bindingDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i][j];
                if (bindingDefinition === undefined) {
                    continue;
                }
                // TODO WEBGPU. Optimize shared samplers visibility for vertex/framgent.
                if (bindingDefinition.isSampler) {
                    bindings.push({
                        binding: j,
                        visibility: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUShaderStageBit_VERTEX | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUShaderStageBit_FRAGMENT,
                        type: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBindingType_sampledTexture,
                    }, {
                        // TODO WEBGPU. No Magic + 1 (coming from current 1 texture 1 sampler startegy).
                        binding: j + 1,
                        visibility: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUShaderStageBit_VERTEX | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUShaderStageBit_FRAGMENT,
                        type: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBindingType_sampler
                    });
                }
                else {
                    bindings.push({
                        binding: j,
                        visibility: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUShaderStageBit_VERTEX | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUShaderStageBit_FRAGMENT,
                        type: _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBindingType_uniformBuffer,
                    });
                }
            }
            if (bindings.length > 0) {
                var uniformsBindGroupLayout = this._device.createBindGroupLayout({
                    bindings: bindings,
                });
                bindGroupLayouts[i] = uniformsBindGroupLayout;
            }
        }
        webgpuPipelineContext.bindGroupLayouts = bindGroupLayouts;
        return this._device.createPipelineLayout({ bindGroupLayouts: bindGroupLayouts });
    };
    WebGPUEngine.prototype._getRenderPipeline = function (fillMode) {
        // This is wrong to cache this way but workarounds the need of cache in the simple demo context.
        var gpuPipeline = this._currentEffect._pipelineContext;
        if (gpuPipeline.renderPipeline) {
            return gpuPipeline.renderPipeline;
        }
        // Unsupported at the moment but needs to be extracted from the MSAA param.
        var topology = this._getTopology(fillMode);
        var rasterizationStateDescriptor = this._getRasterizationStateDescriptor();
        var depthStateDescriptor = this._getDepthStencilStateDescriptor();
        var colorStateDescriptors = this._getColorStateDescriptors();
        var stages = this._getStages();
        var inputStateDescriptor = this._getVertexInputDescriptor();
        var pipelineLayout = this._getPipelineLayout();
        gpuPipeline.renderPipeline = this._device.createRenderPipeline(tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ sampleCount: this._mainPassSampleCount, primitiveTopology: topology, rasterizationState: rasterizationStateDescriptor, depthStencilState: depthStateDescriptor, colorStates: colorStateDescriptors }, stages, { vertexInput: inputStateDescriptor, layout: pipelineLayout }));
        return gpuPipeline.renderPipeline;
    };
    WebGPUEngine.prototype._getVertexInputsToRender = function () {
        var effect = this._currentEffect;
        var gpuContext = this._currentEffect._pipelineContext;
        var vertexInputs = gpuContext.vertexInputs;
        if (vertexInputs) {
            return vertexInputs;
        }
        vertexInputs = {
            indexBuffer: null,
            indexOffset: 0,
            vertexStartSlot: 0,
            vertexBuffers: [],
            vertexOffsets: [],
        };
        gpuContext.vertexInputs = vertexInputs;
        if (this._currentIndexBuffer) {
            // TODO WEBGPU. Check if cache would be worth it.
            vertexInputs.indexBuffer = this._currentIndexBuffer.underlyingResource;
            vertexInputs.indexOffset = 0;
        }
        else {
            vertexInputs.indexBuffer = null;
        }
        var attributes = effect.getAttributesNames();
        for (var index = 0; index < attributes.length; index++) {
            var order = effect.getAttributeLocation(index);
            if (order >= 0) {
                var vertexBuffer = this._currentVertexBuffers[attributes[index]];
                if (!vertexBuffer) {
                    continue;
                }
                var buffer = vertexBuffer.getBuffer();
                if (buffer) {
                    vertexInputs.vertexBuffers.push(buffer.underlyingResource);
                    vertexInputs.vertexOffsets.push(vertexBuffer.byteOffset);
                }
            }
        }
        // TODO WEBGPU. Optimize buffer reusability and types as more are now allowed.
        return vertexInputs;
    };
    WebGPUEngine.prototype._getBindGroupsToRender = function () {
        var webgpuPipelineContext = this._currentEffect._pipelineContext;
        var bindGroups = webgpuPipelineContext.bindGroups;
        if (bindGroups) {
            if (webgpuPipelineContext.uniformBuffer) {
                webgpuPipelineContext.uniformBuffer.update();
            }
            return bindGroups;
        }
        if (webgpuPipelineContext.uniformBuffer) {
            this.bindUniformBufferBase(webgpuPipelineContext.uniformBuffer.getBuffer(), 0, "LeftOver");
            webgpuPipelineContext.uniformBuffer.update();
        }
        bindGroups = [];
        webgpuPipelineContext.bindGroups = bindGroups;
        var bindGroupLayouts = webgpuPipelineContext.bindGroupLayouts;
        for (var i = 0; i < webgpuPipelineContext.orderedUBOsAndSamplers.length; i++) {
            var setDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i];
            if (setDefinition === undefined) {
                var groupLayout_1 = bindGroupLayouts[i];
                if (groupLayout_1) {
                    bindGroups[i] = this._device.createBindGroup({
                        layout: groupLayout_1,
                        bindings: [],
                    });
                }
                continue;
            }
            var bindings = [];
            for (var j = 0; j < setDefinition.length; j++) {
                var bindingDefinition = webgpuPipelineContext.orderedUBOsAndSamplers[i][j];
                if (bindingDefinition === undefined) {
                    continue;
                }
                // TODO WEBGPU. Authorize shared samplers and Vertex Textures.
                if (bindingDefinition.isSampler) {
                    var bindingInfo = webgpuPipelineContext.samplers[bindingDefinition.name];
                    if (bindingInfo) {
                        if (!bindingInfo.texture._webGPUSampler) {
                            var samplerDescriptor = this._getSamplerDescriptor(bindingInfo.texture);
                            var gpuSampler = this._device.createSampler(samplerDescriptor);
                            bindingInfo.texture._webGPUSampler = gpuSampler;
                        }
                        bindings.push({
                            binding: bindingInfo.textureBinding,
                            resource: bindingInfo.texture._webGPUTextureView,
                        }, {
                            binding: bindingInfo.samplerBinding,
                            resource: bindingInfo.texture._webGPUSampler,
                        });
                    }
                    else {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Sampler has not been bound: " + bindingDefinition.name);
                    }
                }
                else {
                    var dataBuffer = this._uniformsBuffers[bindingDefinition.name];
                    if (dataBuffer) {
                        var webgpuBuffer = dataBuffer.underlyingResource;
                        bindings.push({
                            binding: j,
                            resource: {
                                buffer: webgpuBuffer,
                                offset: 0,
                                size: dataBuffer.capacity,
                            },
                        });
                    }
                    else {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("UBO has not been bound: " + bindingDefinition.name);
                    }
                }
            }
            var groupLayout = bindGroupLayouts[i];
            if (groupLayout) {
                bindGroups[i] = this._device.createBindGroup({
                    layout: groupLayout,
                    bindings: bindings,
                });
            }
        }
        return bindGroups;
    };
    WebGPUEngine.prototype._bindVertexInputs = function (vertexInputs) {
        var renderPass = this._currentRenderPass;
        if (vertexInputs.indexBuffer) {
            // TODO WEBGPU. Check if cache would be worth it.
            renderPass.setIndexBuffer(vertexInputs.indexBuffer, vertexInputs.indexOffset);
        }
        // TODO WEBGPU. Optimize buffer reusability and types as more are now allowed.
        this._currentRenderPass.setVertexBuffers(vertexInputs.vertexStartSlot, vertexInputs.vertexBuffers, vertexInputs.vertexOffsets);
    };
    WebGPUEngine.prototype._setRenderBindGroups = function (bindGroups) {
        // TODO WEBGPU. Only set groups if changes happened.
        var renderPass = this._currentRenderPass;
        for (var i = 0; i < bindGroups.length; i++) {
            renderPass.setBindGroup(i, bindGroups[i]);
        }
    };
    WebGPUEngine.prototype._setRenderPipeline = function (fillMode) {
        var pipeline = this._getRenderPipeline(fillMode);
        this._currentRenderPass.setPipeline(pipeline);
        var vertexInputs = this._getVertexInputsToRender();
        this._bindVertexInputs(vertexInputs);
        var bindGroups = this._getBindGroupsToRender();
        this._setRenderBindGroups(bindGroups);
        if (this._alphaState.alphaBlend && this._alphaState._isBlendConstantsDirty) {
            this._currentRenderPass.setBlendColor(this._alphaState._blendConstants);
        }
    };
    WebGPUEngine.prototype.drawElementsType = function (fillMode, indexStart, indexCount, instancesCount) {
        if (instancesCount === void 0) { instancesCount = 1; }
        this._setRenderPipeline(fillMode);
        this._currentRenderPass.drawIndexed(indexCount, instancesCount, indexStart, 0, 0);
    };
    WebGPUEngine.prototype.drawArraysType = function (fillMode, verticesStart, verticesCount, instancesCount) {
        if (instancesCount === void 0) { instancesCount = 1; }
        this._currentIndexBuffer = null;
        this._setRenderPipeline(fillMode);
        this._currentRenderPass.draw(verticesCount, instancesCount, verticesStart, 0);
    };
    /**
     * Force a specific size of the canvas
     * @param width defines the new canvas' width
     * @param height defines the new canvas' height
     */
    WebGPUEngine.prototype.setSize = function (width, height) {
        _super.prototype.setSize.call(this, width, height);
        this._initializeMainAttachments();
    };
    //------------------------------------------------------------------------------
    //                              Dispose
    //------------------------------------------------------------------------------
    /**
     * Dispose and release all associated resources
     */
    WebGPUEngine.prototype.dispose = function () {
        this._decodeEngine.dispose();
        this._compiledShaders = {};
        if (this._mainTexture) {
            this._mainTexture.destroy();
        }
        if (this._depthTexture) {
            this._depthTexture.destroy();
        }
        _super.prototype.dispose.call(this);
    };
    //------------------------------------------------------------------------------
    //                              Misc
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.getRenderWidth = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.width;
        }
        return this._canvas.width;
    };
    WebGPUEngine.prototype.getRenderHeight = function (useScreen) {
        if (useScreen === void 0) { useScreen = false; }
        if (!useScreen && this._currentRenderTarget) {
            return this._currentRenderTarget.height;
        }
        return this._canvas.height;
    };
    WebGPUEngine.prototype.getRenderingCanvas = function () {
        return this._canvas;
    };
    //------------------------------------------------------------------------------
    //                              Errors
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.getError = function () {
        // TODO WEBGPU. from the webgpu errors.
        return 0;
    };
    //------------------------------------------------------------------------------
    //                              Unused WebGPU
    //------------------------------------------------------------------------------
    WebGPUEngine.prototype.areAllEffectsReady = function () {
        // No parallel shader compilation.
        return true;
    };
    WebGPUEngine.prototype._executeWhenRenderingStateIsCompiled = function (pipelineContext, action) {
        // No parallel shader compilation.
        // No Async, so direct launch
        action();
    };
    WebGPUEngine.prototype._isRenderingStateCompiled = function (pipelineContext) {
        // No parallel shader compilation.
        return true;
    };
    WebGPUEngine.prototype._getUnpackAlignement = function () {
        return 1;
    };
    WebGPUEngine.prototype._unpackFlipY = function (value) { };
    // TODO WEBGPU. All of the below should go once engine split with baseEngine.
    WebGPUEngine.prototype.applyStates = function () {
        // Apply States dynamically.
        // This is done at the pipeline creation level for the moment...
    };
    /** @hidden */
    WebGPUEngine.prototype._getSamplingParameters = function (samplingMode, generateMipMaps) {
        throw "_getSamplingParameters is not available in WebGPU";
    };
    WebGPUEngine.prototype.bindUniformBlock = function (pipelineContext, blockName, index) {
    };
    WebGPUEngine.prototype.getUniforms = function (pipelineContext, uniformsNames) {
        return [];
    };
    WebGPUEngine.prototype.setIntArray = function (uniform, array) {
    };
    WebGPUEngine.prototype.setIntArray2 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setIntArray3 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setIntArray4 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setFloatArray = function (uniform, array) {
    };
    WebGPUEngine.prototype.setFloatArray2 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setFloatArray3 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setFloatArray4 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setArray = function (uniform, array) {
    };
    WebGPUEngine.prototype.setArray2 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setArray3 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setArray4 = function (uniform, array) {
    };
    WebGPUEngine.prototype.setMatrices = function (uniform, matrices) {
    };
    WebGPUEngine.prototype.setMatrix3x3 = function (uniform, matrix) {
    };
    WebGPUEngine.prototype.setMatrix2x2 = function (uniform, matrix) {
    };
    WebGPUEngine.prototype.setFloat = function (uniform, value) {
    };
    WebGPUEngine.prototype.setFloat2 = function (uniform, x, y) {
    };
    WebGPUEngine.prototype.setFloat3 = function (uniform, x, y, z) {
    };
    WebGPUEngine.prototype.setBool = function (uniform, bool) {
    };
    WebGPUEngine.prototype.setFloat4 = function (uniform, x, y, z, w) {
    };
    // Default shaderc options.
    WebGPUEngine._shadercDefaultOptions = {
        jsPath: "https://preview.babylonjs.com/shaderc/shaderc.js",
        wasmPath: "https://preview.babylonjs.com/shaderc/shaderc.wasm"
    };
    return WebGPUEngine;
}(_Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"]));



/***/ }),

/***/ "./Events/clipboardEvents.ts":
/*!***********************************!*\
  !*** ./Events/clipboardEvents.ts ***!
  \***********************************/
/*! exports provided: ClipboardEventTypes, ClipboardInfo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClipboardEventTypes", function() { return ClipboardEventTypes; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClipboardInfo", function() { return ClipboardInfo; });
/**
 * Gather the list of clipboard event types as constants.
 */
var ClipboardEventTypes = /** @class */ (function () {
    function ClipboardEventTypes() {
    }
    /**
     * The clipboard event is fired when a copy command is active (pressed).
     */
    ClipboardEventTypes.COPY = 0x01; //
    /**
     *  The clipboard event is fired when a cut command is active (pressed).
     */
    ClipboardEventTypes.CUT = 0x02;
    /**
     * The clipboard event is fired when a paste command is active (pressed).
     */
    ClipboardEventTypes.PASTE = 0x03;
    return ClipboardEventTypes;
}());

/**
 * This class is used to store clipboard related info for the onClipboardObservable event.
 */
var ClipboardInfo = /** @class */ (function () {
    /**
     *Creates an instance of ClipboardInfo.
     * @param type Defines the type of event (BABYLON.ClipboardEventTypes)
     * @param event Defines the related dom event
     */
    function ClipboardInfo(
    /**
     * Defines the type of event (BABYLON.ClipboardEventTypes)
     */
    type,
    /**
     * Defines the related dom event
     */
    event) {
        this.type = type;
        this.event = event;
    }
    /**
     *  Get the clipboard event's type from the keycode.
     * @param keyCode Defines the keyCode for the current keyboard event.
     * @return {number}
     */
    ClipboardInfo.GetTypeFromCharacter = function (keyCode) {
        var charCode = keyCode;
        //TODO: add codes for extended ASCII
        switch (charCode) {
            case 67: return ClipboardEventTypes.COPY;
            case 86: return ClipboardEventTypes.PASTE;
            case 88: return ClipboardEventTypes.CUT;
            default: return -1;
        }
    };
    return ClipboardInfo;
}());



/***/ }),

/***/ "./Events/index.ts":
/*!*************************!*\
  !*** ./Events/index.ts ***!
  \*************************/
/*! exports provided: KeyboardEventTypes, KeyboardInfo, KeyboardInfoPre, PointerEventTypes, PointerInfoBase, PointerInfoPre, PointerInfo, ClipboardEventTypes, ClipboardInfo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _keyboardEvents__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./keyboardEvents */ "./Events/keyboardEvents.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardEventTypes", function() { return _keyboardEvents__WEBPACK_IMPORTED_MODULE_0__["KeyboardEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfo", function() { return _keyboardEvents__WEBPACK_IMPORTED_MODULE_0__["KeyboardInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfoPre", function() { return _keyboardEvents__WEBPACK_IMPORTED_MODULE_0__["KeyboardInfoPre"]; });

/* harmony import */ var _pointerEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pointerEvents */ "./Events/pointerEvents.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerEventTypes", function() { return _pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfoBase", function() { return _pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerInfoBase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfoPre", function() { return _pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerInfoPre"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfo", function() { return _pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerInfo"]; });

/* harmony import */ var _clipboardEvents__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./clipboardEvents */ "./Events/clipboardEvents.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardEventTypes", function() { return _clipboardEvents__WEBPACK_IMPORTED_MODULE_2__["ClipboardEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardInfo", function() { return _clipboardEvents__WEBPACK_IMPORTED_MODULE_2__["ClipboardInfo"]; });






/***/ }),

/***/ "./Events/keyboardEvents.ts":
/*!**********************************!*\
  !*** ./Events/keyboardEvents.ts ***!
  \**********************************/
/*! exports provided: KeyboardEventTypes, KeyboardInfo, KeyboardInfoPre */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyboardEventTypes", function() { return KeyboardEventTypes; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfo", function() { return KeyboardInfo; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfoPre", function() { return KeyboardInfoPre; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");

/**
 * Gather the list of keyboard event types as constants.
 */
var KeyboardEventTypes = /** @class */ (function () {
    function KeyboardEventTypes() {
    }
    /**
     * The keydown event is fired when a key becomes active (pressed).
     */
    KeyboardEventTypes.KEYDOWN = 0x01;
    /**
     * The keyup event is fired when a key has been released.
     */
    KeyboardEventTypes.KEYUP = 0x02;
    return KeyboardEventTypes;
}());

/**
 * This class is used to store keyboard related info for the onKeyboardObservable event.
 */
var KeyboardInfo = /** @class */ (function () {
    /**
     * Instantiates a new keyboard info.
     * This class is used to store keyboard related info for the onKeyboardObservable event.
     * @param type Defines the type of event (KeyboardEventTypes)
     * @param event Defines the related dom event
     */
    function KeyboardInfo(
    /**
     * Defines the type of event (KeyboardEventTypes)
     */
    type,
    /**
     * Defines the related dom event
     */
    event) {
        this.type = type;
        this.event = event;
    }
    return KeyboardInfo;
}());

/**
 * This class is used to store keyboard related info for the onPreKeyboardObservable event.
 * Set the skipOnKeyboardObservable property to true if you want the engine to stop any process after this event is triggered, even not calling onKeyboardObservable
 */
var KeyboardInfoPre = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](KeyboardInfoPre, _super);
    /**
     * Instantiates a new keyboard pre info.
     * This class is used to store keyboard related info for the onPreKeyboardObservable event.
     * @param type Defines the type of event (KeyboardEventTypes)
     * @param event Defines the related dom event
     */
    function KeyboardInfoPre(
    /**
     * Defines the type of event (KeyboardEventTypes)
     */
    type,
    /**
     * Defines the related dom event
     */
    event) {
        var _this = _super.call(this, type, event) || this;
        _this.type = type;
        _this.event = event;
        _this.skipOnPointerObservable = false;
        return _this;
    }
    return KeyboardInfoPre;
}(KeyboardInfo));



/***/ }),

/***/ "./Events/pointerEvents.ts":
/*!*********************************!*\
  !*** ./Events/pointerEvents.ts ***!
  \*********************************/
/*! exports provided: PointerEventTypes, PointerInfoBase, PointerInfoPre, PointerInfo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointerEventTypes", function() { return PointerEventTypes; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointerInfoBase", function() { return PointerInfoBase; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointerInfoPre", function() { return PointerInfoPre; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointerInfo", function() { return PointerInfo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");


/**
 * Gather the list of pointer event types as constants.
 */
var PointerEventTypes = /** @class */ (function () {
    function PointerEventTypes() {
    }
    /**
     * The pointerdown event is fired when a pointer becomes active. For mouse, it is fired when the device transitions from no buttons depressed to at least one button depressed. For touch, it is fired when physical contact is made with the digitizer. For pen, it is fired when the stylus makes physical contact with the digitizer.
     */
    PointerEventTypes.POINTERDOWN = 0x01;
    /**
     * The pointerup event is fired when a pointer is no longer active.
     */
    PointerEventTypes.POINTERUP = 0x02;
    /**
     * The pointermove event is fired when a pointer changes coordinates.
     */
    PointerEventTypes.POINTERMOVE = 0x04;
    /**
     * The pointerwheel event is fired when a mouse wheel has been rotated.
     */
    PointerEventTypes.POINTERWHEEL = 0x08;
    /**
     * The pointerpick event is fired when a mesh or sprite has been picked by the pointer.
     */
    PointerEventTypes.POINTERPICK = 0x10;
    /**
     * The pointertap event is fired when a the object has been touched and released without drag.
     */
    PointerEventTypes.POINTERTAP = 0x20;
    /**
     * The pointerdoubletap event is fired when a the object has been touched and released twice without drag.
     */
    PointerEventTypes.POINTERDOUBLETAP = 0x40;
    return PointerEventTypes;
}());

/**
 * Base class of pointer info types.
 */
var PointerInfoBase = /** @class */ (function () {
    /**
     * Instantiates the base class of pointers info.
     * @param type Defines the type of event (PointerEventTypes)
     * @param event Defines the related dom event
     */
    function PointerInfoBase(
    /**
     * Defines the type of event (PointerEventTypes)
     */
    type,
    /**
     * Defines the related dom event
     */
    event) {
        this.type = type;
        this.event = event;
    }
    return PointerInfoBase;
}());

/**
 * This class is used to store pointer related info for the onPrePointerObservable event.
 * Set the skipOnPointerObservable property to true if you want the engine to stop any process after this event is triggered, even not calling onPointerObservable
 */
var PointerInfoPre = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PointerInfoPre, _super);
    /**
     * Instantiates a PointerInfoPre to store pointer related info to the onPrePointerObservable event.
     * @param type Defines the type of event (PointerEventTypes)
     * @param event Defines the related dom event
     * @param localX Defines the local x coordinates of the pointer when the event occured
     * @param localY Defines the local y coordinates of the pointer when the event occured
     */
    function PointerInfoPre(type, event, localX, localY) {
        var _this = _super.call(this, type, event) || this;
        /**
         * Ray from a pointer if availible (eg. 6dof controller)
         */
        _this.ray = null;
        _this.skipOnPointerObservable = false;
        _this.localPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](localX, localY);
        return _this;
    }
    return PointerInfoPre;
}(PointerInfoBase));

/**
 * This type contains all the data related to a pointer event in Babylon.js.
 * The event member is an instance of PointerEvent for all types except PointerWheel and is of type MouseWheelEvent when type equals PointerWheel. The different event types can be found in the PointerEventTypes class.
 */
var PointerInfo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PointerInfo, _super);
    /**
     * Instantiates a PointerInfo to store pointer related info to the onPointerObservable event.
     * @param type Defines the type of event (PointerEventTypes)
     * @param event Defines the related dom event
     * @param pickInfo Defines the picking info associated to the info (if any)\
     */
    function PointerInfo(type, event,
    /**
     * Defines the picking info associated to the info (if any)\
     */
    pickInfo) {
        var _this = _super.call(this, type, event) || this;
        _this.pickInfo = pickInfo;
        return _this;
    }
    return PointerInfo;
}(PointerInfoBase));



/***/ }),

/***/ "./Gamepads/Controllers/daydreamController.ts":
/*!****************************************************!*\
  !*** ./Gamepads/Controllers/daydreamController.ts ***!
  \****************************************************/
/*! exports provided: DaydreamController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DaydreamController", function() { return DaydreamController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");





/**
 * Google Daydream controller
 */
var DaydreamController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DaydreamController, _super);
    /**
     * Creates a new DaydreamController from a gamepad
     * @param vrGamepad the gamepad that the controller should be created from
     */
    function DaydreamController(vrGamepad) {
        var _this = _super.call(this, vrGamepad) || this;
        _this.controllerType = _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledControllerType"].DAYDREAM;
        return _this;
    }
    /**
     * Implements abstract method on WebVRController class, loading controller meshes and calling this.attachToMesh if successful.
     * @param scene scene in which to add meshes
     * @param meshLoaded optional callback function that will be called if the mesh loads successfully.
     */
    DaydreamController.prototype.initControllerMesh = function (scene, meshLoaded) {
        var _this = this;
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_2__["SceneLoader"].ImportMesh("", DaydreamController.MODEL_BASE_URL, DaydreamController.MODEL_FILENAME, scene, function (newMeshes) {
            _this._defaultModel = newMeshes[1];
            _this.attachToMesh(_this._defaultModel);
            if (meshLoaded) {
                meshLoaded(_this._defaultModel);
            }
        });
    };
    /**
     * Called once for each button that changed state since the last frame
     * @param buttonIdx Which button index changed
     * @param state New state of the button
     * @param changes Which properties on the state changed since last frame
     */
    DaydreamController.prototype._handleButtonChange = function (buttonIdx, state, changes) {
        // Daydream controller only has 1 GamepadButton (on the trackpad).
        if (buttonIdx === 0) {
            var observable = this.onTriggerStateChangedObservable;
            if (observable) {
                observable.notifyObservers(state);
            }
        }
        else {
            // If the app or home buttons are ever made available
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Unrecognized Daydream button index: " + buttonIdx);
        }
    };
    /**
     * Base Url for the controller model.
     */
    DaydreamController.MODEL_BASE_URL = 'https://controllers.babylonjs.com/generic/';
    /**
     * File name for the controller model.
     */
    DaydreamController.MODEL_FILENAME = 'generic.babylon';
    /**
     * Gamepad Id prefix used to identify Daydream Controller.
     */
    DaydreamController.GAMEPAD_ID_PREFIX = 'Daydream'; // id is 'Daydream Controller'
    return DaydreamController;
}(_webVRController__WEBPACK_IMPORTED_MODULE_3__["WebVRController"]));

_poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledControllerHelper"]._ControllerFactories.push({
    canCreate: function (gamepadInfo) {
        return gamepadInfo.id.indexOf(DaydreamController.GAMEPAD_ID_PREFIX) === 0;
    },
    create: function (gamepadInfo) {
        return new DaydreamController(gamepadInfo);
    }
});


/***/ }),

/***/ "./Gamepads/Controllers/gearVRController.ts":
/*!**************************************************!*\
  !*** ./Gamepads/Controllers/gearVRController.ts ***!
  \**************************************************/
/*! exports provided: GearVRController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GearVRController", function() { return GearVRController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");






/**
     * Gear VR Controller
     */
var GearVRController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GearVRController, _super);
    /**
     * Creates a new GearVRController from a gamepad
     * @param vrGamepad the gamepad that the controller should be created from
     */
    function GearVRController(vrGamepad) {
        var _this = _super.call(this, vrGamepad) || this;
        _this._buttonIndexToObservableNameMap = [
            'onPadStateChangedObservable',
            'onTriggerStateChangedObservable' // Trigger
        ];
        _this.controllerType = _poseEnabledController__WEBPACK_IMPORTED_MODULE_5__["PoseEnabledControllerType"].GEAR_VR;
        // Initial starting position defaults to where hand would be (incase of only 3dof controller)
        _this._calculatedPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](_this.hand == "left" ? -0.15 : 0.15, -0.5, 0.25);
        _this._disableTrackPosition(_this._calculatedPosition);
        return _this;
    }
    /**
     * Implements abstract method on WebVRController class, loading controller meshes and calling this.attachToMesh if successful.
     * @param scene scene in which to add meshes
     * @param meshLoaded optional callback function that will be called if the mesh loads successfully.
     */
    GearVRController.prototype.initControllerMesh = function (scene, meshLoaded) {
        var _this = this;
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_3__["SceneLoader"].ImportMesh("", GearVRController.MODEL_BASE_URL, GearVRController.MODEL_FILENAME, scene, function (newMeshes) {
            // Offset the controller so it will rotate around the users wrist
            var mesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]("", scene);
            newMeshes[1].parent = mesh;
            newMeshes[1].position.z = -0.15;
            _this._defaultModel = mesh;
            _this.attachToMesh(_this._defaultModel);
            if (meshLoaded) {
                meshLoaded(_this._defaultModel);
            }
        });
    };
    /**
     * Called once for each button that changed state since the last frame
     * @param buttonIdx Which button index changed
     * @param state New state of the button
     * @param changes Which properties on the state changed since last frame
     */
    GearVRController.prototype._handleButtonChange = function (buttonIdx, state, changes) {
        if (buttonIdx < this._buttonIndexToObservableNameMap.length) {
            var observableName = this._buttonIndexToObservableNameMap[buttonIdx];
            // Only emit events for buttons that we know how to map from index to observable
            var observable = this[observableName];
            if (observable) {
                observable.notifyObservers(state);
            }
        }
    };
    /**
     * Base Url for the controller model.
     */
    GearVRController.MODEL_BASE_URL = 'https://controllers.babylonjs.com/generic/';
    /**
     * File name for the controller model.
     */
    GearVRController.MODEL_FILENAME = 'generic.babylon';
    /**
     * Gamepad Id prefix used to identify this controller.
     */
    GearVRController.GAMEPAD_ID_PREFIX = 'Gear VR'; // id is 'Gear VR Controller'
    return GearVRController;
}(_webVRController__WEBPACK_IMPORTED_MODULE_4__["WebVRController"]));

_poseEnabledController__WEBPACK_IMPORTED_MODULE_5__["PoseEnabledControllerHelper"]._ControllerFactories.push({
    canCreate: function (gamepadInfo) {
        return gamepadInfo.id.indexOf(GearVRController.GAMEPAD_ID_PREFIX) === 0 ||
            gamepadInfo.id.indexOf('Oculus Go') !== -1 ||
            gamepadInfo.id.indexOf('Vive Focus') !== -1;
    },
    create: function (gamepadInfo) {
        return new GearVRController(gamepadInfo);
    }
});


/***/ }),

/***/ "./Gamepads/Controllers/genericController.ts":
/*!***************************************************!*\
  !*** ./Gamepads/Controllers/genericController.ts ***!
  \***************************************************/
/*! exports provided: GenericController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GenericController", function() { return GenericController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");




/**
 * Generic Controller
 */
var GenericController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GenericController, _super);
    /**
     * Creates a new GenericController from a gamepad
     * @param vrGamepad the gamepad that the controller should be created from
     */
    function GenericController(vrGamepad) {
        return _super.call(this, vrGamepad) || this;
    }
    /**
     * Implements abstract method on WebVRController class, loading controller meshes and calling this.attachToMesh if successful.
     * @param scene scene in which to add meshes
     * @param meshLoaded optional callback function that will be called if the mesh loads successfully.
     */
    GenericController.prototype.initControllerMesh = function (scene, meshLoaded) {
        var _this = this;
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_1__["SceneLoader"].ImportMesh("", GenericController.MODEL_BASE_URL, GenericController.MODEL_FILENAME, scene, function (newMeshes) {
            _this._defaultModel = newMeshes[1];
            _this.attachToMesh(_this._defaultModel);
            if (meshLoaded) {
                meshLoaded(_this._defaultModel);
            }
        });
    };
    /**
     * Called once for each button that changed state since the last frame
     * @param buttonIdx Which button index changed
     * @param state New state of the button
     * @param changes Which properties on the state changed since last frame
     */
    GenericController.prototype._handleButtonChange = function (buttonIdx, state, changes) {
        console.log("Button id: " + buttonIdx + "state: ");
        console.dir(state);
    };
    /**
     * Base Url for the controller model.
     */
    GenericController.MODEL_BASE_URL = 'https://controllers.babylonjs.com/generic/';
    /**
     * File name for the controller model.
     */
    GenericController.MODEL_FILENAME = 'generic.babylon';
    return GenericController;
}(_webVRController__WEBPACK_IMPORTED_MODULE_2__["WebVRController"]));

_poseEnabledController__WEBPACK_IMPORTED_MODULE_3__["PoseEnabledControllerHelper"]._DefaultControllerFactory = function (gamepadInfo) { return new GenericController(gamepadInfo); };


/***/ }),

/***/ "./Gamepads/Controllers/index.ts":
/*!***************************************!*\
  !*** ./Gamepads/Controllers/index.ts ***!
  \***************************************/
/*! exports provided: DaydreamController, GearVRController, GenericController, OculusTouchController, PoseEnabledControllerType, PoseEnabledControllerHelper, PoseEnabledController, ViveController, WebVRController, WindowsMotionController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _daydreamController__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./daydreamController */ "./Gamepads/Controllers/daydreamController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DaydreamController", function() { return _daydreamController__WEBPACK_IMPORTED_MODULE_0__["DaydreamController"]; });

/* harmony import */ var _gearVRController__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./gearVRController */ "./Gamepads/Controllers/gearVRController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GearVRController", function() { return _gearVRController__WEBPACK_IMPORTED_MODULE_1__["GearVRController"]; });

/* harmony import */ var _genericController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./genericController */ "./Gamepads/Controllers/genericController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericController", function() { return _genericController__WEBPACK_IMPORTED_MODULE_2__["GenericController"]; });

/* harmony import */ var _oculusTouchController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./oculusTouchController */ "./Gamepads/Controllers/oculusTouchController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OculusTouchController", function() { return _oculusTouchController__WEBPACK_IMPORTED_MODULE_3__["OculusTouchController"]; });

/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerType", function() { return _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledControllerType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerHelper", function() { return _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledControllerHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledController", function() { return _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledController"]; });

/* harmony import */ var _viveController__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./viveController */ "./Gamepads/Controllers/viveController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViveController", function() { return _viveController__WEBPACK_IMPORTED_MODULE_5__["ViveController"]; });

/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRController", function() { return _webVRController__WEBPACK_IMPORTED_MODULE_6__["WebVRController"]; });

/* harmony import */ var _windowsMotionController__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./windowsMotionController */ "./Gamepads/Controllers/windowsMotionController.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WindowsMotionController", function() { return _windowsMotionController__WEBPACK_IMPORTED_MODULE_7__["WindowsMotionController"]; });











/***/ }),

/***/ "./Gamepads/Controllers/oculusTouchController.ts":
/*!*******************************************************!*\
  !*** ./Gamepads/Controllers/oculusTouchController.ts ***!
  \*******************************************************/
/*! exports provided: OculusTouchController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OculusTouchController", function() { return OculusTouchController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");






/**
 * Oculus Touch Controller
 */
var OculusTouchController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OculusTouchController, _super);
    /**
     * Creates a new OculusTouchController from a gamepad
     * @param vrGamepad the gamepad that the controller should be created from
     */
    function OculusTouchController(vrGamepad) {
        var _this = _super.call(this, vrGamepad) || this;
        /**
         * Fired when the secondary trigger on this controller is modified
         */
        _this.onSecondaryTriggerStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when the thumb rest on this controller is modified
         */
        _this.onThumbRestChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this.controllerType = _poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledControllerType"].OCULUS;
        return _this;
    }
    /**
     * Implements abstract method on WebVRController class, loading controller meshes and calling this.attachToMesh if successful.
     * @param scene scene in which to add meshes
     * @param meshLoaded optional callback function that will be called if the mesh loads successfully.
     */
    OculusTouchController.prototype.initControllerMesh = function (scene, meshLoaded) {
        var _this = this;
        var meshName;
        // Hand
        if (this.hand === 'left') {
            meshName = OculusTouchController.MODEL_LEFT_FILENAME;
        }
        else { // Right is the default if no hand is specified
            meshName = OculusTouchController.MODEL_RIGHT_FILENAME;
        }
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_2__["SceneLoader"].ImportMesh("", OculusTouchController._IsQuest ? OculusTouchController.QUEST_MODEL_BASE_URL : OculusTouchController.MODEL_BASE_URL, meshName, scene, function (newMeshes) {
            /*
            Parent Mesh name: oculus_touch_left
            - body
            - trigger
            - thumbstick
            - grip
            - button_y
            - button_x
            - button_enter
            */
            _this._defaultModel = OculusTouchController._IsQuest ? newMeshes[0] : newMeshes[1];
            _this.attachToMesh(_this._defaultModel);
            if (meshLoaded) {
                meshLoaded(_this._defaultModel);
            }
        });
    };
    Object.defineProperty(OculusTouchController.prototype, "onAButtonStateChangedObservable", {
        /**
         * Fired when the A button on this controller is modified
         */
        get: function () {
            if (this.hand === 'right') {
                return this.onMainButtonStateChangedObservable;
            }
            else {
                throw new Error('No A button on left hand');
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(OculusTouchController.prototype, "onBButtonStateChangedObservable", {
        /**
         * Fired when the B button on this controller is modified
         */
        get: function () {
            if (this.hand === 'right') {
                return this.onSecondaryButtonStateChangedObservable;
            }
            else {
                throw new Error('No B button on left hand');
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(OculusTouchController.prototype, "onXButtonStateChangedObservable", {
        /**
         * Fired when the X button on this controller is modified
         */
        get: function () {
            if (this.hand === 'left') {
                return this.onMainButtonStateChangedObservable;
            }
            else {
                throw new Error('No X button on right hand');
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(OculusTouchController.prototype, "onYButtonStateChangedObservable", {
        /**
         * Fired when the Y button on this controller is modified
         */
        get: function () {
            if (this.hand === 'left') {
                return this.onSecondaryButtonStateChangedObservable;
            }
            else {
                throw new Error('No Y button on right hand');
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
      * Called once for each button that changed state since the last frame
      * 0) thumb stick (touch, press, value = pressed (0,1)). value is in this.leftStick
      * 1) index trigger (touch (?), press (only when value > 0.1), value 0 to 1)
      * 2) secondary trigger (same)
      * 3) A (right) X (left), touch, pressed = value
      * 4) B / Y
      * 5) thumb rest
      * @param buttonIdx Which button index changed
      * @param state New state of the button
      * @param changes Which properties on the state changed since last frame
      */
    OculusTouchController.prototype._handleButtonChange = function (buttonIdx, state, changes) {
        var notifyObject = state; //{ state: state, changes: changes };
        var triggerDirection = this.hand === 'right' ? -1 : 1;
        switch (buttonIdx) {
            case 0:
                this.onPadStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 1: // index trigger
                if (!OculusTouchController._IsQuest && this._defaultModel) {
                    (this._defaultModel.getChildren()[3]).rotation.x = -notifyObject.value * 0.20;
                    (this._defaultModel.getChildren()[3]).position.y = -notifyObject.value * 0.005;
                    (this._defaultModel.getChildren()[3]).position.z = -notifyObject.value * 0.005;
                }
                this.onTriggerStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 2: // secondary trigger
                if (!OculusTouchController._IsQuest && this._defaultModel) {
                    (this._defaultModel.getChildren()[4]).position.x = triggerDirection * notifyObject.value * 0.0035;
                }
                this.onSecondaryTriggerStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 3:
                if (!OculusTouchController._IsQuest && this._defaultModel) {
                    if (notifyObject.pressed) {
                        (this._defaultModel.getChildren()[1]).position.y = -0.001;
                    }
                    else {
                        (this._defaultModel.getChildren()[1]).position.y = 0;
                    }
                }
                this.onMainButtonStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 4:
                if (!OculusTouchController._IsQuest && this._defaultModel) {
                    if (notifyObject.pressed) {
                        (this._defaultModel.getChildren()[2]).position.y = -0.001;
                    }
                    else {
                        (this._defaultModel.getChildren()[2]).position.y = 0;
                    }
                }
                this.onSecondaryButtonStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 5:
                this.onThumbRestChangedObservable.notifyObservers(notifyObject);
                return;
        }
    };
    /**
     * Base Url for the controller model.
     */
    OculusTouchController.MODEL_BASE_URL = 'https://controllers.babylonjs.com/oculus/';
    /**
     * File name for the left controller model.
     */
    OculusTouchController.MODEL_LEFT_FILENAME = 'left.babylon';
    /**
     * File name for the right controller model.
     */
    OculusTouchController.MODEL_RIGHT_FILENAME = 'right.babylon';
    /**
     * Base Url for the Quest controller model.
     */
    OculusTouchController.QUEST_MODEL_BASE_URL = 'https://controllers.babylonjs.com/oculusQuest/';
    /**
     * @hidden
     * If the controllers are running on a device that needs the updated Quest controller models
     */
    OculusTouchController._IsQuest = false;
    return OculusTouchController;
}(_webVRController__WEBPACK_IMPORTED_MODULE_3__["WebVRController"]));

_poseEnabledController__WEBPACK_IMPORTED_MODULE_4__["PoseEnabledControllerHelper"]._ControllerFactories.push({
    canCreate: function (gamepadInfo) {
        // If the headset reports being an Oculus Quest, use the Quest controller models
        if (_Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].LastCreatedEngine && _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].LastCreatedEngine._vrDisplay && _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].LastCreatedEngine._vrDisplay.displayName === "Oculus Quest") {
            OculusTouchController._IsQuest = true;
        }
        return gamepadInfo.id.indexOf('Oculus Touch') !== -1;
    },
    create: function (gamepadInfo) {
        return new OculusTouchController(gamepadInfo);
    }
});


/***/ }),

/***/ "./Gamepads/Controllers/poseEnabledController.ts":
/*!*******************************************************!*\
  !*** ./Gamepads/Controllers/poseEnabledController.ts ***!
  \*******************************************************/
/*! exports provided: PoseEnabledControllerType, PoseEnabledControllerHelper, PoseEnabledController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerType", function() { return PoseEnabledControllerType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerHelper", function() { return PoseEnabledControllerHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledController", function() { return PoseEnabledController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Gamepads/gamepad */ "./Gamepads/gamepad.ts");






/**
* Defines the types of pose enabled controllers that are supported
*/
var PoseEnabledControllerType;
(function (PoseEnabledControllerType) {
    /**
     * HTC Vive
     */
    PoseEnabledControllerType[PoseEnabledControllerType["VIVE"] = 0] = "VIVE";
    /**
     * Oculus Rift
     */
    PoseEnabledControllerType[PoseEnabledControllerType["OCULUS"] = 1] = "OCULUS";
    /**
     * Windows mixed reality
     */
    PoseEnabledControllerType[PoseEnabledControllerType["WINDOWS"] = 2] = "WINDOWS";
    /**
     * Samsung gear VR
     */
    PoseEnabledControllerType[PoseEnabledControllerType["GEAR_VR"] = 3] = "GEAR_VR";
    /**
     * Google Daydream
     */
    PoseEnabledControllerType[PoseEnabledControllerType["DAYDREAM"] = 4] = "DAYDREAM";
    /**
     * Generic
     */
    PoseEnabledControllerType[PoseEnabledControllerType["GENERIC"] = 5] = "GENERIC";
})(PoseEnabledControllerType || (PoseEnabledControllerType = {}));
/**
 * Defines the PoseEnabledControllerHelper object that is used initialize a gamepad as the controller type it is specified as (eg. windows mixed reality controller)
 */
var PoseEnabledControllerHelper = /** @class */ (function () {
    function PoseEnabledControllerHelper() {
    }
    /**
     * Initializes a gamepad as the controller type it is specified as (eg. windows mixed reality controller)
     * @param vrGamepad the gamepad to initialized
     * @returns a vr controller of the type the gamepad identified as
     */
    PoseEnabledControllerHelper.InitiateController = function (vrGamepad) {
        for (var _i = 0, _a = this._ControllerFactories; _i < _a.length; _i++) {
            var factory = _a[_i];
            if (factory.canCreate(vrGamepad)) {
                return factory.create(vrGamepad);
            }
        }
        if (this._DefaultControllerFactory) {
            return this._DefaultControllerFactory(vrGamepad);
        }
        throw "The type of gamepad you are trying to load needs to be imported first or is not supported.";
    };
    /** @hidden */
    PoseEnabledControllerHelper._ControllerFactories = [];
    /** @hidden */
    PoseEnabledControllerHelper._DefaultControllerFactory = null;
    return PoseEnabledControllerHelper;
}());

/**
 * Defines the PoseEnabledController object that contains state of a vr capable controller
 */
var PoseEnabledController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PoseEnabledController, _super);
    /**
     * Creates a new PoseEnabledController from a gamepad
     * @param browserGamepad the gamepad that the PoseEnabledController should be created from
     */
    function PoseEnabledController(browserGamepad) {
        var _this = _super.call(this, browserGamepad.id, browserGamepad.index, browserGamepad) || this;
        /**
         * If the controller is used in a webXR session
         */
        _this.isXR = false;
        // Represents device position and rotation in room space. Should only be used to help calculate babylon space values
        _this._deviceRoomPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._deviceRoomRotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        /**
         * The device position in babylon space
         */
        _this.devicePosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        /**
         * The device rotation in babylon space
         */
        _this.deviceRotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        /**
         * The scale factor of the device in babylon space
         */
        _this.deviceScaleFactor = 1;
        // Used to convert 6dof controllers to 3dof
        _this._trackPosition = true;
        _this._maxRotationDistFromHeadset = Math.PI / 5;
        _this._draggedRoomRotation = 0;
        _this._leftHandSystemQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        /**
         * Internal, matrix used to convert room space to babylon space
         * @hidden
         */
        _this._deviceToWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Identity();
        /**
         * Node to be used when casting a ray from the controller
         * @hidden
         */
        _this._pointingPoseNode = null;
        _this._workingMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Identity();
        /**
         * @hidden
         */
        _this._meshAttachedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this.type = _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_5__["Gamepad"].POSE_ENABLED;
        _this.controllerType = PoseEnabledControllerType.GENERIC;
        _this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        _this._calculatedPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._calculatedRotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].RotationYawPitchRollToRef(Math.PI, 0, 0, _this._leftHandSystemQuaternion);
        return _this;
    }
    /**
     * @hidden
     */
    PoseEnabledController.prototype._disableTrackPosition = function (fixedPosition) {
        if (this._trackPosition) {
            this._calculatedPosition.copyFrom(fixedPosition);
            this._trackPosition = false;
        }
    };
    /**
     * Updates the state of the pose enbaled controller and mesh based on the current position and rotation of the controller
     */
    PoseEnabledController.prototype.update = function () {
        if (this.isXR) {
            return;
        }
        _super.prototype.update.call(this);
        this._updatePoseAndMesh();
    };
    /**
     * Updates only the pose device and mesh without doing any button event checking
     */
    PoseEnabledController.prototype._updatePoseAndMesh = function () {
        if (this.isXR) {
            return;
        }
        var pose = this.browserGamepad.pose;
        this.updateFromDevice(pose);
        if (!this._trackPosition && _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene && _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene.activeCamera && _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene.activeCamera.devicePosition) {
            var camera = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene.activeCamera;
            camera._computeDevicePosition();
            this._deviceToWorld.setTranslation(camera.devicePosition);
            if (camera.deviceRotationQuaternion) {
                var camera = camera;
                camera._deviceRoomRotationQuaternion.toEulerAnglesToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Vector3[0]);
                // Find the radian distance away that the headset is from the controllers rotation
                var distanceAway = Math.atan2(Math.sin(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Vector3[0].y - this._draggedRoomRotation), Math.cos(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["TmpVectors"].Vector3[0].y - this._draggedRoomRotation));
                if (Math.abs(distanceAway) > this._maxRotationDistFromHeadset) {
                    // Only rotate enouph to be within the _maxRotationDistFromHeadset
                    var rotationAmount = distanceAway - (distanceAway < 0 ? -this._maxRotationDistFromHeadset : this._maxRotationDistFromHeadset);
                    this._draggedRoomRotation += rotationAmount;
                    // Rotate controller around headset
                    var sin = Math.sin(-rotationAmount);
                    var cos = Math.cos(-rotationAmount);
                    this._calculatedPosition.x = this._calculatedPosition.x * cos - this._calculatedPosition.z * sin;
                    this._calculatedPosition.z = this._calculatedPosition.x * sin + this._calculatedPosition.z * cos;
                }
            }
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(this._calculatedPosition, this._deviceToWorld, this.devicePosition);
        this._deviceToWorld.getRotationMatrixToRef(this._workingMatrix);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].FromRotationMatrixToRef(this._workingMatrix, this.deviceRotationQuaternion);
        this.deviceRotationQuaternion.multiplyInPlace(this._calculatedRotation);
        if (this._mesh) {
            this._mesh.position.copyFrom(this.devicePosition);
            if (this._mesh.rotationQuaternion) {
                this._mesh.rotationQuaternion.copyFrom(this.deviceRotationQuaternion);
            }
        }
    };
    /**
     * Updates the state of the pose enbaled controller based on the raw pose data from the device
     * @param poseData raw pose fromthe device
     */
    PoseEnabledController.prototype.updateFromDevice = function (poseData) {
        if (this.isXR) {
            return;
        }
        if (poseData) {
            this.rawPose = poseData;
            if (poseData.position) {
                this._deviceRoomPosition.copyFromFloats(poseData.position[0], poseData.position[1], -poseData.position[2]);
                if (this._mesh && this._mesh.getScene().useRightHandedSystem) {
                    this._deviceRoomPosition.z *= -1;
                }
                if (this._trackPosition) {
                    this._deviceRoomPosition.scaleToRef(this.deviceScaleFactor, this._calculatedPosition);
                }
                this._calculatedPosition.addInPlace(this.position);
            }
            var pose = this.rawPose;
            if (poseData.orientation && pose.orientation && pose.orientation.length === 4) {
                this._deviceRoomRotationQuaternion.copyFromFloats(pose.orientation[0], pose.orientation[1], -pose.orientation[2], -pose.orientation[3]);
                if (this._mesh) {
                    if (this._mesh.getScene().useRightHandedSystem) {
                        this._deviceRoomRotationQuaternion.z *= -1;
                        this._deviceRoomRotationQuaternion.w *= -1;
                    }
                    else {
                        this._deviceRoomRotationQuaternion.multiplyToRef(this._leftHandSystemQuaternion, this._deviceRoomRotationQuaternion);
                    }
                }
                // if the camera is set, rotate to the camera's rotation
                this._deviceRoomRotationQuaternion.multiplyToRef(this.rotationQuaternion, this._calculatedRotation);
            }
        }
    };
    /**
     * Attaches a mesh to the controller
     * @param mesh the mesh to be attached
     */
    PoseEnabledController.prototype.attachToMesh = function (mesh) {
        if (this._mesh) {
            this._mesh.parent = null;
        }
        this._mesh = mesh;
        if (this._poseControlledCamera) {
            this._mesh.parent = this._poseControlledCamera;
        }
        if (!this._mesh.rotationQuaternion) {
            this._mesh.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        }
        // Sync controller mesh and pointing pose node's state with controller, this is done to avoid a frame where position is 0,0,0 when attaching mesh
        if (!this.isXR) {
            this._updatePoseAndMesh();
            if (this._pointingPoseNode) {
                var parents = [];
                var obj = this._pointingPoseNode;
                while (obj.parent) {
                    parents.push(obj.parent);
                    obj = obj.parent;
                }
                parents.reverse().forEach(function (p) { p.computeWorldMatrix(true); });
            }
        }
        this._meshAttachedObservable.notifyObservers(mesh);
    };
    /**
     * Attaches the controllers mesh to a camera
     * @param camera the camera the mesh should be attached to
     */
    PoseEnabledController.prototype.attachToPoseControlledCamera = function (camera) {
        this._poseControlledCamera = camera;
        if (this._mesh) {
            this._mesh.parent = this._poseControlledCamera;
        }
    };
    /**
     * Disposes of the controller
     */
    PoseEnabledController.prototype.dispose = function () {
        if (this._mesh) {
            this._mesh.dispose();
        }
        this._mesh = null;
        _super.prototype.dispose.call(this);
    };
    Object.defineProperty(PoseEnabledController.prototype, "mesh", {
        /**
         * The mesh that is attached to the controller
         */
        get: function () {
            return this._mesh;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the ray of the controller in the direction the controller is pointing
     * @param length the length the resulting ray should be
     * @returns a ray in the direction the controller is pointing
     */
    PoseEnabledController.prototype.getForwardRay = function (length) {
        if (length === void 0) { length = 100; }
        if (!this.mesh) {
            return new _Culling_ray__WEBPACK_IMPORTED_MODULE_3__["Ray"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 0, 1), length);
        }
        var m = this._pointingPoseNode ? this._pointingPoseNode.getWorldMatrix() : this.mesh.getWorldMatrix();
        var origin = m.getTranslation();
        var forward = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 0, -1);
        var forwardWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformNormal(forward, m);
        var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(forwardWorld);
        return new _Culling_ray__WEBPACK_IMPORTED_MODULE_3__["Ray"](origin, direction, length);
    };
    /**
     * Name of the child mesh that can be used to cast a ray from the controller
     */
    PoseEnabledController.POINTING_POSE = "POINTING_POSE";
    return PoseEnabledController;
}(_Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_5__["Gamepad"]));



/***/ }),

/***/ "./Gamepads/Controllers/viveController.ts":
/*!************************************************!*\
  !*** ./Gamepads/Controllers/viveController.ts ***!
  \************************************************/
/*! exports provided: ViveController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViveController", function() { return ViveController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");




/**
 * Vive Controller
 */
var ViveController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ViveController, _super);
    /**
     * Creates a new ViveController from a gamepad
     * @param vrGamepad the gamepad that the controller should be created from
     */
    function ViveController(vrGamepad) {
        var _this = _super.call(this, vrGamepad) || this;
        _this.controllerType = _poseEnabledController__WEBPACK_IMPORTED_MODULE_3__["PoseEnabledControllerType"].VIVE;
        _this._invertLeftStickY = true;
        return _this;
    }
    /**
     * Implements abstract method on WebVRController class, loading controller meshes and calling this.attachToMesh if successful.
     * @param scene scene in which to add meshes
     * @param meshLoaded optional callback function that will be called if the mesh loads successfully.
     */
    ViveController.prototype.initControllerMesh = function (scene, meshLoaded) {
        var _this = this;
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_1__["SceneLoader"].ImportMesh("", ViveController.MODEL_BASE_URL, ViveController.MODEL_FILENAME, scene, function (newMeshes) {
            /*
            Parent Mesh name: ViveWand
            - body
            - r_gripper
            - l_gripper
            - menu_button
            - system_button
            - trackpad
            - trigger
            - LED
            */
            _this._defaultModel = newMeshes[1];
            _this.attachToMesh(_this._defaultModel);
            if (meshLoaded) {
                meshLoaded(_this._defaultModel);
            }
        });
    };
    Object.defineProperty(ViveController.prototype, "onLeftButtonStateChangedObservable", {
        /**
         * Fired when the left button on this controller is modified
         */
        get: function () {
            return this.onMainButtonStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ViveController.prototype, "onRightButtonStateChangedObservable", {
        /**
         * Fired when the right button on this controller is modified
         */
        get: function () {
            return this.onMainButtonStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ViveController.prototype, "onMenuButtonStateChangedObservable", {
        /**
         * Fired when the menu button on this controller is modified
         */
        get: function () {
            return this.onSecondaryButtonStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Called once for each button that changed state since the last frame
     * Vive mapping:
     * 0: touchpad
     * 1: trigger
     * 2: left AND right buttons
     * 3: menu button
     * @param buttonIdx Which button index changed
     * @param state New state of the button
     * @param changes Which properties on the state changed since last frame
     */
    ViveController.prototype._handleButtonChange = function (buttonIdx, state, changes) {
        var notifyObject = state; //{ state: state, changes: changes };
        switch (buttonIdx) {
            case 0:
                this.onPadStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 1: // index trigger
                if (this._defaultModel) {
                    (this._defaultModel.getChildren()[6]).rotation.x = -notifyObject.value * 0.15;
                }
                this.onTriggerStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 2: // left AND right button
                this.onMainButtonStateChangedObservable.notifyObservers(notifyObject);
                return;
            case 3:
                if (this._defaultModel) {
                    if (notifyObject.pressed) {
                        (this._defaultModel.getChildren()[2]).position.y = -0.001;
                    }
                    else {
                        (this._defaultModel.getChildren()[2]).position.y = 0;
                    }
                }
                this.onSecondaryButtonStateChangedObservable.notifyObservers(notifyObject);
                return;
        }
    };
    /**
     * Base Url for the controller model.
     */
    ViveController.MODEL_BASE_URL = 'https://controllers.babylonjs.com/vive/';
    /**
     * File name for the controller model.
     */
    ViveController.MODEL_FILENAME = 'wand.babylon';
    return ViveController;
}(_webVRController__WEBPACK_IMPORTED_MODULE_2__["WebVRController"]));

_poseEnabledController__WEBPACK_IMPORTED_MODULE_3__["PoseEnabledControllerHelper"]._ControllerFactories.push({
    canCreate: function (gamepadInfo) {
        return gamepadInfo.id.toLowerCase().indexOf('openvr') !== -1;
    },
    create: function (gamepadInfo) {
        return new ViveController(gamepadInfo);
    }
});


/***/ }),

/***/ "./Gamepads/Controllers/webVRController.ts":
/*!*************************************************!*\
  !*** ./Gamepads/Controllers/webVRController.ts ***!
  \*************************************************/
/*! exports provided: WebVRController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebVRController", function() { return WebVRController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");



/**
 * Defines the WebVRController object that represents controllers tracked in 3D space
 */
var WebVRController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WebVRController, _super);
    /**
     * Creates a new WebVRController from a gamepad
     * @param vrGamepad the gamepad that the WebVRController should be created from
     */
    function WebVRController(vrGamepad) {
        var _this = _super.call(this, vrGamepad) || this;
        // Observables
        /**
         * Fired when the trigger state has changed
         */
        _this.onTriggerStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when the main button state has changed
         */
        _this.onMainButtonStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when the secondary button state has changed
         */
        _this.onSecondaryButtonStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when the pad state has changed
         */
        _this.onPadStateChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when controllers stick values have changed
         */
        _this.onPadValuesChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * X and Y axis corresponding to the controllers joystick
         */
        _this.pad = { x: 0, y: 0 };
        // avoid GC, store state in a tmp object
        _this._changes = {
            pressChanged: false,
            touchChanged: false,
            valueChanged: false,
            changed: false
        };
        _this._buttons = new Array(vrGamepad.buttons.length);
        _this.hand = vrGamepad.hand;
        return _this;
    }
    /**
     * Fired when a controller button's state has changed
     * @param callback the callback containing the button that was modified
     */
    WebVRController.prototype.onButtonStateChange = function (callback) {
        this._onButtonStateChange = callback;
    };
    Object.defineProperty(WebVRController.prototype, "defaultModel", {
        /**
         * The default controller model for the controller
         */
        get: function () {
            return this._defaultModel;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Updates the state of the controller and mesh based on the current position and rotation of the controller
     */
    WebVRController.prototype.update = function () {
        _super.prototype.update.call(this);
        for (var index = 0; index < this._buttons.length; index++) {
            this._setButtonValue(this.browserGamepad.buttons[index], this._buttons[index], index);
        }
        if (this.leftStick.x !== this.pad.x || this.leftStick.y !== this.pad.y) {
            this.pad.x = this.leftStick.x;
            this.pad.y = this.leftStick.y;
            this.onPadValuesChangedObservable.notifyObservers(this.pad);
        }
    };
    WebVRController.prototype._setButtonValue = function (newState, currentState, buttonIndex) {
        if (!newState) {
            newState = {
                pressed: false,
                touched: false,
                value: 0
            };
        }
        if (!currentState) {
            this._buttons[buttonIndex] = {
                pressed: newState.pressed,
                touched: newState.touched,
                value: newState.value
            };
            return;
        }
        this._checkChanges(newState, currentState);
        if (this._changes.changed) {
            this._onButtonStateChange && this._onButtonStateChange(this.index, buttonIndex, newState);
            this._handleButtonChange(buttonIndex, newState, this._changes);
        }
        this._buttons[buttonIndex].pressed = newState.pressed;
        this._buttons[buttonIndex].touched = newState.touched;
        // oculus triggers are never 0, thou not touched.
        this._buttons[buttonIndex].value = newState.value < 0.00000001 ? 0 : newState.value;
    };
    WebVRController.prototype._checkChanges = function (newState, currentState) {
        this._changes.pressChanged = newState.pressed !== currentState.pressed;
        this._changes.touchChanged = newState.touched !== currentState.touched;
        this._changes.valueChanged = newState.value !== currentState.value;
        this._changes.changed = this._changes.pressChanged || this._changes.touchChanged || this._changes.valueChanged;
        return this._changes;
    };
    /**
     * Disposes of th webVRCOntroller
     */
    WebVRController.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.onTriggerStateChangedObservable.clear();
        this.onMainButtonStateChangedObservable.clear();
        this.onSecondaryButtonStateChangedObservable.clear();
        this.onPadStateChangedObservable.clear();
        this.onPadValuesChangedObservable.clear();
    };
    return WebVRController;
}(_poseEnabledController__WEBPACK_IMPORTED_MODULE_2__["PoseEnabledController"]));



/***/ }),

/***/ "./Gamepads/Controllers/windowsMotionController.ts":
/*!*********************************************************!*\
  !*** ./Gamepads/Controllers/windowsMotionController.ts ***!
  \*********************************************************/
/*! exports provided: WindowsMotionController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WindowsMotionController", function() { return WindowsMotionController; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _webVRController__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./webVRController */ "./Gamepads/Controllers/webVRController.ts");
/* harmony import */ var _genericController__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./genericController */ "./Gamepads/Controllers/genericController.ts");
/* harmony import */ var _poseEnabledController__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");










/**
 * Defines the LoadedMeshInfo object that describes information about the loaded webVR controller mesh
 */
var LoadedMeshInfo = /** @class */ (function () {
    function LoadedMeshInfo() {
        /**
         * Map of the button meshes contained in the controller
         */
        this.buttonMeshes = {};
        /**
         * Map of the axis meshes contained in the controller
         */
        this.axisMeshes = {};
    }
    return LoadedMeshInfo;
}());
/**
 * Defines the WindowsMotionController object that the state of the windows motion controller
 */
var WindowsMotionController = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowsMotionController, _super);
    /**
     * Creates a new WindowsMotionController from a gamepad
     * @param vrGamepad the gamepad that the controller should be created from
     */
    function WindowsMotionController(vrGamepad) {
        var _this = _super.call(this, vrGamepad) || this;
        _this._mapping = {
            // Semantic button names
            buttons: ['thumbstick', 'trigger', 'grip', 'menu', 'trackpad'],
            // A mapping of the button name to glTF model node name
            // that should be transformed by button value.
            buttonMeshNames: {
                'trigger': 'SELECT',
                'menu': 'MENU',
                'grip': 'GRASP',
                'thumbstick': 'THUMBSTICK_PRESS',
                'trackpad': 'TOUCHPAD_PRESS'
            },
            // This mapping is used to translate from the Motion Controller to Babylon semantics
            buttonObservableNames: {
                'trigger': 'onTriggerStateChangedObservable',
                'menu': 'onSecondaryButtonStateChangedObservable',
                'grip': 'onMainButtonStateChangedObservable',
                'thumbstick': 'onPadStateChangedObservable',
                'trackpad': 'onTrackpadChangedObservable'
            },
            // A mapping of the axis name to glTF model node name
            // that should be transformed by axis value.
            // This array mirrors the browserGamepad.axes array, such that
            // the mesh corresponding to axis 0 is in this array index 0.
            axisMeshNames: [
                'THUMBSTICK_X',
                'THUMBSTICK_Y',
                'TOUCHPAD_TOUCH_X',
                'TOUCHPAD_TOUCH_Y'
            ],
            pointingPoseMeshName: _poseEnabledController__WEBPACK_IMPORTED_MODULE_9__["PoseEnabledController"].POINTING_POSE
        };
        /**
         * Fired when the trackpad on this controller is clicked
         */
        _this.onTrackpadChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Fired when the trackpad on this controller is modified
         */
        _this.onTrackpadValuesChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * The current x and y values of this controller's trackpad
         */
        _this.trackpad = { x: 0, y: 0 };
        _this.controllerType = _poseEnabledController__WEBPACK_IMPORTED_MODULE_9__["PoseEnabledControllerType"].WINDOWS;
        _this._loadedMeshInfo = null;
        return _this;
    }
    Object.defineProperty(WindowsMotionController.prototype, "onTriggerButtonStateChangedObservable", {
        /**
         * Fired when the trigger on this controller is modified
         */
        get: function () {
            return this.onTriggerStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WindowsMotionController.prototype, "onMenuButtonStateChangedObservable", {
        /**
         * Fired when the menu button on this controller is modified
         */
        get: function () {
            return this.onSecondaryButtonStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WindowsMotionController.prototype, "onGripButtonStateChangedObservable", {
        /**
         * Fired when the grip button on this controller is modified
         */
        get: function () {
            return this.onMainButtonStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WindowsMotionController.prototype, "onThumbstickButtonStateChangedObservable", {
        /**
         * Fired when the thumbstick button on this controller is modified
         */
        get: function () {
            return this.onPadStateChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WindowsMotionController.prototype, "onTouchpadButtonStateChangedObservable", {
        /**
         * Fired when the touchpad button on this controller is modified
         */
        get: function () {
            return this.onTrackpadChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WindowsMotionController.prototype, "onTouchpadValuesChangedObservable", {
        /**
         * Fired when the touchpad values on this controller are modified
         */
        get: function () {
            return this.onTrackpadValuesChangedObservable;
        },
        enumerable: true,
        configurable: true
    });
    WindowsMotionController.prototype._updateTrackpad = function () {
        if (this.browserGamepad.axes && (this.browserGamepad.axes[2] != this.trackpad.x || this.browserGamepad.axes[3] != this.trackpad.y)) {
            this.trackpad.x = this.browserGamepad["axes"][2];
            this.trackpad.y = this.browserGamepad["axes"][3];
            this.onTrackpadValuesChangedObservable.notifyObservers(this.trackpad);
        }
    };
    /**
     * Called once per frame by the engine.
     */
    WindowsMotionController.prototype.update = function () {
        _super.prototype.update.call(this);
        if (this.browserGamepad.axes) {
            this._updateTrackpad();
            // Only need to animate axes if there is a loaded mesh
            if (this._loadedMeshInfo) {
                for (var axis = 0; axis < this._mapping.axisMeshNames.length; axis++) {
                    this._lerpAxisTransform(axis, this.browserGamepad.axes[axis]);
                }
            }
        }
    };
    /**
     * Called once for each button that changed state since the last frame
     * @param buttonIdx Which button index changed
     * @param state New state of the button
     * @param changes Which properties on the state changed since last frame
     */
    WindowsMotionController.prototype._handleButtonChange = function (buttonIdx, state, changes) {
        var buttonName = this._mapping.buttons[buttonIdx];
        if (!buttonName) {
            return;
        }
        // Update the trackpad to ensure trackpad.x/y are accurate during button events between frames
        this._updateTrackpad();
        // Only emit events for buttons that we know how to map from index to name
        var observable = this[(this._mapping.buttonObservableNames)[buttonName]];
        if (observable) {
            observable.notifyObservers(state);
        }
        this._lerpButtonTransform(buttonName, state.value);
    };
    /**
     * Moves the buttons on the controller mesh based on their current state
     * @param buttonName the name of the button to move
     * @param buttonValue the value of the button which determines the buttons new position
     */
    WindowsMotionController.prototype._lerpButtonTransform = function (buttonName, buttonValue) {
        // If there is no loaded mesh, there is nothing to transform.
        if (!this._loadedMeshInfo) {
            return;
        }
        var meshInfo = this._loadedMeshInfo.buttonMeshes[buttonName];
        if (!meshInfo.unpressed.rotationQuaternion || !meshInfo.pressed.rotationQuaternion || !meshInfo.value.rotationQuaternion) {
            return;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].SlerpToRef(meshInfo.unpressed.rotationQuaternion, meshInfo.pressed.rotationQuaternion, buttonValue, meshInfo.value.rotationQuaternion);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].LerpToRef(meshInfo.unpressed.position, meshInfo.pressed.position, buttonValue, meshInfo.value.position);
    };
    /**
     * Moves the axis on the controller mesh based on its current state
     * @param axis the index of the axis
     * @param axisValue the value of the axis which determines the meshes new position
     * @hidden
     */
    WindowsMotionController.prototype._lerpAxisTransform = function (axis, axisValue) {
        if (!this._loadedMeshInfo) {
            return;
        }
        var meshInfo = this._loadedMeshInfo.axisMeshes[axis];
        if (!meshInfo) {
            return;
        }
        if (!meshInfo.min.rotationQuaternion || !meshInfo.max.rotationQuaternion || !meshInfo.value.rotationQuaternion) {
            return;
        }
        // Convert from gamepad value range (-1 to +1) to lerp range (0 to 1)
        var lerpValue = axisValue * 0.5 + 0.5;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].SlerpToRef(meshInfo.min.rotationQuaternion, meshInfo.max.rotationQuaternion, lerpValue, meshInfo.value.rotationQuaternion);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].LerpToRef(meshInfo.min.position, meshInfo.max.position, lerpValue, meshInfo.value.position);
    };
    /**
     * Implements abstract method on WebVRController class, loading controller meshes and calling this.attachToMesh if successful.
     * @param scene scene in which to add meshes
     * @param meshLoaded optional callback function that will be called if the mesh loads successfully.
     */
    WindowsMotionController.prototype.initControllerMesh = function (scene, meshLoaded, forceDefault) {
        var _this = this;
        if (forceDefault === void 0) { forceDefault = false; }
        var path;
        var filename;
        // Checking if GLB loader is present
        if (_Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_6__["SceneLoader"].IsPluginForExtensionAvailable(".glb")) {
            // Determine the device specific folder based on the ID suffix
            var device = 'default';
            if (this.id && !forceDefault) {
                var match = this.id.match(WindowsMotionController.GAMEPAD_ID_PATTERN);
                device = ((match && match[0]) || device);
            }
            // Hand
            if (this.hand === 'left') {
                filename = WindowsMotionController.MODEL_LEFT_FILENAME;
            }
            else { // Right is the default if no hand is specified
                filename = WindowsMotionController.MODEL_RIGHT_FILENAME;
            }
            path = WindowsMotionController.MODEL_BASE_URL + device + '/';
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("You need to reference GLTF loader to load Windows Motion Controllers model. Falling back to generic models");
            path = _genericController__WEBPACK_IMPORTED_MODULE_8__["GenericController"].MODEL_BASE_URL;
            filename = _genericController__WEBPACK_IMPORTED_MODULE_8__["GenericController"].MODEL_FILENAME;
        }
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_6__["SceneLoader"].ImportMesh("", path, filename, scene, function (meshes) {
            // glTF files successfully loaded from the remote server, now process them to ensure they are in the right format.
            _this._loadedMeshInfo = _this.processModel(scene, meshes);
            if (!_this._loadedMeshInfo) {
                return;
            }
            _this._defaultModel = _this._loadedMeshInfo.rootNode;
            _this.attachToMesh(_this._defaultModel);
            if (meshLoaded) {
                meshLoaded(_this._defaultModel);
            }
        }, null, function (scene, message) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Log(message);
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Failed to retrieve controller model from the remote server: ' + path + filename);
            if (!forceDefault) {
                _this.initControllerMesh(scene, meshLoaded, true);
            }
        });
    };
    /**
     * Takes a list of meshes (as loaded from the glTF file) and finds the root node, as well as nodes that
     * can be transformed by button presses and axes values, based on this._mapping.
     *
     * @param scene scene in which the meshes exist
     * @param meshes list of meshes that make up the controller model to process
     * @return structured view of the given meshes, with mapping of buttons and axes to meshes that can be transformed.
     */
    WindowsMotionController.prototype.processModel = function (scene, meshes) {
        var loadedMeshInfo = null;
        // Create a new mesh to contain the glTF hierarchy
        var parentMesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"](this.id + " " + this.hand, scene);
        // Find the root node in the loaded glTF scene, and attach it as a child of 'parentMesh'
        var childMesh = null;
        for (var i = 0; i < meshes.length; i++) {
            var mesh = meshes[i];
            if (!mesh.parent) {
                // Exclude controller meshes from picking results
                mesh.isPickable = false;
                // Handle root node, attach to the new parentMesh
                childMesh = mesh;
                break;
            }
        }
        if (childMesh) {
            childMesh.setParent(parentMesh);
            // Create our mesh info. Note that this method will always return non-null.
            loadedMeshInfo = this.createMeshInfo(parentMesh);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Could not find root node in model file.');
        }
        return loadedMeshInfo;
    };
    WindowsMotionController.prototype.createMeshInfo = function (rootNode) {
        var loadedMeshInfo = new LoadedMeshInfo();
        var i;
        loadedMeshInfo.rootNode = rootNode;
        // Reset the caches
        loadedMeshInfo.buttonMeshes = {};
        loadedMeshInfo.axisMeshes = {};
        // Button Meshes
        for (i = 0; i < this._mapping.buttons.length; i++) {
            var buttonMeshName = this._mapping.buttonMeshNames[this._mapping.buttons[i]];
            if (!buttonMeshName) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Log('Skipping unknown button at index: ' + i + ' with mapped name: ' + this._mapping.buttons[i]);
                continue;
            }
            var buttonMesh = getChildByName(rootNode, buttonMeshName);
            if (!buttonMesh) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Missing button mesh with name: ' + buttonMeshName);
                continue;
            }
            var buttonMeshInfo = {
                index: i,
                value: getImmediateChildByName(buttonMesh, 'VALUE'),
                pressed: getImmediateChildByName(buttonMesh, 'PRESSED'),
                unpressed: getImmediateChildByName(buttonMesh, 'UNPRESSED')
            };
            if (buttonMeshInfo.value && buttonMeshInfo.pressed && buttonMeshInfo.unpressed) {
                loadedMeshInfo.buttonMeshes[this._mapping.buttons[i]] = buttonMeshInfo;
            }
            else {
                // If we didn't find the mesh, it simply means this button won't have transforms applied as mapped button value changes.
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Missing button submesh under mesh with name: ' + buttonMeshName +
                    '(VALUE: ' + !!buttonMeshInfo.value +
                    ', PRESSED: ' + !!buttonMeshInfo.pressed +
                    ', UNPRESSED:' + !!buttonMeshInfo.unpressed +
                    ')');
            }
        }
        // Axis Meshes
        for (i = 0; i < this._mapping.axisMeshNames.length; i++) {
            var axisMeshName = this._mapping.axisMeshNames[i];
            if (!axisMeshName) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Log('Skipping unknown axis at index: ' + i);
                continue;
            }
            var axisMesh = getChildByName(rootNode, axisMeshName);
            if (!axisMesh) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Missing axis mesh with name: ' + axisMeshName);
                continue;
            }
            var axisMeshInfo = {
                index: i,
                value: getImmediateChildByName(axisMesh, 'VALUE'),
                min: getImmediateChildByName(axisMesh, 'MIN'),
                max: getImmediateChildByName(axisMesh, 'MAX')
            };
            if (axisMeshInfo.value && axisMeshInfo.min && axisMeshInfo.max) {
                loadedMeshInfo.axisMeshes[i] = axisMeshInfo;
            }
            else {
                // If we didn't find the mesh, it simply means thit axis won't have transforms applied as mapped axis values change.
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Missing axis submesh under mesh with name: ' + axisMeshName +
                    '(VALUE: ' + !!axisMeshInfo.value +
                    ', MIN: ' + !!axisMeshInfo.min +
                    ', MAX:' + !!axisMeshInfo.max +
                    ')');
            }
        }
        // Pointing Ray
        loadedMeshInfo.pointingPoseNode = getChildByName(rootNode, this._mapping.pointingPoseMeshName);
        if (!loadedMeshInfo.pointingPoseNode) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Missing pointing pose mesh with name: ' + this._mapping.pointingPoseMeshName);
        }
        else {
            this._pointingPoseNode = loadedMeshInfo.pointingPoseNode;
        }
        return loadedMeshInfo;
        // Look through all children recursively. This will return null if no mesh exists with the given name.
        function getChildByName(node, name) {
            return node.getChildren(function (n) { return n.name === name; }, false)[0];
        }
        // Look through only immediate children. This will return null if no mesh exists with the given name.
        function getImmediateChildByName(node, name) {
            return node.getChildren(function (n) { return n.name == name; }, true)[0];
        }
    };
    /**
     * Gets the ray of the controller in the direction the controller is pointing
     * @param length the length the resulting ray should be
     * @returns a ray in the direction the controller is pointing
     */
    WindowsMotionController.prototype.getForwardRay = function (length) {
        if (length === void 0) { length = 100; }
        if (!(this._loadedMeshInfo && this._loadedMeshInfo.pointingPoseNode)) {
            return _super.prototype.getForwardRay.call(this, length);
        }
        var m = this._loadedMeshInfo.pointingPoseNode.getWorldMatrix();
        var origin = m.getTranslation();
        var forward = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, -1);
        var forwardWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(forward, m);
        var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Normalize(forwardWorld);
        return new _Culling_ray__WEBPACK_IMPORTED_MODULE_5__["Ray"](origin, direction, length);
    };
    /**
    * Disposes of the controller
    */
    WindowsMotionController.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.onTrackpadChangedObservable.clear();
    };
    /**
     * The base url used to load the left and right controller models
     */
    WindowsMotionController.MODEL_BASE_URL = 'https://controllers.babylonjs.com/microsoft/';
    /**
     * The name of the left controller model file
     */
    WindowsMotionController.MODEL_LEFT_FILENAME = 'left.glb';
    /**
     * The name of the right controller model file
     */
    WindowsMotionController.MODEL_RIGHT_FILENAME = 'right.glb';
    /**
     * The controller name prefix for this controller type
     */
    WindowsMotionController.GAMEPAD_ID_PREFIX = 'Spatial Controller (Spatial Interaction Source) ';
    /**
     * The controller id pattern for this controller type
     */
    WindowsMotionController.GAMEPAD_ID_PATTERN = /([0-9a-zA-Z]+-[0-9a-zA-Z]+)$/;
    return WindowsMotionController;
}(_webVRController__WEBPACK_IMPORTED_MODULE_7__["WebVRController"]));

_poseEnabledController__WEBPACK_IMPORTED_MODULE_9__["PoseEnabledControllerHelper"]._ControllerFactories.push({
    canCreate: function (gamepadInfo) {
        return gamepadInfo.id.indexOf(WindowsMotionController.GAMEPAD_ID_PREFIX) === 0;
    },
    create: function (gamepadInfo) {
        return new WindowsMotionController(gamepadInfo);
    }
});


/***/ }),

/***/ "./Gamepads/dualShockGamepad.ts":
/*!**************************************!*\
  !*** ./Gamepads/dualShockGamepad.ts ***!
  \**************************************/
/*! exports provided: DualShockButton, DualShockDpad, DualShockPad */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DualShockButton", function() { return DualShockButton; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DualShockDpad", function() { return DualShockDpad; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DualShockPad", function() { return DualShockPad; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _gamepad__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gamepad */ "./Gamepads/gamepad.ts");



/**
 * Defines supported buttons for DualShock compatible gamepads
 */
var DualShockButton;
(function (DualShockButton) {
    /** Cross */
    DualShockButton[DualShockButton["Cross"] = 0] = "Cross";
    /** Circle */
    DualShockButton[DualShockButton["Circle"] = 1] = "Circle";
    /** Square */
    DualShockButton[DualShockButton["Square"] = 2] = "Square";
    /** Triangle */
    DualShockButton[DualShockButton["Triangle"] = 3] = "Triangle";
    /** Options */
    DualShockButton[DualShockButton["Options"] = 4] = "Options";
    /** Share */
    DualShockButton[DualShockButton["Share"] = 5] = "Share";
    /** L1 */
    DualShockButton[DualShockButton["L1"] = 6] = "L1";
    /** R1 */
    DualShockButton[DualShockButton["R1"] = 7] = "R1";
    /** Left stick */
    DualShockButton[DualShockButton["LeftStick"] = 8] = "LeftStick";
    /** Right stick */
    DualShockButton[DualShockButton["RightStick"] = 9] = "RightStick";
})(DualShockButton || (DualShockButton = {}));
/** Defines values for DualShock DPad  */
var DualShockDpad;
(function (DualShockDpad) {
    /** Up */
    DualShockDpad[DualShockDpad["Up"] = 0] = "Up";
    /** Down */
    DualShockDpad[DualShockDpad["Down"] = 1] = "Down";
    /** Left */
    DualShockDpad[DualShockDpad["Left"] = 2] = "Left";
    /** Right */
    DualShockDpad[DualShockDpad["Right"] = 3] = "Right";
})(DualShockDpad || (DualShockDpad = {}));
/**
 * Defines a DualShock gamepad
 */
var DualShockPad = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DualShockPad, _super);
    /**
     * Creates a new DualShock gamepad object
     * @param id defines the id of this gamepad
     * @param index defines its index
     * @param gamepad defines the internal HTML gamepad object
     */
    function DualShockPad(id, index, gamepad) {
        var _this = _super.call(this, id.replace("STANDARD GAMEPAD", "SONY PLAYSTATION DUALSHOCK"), index, gamepad, 0, 1, 2, 3) || this;
        _this._leftTrigger = 0;
        _this._rightTrigger = 0;
        /** Observable raised when a button is pressed */
        _this.onButtonDownObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** Observable raised when a button is released */
        _this.onButtonUpObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** Observable raised when a pad is pressed */
        _this.onPadDownObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** Observable raised when a pad is released */
        _this.onPadUpObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._buttonCross = 0;
        _this._buttonCircle = 0;
        _this._buttonSquare = 0;
        _this._buttonTriangle = 0;
        _this._buttonShare = 0;
        _this._buttonOptions = 0;
        _this._buttonL1 = 0;
        _this._buttonR1 = 0;
        _this._buttonLeftStick = 0;
        _this._buttonRightStick = 0;
        _this._dPadUp = 0;
        _this._dPadDown = 0;
        _this._dPadLeft = 0;
        _this._dPadRight = 0;
        _this.type = _gamepad__WEBPACK_IMPORTED_MODULE_2__["Gamepad"].DUALSHOCK;
        return _this;
    }
    /**
     * Defines the callback to call when left trigger is pressed
     * @param callback defines the callback to use
     */
    DualShockPad.prototype.onlefttriggerchanged = function (callback) {
        this._onlefttriggerchanged = callback;
    };
    /**
     * Defines the callback to call when right trigger is pressed
     * @param callback defines the callback to use
     */
    DualShockPad.prototype.onrighttriggerchanged = function (callback) {
        this._onrighttriggerchanged = callback;
    };
    Object.defineProperty(DualShockPad.prototype, "leftTrigger", {
        /**
         * Gets the left trigger value
         */
        get: function () {
            return this._leftTrigger;
        },
        /**
         * Sets the left trigger value
         */
        set: function (newValue) {
            if (this._onlefttriggerchanged && this._leftTrigger !== newValue) {
                this._onlefttriggerchanged(newValue);
            }
            this._leftTrigger = newValue;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "rightTrigger", {
        /**
         * Gets the right trigger value
         */
        get: function () {
            return this._rightTrigger;
        },
        /**
         * Sets the right trigger value
         */
        set: function (newValue) {
            if (this._onrighttriggerchanged && this._rightTrigger !== newValue) {
                this._onrighttriggerchanged(newValue);
            }
            this._rightTrigger = newValue;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Defines the callback to call when a button is pressed
     * @param callback defines the callback to use
     */
    DualShockPad.prototype.onbuttondown = function (callback) {
        this._onbuttondown = callback;
    };
    /**
     * Defines the callback to call when a button is released
     * @param callback defines the callback to use
     */
    DualShockPad.prototype.onbuttonup = function (callback) {
        this._onbuttonup = callback;
    };
    /**
     * Defines the callback to call when a pad is pressed
     * @param callback defines the callback to use
     */
    DualShockPad.prototype.ondpaddown = function (callback) {
        this._ondpaddown = callback;
    };
    /**
     * Defines the callback to call when a pad is released
     * @param callback defines the callback to use
     */
    DualShockPad.prototype.ondpadup = function (callback) {
        this._ondpadup = callback;
    };
    DualShockPad.prototype._setButtonValue = function (newValue, currentValue, buttonType) {
        if (newValue !== currentValue) {
            if (newValue === 1) {
                if (this._onbuttondown) {
                    this._onbuttondown(buttonType);
                }
                this.onButtonDownObservable.notifyObservers(buttonType);
            }
            if (newValue === 0) {
                if (this._onbuttonup) {
                    this._onbuttonup(buttonType);
                }
                this.onButtonUpObservable.notifyObservers(buttonType);
            }
        }
        return newValue;
    };
    DualShockPad.prototype._setDPadValue = function (newValue, currentValue, buttonType) {
        if (newValue !== currentValue) {
            if (newValue === 1) {
                if (this._ondpaddown) {
                    this._ondpaddown(buttonType);
                }
                this.onPadDownObservable.notifyObservers(buttonType);
            }
            if (newValue === 0) {
                if (this._ondpadup) {
                    this._ondpadup(buttonType);
                }
                this.onPadUpObservable.notifyObservers(buttonType);
            }
        }
        return newValue;
    };
    Object.defineProperty(DualShockPad.prototype, "buttonCross", {
        /**
         * Gets the value of the `Cross` button
         */
        get: function () {
            return this._buttonCross;
        },
        /**
         * Sets the value of the `Cross` button
         */
        set: function (value) {
            this._buttonCross = this._setButtonValue(value, this._buttonCross, DualShockButton.Cross);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonCircle", {
        /**
         * Gets the value of the `Circle` button
         */
        get: function () {
            return this._buttonCircle;
        },
        /**
         * Sets the value of the `Circle` button
         */
        set: function (value) {
            this._buttonCircle = this._setButtonValue(value, this._buttonCircle, DualShockButton.Circle);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonSquare", {
        /**
         * Gets the value of the `Square` button
         */
        get: function () {
            return this._buttonSquare;
        },
        /**
         * Sets the value of the `Square` button
         */
        set: function (value) {
            this._buttonSquare = this._setButtonValue(value, this._buttonSquare, DualShockButton.Square);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonTriangle", {
        /**
         * Gets the value of the `Triangle` button
         */
        get: function () {
            return this._buttonTriangle;
        },
        /**
         * Sets the value of the `Triangle` button
         */
        set: function (value) {
            this._buttonTriangle = this._setButtonValue(value, this._buttonTriangle, DualShockButton.Triangle);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonOptions", {
        /**
         * Gets the value of the `Options` button
         */
        get: function () {
            return this._buttonOptions;
        },
        /**
         * Sets the value of the `Options` button
         */
        set: function (value) {
            this._buttonOptions = this._setButtonValue(value, this._buttonOptions, DualShockButton.Options);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonShare", {
        /**
         * Gets the value of the `Share` button
         */
        get: function () {
            return this._buttonShare;
        },
        /**
         * Sets the value of the `Share` button
         */
        set: function (value) {
            this._buttonShare = this._setButtonValue(value, this._buttonShare, DualShockButton.Share);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonL1", {
        /**
         * Gets the value of the `L1` button
         */
        get: function () {
            return this._buttonL1;
        },
        /**
         * Sets the value of the `L1` button
         */
        set: function (value) {
            this._buttonL1 = this._setButtonValue(value, this._buttonL1, DualShockButton.L1);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonR1", {
        /**
         * Gets the value of the `R1` button
         */
        get: function () {
            return this._buttonR1;
        },
        /**
         * Sets the value of the `R1` button
         */
        set: function (value) {
            this._buttonR1 = this._setButtonValue(value, this._buttonR1, DualShockButton.R1);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonLeftStick", {
        /**
         * Gets the value of the Left joystick
         */
        get: function () {
            return this._buttonLeftStick;
        },
        /**
         * Sets the value of the Left joystick
         */
        set: function (value) {
            this._buttonLeftStick = this._setButtonValue(value, this._buttonLeftStick, DualShockButton.LeftStick);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "buttonRightStick", {
        /**
         * Gets the value of the Right joystick
         */
        get: function () {
            return this._buttonRightStick;
        },
        /**
         * Sets the value of the Right joystick
         */
        set: function (value) {
            this._buttonRightStick = this._setButtonValue(value, this._buttonRightStick, DualShockButton.RightStick);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "dPadUp", {
        /**
         * Gets the value of D-pad up
         */
        get: function () {
            return this._dPadUp;
        },
        /**
         * Sets the value of D-pad up
         */
        set: function (value) {
            this._dPadUp = this._setDPadValue(value, this._dPadUp, DualShockDpad.Up);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "dPadDown", {
        /**
         * Gets the value of D-pad down
         */
        get: function () {
            return this._dPadDown;
        },
        /**
         * Sets the value of D-pad down
         */
        set: function (value) {
            this._dPadDown = this._setDPadValue(value, this._dPadDown, DualShockDpad.Down);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "dPadLeft", {
        /**
         * Gets the value of D-pad left
         */
        get: function () {
            return this._dPadLeft;
        },
        /**
         * Sets the value of D-pad left
         */
        set: function (value) {
            this._dPadLeft = this._setDPadValue(value, this._dPadLeft, DualShockDpad.Left);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DualShockPad.prototype, "dPadRight", {
        /**
         * Gets the value of D-pad right
         */
        get: function () {
            return this._dPadRight;
        },
        /**
         * Sets the value of D-pad right
         */
        set: function (value) {
            this._dPadRight = this._setDPadValue(value, this._dPadRight, DualShockDpad.Right);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Force the gamepad to synchronize with device values
     */
    DualShockPad.prototype.update = function () {
        _super.prototype.update.call(this);
        this.buttonCross = this.browserGamepad.buttons[0].value;
        this.buttonCircle = this.browserGamepad.buttons[1].value;
        this.buttonSquare = this.browserGamepad.buttons[2].value;
        this.buttonTriangle = this.browserGamepad.buttons[3].value;
        this.buttonL1 = this.browserGamepad.buttons[4].value;
        this.buttonR1 = this.browserGamepad.buttons[5].value;
        this.leftTrigger = this.browserGamepad.buttons[6].value;
        this.rightTrigger = this.browserGamepad.buttons[7].value;
        this.buttonShare = this.browserGamepad.buttons[8].value;
        this.buttonOptions = this.browserGamepad.buttons[9].value;
        this.buttonLeftStick = this.browserGamepad.buttons[10].value;
        this.buttonRightStick = this.browserGamepad.buttons[11].value;
        this.dPadUp = this.browserGamepad.buttons[12].value;
        this.dPadDown = this.browserGamepad.buttons[13].value;
        this.dPadLeft = this.browserGamepad.buttons[14].value;
        this.dPadRight = this.browserGamepad.buttons[15].value;
    };
    /**
     * Disposes the gamepad
     */
    DualShockPad.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.onButtonDownObservable.clear();
        this.onButtonUpObservable.clear();
        this.onPadDownObservable.clear();
        this.onPadUpObservable.clear();
    };
    return DualShockPad;
}(_gamepad__WEBPACK_IMPORTED_MODULE_2__["Gamepad"]));



/***/ }),

/***/ "./Gamepads/gamepad.ts":
/*!*****************************!*\
  !*** ./Gamepads/gamepad.ts ***!
  \*****************************/
/*! exports provided: StickValues, Gamepad, GenericPad */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StickValues", function() { return StickValues; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Gamepad", function() { return Gamepad; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GenericPad", function() { return GenericPad; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");


/**
 * Represents a gamepad control stick position
 */
var StickValues = /** @class */ (function () {
    /**
     * Initializes the gamepad x and y control stick values
     * @param x The x component of the gamepad control stick value
     * @param y The y component of the gamepad control stick value
     */
    function StickValues(
    /**
     * The x component of the control stick
     */
    x,
    /**
     * The y component of the control stick
     */
    y) {
        this.x = x;
        this.y = y;
    }
    return StickValues;
}());

/**
 * Represents a gamepad
 */
var Gamepad = /** @class */ (function () {
    /**
     * Initializes the gamepad
     * @param id The id of the gamepad
     * @param index The index of the gamepad
     * @param browserGamepad The browser gamepad
     * @param leftStickX The x component of the left joystick
     * @param leftStickY The y component of the left joystick
     * @param rightStickX The x component of the right joystick
     * @param rightStickY The y component of the right joystick
     */
    function Gamepad(
    /**
     * The id of the gamepad
     */
    id,
    /**
     * The index of the gamepad
     */
    index,
    /**
     * The browser gamepad
     */
    browserGamepad, leftStickX, leftStickY, rightStickX, rightStickY) {
        if (leftStickX === void 0) { leftStickX = 0; }
        if (leftStickY === void 0) { leftStickY = 1; }
        if (rightStickX === void 0) { rightStickX = 2; }
        if (rightStickY === void 0) { rightStickY = 3; }
        this.id = id;
        this.index = index;
        this.browserGamepad = browserGamepad;
        this._leftStick = { x: 0, y: 0 };
        this._rightStick = { x: 0, y: 0 };
        /** @hidden */
        this._isConnected = true;
        /**
         * Specifies whether the left control stick should be Y-inverted
         */
        this._invertLeftStickY = false;
        this.type = Gamepad.GAMEPAD;
        this._leftStickAxisX = leftStickX;
        this._leftStickAxisY = leftStickY;
        this._rightStickAxisX = rightStickX;
        this._rightStickAxisY = rightStickY;
        if (this.browserGamepad.axes.length >= 2) {
            this._leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };
        }
        if (this.browserGamepad.axes.length >= 4) {
            this._rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };
        }
    }
    Object.defineProperty(Gamepad.prototype, "isConnected", {
        /**
         * Specifies if the gamepad has been connected
         */
        get: function () {
            return this._isConnected;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Callback triggered when the left joystick has changed
     * @param callback
     */
    Gamepad.prototype.onleftstickchanged = function (callback) {
        this._onleftstickchanged = callback;
    };
    /**
     * Callback triggered when the right joystick has changed
     * @param callback
     */
    Gamepad.prototype.onrightstickchanged = function (callback) {
        this._onrightstickchanged = callback;
    };
    Object.defineProperty(Gamepad.prototype, "leftStick", {
        /**
         * Gets the left joystick
         */
        get: function () {
            return this._leftStick;
        },
        /**
         * Sets the left joystick values
         */
        set: function (newValues) {
            if (this._onleftstickchanged && (this._leftStick.x !== newValues.x || this._leftStick.y !== newValues.y)) {
                this._onleftstickchanged(newValues);
            }
            this._leftStick = newValues;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Gamepad.prototype, "rightStick", {
        /**
         * Gets the right joystick
         */
        get: function () {
            return this._rightStick;
        },
        /**
         * Sets the right joystick value
         */
        set: function (newValues) {
            if (this._onrightstickchanged && (this._rightStick.x !== newValues.x || this._rightStick.y !== newValues.y)) {
                this._onrightstickchanged(newValues);
            }
            this._rightStick = newValues;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Updates the gamepad joystick positions
     */
    Gamepad.prototype.update = function () {
        if (this._leftStick) {
            this.leftStick = { x: this.browserGamepad.axes[this._leftStickAxisX], y: this.browserGamepad.axes[this._leftStickAxisY] };
            if (this._invertLeftStickY) {
                this.leftStick.y *= -1;
            }
        }
        if (this._rightStick) {
            this.rightStick = { x: this.browserGamepad.axes[this._rightStickAxisX], y: this.browserGamepad.axes[this._rightStickAxisY] };
        }
    };
    /**
     * Disposes the gamepad
     */
    Gamepad.prototype.dispose = function () {
    };
    /**
     * Represents a gamepad controller
     */
    Gamepad.GAMEPAD = 0;
    /**
     * Represents a generic controller
     */
    Gamepad.GENERIC = 1;
    /**
     * Represents an XBox controller
     */
    Gamepad.XBOX = 2;
    /**
     * Represents a pose-enabled controller
     */
    Gamepad.POSE_ENABLED = 3;
    /**
     * Represents an Dual Shock controller
     */
    Gamepad.DUALSHOCK = 4;
    return Gamepad;
}());

/**
 * Represents a generic gamepad
 */
var GenericPad = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GenericPad, _super);
    /**
     * Initializes the generic gamepad
     * @param id The id of the generic gamepad
     * @param index The index of the generic gamepad
     * @param browserGamepad The browser gamepad
     */
    function GenericPad(id, index, browserGamepad) {
        var _this = _super.call(this, id, index, browserGamepad) || this;
        /**
         * Observable triggered when a button has been pressed
         */
        _this.onButtonDownObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Observable triggered when a button has been released
         */
        _this.onButtonUpObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this.type = Gamepad.GENERIC;
        _this._buttons = new Array(browserGamepad.buttons.length);
        return _this;
    }
    /**
     * Callback triggered when a button has been pressed
     * @param callback Called when a button has been pressed
     */
    GenericPad.prototype.onbuttondown = function (callback) {
        this._onbuttondown = callback;
    };
    /**
     * Callback triggered when a button has been released
     * @param callback Called when a button has been released
     */
    GenericPad.prototype.onbuttonup = function (callback) {
        this._onbuttonup = callback;
    };
    GenericPad.prototype._setButtonValue = function (newValue, currentValue, buttonIndex) {
        if (newValue !== currentValue) {
            if (newValue === 1) {
                if (this._onbuttondown) {
                    this._onbuttondown(buttonIndex);
                }
                this.onButtonDownObservable.notifyObservers(buttonIndex);
            }
            if (newValue === 0) {
                if (this._onbuttonup) {
                    this._onbuttonup(buttonIndex);
                }
                this.onButtonUpObservable.notifyObservers(buttonIndex);
            }
        }
        return newValue;
    };
    /**
     * Updates the generic gamepad
     */
    GenericPad.prototype.update = function () {
        _super.prototype.update.call(this);
        for (var index = 0; index < this._buttons.length; index++) {
            this._buttons[index] = this._setButtonValue(this.browserGamepad.buttons[index].value, this._buttons[index], index);
        }
    };
    /**
     * Disposes the generic gamepad
     */
    GenericPad.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.onButtonDownObservable.clear();
        this.onButtonUpObservable.clear();
    };
    return GenericPad;
}(Gamepad));



/***/ }),

/***/ "./Gamepads/gamepadManager.ts":
/*!************************************!*\
  !*** ./Gamepads/gamepadManager.ts ***!
  \************************************/
/*! exports provided: GamepadManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GamepadManager", function() { return GamepadManager; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_domManagement__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/domManagement */ "./Misc/domManagement.ts");
/* harmony import */ var _Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Gamepads/Controllers/poseEnabledController */ "./Gamepads/Controllers/poseEnabledController.ts");
/* harmony import */ var _xboxGamepad__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./xboxGamepad */ "./Gamepads/xboxGamepad.ts");
/* harmony import */ var _gamepad__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./gamepad */ "./Gamepads/gamepad.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _dualShockGamepad__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dualShockGamepad */ "./Gamepads/dualShockGamepad.ts");







/**
 * Manager for handling gamepads
 */
var GamepadManager = /** @class */ (function () {
    /**
     * Initializes the gamepad manager
     * @param _scene BabylonJS scene
     */
    function GamepadManager(_scene) {
        var _this = this;
        this._scene = _scene;
        this._babylonGamepads = [];
        this._oneGamepadConnected = false;
        /** @hidden */
        this._isMonitoring = false;
        /**
         * observable to be triggered when the gamepad controller has been disconnected
         */
        this.onGamepadDisconnectedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        if (!_Misc_domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsWindowObjectExist()) {
            this._gamepadEventSupported = false;
        }
        else {
            this._gamepadEventSupported = 'GamepadEvent' in window;
            this._gamepadSupport = (navigator.getGamepads ||
                navigator.webkitGetGamepads || navigator.msGetGamepads || navigator.webkitGamepads);
        }
        this.onGamepadConnectedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](function (observer) {
            // This will be used to raise the onGamepadConnected for all gamepads ALREADY connected
            for (var i in _this._babylonGamepads) {
                var gamepad = _this._babylonGamepads[i];
                if (gamepad && gamepad._isConnected) {
                    _this.onGamepadConnectedObservable.notifyObserver(observer, gamepad);
                }
            }
        });
        this._onGamepadConnectedEvent = function (evt) {
            var gamepad = evt.gamepad;
            if (gamepad.index in _this._babylonGamepads) {
                if (_this._babylonGamepads[gamepad.index].isConnected) {
                    return;
                }
            }
            var newGamepad;
            if (_this._babylonGamepads[gamepad.index]) {
                newGamepad = _this._babylonGamepads[gamepad.index];
                newGamepad.browserGamepad = gamepad;
                newGamepad._isConnected = true;
            }
            else {
                newGamepad = _this._addNewGamepad(gamepad);
            }
            _this.onGamepadConnectedObservable.notifyObservers(newGamepad);
            _this._startMonitoringGamepads();
        };
        this._onGamepadDisconnectedEvent = function (evt) {
            var gamepad = evt.gamepad;
            // Remove the gamepad from the list of gamepads to monitor.
            for (var i in _this._babylonGamepads) {
                if (_this._babylonGamepads[i].index === gamepad.index) {
                    var disconnectedGamepad = _this._babylonGamepads[i];
                    disconnectedGamepad._isConnected = false;
                    _this.onGamepadDisconnectedObservable.notifyObservers(disconnectedGamepad);
                    break;
                }
            }
        };
        if (this._gamepadSupport) {
            //first add already-connected gamepads
            this._updateGamepadObjects();
            if (this._babylonGamepads.length) {
                this._startMonitoringGamepads();
            }
            // Checking if the gamepad connected event is supported (like in Firefox)
            if (this._gamepadEventSupported) {
                var hostWindow = this._scene ? this._scene.getEngine().getHostWindow() : window;
                hostWindow.addEventListener('gamepadconnected', this._onGamepadConnectedEvent, false);
                hostWindow.addEventListener('gamepaddisconnected', this._onGamepadDisconnectedEvent, false);
            }
            else {
                this._startMonitoringGamepads();
            }
        }
    }
    Object.defineProperty(GamepadManager.prototype, "gamepads", {
        /**
         * The gamepads in the game pad manager
         */
        get: function () {
            return this._babylonGamepads;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the gamepad controllers based on type
     * @param type The type of gamepad controller
     * @returns Nullable gamepad
     */
    GamepadManager.prototype.getGamepadByType = function (type) {
        if (type === void 0) { type = _gamepad__WEBPACK_IMPORTED_MODULE_4__["Gamepad"].XBOX; }
        for (var _i = 0, _a = this._babylonGamepads; _i < _a.length; _i++) {
            var gamepad = _a[_i];
            if (gamepad && gamepad.type === type) {
                return gamepad;
            }
        }
        return null;
    };
    /**
     * Disposes the gamepad manager
     */
    GamepadManager.prototype.dispose = function () {
        if (this._gamepadEventSupported) {
            if (this._onGamepadConnectedEvent) {
                window.removeEventListener('gamepadconnected', this._onGamepadConnectedEvent);
            }
            if (this._onGamepadDisconnectedEvent) {
                window.removeEventListener('gamepaddisconnected', this._onGamepadDisconnectedEvent);
            }
            this._onGamepadConnectedEvent = null;
            this._onGamepadDisconnectedEvent = null;
        }
        this._babylonGamepads.forEach(function (gamepad) {
            gamepad.dispose();
        });
        this.onGamepadConnectedObservable.clear();
        this.onGamepadDisconnectedObservable.clear();
        this._oneGamepadConnected = false;
        this._stopMonitoringGamepads();
        this._babylonGamepads = [];
    };
    GamepadManager.prototype._addNewGamepad = function (gamepad) {
        if (!this._oneGamepadConnected) {
            this._oneGamepadConnected = true;
        }
        var newGamepad;
        var dualShock = (gamepad.id.search("054c") !== -1);
        var xboxOne = (gamepad.id.search("Xbox One") !== -1);
        if (xboxOne || gamepad.id.search("Xbox 360") !== -1 || gamepad.id.search("xinput") !== -1) {
            newGamepad = new _xboxGamepad__WEBPACK_IMPORTED_MODULE_3__["Xbox360Pad"](gamepad.id, gamepad.index, gamepad, xboxOne);
        }
        else if (dualShock) {
            newGamepad = new _dualShockGamepad__WEBPACK_IMPORTED_MODULE_6__["DualShockPad"](gamepad.id, gamepad.index, gamepad);
        }
        // if pose is supported, use the (WebVR) pose enabled controller
        else if (gamepad.pose) {
            newGamepad = _Gamepads_Controllers_poseEnabledController__WEBPACK_IMPORTED_MODULE_2__["PoseEnabledControllerHelper"].InitiateController(gamepad);
        }
        else {
            newGamepad = new _gamepad__WEBPACK_IMPORTED_MODULE_4__["GenericPad"](gamepad.id, gamepad.index, gamepad);
        }
        this._babylonGamepads[newGamepad.index] = newGamepad;
        return newGamepad;
    };
    GamepadManager.prototype._startMonitoringGamepads = function () {
        if (!this._isMonitoring) {
            this._isMonitoring = true;
            //back-comp
            if (!this._scene) {
                this._checkGamepadsStatus();
            }
        }
    };
    GamepadManager.prototype._stopMonitoringGamepads = function () {
        this._isMonitoring = false;
    };
    /** @hidden */
    GamepadManager.prototype._checkGamepadsStatus = function () {
        var _this = this;
        // Hack to be compatible Chrome
        this._updateGamepadObjects();
        for (var i in this._babylonGamepads) {
            var gamepad = this._babylonGamepads[i];
            if (!gamepad || !gamepad.isConnected) {
                continue;
            }
            gamepad.update();
        }
        if (this._isMonitoring && !this._scene) {
            _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].QueueNewFrame(function () { _this._checkGamepadsStatus(); });
        }
    };
    // This function is called only on Chrome, which does not properly support
    // connection/disconnection events and forces you to recopy again the gamepad object
    GamepadManager.prototype._updateGamepadObjects = function () {
        var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []);
        for (var i = 0; i < gamepads.length; i++) {
            var gamepad = gamepads[i];
            if (gamepad) {
                if (!this._babylonGamepads[gamepad.index]) {
                    var newGamepad = this._addNewGamepad(gamepad);
                    this.onGamepadConnectedObservable.notifyObservers(newGamepad);
                }
                else {
                    // Forced to copy again this object for Chrome for unknown reason
                    this._babylonGamepads[i].browserGamepad = gamepad;
                    if (!this._babylonGamepads[i].isConnected) {
                        this._babylonGamepads[i]._isConnected = true;
                        this.onGamepadConnectedObservable.notifyObservers(this._babylonGamepads[i]);
                    }
                }
            }
        }
    };
    return GamepadManager;
}());



/***/ }),

/***/ "./Gamepads/gamepadSceneComponent.ts":
/*!*******************************************!*\
  !*** ./Gamepads/gamepadSceneComponent.ts ***!
  \*******************************************/
/*! exports provided: GamepadSystemSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GamepadSystemSceneComponent", function() { return GamepadSystemSceneComponent; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _gamepadManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gamepadManager */ "./Gamepads/gamepadManager.ts");
/* harmony import */ var _Cameras_freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Cameras/freeCameraInputsManager */ "./Cameras/freeCameraInputsManager.ts");
/* harmony import */ var _Cameras_Inputs_freeCameraGamepadInput__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Cameras/Inputs/freeCameraGamepadInput */ "./Cameras/Inputs/freeCameraGamepadInput.ts");
/* harmony import */ var _Cameras_arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Cameras/arcRotateCameraInputsManager */ "./Cameras/arcRotateCameraInputsManager.ts");
/* harmony import */ var _Cameras_Inputs_arcRotateCameraGamepadInput__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Cameras/Inputs/arcRotateCameraGamepadInput */ "./Cameras/Inputs/arcRotateCameraGamepadInput.ts");







Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype, "gamepadManager", {
    get: function () {
        if (!this._gamepadManager) {
            this._gamepadManager = new _gamepadManager__WEBPACK_IMPORTED_MODULE_2__["GamepadManager"](this);
            var component = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_GAMEPAD);
            if (!component) {
                component = new GamepadSystemSceneComponent(this);
                this._addComponent(component);
            }
        }
        return this._gamepadManager;
    },
    enumerable: true,
    configurable: true
});
/**
 * Adds a gamepad to the free camera inputs manager
 */
_Cameras_freeCameraInputsManager__WEBPACK_IMPORTED_MODULE_3__["FreeCameraInputsManager"].prototype.addGamepad = function () {
    this.add(new _Cameras_Inputs_freeCameraGamepadInput__WEBPACK_IMPORTED_MODULE_4__["FreeCameraGamepadInput"]());
    return this;
};
/**
 * Adds a gamepad to the arc rotate camera inputs manager
 */
_Cameras_arcRotateCameraInputsManager__WEBPACK_IMPORTED_MODULE_5__["ArcRotateCameraInputsManager"].prototype.addGamepad = function () {
    this.add(new _Cameras_Inputs_arcRotateCameraGamepadInput__WEBPACK_IMPORTED_MODULE_6__["ArcRotateCameraGamepadInput"]());
    return this;
};
/**
  * Defines the gamepad scene component responsible to manage gamepads in a given scene
  */
var GamepadSystemSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function GamepadSystemSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_GAMEPAD;
        this.scene = scene;
    }
    /**
     * Registers the component in a given scene
     */
    GamepadSystemSceneComponent.prototype.register = function () {
        this.scene._beforeCameraUpdateStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_BEFORECAMERAUPDATE_GAMEPAD, this, this._beforeCameraUpdate);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    GamepadSystemSceneComponent.prototype.rebuild = function () {
        // Nothing to do for gamepads
    };
    /**
     * Disposes the component and the associated ressources
     */
    GamepadSystemSceneComponent.prototype.dispose = function () {
        var gamepadManager = this.scene._gamepadManager;
        if (gamepadManager) {
            gamepadManager.dispose();
            this.scene._gamepadManager = null;
        }
    };
    GamepadSystemSceneComponent.prototype._beforeCameraUpdate = function () {
        var gamepadManager = this.scene._gamepadManager;
        if (gamepadManager && gamepadManager._isMonitoring) {
            gamepadManager._checkGamepadsStatus();
        }
    };
    return GamepadSystemSceneComponent;
}());



/***/ }),

/***/ "./Gamepads/index.ts":
/*!***************************!*\
  !*** ./Gamepads/index.ts ***!
  \***************************/
/*! exports provided: StickValues, Gamepad, GenericPad, GamepadManager, GamepadSystemSceneComponent, Xbox360Button, Xbox360Dpad, Xbox360Pad, DualShockButton, DualShockDpad, DualShockPad, DaydreamController, GearVRController, GenericController, OculusTouchController, PoseEnabledControllerType, PoseEnabledControllerHelper, PoseEnabledController, ViveController, WebVRController, WindowsMotionController */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Controllers_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Controllers/index */ "./Gamepads/Controllers/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DaydreamController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["DaydreamController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GearVRController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["GearVRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["GenericController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OculusTouchController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["OculusTouchController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerType", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["PoseEnabledControllerType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerHelper", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["PoseEnabledControllerHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["PoseEnabledController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViveController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["ViveController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["WebVRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WindowsMotionController", function() { return _Controllers_index__WEBPACK_IMPORTED_MODULE_0__["WindowsMotionController"]; });

/* harmony import */ var _gamepad__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./gamepad */ "./Gamepads/gamepad.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StickValues", function() { return _gamepad__WEBPACK_IMPORTED_MODULE_1__["StickValues"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Gamepad", function() { return _gamepad__WEBPACK_IMPORTED_MODULE_1__["Gamepad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericPad", function() { return _gamepad__WEBPACK_IMPORTED_MODULE_1__["GenericPad"]; });

/* harmony import */ var _gamepadManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gamepadManager */ "./Gamepads/gamepadManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadManager", function() { return _gamepadManager__WEBPACK_IMPORTED_MODULE_2__["GamepadManager"]; });

/* harmony import */ var _gamepadSceneComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./gamepadSceneComponent */ "./Gamepads/gamepadSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadSystemSceneComponent", function() { return _gamepadSceneComponent__WEBPACK_IMPORTED_MODULE_3__["GamepadSystemSceneComponent"]; });

/* harmony import */ var _xboxGamepad__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./xboxGamepad */ "./Gamepads/xboxGamepad.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Button", function() { return _xboxGamepad__WEBPACK_IMPORTED_MODULE_4__["Xbox360Button"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Dpad", function() { return _xboxGamepad__WEBPACK_IMPORTED_MODULE_4__["Xbox360Dpad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Pad", function() { return _xboxGamepad__WEBPACK_IMPORTED_MODULE_4__["Xbox360Pad"]; });

/* harmony import */ var _dualShockGamepad__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./dualShockGamepad */ "./Gamepads/dualShockGamepad.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockButton", function() { return _dualShockGamepad__WEBPACK_IMPORTED_MODULE_5__["DualShockButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockDpad", function() { return _dualShockGamepad__WEBPACK_IMPORTED_MODULE_5__["DualShockDpad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockPad", function() { return _dualShockGamepad__WEBPACK_IMPORTED_MODULE_5__["DualShockPad"]; });









/***/ }),

/***/ "./Gamepads/xboxGamepad.ts":
/*!*********************************!*\
  !*** ./Gamepads/xboxGamepad.ts ***!
  \*********************************/
/*! exports provided: Xbox360Button, Xbox360Dpad, Xbox360Pad */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Xbox360Button", function() { return Xbox360Button; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Xbox360Dpad", function() { return Xbox360Dpad; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Xbox360Pad", function() { return Xbox360Pad; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Gamepads/gamepad */ "./Gamepads/gamepad.ts");



/**
 * Defines supported buttons for XBox360 compatible gamepads
 */
var Xbox360Button;
(function (Xbox360Button) {
    /** A */
    Xbox360Button[Xbox360Button["A"] = 0] = "A";
    /** B */
    Xbox360Button[Xbox360Button["B"] = 1] = "B";
    /** X */
    Xbox360Button[Xbox360Button["X"] = 2] = "X";
    /** Y */
    Xbox360Button[Xbox360Button["Y"] = 3] = "Y";
    /** Start */
    Xbox360Button[Xbox360Button["Start"] = 4] = "Start";
    /** Back */
    Xbox360Button[Xbox360Button["Back"] = 5] = "Back";
    /** Left button */
    Xbox360Button[Xbox360Button["LB"] = 6] = "LB";
    /** Right button */
    Xbox360Button[Xbox360Button["RB"] = 7] = "RB";
    /** Left stick */
    Xbox360Button[Xbox360Button["LeftStick"] = 8] = "LeftStick";
    /** Right stick */
    Xbox360Button[Xbox360Button["RightStick"] = 9] = "RightStick";
})(Xbox360Button || (Xbox360Button = {}));
/** Defines values for XBox360 DPad  */
var Xbox360Dpad;
(function (Xbox360Dpad) {
    /** Up */
    Xbox360Dpad[Xbox360Dpad["Up"] = 0] = "Up";
    /** Down */
    Xbox360Dpad[Xbox360Dpad["Down"] = 1] = "Down";
    /** Left */
    Xbox360Dpad[Xbox360Dpad["Left"] = 2] = "Left";
    /** Right */
    Xbox360Dpad[Xbox360Dpad["Right"] = 3] = "Right";
})(Xbox360Dpad || (Xbox360Dpad = {}));
/**
 * Defines a XBox360 gamepad
 */
var Xbox360Pad = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Xbox360Pad, _super);
    /**
     * Creates a new XBox360 gamepad object
     * @param id defines the id of this gamepad
     * @param index defines its index
     * @param gamepad defines the internal HTML gamepad object
     * @param xboxOne defines if it is a XBox One gamepad
     */
    function Xbox360Pad(id, index, gamepad, xboxOne) {
        if (xboxOne === void 0) { xboxOne = false; }
        var _this = _super.call(this, id, index, gamepad, 0, 1, 2, 3) || this;
        _this._leftTrigger = 0;
        _this._rightTrigger = 0;
        /** Observable raised when a button is pressed */
        _this.onButtonDownObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** Observable raised when a button is released */
        _this.onButtonUpObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** Observable raised when a pad is pressed */
        _this.onPadDownObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** Observable raised when a pad is released */
        _this.onPadUpObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._buttonA = 0;
        _this._buttonB = 0;
        _this._buttonX = 0;
        _this._buttonY = 0;
        _this._buttonBack = 0;
        _this._buttonStart = 0;
        _this._buttonLB = 0;
        _this._buttonRB = 0;
        _this._buttonLeftStick = 0;
        _this._buttonRightStick = 0;
        _this._dPadUp = 0;
        _this._dPadDown = 0;
        _this._dPadLeft = 0;
        _this._dPadRight = 0;
        _this._isXboxOnePad = false;
        _this.type = _Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_2__["Gamepad"].XBOX;
        _this._isXboxOnePad = xboxOne;
        return _this;
    }
    /**
     * Defines the callback to call when left trigger is pressed
     * @param callback defines the callback to use
     */
    Xbox360Pad.prototype.onlefttriggerchanged = function (callback) {
        this._onlefttriggerchanged = callback;
    };
    /**
     * Defines the callback to call when right trigger is pressed
     * @param callback defines the callback to use
     */
    Xbox360Pad.prototype.onrighttriggerchanged = function (callback) {
        this._onrighttriggerchanged = callback;
    };
    Object.defineProperty(Xbox360Pad.prototype, "leftTrigger", {
        /**
         * Gets the left trigger value
         */
        get: function () {
            return this._leftTrigger;
        },
        /**
         * Sets the left trigger value
         */
        set: function (newValue) {
            if (this._onlefttriggerchanged && this._leftTrigger !== newValue) {
                this._onlefttriggerchanged(newValue);
            }
            this._leftTrigger = newValue;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "rightTrigger", {
        /**
         * Gets the right trigger value
         */
        get: function () {
            return this._rightTrigger;
        },
        /**
         * Sets the right trigger value
         */
        set: function (newValue) {
            if (this._onrighttriggerchanged && this._rightTrigger !== newValue) {
                this._onrighttriggerchanged(newValue);
            }
            this._rightTrigger = newValue;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Defines the callback to call when a button is pressed
     * @param callback defines the callback to use
     */
    Xbox360Pad.prototype.onbuttondown = function (callback) {
        this._onbuttondown = callback;
    };
    /**
     * Defines the callback to call when a button is released
     * @param callback defines the callback to use
     */
    Xbox360Pad.prototype.onbuttonup = function (callback) {
        this._onbuttonup = callback;
    };
    /**
     * Defines the callback to call when a pad is pressed
     * @param callback defines the callback to use
     */
    Xbox360Pad.prototype.ondpaddown = function (callback) {
        this._ondpaddown = callback;
    };
    /**
     * Defines the callback to call when a pad is released
     * @param callback defines the callback to use
     */
    Xbox360Pad.prototype.ondpadup = function (callback) {
        this._ondpadup = callback;
    };
    Xbox360Pad.prototype._setButtonValue = function (newValue, currentValue, buttonType) {
        if (newValue !== currentValue) {
            if (newValue === 1) {
                if (this._onbuttondown) {
                    this._onbuttondown(buttonType);
                }
                this.onButtonDownObservable.notifyObservers(buttonType);
            }
            if (newValue === 0) {
                if (this._onbuttonup) {
                    this._onbuttonup(buttonType);
                }
                this.onButtonUpObservable.notifyObservers(buttonType);
            }
        }
        return newValue;
    };
    Xbox360Pad.prototype._setDPadValue = function (newValue, currentValue, buttonType) {
        if (newValue !== currentValue) {
            if (newValue === 1) {
                if (this._ondpaddown) {
                    this._ondpaddown(buttonType);
                }
                this.onPadDownObservable.notifyObservers(buttonType);
            }
            if (newValue === 0) {
                if (this._ondpadup) {
                    this._ondpadup(buttonType);
                }
                this.onPadUpObservable.notifyObservers(buttonType);
            }
        }
        return newValue;
    };
    Object.defineProperty(Xbox360Pad.prototype, "buttonA", {
        /**
         * Gets the value of the `A` button
         */
        get: function () {
            return this._buttonA;
        },
        /**
         * Sets the value of the `A` button
         */
        set: function (value) {
            this._buttonA = this._setButtonValue(value, this._buttonA, Xbox360Button.A);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonB", {
        /**
         * Gets the value of the `B` button
         */
        get: function () {
            return this._buttonB;
        },
        /**
         * Sets the value of the `B` button
         */
        set: function (value) {
            this._buttonB = this._setButtonValue(value, this._buttonB, Xbox360Button.B);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonX", {
        /**
         * Gets the value of the `X` button
         */
        get: function () {
            return this._buttonX;
        },
        /**
         * Sets the value of the `X` button
         */
        set: function (value) {
            this._buttonX = this._setButtonValue(value, this._buttonX, Xbox360Button.X);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonY", {
        /**
         * Gets the value of the `Y` button
         */
        get: function () {
            return this._buttonY;
        },
        /**
         * Sets the value of the `Y` button
         */
        set: function (value) {
            this._buttonY = this._setButtonValue(value, this._buttonY, Xbox360Button.Y);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonStart", {
        /**
         * Gets the value of the `Start` button
         */
        get: function () {
            return this._buttonStart;
        },
        /**
         * Sets the value of the `Start` button
         */
        set: function (value) {
            this._buttonStart = this._setButtonValue(value, this._buttonStart, Xbox360Button.Start);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonBack", {
        /**
         * Gets the value of the `Back` button
         */
        get: function () {
            return this._buttonBack;
        },
        /**
         * Sets the value of the `Back` button
         */
        set: function (value) {
            this._buttonBack = this._setButtonValue(value, this._buttonBack, Xbox360Button.Back);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonLB", {
        /**
         * Gets the value of the `Left` button
         */
        get: function () {
            return this._buttonLB;
        },
        /**
         * Sets the value of the `Left` button
         */
        set: function (value) {
            this._buttonLB = this._setButtonValue(value, this._buttonLB, Xbox360Button.LB);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonRB", {
        /**
         * Gets the value of the `Right` button
         */
        get: function () {
            return this._buttonRB;
        },
        /**
         * Sets the value of the `Right` button
         */
        set: function (value) {
            this._buttonRB = this._setButtonValue(value, this._buttonRB, Xbox360Button.RB);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonLeftStick", {
        /**
         * Gets the value of the Left joystick
         */
        get: function () {
            return this._buttonLeftStick;
        },
        /**
         * Sets the value of the Left joystick
         */
        set: function (value) {
            this._buttonLeftStick = this._setButtonValue(value, this._buttonLeftStick, Xbox360Button.LeftStick);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "buttonRightStick", {
        /**
         * Gets the value of the Right joystick
         */
        get: function () {
            return this._buttonRightStick;
        },
        /**
         * Sets the value of the Right joystick
         */
        set: function (value) {
            this._buttonRightStick = this._setButtonValue(value, this._buttonRightStick, Xbox360Button.RightStick);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "dPadUp", {
        /**
         * Gets the value of D-pad up
         */
        get: function () {
            return this._dPadUp;
        },
        /**
         * Sets the value of D-pad up
         */
        set: function (value) {
            this._dPadUp = this._setDPadValue(value, this._dPadUp, Xbox360Dpad.Up);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "dPadDown", {
        /**
         * Gets the value of D-pad down
         */
        get: function () {
            return this._dPadDown;
        },
        /**
         * Sets the value of D-pad down
         */
        set: function (value) {
            this._dPadDown = this._setDPadValue(value, this._dPadDown, Xbox360Dpad.Down);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "dPadLeft", {
        /**
         * Gets the value of D-pad left
         */
        get: function () {
            return this._dPadLeft;
        },
        /**
         * Sets the value of D-pad left
         */
        set: function (value) {
            this._dPadLeft = this._setDPadValue(value, this._dPadLeft, Xbox360Dpad.Left);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Xbox360Pad.prototype, "dPadRight", {
        /**
         * Gets the value of D-pad right
         */
        get: function () {
            return this._dPadRight;
        },
        /**
         * Sets the value of D-pad right
         */
        set: function (value) {
            this._dPadRight = this._setDPadValue(value, this._dPadRight, Xbox360Dpad.Right);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Force the gamepad to synchronize with device values
     */
    Xbox360Pad.prototype.update = function () {
        _super.prototype.update.call(this);
        if (this._isXboxOnePad) {
            this.buttonA = this.browserGamepad.buttons[0].value;
            this.buttonB = this.browserGamepad.buttons[1].value;
            this.buttonX = this.browserGamepad.buttons[2].value;
            this.buttonY = this.browserGamepad.buttons[3].value;
            this.buttonLB = this.browserGamepad.buttons[4].value;
            this.buttonRB = this.browserGamepad.buttons[5].value;
            this.leftTrigger = this.browserGamepad.buttons[6].value;
            this.rightTrigger = this.browserGamepad.buttons[7].value;
            this.buttonBack = this.browserGamepad.buttons[8].value;
            this.buttonStart = this.browserGamepad.buttons[9].value;
            this.buttonLeftStick = this.browserGamepad.buttons[10].value;
            this.buttonRightStick = this.browserGamepad.buttons[11].value;
            this.dPadUp = this.browserGamepad.buttons[12].value;
            this.dPadDown = this.browserGamepad.buttons[13].value;
            this.dPadLeft = this.browserGamepad.buttons[14].value;
            this.dPadRight = this.browserGamepad.buttons[15].value;
        }
        else {
            this.buttonA = this.browserGamepad.buttons[0].value;
            this.buttonB = this.browserGamepad.buttons[1].value;
            this.buttonX = this.browserGamepad.buttons[2].value;
            this.buttonY = this.browserGamepad.buttons[3].value;
            this.buttonLB = this.browserGamepad.buttons[4].value;
            this.buttonRB = this.browserGamepad.buttons[5].value;
            this.leftTrigger = this.browserGamepad.buttons[6].value;
            this.rightTrigger = this.browserGamepad.buttons[7].value;
            this.buttonBack = this.browserGamepad.buttons[8].value;
            this.buttonStart = this.browserGamepad.buttons[9].value;
            this.buttonLeftStick = this.browserGamepad.buttons[10].value;
            this.buttonRightStick = this.browserGamepad.buttons[11].value;
            this.dPadUp = this.browserGamepad.buttons[12].value;
            this.dPadDown = this.browserGamepad.buttons[13].value;
            this.dPadLeft = this.browserGamepad.buttons[14].value;
            this.dPadRight = this.browserGamepad.buttons[15].value;
        }
    };
    /**
     * Disposes the gamepad
     */
    Xbox360Pad.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.onButtonDownObservable.clear();
        this.onButtonUpObservable.clear();
        this.onPadDownObservable.clear();
        this.onPadUpObservable.clear();
    };
    return Xbox360Pad;
}(_Gamepads_gamepad__WEBPACK_IMPORTED_MODULE_2__["Gamepad"]));



/***/ }),

/***/ "./Gizmos/axisDragGizmo.ts":
/*!*********************************!*\
  !*** ./Gizmos/axisDragGizmo.ts ***!
  \*********************************/
/*! exports provided: AxisDragGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AxisDragGizmo", function() { return AxisDragGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/Builders/cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");
/* harmony import */ var _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Behaviors/Meshes/pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");










/**
 * Single axis drag gizmo
 */
var AxisDragGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AxisDragGizmo, _super);
    /**
     * Creates an AxisDragGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     * @param dragAxis The axis which the gizmo will be able to drag on
     * @param color The color of the gizmo
     */
    function AxisDragGizmo(dragAxis, color, gizmoLayer, parent) {
        if (color === void 0) { color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color3"].Gray(); }
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_7__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        if (parent === void 0) { parent = null; }
        var _this = _super.call(this, gizmoLayer) || this;
        _this._pointerObserver = null;
        /**
         * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)
         */
        _this.snapDistance = 0;
        /**
         * Event that fires each time the gizmo snaps to a new location.
         * * snapDistance is the the change in distance
         */
        _this.onSnapObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._isEnabled = true;
        _this._parent = null;
        _this._parent = parent;
        // Create Material
        _this._coloredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_8__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this._coloredMaterial.diffuseColor = color;
        _this._coloredMaterial.specularColor = color.subtract(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color3"](0.1, 0.1, 0.1));
        _this._hoverMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_8__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this._hoverMaterial.diffuseColor = color.add(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color3"](0.3, 0.3, 0.3));
        // Build mesh on root node
        _this._arrow = AxisDragGizmo._CreateArrow(gizmoLayer.utilityLayerScene, _this._coloredMaterial);
        _this._arrow.lookAt(_this._rootMesh.position.add(dragAxis));
        _this._arrow.scaling.scaleInPlace(1 / 3);
        _this._arrow.parent = _this._rootMesh;
        var currentSnapDragDistance = 0;
        var tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var tmpSnapEvent = { snapDistance: 0 };
        // Add drag behavior to handle events when the gizmo is dragged
        _this.dragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_5__["PointerDragBehavior"]({ dragAxis: dragAxis });
        _this.dragBehavior.moveAttached = false;
        _this._rootMesh.addBehavior(_this.dragBehavior);
        var localDelta = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        _this.dragBehavior.onDragObservable.add(function (event) {
            if (_this.attachedMesh) {
                // Convert delta to local translation if it has a parent
                if (_this.attachedMesh.parent) {
                    _this.attachedMesh.parent.computeWorldMatrix().invertToRef(tmpMatrix);
                    tmpMatrix.setTranslationFromFloats(0, 0, 0);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(event.delta, tmpMatrix, localDelta);
                }
                else {
                    localDelta.copyFrom(event.delta);
                }
                // Snapping logic
                if (_this.snapDistance == 0) {
                    _this.attachedMesh.position.addInPlace(localDelta);
                }
                else {
                    currentSnapDragDistance += event.dragDistance;
                    if (Math.abs(currentSnapDragDistance) > _this.snapDistance) {
                        var dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / _this.snapDistance);
                        currentSnapDragDistance = currentSnapDragDistance % _this.snapDistance;
                        localDelta.normalizeToRef(tmpVector);
                        tmpVector.scaleInPlace(_this.snapDistance * dragSteps);
                        _this.attachedMesh.position.addInPlace(tmpVector);
                        tmpSnapEvent.snapDistance = _this.snapDistance * dragSteps;
                        _this.onSnapObservable.notifyObservers(tmpSnapEvent);
                    }
                }
            }
        });
        _this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add(function (pointerInfo) {
            if (_this._customMeshSet) {
                return;
            }
            var isHovered = pointerInfo.pickInfo && (_this._rootMesh.getChildMeshes().indexOf(pointerInfo.pickInfo.pickedMesh) != -1);
            var material = isHovered ? _this._hoverMaterial : _this._coloredMaterial;
            _this._rootMesh.getChildMeshes().forEach(function (m) {
                m.material = material;
                if (m.color) {
                    m.color = material.diffuseColor;
                }
            });
        });
        var light = gizmoLayer._getSharedGizmoLight();
        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(_this._rootMesh.getChildMeshes(false));
        return _this;
    }
    /** @hidden */
    AxisDragGizmo._CreateArrow = function (scene, material) {
        var arrow = new _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_3__["TransformNode"]("arrow", scene);
        var cylinder = _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_4__["CylinderBuilder"].CreateCylinder("cylinder", { diameterTop: 0, height: 0.075, diameterBottom: 0.0375, tessellation: 96 }, scene);
        var line = _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_4__["CylinderBuilder"].CreateCylinder("cylinder", { diameterTop: 0.005, height: 0.275, diameterBottom: 0.005, tessellation: 96 }, scene);
        line.material = material;
        cylinder.parent = arrow;
        line.parent = arrow;
        // Position arrow pointing in its drag axis
        cylinder.material = material;
        cylinder.rotation.x = Math.PI / 2;
        cylinder.position.z += 0.3;
        line.position.z += 0.275 / 2;
        line.rotation.x = Math.PI / 2;
        return arrow;
    };
    /** @hidden */
    AxisDragGizmo._CreateArrowInstance = function (scene, arrow) {
        var instance = new _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_3__["TransformNode"]("arrow", scene);
        for (var _i = 0, _a = arrow.getChildMeshes(); _i < _a.length; _i++) {
            var mesh = _a[_i];
            var childInstance = mesh.createInstance(mesh.name);
            childInstance.parent = instance;
        }
        return instance;
    };
    AxisDragGizmo.prototype._attachedMeshChanged = function (value) {
        if (this.dragBehavior) {
            this.dragBehavior.enabled = value ? true : false;
        }
    };
    Object.defineProperty(AxisDragGizmo.prototype, "isEnabled", {
        get: function () {
            return this._isEnabled;
        },
        /**
         * If the gizmo is enabled
         */
        set: function (value) {
            this._isEnabled = value;
            if (!value) {
                this.attachedMesh = null;
            }
            else {
                if (this._parent) {
                    this.attachedMesh = this._parent.attachedMesh;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    AxisDragGizmo.prototype.dispose = function () {
        this.onSnapObservable.clear();
        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
        this.dragBehavior.detach();
        if (this._arrow) {
            this._arrow.dispose();
        }
        [this._coloredMaterial, this._hoverMaterial].forEach(function (matl) {
            if (matl) {
                matl.dispose();
            }
        });
        _super.prototype.dispose.call(this);
    };
    return AxisDragGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_6__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/axisScaleGizmo.ts":
/*!**********************************!*\
  !*** ./Gizmos/axisScaleGizmo.ts ***!
  \**********************************/
/*! exports provided: AxisScaleGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AxisScaleGizmo", function() { return AxisScaleGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/Builders/cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Behaviors/Meshes/pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");











/**
 * Single axis scale gizmo
 */
var AxisScaleGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AxisScaleGizmo, _super);
    /**
     * Creates an AxisScaleGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     * @param dragAxis The axis which the gizmo will be able to scale on
     * @param color The color of the gizmo
     */
    function AxisScaleGizmo(dragAxis, color, gizmoLayer, parent) {
        if (color === void 0) { color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"].Gray(); }
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_9__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        if (parent === void 0) { parent = null; }
        var _this = _super.call(this, gizmoLayer) || this;
        _this._pointerObserver = null;
        /**
         * Scale distance in babylon units that the gizmo will snap to when dragged (Default: 0)
         */
        _this.snapDistance = 0;
        /**
         * Event that fires each time the gizmo snaps to a new location.
         * * snapDistance is the the change in distance
         */
        _this.onSnapObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * If the scaling operation should be done on all axis (default: false)
         */
        _this.uniformScaling = false;
        _this._isEnabled = true;
        _this._parent = null;
        _this._parent = parent;
        // Create Material
        _this._coloredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this._coloredMaterial.diffuseColor = color;
        _this._coloredMaterial.specularColor = color.subtract(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.1, 0.1, 0.1));
        _this._hoverMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this._hoverMaterial.diffuseColor = color.add(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color3"](0.3, 0.3, 0.3));
        // Build mesh on root node
        _this._arrow = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__["AbstractMesh"]("", gizmoLayer.utilityLayerScene);
        var arrowMesh = _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_4__["BoxBuilder"].CreateBox("yPosMesh", { size: 0.4 }, gizmoLayer.utilityLayerScene);
        var arrowTail = _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_5__["CylinderBuilder"].CreateCylinder("cylinder", { diameterTop: 0.005, height: 0.275, diameterBottom: 0.005, tessellation: 96 }, gizmoLayer.utilityLayerScene);
        arrowTail.material = _this._coloredMaterial;
        _this._arrow.addChild(arrowMesh);
        _this._arrow.addChild(arrowTail);
        // Position arrow pointing in its drag axis
        arrowMesh.scaling.scaleInPlace(0.1);
        arrowMesh.material = _this._coloredMaterial;
        arrowMesh.rotation.x = Math.PI / 2;
        arrowMesh.position.z += 0.3;
        arrowTail.position.z += 0.275 / 2;
        arrowTail.rotation.x = Math.PI / 2;
        _this._arrow.lookAt(_this._rootMesh.position.add(dragAxis));
        _this._rootMesh.addChild(_this._arrow);
        _this._arrow.scaling.scaleInPlace(1 / 3);
        // Add drag behavior to handle events when the gizmo is dragged
        _this.dragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_7__["PointerDragBehavior"]({ dragAxis: dragAxis });
        _this.dragBehavior.moveAttached = false;
        _this._rootMesh.addBehavior(_this.dragBehavior);
        var currentSnapDragDistance = 0;
        var tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var tmpSnapEvent = { snapDistance: 0 };
        _this.dragBehavior.onDragObservable.add(function (event) {
            if (_this.attachedMesh) {
                // Drag strength is modified by the scale of the gizmo (eg. for small objects like boombox the strength will be increased to match the behavior of larger objects)
                var dragStrength = event.dragDistance * ((_this.scaleRatio * 3) / _this._rootMesh.scaling.length());
                // Snapping logic
                var snapped = false;
                var dragSteps = 0;
                if (_this.uniformScaling) {
                    _this.attachedMesh.scaling.normalizeToRef(tmpVector);
                    if (tmpVector.y < 0) {
                        tmpVector.scaleInPlace(-1);
                    }
                }
                else {
                    tmpVector.copyFrom(dragAxis);
                }
                if (_this.snapDistance == 0) {
                    tmpVector.scaleToRef(dragStrength, tmpVector);
                }
                else {
                    currentSnapDragDistance += dragStrength;
                    if (Math.abs(currentSnapDragDistance) > _this.snapDistance) {
                        dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / _this.snapDistance);
                        if (currentSnapDragDistance < 0) {
                            dragSteps *= -1;
                        }
                        currentSnapDragDistance = currentSnapDragDistance % _this.snapDistance;
                        tmpVector.scaleToRef(_this.snapDistance * dragSteps, tmpVector);
                        snapped = true;
                    }
                    else {
                        tmpVector.scaleInPlace(0);
                    }
                }
                _this.attachedMesh.scaling.addInPlace(tmpVector);
                if (snapped) {
                    tmpSnapEvent.snapDistance = _this.snapDistance * dragSteps;
                    _this.onSnapObservable.notifyObservers(tmpSnapEvent);
                }
            }
        });
        _this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add(function (pointerInfo) {
            if (_this._customMeshSet) {
                return;
            }
            var isHovered = pointerInfo.pickInfo && (_this._rootMesh.getChildMeshes().indexOf(pointerInfo.pickInfo.pickedMesh) != -1);
            var material = isHovered ? _this._hoverMaterial : _this._coloredMaterial;
            _this._rootMesh.getChildMeshes().forEach(function (m) {
                m.material = material;
                if (m.color) {
                    m.color = material.diffuseColor;
                }
            });
        });
        var light = gizmoLayer._getSharedGizmoLight();
        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(_this._rootMesh.getChildMeshes());
        return _this;
    }
    AxisScaleGizmo.prototype._attachedMeshChanged = function (value) {
        if (this.dragBehavior) {
            this.dragBehavior.enabled = value ? true : false;
        }
    };
    Object.defineProperty(AxisScaleGizmo.prototype, "isEnabled", {
        get: function () {
            return this._isEnabled;
        },
        /**
     * If the gizmo is enabled
     */
        set: function (value) {
            this._isEnabled = value;
            if (!value) {
                this.attachedMesh = null;
            }
            else {
                if (this._parent) {
                    this.attachedMesh = this._parent.attachedMesh;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    AxisScaleGizmo.prototype.dispose = function () {
        this.onSnapObservable.clear();
        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
        this.dragBehavior.detach();
        if (this._arrow) {
            this._arrow.dispose();
        }
        [this._coloredMaterial, this._hoverMaterial].forEach(function (matl) {
            if (matl) {
                matl.dispose();
            }
        });
        _super.prototype.dispose.call(this);
    };
    /**
     * Disposes and replaces the current meshes in the gizmo with the specified mesh
     * @param mesh The mesh to replace the default mesh of the gizmo
     * @param useGizmoMaterial If the gizmo's default material should be used (default: false)
     */
    AxisScaleGizmo.prototype.setCustomMesh = function (mesh, useGizmoMaterial) {
        var _this = this;
        if (useGizmoMaterial === void 0) { useGizmoMaterial = false; }
        _super.prototype.setCustomMesh.call(this, mesh);
        if (useGizmoMaterial) {
            this._rootMesh.getChildMeshes().forEach(function (m) {
                m.material = _this._coloredMaterial;
                if (m.color) {
                    m.color = _this._coloredMaterial.diffuseColor;
                }
            });
            this._customMeshSet = false;
        }
    };
    return AxisScaleGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_8__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/boundingBoxGizmo.ts":
/*!************************************!*\
  !*** ./Gizmos/boundingBoxGizmo.ts ***!
  \************************************/
/*! exports provided: BoundingBoxGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxGizmo", function() { return BoundingBoxGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Meshes/Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Meshes/Builders/linesBuilder */ "./Meshes/Builders/linesBuilder.ts");
/* harmony import */ var _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Behaviors/Meshes/pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Misc/pivotTools */ "./Misc/pivotTools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");

















/**
 * Bounding box gizmo
 */
var BoundingBoxGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BoundingBoxGizmo, _super);
    /**
     * Creates an BoundingBoxGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     * @param color The color of the gizmo
     */
    function BoundingBoxGizmo(color, gizmoLayer) {
        if (color === void 0) { color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_14__["Color3"].Gray(); }
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_11__["UtilityLayerRenderer"].DefaultKeepDepthUtilityLayer; }
        var _this = _super.call(this, gizmoLayer) || this;
        _this._boundingDimensions = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 1, 1);
        _this._renderObserver = null;
        _this._pointerObserver = null;
        _this._scaleDragSpeed = 0.2;
        _this._tmpQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        _this._tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        _this._tmpRotationMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
        /**
         * If child meshes should be ignored when calculating the boudning box. This should be set to true to avoid perf hits with heavily nested meshes (Default: false)
         */
        _this.ignoreChildren = false;
        /**
         * Returns true if a descendant should be included when computing the bounding box. When null, all descendants are included. If ignoreChildren is set this will be ignored. (Default: null)
         */
        _this.includeChildPredicate = null;
        /**
         * The size of the rotation spheres attached to the bounding box (Default: 0.1)
         */
        _this.rotationSphereSize = 0.1;
        /**
         * The size of the scale boxes attached to the bounding box (Default: 0.1)
         */
        _this.scaleBoxSize = 0.1;
        /**
         * If set, the rotation spheres and scale boxes will increase in size based on the distance away from the camera to have a consistent screen size (Default: false)
         */
        _this.fixedDragMeshScreenSize = false;
        /**
         * The distance away from the object which the draggable meshes should appear world sized when fixedDragMeshScreenSize is set to true (default: 10)
         */
        _this.fixedDragMeshScreenSizeDistanceFactor = 10;
        /**
         * Fired when a rotation sphere or scale box is dragged
         */
        _this.onDragStartObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when a scale box is dragged
         */
        _this.onScaleBoxDragObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
          * Fired when a scale box drag is ended
         */
        _this.onScaleBoxDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when a rotation sphere is dragged
         */
        _this.onRotationSphereDragObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Fired when a rotation sphere drag is ended
         */
        _this.onRotationSphereDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * Relative bounding box pivot used when scaling the attached mesh. When null object with scale from the opposite corner. 0.5,0.5,0.5 for center and 0.5,0,0.5 for bottom (Default: null)
         */
        _this.scalePivot = null;
        _this._existingMeshScale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"]();
        // Dragging
        _this._dragMesh = null;
        _this.pointerDragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_9__["PointerDragBehavior"]();
        // Do not update the gizmo's scale so it has a fixed size to the object its attached to
        _this.updateScale = false;
        _this._anchorMesh = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__["AbstractMesh"]("anchor", gizmoLayer.utilityLayerScene);
        // Create Materials
        _this.coloredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_12__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this.coloredMaterial.disableLighting = true;
        _this.hoverColoredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_12__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this.hoverColoredMaterial.disableLighting = true;
        // Build bounding box out of lines
        _this._lineBoundingBox = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__["AbstractMesh"]("", gizmoLayer.utilityLayerScene);
        _this._lineBoundingBox.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        var lines = [];
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, 0, 0)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, _this._boundingDimensions.y, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, _this._boundingDimensions.y, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, _this._boundingDimensions.z), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, _this._boundingDimensions.z), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, _this._boundingDimensions.y, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, 0, _this._boundingDimensions.z)] }, gizmoLayer.utilityLayerScene));
        lines.push(_Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines("lines", { points: [new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, _this._boundingDimensions.y, _this._boundingDimensions.z), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](_this._boundingDimensions.x, _this._boundingDimensions.y, 0)] }, gizmoLayer.utilityLayerScene));
        lines.forEach(function (l) {
            l.color = color;
            l.position.addInPlace(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-_this._boundingDimensions.x / 2, -_this._boundingDimensions.y / 2, -_this._boundingDimensions.z / 2));
            l.isPickable = false;
            _this._lineBoundingBox.addChild(l);
        });
        _this._rootMesh.addChild(_this._lineBoundingBox);
        _this.setColor(color);
        // Create rotation spheres
        _this._rotateSpheresParent = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__["AbstractMesh"]("", gizmoLayer.utilityLayerScene);
        _this._rotateSpheresParent.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        var _loop_1 = function (i_1) {
            var sphere = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_6__["SphereBuilder"].CreateSphere("", { diameter: 1 }, gizmoLayer.utilityLayerScene);
            sphere.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
            sphere.material = this_1.coloredMaterial;
            // Drag behavior
            _dragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_9__["PointerDragBehavior"]({});
            _dragBehavior.moveAttached = false;
            _dragBehavior.updateDragPlane = false;
            sphere.addBehavior(_dragBehavior);
            var startingTurnDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 0, 0);
            var totalTurnAmountOfDrag = 0;
            _dragBehavior.onDragStartObservable.add(function () {
                startingTurnDirection.copyFrom(sphere.forward);
                totalTurnAmountOfDrag = 0;
            });
            _dragBehavior.onDragObservable.add(function (event) {
                _this.onRotationSphereDragObservable.notifyObservers({});
                if (_this.attachedMesh) {
                    var originalParent = _this.attachedMesh.parent;
                    if (originalParent && (originalParent.scaling && originalParent.scaling.isNonUniformWithinEpsilon(0.001))) {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("BoundingBoxGizmo controls are not supported on child meshes with non-uniform parent scaling");
                        return;
                    }
                    _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RemoveAndStorePivotPoint(_this.attachedMesh);
                    var worldDragDirection = startingTurnDirection;
                    // Project the world right on to the drag plane
                    var toSub = event.dragPlaneNormal.scale(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(event.dragPlaneNormal, worldDragDirection));
                    var dragAxis = worldDragDirection.subtract(toSub).normalizeToNew();
                    // project drag delta on to the resulting drag axis and rotate based on that
                    var projectDist = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(dragAxis, event.delta) < 0 ? Math.abs(event.delta.length()) : -Math.abs(event.delta.length());
                    // Make rotation relative to size of mesh.
                    projectDist = (projectDist / _this._boundingDimensions.length()) * _this._anchorMesh.scaling.length();
                    // Rotate based on axis
                    if (!_this.attachedMesh.rotationQuaternion) {
                        _this.attachedMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(_this.attachedMesh.rotation.y, _this.attachedMesh.rotation.x, _this.attachedMesh.rotation.z);
                    }
                    if (!_this._anchorMesh.rotationQuaternion) {
                        _this._anchorMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(_this._anchorMesh.rotation.y, _this._anchorMesh.rotation.x, _this._anchorMesh.rotation.z);
                    }
                    // Do not allow the object to turn more than a full circle
                    totalTurnAmountOfDrag += projectDist;
                    if (Math.abs(totalTurnAmountOfDrag) <= 2 * Math.PI) {
                        if (i_1 >= 8) {
                            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(0, 0, projectDist, _this._tmpQuaternion);
                        }
                        else if (i_1 >= 4) {
                            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(projectDist, 0, 0, _this._tmpQuaternion);
                        }
                        else {
                            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(0, projectDist, 0, _this._tmpQuaternion);
                        }
                        // Rotate around center of bounding box
                        _this._anchorMesh.addChild(_this.attachedMesh);
                        _this._anchorMesh.rotationQuaternion.multiplyToRef(_this._tmpQuaternion, _this._anchorMesh.rotationQuaternion);
                        _this._anchorMesh.removeChild(_this.attachedMesh);
                        _this.attachedMesh.setParent(originalParent);
                    }
                    _this.updateBoundingBox();
                    _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RestorePivotPoint(_this.attachedMesh);
                }
                _this._updateDummy();
            });
            // Selection/deselection
            _dragBehavior.onDragStartObservable.add(function () {
                _this.onDragStartObservable.notifyObservers({});
                _this._selectNode(sphere);
            });
            _dragBehavior.onDragEndObservable.add(function () {
                _this.onRotationSphereDragEndObservable.notifyObservers({});
                _this._selectNode(null);
                _this._updateDummy();
            });
            this_1._rotateSpheresParent.addChild(sphere);
        };
        var this_1 = this, _dragBehavior;
        for (var i_1 = 0; i_1 < 12; i_1++) {
            _loop_1(i_1);
        }
        _this._rootMesh.addChild(_this._rotateSpheresParent);
        // Create scale cubes
        _this._scaleBoxesParent = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__["AbstractMesh"]("", gizmoLayer.utilityLayerScene);
        _this._scaleBoxesParent.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        for (var i = 0; i < 2; i++) {
            for (var j = 0; j < 2; j++) {
                var _loop_2 = function () {
                    var box = _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_7__["BoxBuilder"].CreateBox("", { size: 1 }, gizmoLayer.utilityLayerScene);
                    box.material = this_2.coloredMaterial;
                    // Dragging logic
                    var dragAxis = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](i == 0 ? -1 : 1, j == 0 ? -1 : 1, k == 0 ? -1 : 1);
                    _dragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_9__["PointerDragBehavior"]({ dragAxis: dragAxis });
                    _dragBehavior.moveAttached = false;
                    box.addBehavior(_dragBehavior);
                    _dragBehavior.onDragObservable.add(function (event) {
                        _this.onScaleBoxDragObservable.notifyObservers({});
                        if (_this.attachedMesh) {
                            var originalParent = _this.attachedMesh.parent;
                            if (originalParent && (originalParent.scaling && originalParent.scaling.isNonUniformWithinEpsilon(0.001))) {
                                _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("BoundingBoxGizmo controls are not supported on child meshes with non-uniform parent scaling");
                                return;
                            }
                            _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RemoveAndStorePivotPoint(_this.attachedMesh);
                            var relativeDragDistance = (event.dragDistance / _this._boundingDimensions.length()) * _this._anchorMesh.scaling.length();
                            var deltaScale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](relativeDragDistance, relativeDragDistance, relativeDragDistance);
                            deltaScale.scaleInPlace(_this._scaleDragSpeed);
                            _this.updateBoundingBox();
                            if (_this.scalePivot) {
                                _this.attachedMesh.getWorldMatrix().getRotationMatrixToRef(_this._tmpRotationMatrix);
                                // Move anchor to desired pivot point (Bottom left corner + dimension/2)
                                _this._boundingDimensions.scaleToRef(0.5, _this._tmpVector);
                                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(_this._tmpVector, _this._tmpRotationMatrix, _this._tmpVector);
                                _this._anchorMesh.position.subtractInPlace(_this._tmpVector);
                                _this._boundingDimensions.multiplyToRef(_this.scalePivot, _this._tmpVector);
                                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(_this._tmpVector, _this._tmpRotationMatrix, _this._tmpVector);
                                _this._anchorMesh.position.addInPlace(_this._tmpVector);
                            }
                            else {
                                // Scale from the position of the opposite corner
                                box.absolutePosition.subtractToRef(_this._anchorMesh.position, _this._tmpVector);
                                _this._anchorMesh.position.subtractInPlace(_this._tmpVector);
                            }
                            _this._anchorMesh.addChild(_this.attachedMesh);
                            _this._anchorMesh.scaling.addInPlace(deltaScale);
                            if (_this._anchorMesh.scaling.x < 0 || _this._anchorMesh.scaling.y < 0 || _this._anchorMesh.scaling.z < 0) {
                                _this._anchorMesh.scaling.subtractInPlace(deltaScale);
                            }
                            _this._anchorMesh.removeChild(_this.attachedMesh);
                            _this.attachedMesh.setParent(originalParent);
                            _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RestorePivotPoint(_this.attachedMesh);
                        }
                        _this._updateDummy();
                    });
                    // Selection/deselection
                    _dragBehavior.onDragStartObservable.add(function () {
                        _this.onDragStartObservable.notifyObservers({});
                        _this._selectNode(box);
                    });
                    _dragBehavior.onDragEndObservable.add(function () {
                        _this.onScaleBoxDragEndObservable.notifyObservers({});
                        _this._selectNode(null);
                        _this._updateDummy();
                    });
                    this_2._scaleBoxesParent.addChild(box);
                };
                var this_2 = this, _dragBehavior;
                for (var k = 0; k < 2; k++) {
                    _loop_2();
                }
            }
        }
        _this._rootMesh.addChild(_this._scaleBoxesParent);
        // Hover color change
        var pointerIds = new Array();
        _this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add(function (pointerInfo) {
            if (!pointerIds[pointerInfo.event.pointerId]) {
                _this._rotateSpheresParent.getChildMeshes().concat(_this._scaleBoxesParent.getChildMeshes()).forEach(function (mesh) {
                    if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh == mesh) {
                        pointerIds[pointerInfo.event.pointerId] = mesh;
                        mesh.material = _this.hoverColoredMaterial;
                    }
                });
            }
            else {
                if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh != pointerIds[pointerInfo.event.pointerId]) {
                    pointerIds[pointerInfo.event.pointerId].material = _this.coloredMaterial;
                    delete pointerIds[pointerInfo.event.pointerId];
                }
            }
        });
        // Update bounding box positions
        _this._renderObserver = _this.gizmoLayer.originalScene.onBeforeRenderObservable.add(function () {
            // Only update the bouding box if scaling has changed
            if (_this.attachedMesh && !_this._existingMeshScale.equals(_this.attachedMesh.scaling)) {
                _this.updateBoundingBox();
            }
            else if (_this.fixedDragMeshScreenSize) {
                _this._updateRotationSpheres();
                _this._updateScaleBoxes();
            }
            // If dragg mesh is enabled and dragging, update the attached mesh pose to match the drag mesh
            if (_this._dragMesh && _this.attachedMesh && _this.pointerDragBehavior.dragging) {
                _this._lineBoundingBox.position.rotateByQuaternionToRef(_this._rootMesh.rotationQuaternion, _this._tmpVector);
                _this.attachedMesh.setAbsolutePosition(_this._dragMesh.position.add(_this._tmpVector.scale(-1)));
            }
        });
        _this.updateBoundingBox();
        return _this;
    }
    /**
     * Sets the color of the bounding box gizmo
     * @param color the color to set
     */
    BoundingBoxGizmo.prototype.setColor = function (color) {
        this.coloredMaterial.emissiveColor = color;
        this.hoverColoredMaterial.emissiveColor = color.clone().add(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_14__["Color3"](0.3, 0.3, 0.3));
        this._lineBoundingBox.getChildren().forEach(function (l) {
            if (l.color) {
                l.color = color;
            }
        });
    };
    BoundingBoxGizmo.prototype._attachedMeshChanged = function (value) {
        var _this = this;
        if (value) {
            // Reset anchor mesh to match attached mesh's scale
            // This is needed to avoid invalid box/sphere position on first drag
            _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RemoveAndStorePivotPoint(value);
            var originalParent = value.parent;
            this._anchorMesh.addChild(value);
            this._anchorMesh.removeChild(value);
            value.setParent(originalParent);
            _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RestorePivotPoint(value);
            this.updateBoundingBox();
            value.getChildMeshes(false).forEach(function (m) {
                m.markAsDirty("scaling");
            });
            this.gizmoLayer.utilityLayerScene.onAfterRenderObservable.addOnce(function () {
                _this._updateDummy();
            });
        }
    };
    BoundingBoxGizmo.prototype._selectNode = function (selectedMesh) {
        this._rotateSpheresParent.getChildMeshes()
            .concat(this._scaleBoxesParent.getChildMeshes()).forEach(function (m) {
            m.isVisible = (!selectedMesh || m == selectedMesh);
        });
    };
    /**
     * Updates the bounding box information for the Gizmo
     */
    BoundingBoxGizmo.prototype.updateBoundingBox = function () {
        if (this.attachedMesh) {
            _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RemoveAndStorePivotPoint(this.attachedMesh);
            // Store original parent
            var originalParent = this.attachedMesh.parent;
            this.attachedMesh.setParent(null);
            // Store original skelton override mesh
            var originalSkeletonOverrideMesh = null;
            if (this.attachedMesh.skeleton) {
                originalSkeletonOverrideMesh = this.attachedMesh.skeleton.overrideMesh;
                this.attachedMesh.skeleton.overrideMesh = null;
            }
            this._update();
            // Rotate based on axis
            if (!this.attachedMesh.rotationQuaternion) {
                this.attachedMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(this.attachedMesh.rotation.y, this.attachedMesh.rotation.x, this.attachedMesh.rotation.z);
            }
            if (!this._anchorMesh.rotationQuaternion) {
                this._anchorMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(this._anchorMesh.rotation.y, this._anchorMesh.rotation.x, this._anchorMesh.rotation.z);
            }
            this._anchorMesh.rotationQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
            // Store original position and reset mesh to origin before computing the bounding box
            this._tmpQuaternion.copyFrom(this.attachedMesh.rotationQuaternion);
            this._tmpVector.copyFrom(this.attachedMesh.position);
            this.attachedMesh.rotationQuaternion.set(0, 0, 0, 1);
            this.attachedMesh.position.set(0, 0, 0);
            // Update bounding dimensions/positions
            var boundingMinMax = this.attachedMesh.getHierarchyBoundingVectors(!this.ignoreChildren, this.includeChildPredicate);
            boundingMinMax.max.subtractToRef(boundingMinMax.min, this._boundingDimensions);
            // Update gizmo to match bounding box scaling and rotation
            // The position set here is the offset from the origin for the boundingbox when the attached mesh is at the origin
            // The position of the gizmo is then set to the attachedMesh in gizmo._update
            this._lineBoundingBox.scaling.copyFrom(this._boundingDimensions);
            this._lineBoundingBox.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
            this._rotateSpheresParent.position.copyFrom(this._lineBoundingBox.position);
            this._scaleBoxesParent.position.copyFrom(this._lineBoundingBox.position);
            this._lineBoundingBox.computeWorldMatrix();
            this._anchorMesh.position.copyFrom(this._lineBoundingBox.absolutePosition);
            // Restore position/rotation values
            this.attachedMesh.rotationQuaternion.copyFrom(this._tmpQuaternion);
            this.attachedMesh.position.copyFrom(this._tmpVector);
            // Restore original parent
            this.attachedMesh.setParent(originalParent);
            // Restore original skeleton override mesh
            if (this.attachedMesh.skeleton) {
                this.attachedMesh.skeleton.overrideMesh = originalSkeletonOverrideMesh;
            }
        }
        this._updateRotationSpheres();
        this._updateScaleBoxes();
        if (this.attachedMesh) {
            this._existingMeshScale.copyFrom(this.attachedMesh.scaling);
            _Misc_pivotTools__WEBPACK_IMPORTED_MODULE_13__["PivotTools"]._RestorePivotPoint(this.attachedMesh);
        }
    };
    BoundingBoxGizmo.prototype._updateRotationSpheres = function () {
        var rotateSpheres = this._rotateSpheresParent.getChildMeshes();
        for (var i = 0; i < 3; i++) {
            for (var j = 0; j < 2; j++) {
                for (var k = 0; k < 2; k++) {
                    var index = ((i * 4) + (j * 2)) + k;
                    if (i == 0) {
                        rotateSpheres[index].position.set(this._boundingDimensions.x / 2, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
                        rotateSpheres[index].position.addInPlace(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
                        rotateSpheres[index].lookAt(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Cross(rotateSpheres[index].position.normalizeToNew(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Right()).normalizeToNew().add(rotateSpheres[index].position));
                    }
                    if (i == 1) {
                        rotateSpheres[index].position.set(this._boundingDimensions.x * j, this._boundingDimensions.y / 2, this._boundingDimensions.z * k);
                        rotateSpheres[index].position.addInPlace(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
                        rotateSpheres[index].lookAt(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Cross(rotateSpheres[index].position.normalizeToNew(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Up()).normalizeToNew().add(rotateSpheres[index].position));
                    }
                    if (i == 2) {
                        rotateSpheres[index].position.set(this._boundingDimensions.x * j, this._boundingDimensions.y * k, this._boundingDimensions.z / 2);
                        rotateSpheres[index].position.addInPlace(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
                        rotateSpheres[index].lookAt(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Cross(rotateSpheres[index].position.normalizeToNew(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Forward()).normalizeToNew().add(rotateSpheres[index].position));
                    }
                    if (this.fixedDragMeshScreenSize && this.gizmoLayer.utilityLayerScene.activeCamera) {
                        rotateSpheres[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera.position, this._tmpVector);
                        var distanceFromCamera = this.rotationSphereSize * this._tmpVector.length() / this.fixedDragMeshScreenSizeDistanceFactor;
                        rotateSpheres[index].scaling.set(distanceFromCamera, distanceFromCamera, distanceFromCamera);
                    }
                    else {
                        rotateSpheres[index].scaling.set(this.rotationSphereSize, this.rotationSphereSize, this.rotationSphereSize);
                    }
                }
            }
        }
    };
    BoundingBoxGizmo.prototype._updateScaleBoxes = function () {
        var scaleBoxes = this._scaleBoxesParent.getChildMeshes();
        for (var i = 0; i < 2; i++) {
            for (var j = 0; j < 2; j++) {
                for (var k = 0; k < 2; k++) {
                    var index = ((i * 4) + (j * 2)) + k;
                    if (scaleBoxes[index]) {
                        scaleBoxes[index].position.set(this._boundingDimensions.x * i, this._boundingDimensions.y * j, this._boundingDimensions.z * k);
                        scaleBoxes[index].position.addInPlace(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-this._boundingDimensions.x / 2, -this._boundingDimensions.y / 2, -this._boundingDimensions.z / 2));
                        if (this.fixedDragMeshScreenSize && this.gizmoLayer.utilityLayerScene.activeCamera) {
                            scaleBoxes[index].absolutePosition.subtractToRef(this.gizmoLayer.utilityLayerScene.activeCamera.position, this._tmpVector);
                            var distanceFromCamera = this.scaleBoxSize * this._tmpVector.length() / this.fixedDragMeshScreenSizeDistanceFactor;
                            scaleBoxes[index].scaling.set(distanceFromCamera, distanceFromCamera, distanceFromCamera);
                        }
                        else {
                            scaleBoxes[index].scaling.set(this.scaleBoxSize, this.scaleBoxSize, this.scaleBoxSize);
                        }
                    }
                }
            }
        }
    };
    /**
     * Enables rotation on the specified axis and disables rotation on the others
     * @param axis The list of axis that should be enabled (eg. "xy" or "xyz")
     */
    BoundingBoxGizmo.prototype.setEnabledRotationAxis = function (axis) {
        this._rotateSpheresParent.getChildMeshes().forEach(function (m, i) {
            if (i < 4) {
                m.setEnabled(axis.indexOf("x") != -1);
            }
            else if (i < 8) {
                m.setEnabled(axis.indexOf("y") != -1);
            }
            else {
                m.setEnabled(axis.indexOf("z") != -1);
            }
        });
    };
    /**
     * Enables/disables scaling
     * @param enable if scaling should be enabled
     */
    BoundingBoxGizmo.prototype.setEnabledScaling = function (enable) {
        this._scaleBoxesParent.getChildMeshes().forEach(function (m, i) {
            m.setEnabled(enable);
        });
    };
    BoundingBoxGizmo.prototype._updateDummy = function () {
        if (this._dragMesh) {
            this._dragMesh.position.copyFrom(this._lineBoundingBox.getAbsolutePosition());
            this._dragMesh.scaling.copyFrom(this._lineBoundingBox.scaling);
            this._dragMesh.rotationQuaternion.copyFrom(this._rootMesh.rotationQuaternion);
        }
    };
    /**
     * Enables a pointer drag behavior on the bounding box of the gizmo
     */
    BoundingBoxGizmo.prototype.enableDragBehavior = function () {
        this._dragMesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].CreateBox("dummy", 1, this.gizmoLayer.utilityLayerScene);
        this._dragMesh.visibility = 0;
        this._dragMesh.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
        this.pointerDragBehavior.useObjectOrienationForDragging = false;
        this._dragMesh.addBehavior(this.pointerDragBehavior);
    };
    /**
     * Disposes of the gizmo
     */
    BoundingBoxGizmo.prototype.dispose = function () {
        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
        this.gizmoLayer.originalScene.onBeforeRenderObservable.remove(this._renderObserver);
        this._lineBoundingBox.dispose();
        this._rotateSpheresParent.dispose();
        this._scaleBoxesParent.dispose();
        if (this._dragMesh) {
            this._dragMesh.dispose();
        }
        _super.prototype.dispose.call(this);
    };
    /**
     * Makes a mesh not pickable and wraps the mesh inside of a bounding box mesh that is pickable. (This is useful to avoid picking within complex geometry)
     * @param mesh the mesh to wrap in the bounding box mesh and make not pickable
     * @returns the bounding box mesh with the passed in mesh as a child
     */
    BoundingBoxGizmo.MakeNotPickableAndWrapInBoundingBox = function (mesh) {
        var makeNotPickable = function (root) {
            root.isPickable = false;
            root.getChildMeshes().forEach(function (c) {
                makeNotPickable(c);
            });
        };
        makeNotPickable(mesh);
        // Reset position to get boudning box from origin with no rotation
        if (!mesh.rotationQuaternion) {
            mesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(mesh.rotation.y, mesh.rotation.x, mesh.rotation.z);
        }
        var oldPos = mesh.position.clone();
        var oldRot = mesh.rotationQuaternion.clone();
        mesh.rotationQuaternion.set(0, 0, 0, 1);
        mesh.position.set(0, 0, 0);
        // Update bounding dimensions/positions
        var box = _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_7__["BoxBuilder"].CreateBox("box", { size: 1 }, mesh.getScene());
        var boundingMinMax = mesh.getHierarchyBoundingVectors();
        boundingMinMax.max.subtractToRef(boundingMinMax.min, box.scaling);
        // Adjust scale to avoid undefined behavior when adding child
        if (box.scaling.y === 0) {
            box.scaling.y = _Maths_math_constants__WEBPACK_IMPORTED_MODULE_15__["Epsilon"];
        }
        if (box.scaling.x === 0) {
            box.scaling.x = _Maths_math_constants__WEBPACK_IMPORTED_MODULE_15__["Epsilon"];
        }
        if (box.scaling.z === 0) {
            box.scaling.z = _Maths_math_constants__WEBPACK_IMPORTED_MODULE_15__["Epsilon"];
        }
        box.position.set((boundingMinMax.max.x + boundingMinMax.min.x) / 2, (boundingMinMax.max.y + boundingMinMax.min.y) / 2, (boundingMinMax.max.z + boundingMinMax.min.z) / 2);
        // Restore original positions
        mesh.addChild(box);
        mesh.rotationQuaternion.copyFrom(oldRot);
        mesh.position.copyFrom(oldPos);
        // Reverse parenting
        mesh.removeChild(box);
        box.addChild(mesh);
        box.visibility = 0;
        return box;
    };
    /**
     * CustomMeshes are not supported by this gizmo
     * @param mesh The mesh to replace the default mesh of the gizmo
     */
    BoundingBoxGizmo.prototype.setCustomMesh = function (mesh) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Error("Custom meshes are not supported on this gizmo");
    };
    return BoundingBoxGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_10__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/gizmo.ts":
/*!*************************!*\
  !*** ./Gizmos/gizmo.ts ***!
  \*************************/
/*! exports provided: Gizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Gizmo", function() { return Gizmo; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");



/**
 * Renders gizmos on top of an existing scene which provide controls for position, rotation, etc.
 */
var Gizmo = /** @class */ (function () {
    /**
     * Creates a gizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     */
    function Gizmo(
    /** The utility layer the gizmo will be added to */
    gizmoLayer) {
        var _this = this;
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_2__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        this.gizmoLayer = gizmoLayer;
        this._attachedMesh = null;
        /**
         * Ratio for the scale of the gizmo (Default: 1)
         */
        this.scaleRatio = 1;
        /**
         * If a custom mesh has been set (Default: false)
         */
        this._customMeshSet = false;
        /**
         * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
         */
        this.updateGizmoRotationToMatchAttachedMesh = true;
        /**
         * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
         */
        this.updateGizmoPositionToMatchAttachedMesh = true;
        /**
         * When set, the gizmo will always appear the same size no matter where the camera is (default: true)
         */
        this.updateScale = true;
        this._interactionsEnabled = true;
        this._tempVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
        this._rootMesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]("gizmoRootNode", gizmoLayer.utilityLayerScene);
        this._rootMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity();
        this._beforeRenderObserver = this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.add(function () {
            _this._update();
        });
    }
    Object.defineProperty(Gizmo.prototype, "attachedMesh", {
        /**
         * Mesh that the gizmo will be attached to. (eg. on a drag gizmo the mesh that will be dragged)
         * * When set, interactions will be enabled
         */
        get: function () {
            return this._attachedMesh;
        },
        set: function (value) {
            this._attachedMesh = value;
            this._rootMesh.setEnabled(value ? true : false);
            this._attachedMeshChanged(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes and replaces the current meshes in the gizmo with the specified mesh
     * @param mesh The mesh to replace the default mesh of the gizmo
     */
    Gizmo.prototype.setCustomMesh = function (mesh) {
        if (mesh.getScene() != this.gizmoLayer.utilityLayerScene) {
            throw "When setting a custom mesh on a gizmo, the custom meshes scene must be the same as the gizmos (eg. gizmo.gizmoLayer.utilityLayerScene)";
        }
        this._rootMesh.getChildMeshes().forEach(function (c) {
            c.dispose();
        });
        mesh.parent = this._rootMesh;
        this._customMeshSet = true;
    };
    Gizmo.prototype._attachedMeshChanged = function (value) {
    };
    /**
     * Updates the gizmo to match the attached mesh's position/rotation
     */
    Gizmo.prototype._update = function () {
        if (this.attachedMesh) {
            var effectiveMesh = this.attachedMesh._effectiveMesh || this.attachedMesh;
            // Position
            if (this.updateGizmoPositionToMatchAttachedMesh) {
                this._rootMesh.position.copyFrom(effectiveMesh.absolutePosition);
            }
            // Rotation
            if (this.updateGizmoRotationToMatchAttachedMesh) {
                effectiveMesh.getWorldMatrix().decompose(undefined, this._rootMesh.rotationQuaternion);
            }
            else {
                this._rootMesh.rotationQuaternion.set(0, 0, 0, 1);
            }
            // Scale
            if (this.updateScale) {
                var activeCamera = this.gizmoLayer.utilityLayerScene.activeCamera;
                var cameraPosition = activeCamera.globalPosition;
                if (activeCamera.devicePosition) {
                    cameraPosition = activeCamera.devicePosition;
                }
                this._rootMesh.position.subtractToRef(cameraPosition, this._tempVector);
                var dist = this._tempVector.length() * this.scaleRatio;
                this._rootMesh.scaling.set(dist, dist, dist);
                // Account for handedness, similar to Matrix.decompose
                if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
                    this._rootMesh.scaling.y *= -1;
                }
            }
            else {
                this._rootMesh.scaling.setAll(this.scaleRatio);
            }
        }
    };
    /**
     * Disposes of the gizmo
     */
    Gizmo.prototype.dispose = function () {
        this._rootMesh.dispose();
        if (this._beforeRenderObserver) {
            this.gizmoLayer.utilityLayerScene.onBeforeRenderObservable.remove(this._beforeRenderObserver);
        }
    };
    return Gizmo;
}());



/***/ }),

/***/ "./Gizmos/gizmoManager.ts":
/*!********************************!*\
  !*** ./Gizmos/gizmoManager.ts ***!
  \********************************/
/*! exports provided: GizmoManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GizmoManager", function() { return GizmoManager; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Behaviors_Meshes_sixDofDragBehavior__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Behaviors/Meshes/sixDofDragBehavior */ "./Behaviors/Meshes/sixDofDragBehavior.ts");
/* harmony import */ var _rotationGizmo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./rotationGizmo */ "./Gizmos/rotationGizmo.ts");
/* harmony import */ var _positionGizmo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./positionGizmo */ "./Gizmos/positionGizmo.ts");
/* harmony import */ var _scaleGizmo__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./scaleGizmo */ "./Gizmos/scaleGizmo.ts");
/* harmony import */ var _boundingBoxGizmo__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./boundingBoxGizmo */ "./Gizmos/boundingBoxGizmo.ts");










/**
 * Helps setup gizmo's in the scene to rotate/scale/position meshes
 */
var GizmoManager = /** @class */ (function () {
    /**
     * Instatiates a gizmo manager
     * @param scene the scene to overlay the gizmos on top of
     */
    function GizmoManager(scene) {
        var _this = this;
        this.scene = scene;
        /** When true, the gizmo will be detached from the current object when a pointer down occurs with an empty picked mesh */
        this.clearGizmoOnEmptyPointerEvent = false;
        /** Fires an event when the manager is attached to a mesh */
        this.onAttachedToMeshObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this._gizmosEnabled = { positionGizmo: false, rotationGizmo: false, scaleGizmo: false, boundingBoxGizmo: false };
        this._pointerObserver = null;
        this._attachedMesh = null;
        this._boundingBoxColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].FromHexString("#0984e3");
        /**
         * When bounding box gizmo is enabled, this can be used to track drag/end events
         */
        this.boundingBoxDragBehavior = new _Behaviors_Meshes_sixDofDragBehavior__WEBPACK_IMPORTED_MODULE_5__["SixDofDragBehavior"]();
        /**
         * Array of meshes which will have the gizmo attached when a pointer selected them. If null, all meshes are attachable. (Default: null)
         */
        this.attachableMeshes = null;
        /**
         * If pointer events should perform attaching/detaching a gizmo, if false this can be done manually via attachToMesh. (Default: true)
         */
        this.usePointerToAttachGizmos = true;
        this._defaultKeepDepthUtilityLayer = new _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_3__["UtilityLayerRenderer"](scene);
        this._defaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
        this._defaultUtilityLayer = new _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_3__["UtilityLayerRenderer"](scene);
        this.gizmos = { positionGizmo: null, rotationGizmo: null, scaleGizmo: null, boundingBoxGizmo: null };
        // Instatiate/dispose gizmos based on pointer actions
        this._pointerObserver = scene.onPointerObservable.add(function (pointerInfo) {
            if (!_this.usePointerToAttachGizmos) {
                return;
            }
            if (pointerInfo.type == _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__["PointerEventTypes"].POINTERDOWN) {
                if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh) {
                    var node = pointerInfo.pickInfo.pickedMesh;
                    if (_this.attachableMeshes == null) {
                        // Attach to the most parent node
                        while (node && node.parent != null) {
                            node = node.parent;
                        }
                    }
                    else {
                        // Attach to the parent node that is an attachableMesh
                        var found = false;
                        _this.attachableMeshes.forEach(function (mesh) {
                            if (node && (node == mesh || node.isDescendantOf(mesh))) {
                                node = mesh;
                                found = true;
                            }
                        });
                        if (!found) {
                            node = null;
                        }
                    }
                    if (node instanceof _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"]) {
                        if (_this._attachedMesh != node) {
                            _this.attachToMesh(node);
                        }
                    }
                    else {
                        if (_this.clearGizmoOnEmptyPointerEvent) {
                            _this.attachToMesh(null);
                        }
                    }
                }
                else {
                    if (_this.clearGizmoOnEmptyPointerEvent) {
                        _this.attachToMesh(null);
                    }
                }
            }
        });
    }
    Object.defineProperty(GizmoManager.prototype, "keepDepthUtilityLayer", {
        /**
         * Utility layer that the bounding box gizmo belongs to
         */
        get: function () {
            return this._defaultKeepDepthUtilityLayer;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GizmoManager.prototype, "utilityLayer", {
        /**
         * Utility layer that all gizmos besides bounding box belong to
         */
        get: function () {
            return this._defaultUtilityLayer;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attaches a set of gizmos to the specified mesh
     * @param mesh The mesh the gizmo's should be attached to
     */
    GizmoManager.prototype.attachToMesh = function (mesh) {
        if (this._attachedMesh) {
            this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
        }
        this._attachedMesh = mesh;
        for (var key in this.gizmos) {
            var gizmo = (this.gizmos[key]);
            if (gizmo && this._gizmosEnabled[key]) {
                gizmo.attachedMesh = mesh;
            }
        }
        if (this.boundingBoxGizmoEnabled && this._attachedMesh) {
            this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
        }
        this.onAttachedToMeshObservable.notifyObservers(mesh);
    };
    Object.defineProperty(GizmoManager.prototype, "positionGizmoEnabled", {
        get: function () {
            return this._gizmosEnabled.positionGizmo;
        },
        /**
         * If the position gizmo is enabled
         */
        set: function (value) {
            if (value) {
                if (!this.gizmos.positionGizmo) {
                    this.gizmos.positionGizmo = new _positionGizmo__WEBPACK_IMPORTED_MODULE_7__["PositionGizmo"](this._defaultUtilityLayer);
                }
                this.gizmos.positionGizmo.attachedMesh = this._attachedMesh;
            }
            else if (this.gizmos.positionGizmo) {
                this.gizmos.positionGizmo.attachedMesh = null;
            }
            this._gizmosEnabled.positionGizmo = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GizmoManager.prototype, "rotationGizmoEnabled", {
        get: function () {
            return this._gizmosEnabled.rotationGizmo;
        },
        /**
         * If the rotation gizmo is enabled
         */
        set: function (value) {
            if (value) {
                if (!this.gizmos.rotationGizmo) {
                    this.gizmos.rotationGizmo = new _rotationGizmo__WEBPACK_IMPORTED_MODULE_6__["RotationGizmo"](this._defaultUtilityLayer);
                }
                this.gizmos.rotationGizmo.attachedMesh = this._attachedMesh;
            }
            else if (this.gizmos.rotationGizmo) {
                this.gizmos.rotationGizmo.attachedMesh = null;
            }
            this._gizmosEnabled.rotationGizmo = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GizmoManager.prototype, "scaleGizmoEnabled", {
        get: function () {
            return this._gizmosEnabled.scaleGizmo;
        },
        /**
         * If the scale gizmo is enabled
         */
        set: function (value) {
            if (value) {
                this.gizmos.scaleGizmo = this.gizmos.scaleGizmo || new _scaleGizmo__WEBPACK_IMPORTED_MODULE_8__["ScaleGizmo"](this._defaultUtilityLayer);
                this.gizmos.scaleGizmo.attachedMesh = this._attachedMesh;
            }
            else if (this.gizmos.scaleGizmo) {
                this.gizmos.scaleGizmo.attachedMesh = null;
            }
            this._gizmosEnabled.scaleGizmo = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GizmoManager.prototype, "boundingBoxGizmoEnabled", {
        get: function () {
            return this._gizmosEnabled.boundingBoxGizmo;
        },
        /**
         * If the boundingBox gizmo is enabled
         */
        set: function (value) {
            if (value) {
                this.gizmos.boundingBoxGizmo = this.gizmos.boundingBoxGizmo || new _boundingBoxGizmo__WEBPACK_IMPORTED_MODULE_9__["BoundingBoxGizmo"](this._boundingBoxColor, this._defaultKeepDepthUtilityLayer);
                this.gizmos.boundingBoxGizmo.attachedMesh = this._attachedMesh;
                if (this._attachedMesh) {
                    this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
                    this._attachedMesh.addBehavior(this.boundingBoxDragBehavior);
                }
            }
            else if (this.gizmos.boundingBoxGizmo) {
                if (this._attachedMesh) {
                    this._attachedMesh.removeBehavior(this.boundingBoxDragBehavior);
                }
                this.gizmos.boundingBoxGizmo.attachedMesh = null;
            }
            this._gizmosEnabled.boundingBoxGizmo = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo manager
     */
    GizmoManager.prototype.dispose = function () {
        this.scene.onPointerObservable.remove(this._pointerObserver);
        for (var key in this.gizmos) {
            var gizmo = (this.gizmos[key]);
            if (gizmo) {
                gizmo.dispose();
            }
        }
        this._defaultKeepDepthUtilityLayer.dispose();
        this._defaultUtilityLayer.dispose();
        this.boundingBoxDragBehavior.detach();
        this.onAttachedToMeshObservable.clear();
    };
    return GizmoManager;
}());



/***/ }),

/***/ "./Gizmos/index.ts":
/*!*************************!*\
  !*** ./Gizmos/index.ts ***!
  \*************************/
/*! exports provided: AxisDragGizmo, AxisScaleGizmo, BoundingBoxGizmo, Gizmo, GizmoManager, PlaneRotationGizmo, PositionGizmo, RotationGizmo, ScaleGizmo, LightGizmo, PlaneDragGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _axisDragGizmo__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./axisDragGizmo */ "./Gizmos/axisDragGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxisDragGizmo", function() { return _axisDragGizmo__WEBPACK_IMPORTED_MODULE_0__["AxisDragGizmo"]; });

/* harmony import */ var _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./axisScaleGizmo */ "./Gizmos/axisScaleGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxisScaleGizmo", function() { return _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_1__["AxisScaleGizmo"]; });

/* harmony import */ var _boundingBoxGizmo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./boundingBoxGizmo */ "./Gizmos/boundingBoxGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxGizmo", function() { return _boundingBoxGizmo__WEBPACK_IMPORTED_MODULE_2__["BoundingBoxGizmo"]; });

/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Gizmo", function() { return _gizmo__WEBPACK_IMPORTED_MODULE_3__["Gizmo"]; });

/* harmony import */ var _gizmoManager__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./gizmoManager */ "./Gizmos/gizmoManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GizmoManager", function() { return _gizmoManager__WEBPACK_IMPORTED_MODULE_4__["GizmoManager"]; });

/* harmony import */ var _planeRotationGizmo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./planeRotationGizmo */ "./Gizmos/planeRotationGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneRotationGizmo", function() { return _planeRotationGizmo__WEBPACK_IMPORTED_MODULE_5__["PlaneRotationGizmo"]; });

/* harmony import */ var _positionGizmo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./positionGizmo */ "./Gizmos/positionGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionGizmo", function() { return _positionGizmo__WEBPACK_IMPORTED_MODULE_6__["PositionGizmo"]; });

/* harmony import */ var _rotationGizmo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./rotationGizmo */ "./Gizmos/rotationGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RotationGizmo", function() { return _rotationGizmo__WEBPACK_IMPORTED_MODULE_7__["RotationGizmo"]; });

/* harmony import */ var _scaleGizmo__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./scaleGizmo */ "./Gizmos/scaleGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleGizmo", function() { return _scaleGizmo__WEBPACK_IMPORTED_MODULE_8__["ScaleGizmo"]; });

/* harmony import */ var _lightGizmo__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./lightGizmo */ "./Gizmos/lightGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightGizmo", function() { return _lightGizmo__WEBPACK_IMPORTED_MODULE_9__["LightGizmo"]; });

/* harmony import */ var _planeDragGizmo__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./planeDragGizmo */ "./Gizmos/planeDragGizmo.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneDragGizmo", function() { return _planeDragGizmo__WEBPACK_IMPORTED_MODULE_10__["PlaneDragGizmo"]; });














/***/ }),

/***/ "./Gizmos/lightGizmo.ts":
/*!******************************!*\
  !*** ./Gizmos/lightGizmo.ts ***!
  \******************************/
/*! exports provided: LightGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightGizmo", function() { return LightGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Lights/hemisphericLight */ "./Lights/hemisphericLight.ts");
/* harmony import */ var _Lights_directionalLight__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Lights/directionalLight */ "./Lights/directionalLight.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Meshes_Builders_hemisphereBuilder__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Meshes/Builders/hemisphereBuilder */ "./Meshes/Builders/hemisphereBuilder.ts");
/* harmony import */ var _Lights_spotLight__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Lights/spotLight */ "./Lights/spotLight.ts");












/**
 * Gizmo that enables viewing a light
 */
var LightGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightGizmo, _super);
    /**
     * Creates a LightGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     */
    function LightGizmo(gizmoLayer) {
        var _this = _super.call(this, gizmoLayer) || this;
        _this.cachedPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]();
        _this.cachedForward = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 0, 1);
        _this._light = null;
        _this.attachedMesh = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__["AbstractMesh"]("", _this.gizmoLayer.utilityLayerScene);
        _this._material = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_6__["StandardMaterial"]("light", _this.gizmoLayer.originalScene);
        _this._material.diffuseColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"](0.5, 0.5, 0.5);
        _this._material.specularColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"](0.1, 0.1, 0.1);
        return _this;
    }
    Object.defineProperty(LightGizmo.prototype, "light", {
        get: function () {
            return this._light;
        },
        /**
         * The light that the gizmo is attached to
         */
        set: function (light) {
            var _this = this;
            this._light = light;
            if (light) {
                // Create the mesh for the given light type
                if (this._lightMesh) {
                    this._lightMesh.dispose();
                }
                if (light instanceof _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_7__["HemisphericLight"]) {
                    this._lightMesh = LightGizmo._CreateHemisphericLightMesh(this.gizmoLayer.utilityLayerScene);
                }
                else if (light instanceof _Lights_directionalLight__WEBPACK_IMPORTED_MODULE_8__["DirectionalLight"]) {
                    this._lightMesh = LightGizmo._CreateDirectionalLightMesh(this.gizmoLayer.utilityLayerScene);
                }
                else if (light instanceof _Lights_spotLight__WEBPACK_IMPORTED_MODULE_11__["SpotLight"]) {
                    this._lightMesh = LightGizmo._CreateSpotLightMesh(this.gizmoLayer.utilityLayerScene);
                }
                else {
                    this._lightMesh = LightGizmo._CreatePointLightMesh(this.gizmoLayer.utilityLayerScene);
                }
                this._lightMesh.getChildMeshes(false).forEach(function (m) {
                    m.material = _this._material;
                });
                this._lightMesh.parent = this._rootMesh;
                // Add lighting to the light gizmo
                var gizmoLight = this.gizmoLayer._getSharedGizmoLight();
                gizmoLight.includedOnlyMeshes = gizmoLight.includedOnlyMeshes.concat(this._lightMesh.getChildMeshes(false));
                this._lightMesh.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]();
                if (!this.attachedMesh.reservedDataStore) {
                    this.attachedMesh.reservedDataStore = {};
                }
                this.attachedMesh.reservedDataStore.lightGizmo = this;
                // Get update position and direction if the light has it
                if (light.position) {
                    this.attachedMesh.position.copyFrom(light.position);
                }
                if (light.direction) {
                    this.attachedMesh.setDirection(light.direction);
                }
                this._update();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightGizmo.prototype, "material", {
        /**
         * Gets the material used to render the light gizmo
         */
        get: function () {
            return this._material;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * @hidden
     * Updates the gizmo to match the attached mesh's position/rotation
     */
    LightGizmo.prototype._update = function () {
        _super.prototype._update.call(this);
        if (!this._light) {
            return;
        }
        if (this._light.position) {
            // If the gizmo is moved update the light otherwise update the gizmo to match the light
            if (!this.attachedMesh.position.equals(this.cachedPosition)) {
                // update light to match gizmo
                this._light.position.copyFrom(this.attachedMesh.position);
                this.cachedPosition.copyFrom(this.attachedMesh.position);
            }
            else {
                // update gizmo to match light
                this.attachedMesh.position.copyFrom(this._light.position);
            }
        }
        if (this._light.direction) {
            // If the gizmo is moved update the light otherwise update the gizmo to match the light
            if (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].DistanceSquared(this.attachedMesh.forward, this.cachedForward) > 0.0001) {
                // update light to match gizmo
                this._light.direction.copyFrom(this.attachedMesh.forward);
                this.cachedForward.copyFrom(this.attachedMesh.forward);
            }
            else if (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].DistanceSquared(this.attachedMesh.forward, this._light.direction) > 0.0001) {
                // update gizmo to match light
                this.attachedMesh.setDirection(this._light.direction);
                this.cachedForward.copyFrom(this._lightMesh.forward);
            }
        }
        if (!this._light.isEnabled()) {
            this._material.diffuseColor.set(0, 0, 0);
        }
        else {
            this._material.diffuseColor.set(this._light.diffuse.r / 3, this._light.diffuse.g / 3, this._light.diffuse.b / 3);
        }
    };
    /**
     * Disposes of the light gizmo
     */
    LightGizmo.prototype.dispose = function () {
        this._material.dispose();
        _super.prototype.dispose.call(this);
    };
    LightGizmo._CreateHemisphericLightMesh = function (scene) {
        var root = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]("hemisphereLight", scene);
        var hemisphere = _Meshes_Builders_hemisphereBuilder__WEBPACK_IMPORTED_MODULE_10__["HemisphereBuilder"].CreateHemisphere(root.name, { segments: 10, diameter: 1 }, scene);
        hemisphere.position.z = -0.15;
        hemisphere.rotation.x = Math.PI / 2;
        hemisphere.parent = root;
        var lines = this._createLightLines(3, scene);
        lines.parent = root;
        lines.position.z - 0.15;
        root.scaling.scaleInPlace(LightGizmo._Scale);
        root.rotation.x = Math.PI / 2;
        return root;
    };
    LightGizmo._CreatePointLightMesh = function (scene) {
        var root = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]("pointLight", scene);
        var sphere = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_9__["SphereBuilder"].CreateSphere(root.name, { segments: 10, diameter: 1 }, scene);
        sphere.rotation.x = Math.PI / 2;
        sphere.parent = root;
        var lines = this._createLightLines(5, scene);
        lines.parent = root;
        root.scaling.scaleInPlace(LightGizmo._Scale);
        root.rotation.x = Math.PI / 2;
        return root;
    };
    LightGizmo._CreateSpotLightMesh = function (scene) {
        var root = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]("spotLight", scene);
        var sphere = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_9__["SphereBuilder"].CreateSphere(root.name, { segments: 10, diameter: 1 }, scene);
        sphere.parent = root;
        var hemisphere = _Meshes_Builders_hemisphereBuilder__WEBPACK_IMPORTED_MODULE_10__["HemisphereBuilder"].CreateHemisphere(root.name, { segments: 10, diameter: 2 }, scene);
        hemisphere.parent = root;
        hemisphere.rotation.x = -Math.PI / 2;
        var lines = this._createLightLines(2, scene);
        lines.parent = root;
        root.scaling.scaleInPlace(LightGizmo._Scale);
        root.rotation.x = Math.PI / 2;
        return root;
    };
    LightGizmo._CreateDirectionalLightMesh = function (scene) {
        var root = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]("directionalLight", scene);
        var mesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"](root.name, scene);
        mesh.parent = root;
        var sphere = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_9__["SphereBuilder"].CreateSphere(root.name, { diameter: 1.2, segments: 10 }, scene);
        sphere.parent = mesh;
        var line = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"].CreateCylinder(root.name, 6, 0.3, 0.3, 6, 1, scene);
        line.parent = mesh;
        var left = line.clone(root.name);
        left.scaling.y = 0.5;
        left.position.x += 1.25;
        var right = line.clone(root.name);
        right.scaling.y = 0.5;
        right.position.x += -1.25;
        var arrowHead = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"].CreateCylinder(root.name, 1, 0, 0.6, 6, 1, scene);
        arrowHead.position.y += 3;
        arrowHead.parent = mesh;
        var left = arrowHead.clone(root.name);
        left.position.y = 1.5;
        left.position.x += 1.25;
        var right = arrowHead.clone(root.name);
        right.position.y = 1.5;
        right.position.x += -1.25;
        mesh.scaling.scaleInPlace(LightGizmo._Scale);
        mesh.rotation.z = Math.PI / 2;
        mesh.rotation.y = Math.PI / 2;
        return root;
    };
    // Static helper methods
    LightGizmo._Scale = 0.007;
    /**
     * Creates the lines for a light mesh
     */
    LightGizmo._createLightLines = function (levels, scene) {
        var distFromSphere = 1.2;
        var root = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]("root", scene);
        root.rotation.x = Math.PI / 2;
        // Create the top line, this will be cloned for all other lines
        var linePivot = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]("linePivot", scene);
        linePivot.parent = root;
        var line = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"].CreateCylinder("line", 2, 0.2, 0.3, 6, 1, scene);
        line.position.y = line.scaling.y / 2 + distFromSphere;
        line.parent = linePivot;
        if (levels < 2) {
            return linePivot;
        }
        for (var i = 0; i < 4; i++) {
            var l = linePivot.clone("lineParentClone");
            l.rotation.z = Math.PI / 4;
            l.rotation.y = (Math.PI / 2) + (Math.PI / 2 * i);
            l.getChildMeshes()[0].scaling.y = 0.5;
            l.getChildMeshes()[0].scaling.x = l.getChildMeshes()[0].scaling.z = 0.8;
            l.getChildMeshes()[0].position.y = l.getChildMeshes()[0].scaling.y / 2 + distFromSphere;
        }
        if (levels < 3) {
            return root;
        }
        for (var i = 0; i < 4; i++) {
            var l = linePivot.clone("linePivotClone");
            l.rotation.z = Math.PI / 2;
            l.rotation.y = (Math.PI / 2 * i);
        }
        if (levels < 4) {
            return root;
        }
        for (var i = 0; i < 4; i++) {
            var l = linePivot.clone("linePivotClone");
            l.rotation.z = Math.PI + (Math.PI / 4);
            l.rotation.y = (Math.PI / 2) + (Math.PI / 2 * i);
            l.getChildMeshes()[0].scaling.y = 0.5;
            l.getChildMeshes()[0].scaling.x = l.getChildMeshes()[0].scaling.z = 0.8;
            l.getChildMeshes()[0].position.y = l.getChildMeshes()[0].scaling.y / 2 + distFromSphere;
        }
        if (levels < 5) {
            return root;
        }
        var l = linePivot.clone("linePivotClone");
        l.rotation.z = Math.PI;
        return root;
    };
    return LightGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_5__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/planeDragGizmo.ts":
/*!**********************************!*\
  !*** ./Gizmos/planeDragGizmo.ts ***!
  \**********************************/
/*! exports provided: PlaneDragGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaneDragGizmo", function() { return PlaneDragGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Meshes_Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/Builders/planeBuilder */ "./Meshes/Builders/planeBuilder.ts");
/* harmony import */ var _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Behaviors/Meshes/pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");










/**
 * Single plane drag gizmo
 */
var PlaneDragGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PlaneDragGizmo, _super);
    /**
     * Creates a PlaneDragGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     * @param dragPlaneNormal The axis normal to which the gizmo will be able to drag on
     * @param color The color of the gizmo
     */
    function PlaneDragGizmo(dragPlaneNormal, color, gizmoLayer, parent) {
        if (color === void 0) { color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].Gray(); }
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        if (parent === void 0) { parent = null; }
        var _this = _super.call(this, gizmoLayer) || this;
        _this._pointerObserver = null;
        /**
         * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)
         */
        _this.snapDistance = 0;
        /**
         * Event that fires each time the gizmo snaps to a new location.
         * * snapDistance is the the change in distance
         */
        _this.onSnapObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._isEnabled = false;
        _this._parent = null;
        _this._parent = parent;
        // Create Material
        _this._coloredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this._coloredMaterial.diffuseColor = color;
        _this._coloredMaterial.specularColor = color.subtract(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0.1, 0.1, 0.1));
        _this._hoverMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        _this._hoverMaterial.diffuseColor = color.add(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0.3, 0.3, 0.3));
        // Build plane mesh on root node
        _this._plane = PlaneDragGizmo._CreatePlane(gizmoLayer.utilityLayerScene, _this._coloredMaterial);
        _this._plane.lookAt(_this._rootMesh.position.add(dragPlaneNormal));
        _this._plane.scaling.scaleInPlace(1 / 3);
        _this._plane.parent = _this._rootMesh;
        var currentSnapDragDistance = 0;
        var tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var tmpSnapEvent = { snapDistance: 0 };
        // Add dragPlaneNormal drag behavior to handle events when the gizmo is dragged
        _this.dragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_6__["PointerDragBehavior"]({ dragPlaneNormal: dragPlaneNormal });
        _this.dragBehavior.moveAttached = false;
        _this._rootMesh.addBehavior(_this.dragBehavior);
        var localDelta = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        _this.dragBehavior.onDragObservable.add(function (event) {
            if (_this.attachedMesh) {
                // Convert delta to local translation if it has a parent
                if (_this.attachedMesh.parent) {
                    _this.attachedMesh.parent.computeWorldMatrix().invertToRef(tmpMatrix);
                    tmpMatrix.setTranslationFromFloats(0, 0, 0);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(event.delta, tmpMatrix, localDelta);
                }
                else {
                    localDelta.copyFrom(event.delta);
                }
                // Snapping logic
                if (_this.snapDistance == 0) {
                    _this.attachedMesh.position.addInPlace(localDelta);
                }
                else {
                    currentSnapDragDistance += event.dragDistance;
                    if (Math.abs(currentSnapDragDistance) > _this.snapDistance) {
                        var dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / _this.snapDistance);
                        currentSnapDragDistance = currentSnapDragDistance % _this.snapDistance;
                        localDelta.normalizeToRef(tmpVector);
                        tmpVector.scaleInPlace(_this.snapDistance * dragSteps);
                        _this.attachedMesh.position.addInPlace(tmpVector);
                        tmpSnapEvent.snapDistance = _this.snapDistance * dragSteps;
                        _this.onSnapObservable.notifyObservers(tmpSnapEvent);
                    }
                }
            }
        });
        _this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add(function (pointerInfo) {
            if (_this._customMeshSet) {
                return;
            }
            var isHovered = pointerInfo.pickInfo && (_this._rootMesh.getChildMeshes().indexOf(pointerInfo.pickInfo.pickedMesh) != -1);
            var material = isHovered ? _this._hoverMaterial : _this._coloredMaterial;
            _this._rootMesh.getChildMeshes().forEach(function (m) {
                m.material = material;
            });
        });
        var light = gizmoLayer._getSharedGizmoLight();
        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(_this._rootMesh.getChildMeshes(false));
        return _this;
    }
    /** @hidden */
    PlaneDragGizmo._CreatePlane = function (scene, material) {
        var plane = new _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_4__["TransformNode"]("plane", scene);
        //make sure plane is double sided
        var dragPlane = _Meshes_Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_5__["PlaneBuilder"].CreatePlane("dragPlane", { width: .1375, height: .1375, sideOrientation: 2 }, scene);
        dragPlane.material = material;
        dragPlane.parent = plane;
        // Position plane pointing normal to dragPlane normal
        dragPlane.material = material;
        return plane;
    };
    /** @hidden */
    PlaneDragGizmo._CreateArrowInstance = function (scene, arrow) {
        var instance = new _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_4__["TransformNode"]("arrow", scene);
        for (var _i = 0, _a = arrow.getChildMeshes(); _i < _a.length; _i++) {
            var mesh = _a[_i];
            var childInstance = mesh.createInstance(mesh.name);
            childInstance.parent = instance;
        }
        return instance;
    };
    PlaneDragGizmo.prototype._attachedMeshChanged = function (value) {
        if (this.dragBehavior) {
            this.dragBehavior.enabled = value ? true : false;
        }
    };
    Object.defineProperty(PlaneDragGizmo.prototype, "isEnabled", {
        get: function () {
            return this._isEnabled;
        },
        /**
         * If the gizmo is enabled
         */
        set: function (value) {
            this._isEnabled = value;
            if (!value) {
                this.attachedMesh = null;
            }
            else {
                if (this._parent) {
                    this.attachedMesh = this._parent.attachedMesh;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    PlaneDragGizmo.prototype.dispose = function () {
        this.onSnapObservable.clear();
        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
        this.dragBehavior.detach();
        _super.prototype.dispose.call(this);
        if (this._plane) {
            this._plane.dispose();
        }
        [this._coloredMaterial, this._hoverMaterial].forEach(function (matl) {
            if (matl) {
                matl.dispose();
            }
        });
    };
    return PlaneDragGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_7__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/planeRotationGizmo.ts":
/*!**************************************!*\
  !*** ./Gizmos/planeRotationGizmo.ts ***!
  \**************************************/
/*! exports provided: PlaneRotationGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaneRotationGizmo", function() { return PlaneRotationGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Behaviors/Meshes/pointerDragBehavior */ "./Behaviors/Meshes/pointerDragBehavior.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Meshes/Builders/linesBuilder */ "./Meshes/Builders/linesBuilder.ts");











/**
 * Single plane rotation gizmo
 */
var PlaneRotationGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PlaneRotationGizmo, _super);
    /**
     * Creates a PlaneRotationGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     * @param planeNormal The normal of the plane which the gizmo will be able to rotate on
     * @param color The color of the gizmo
     * @param tessellation Amount of tessellation to be used when creating rotation circles
     * @param useEulerRotation Use and update Euler angle instead of quaternion
     */
    function PlaneRotationGizmo(planeNormal, color, gizmoLayer, tessellation, parent, useEulerRotation) {
        if (color === void 0) { color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].Gray(); }
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        if (tessellation === void 0) { tessellation = 32; }
        if (parent === void 0) { parent = null; }
        if (useEulerRotation === void 0) { useEulerRotation = false; }
        var _this = _super.call(this, gizmoLayer) || this;
        _this._pointerObserver = null;
        /**
         * Rotation distance in radians that the gizmo will snap to (Default: 0)
         */
        _this.snapDistance = 0;
        /**
         * Event that fires each time the gizmo snaps to a new location.
         * * snapDistance is the the change in distance
         */
        _this.onSnapObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._isEnabled = true;
        _this._parent = null;
        _this._parent = parent;
        // Create Material
        var coloredMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        coloredMaterial.diffuseColor = color;
        coloredMaterial.specularColor = color.subtract(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0.1, 0.1, 0.1));
        var hoverMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__["StandardMaterial"]("", gizmoLayer.utilityLayerScene);
        hoverMaterial.diffuseColor = color.add(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0.3, 0.3, 0.3));
        // Build mesh on root node
        var parentMesh = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__["AbstractMesh"]("", gizmoLayer.utilityLayerScene);
        var drag = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].CreateTorus("", 0.6, 0.03, tessellation, gizmoLayer.utilityLayerScene);
        drag.visibility = 0;
        var rotationMesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].CreateTorus("", 0.6, 0.005, tessellation, gizmoLayer.utilityLayerScene);
        rotationMesh.material = coloredMaterial;
        // Position arrow pointing in its drag axis
        rotationMesh.rotation.x = Math.PI / 2;
        drag.rotation.x = Math.PI / 2;
        parentMesh.addChild(rotationMesh);
        parentMesh.addChild(drag);
        parentMesh.lookAt(_this._rootMesh.position.add(planeNormal));
        _this._rootMesh.addChild(parentMesh);
        parentMesh.scaling.scaleInPlace(1 / 3);
        // Add drag behavior to handle events when the gizmo is dragged
        _this.dragBehavior = new _Behaviors_Meshes_pointerDragBehavior__WEBPACK_IMPORTED_MODULE_6__["PointerDragBehavior"]({ dragPlaneNormal: planeNormal });
        _this.dragBehavior.moveAttached = false;
        _this.dragBehavior.maxDragAngle = Math.PI * 9 / 20;
        _this.dragBehavior._useAlternatePickedPointAboveMaxDragAngle = true;
        _this._rootMesh.addBehavior(_this.dragBehavior);
        var lastDragPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        _this.dragBehavior.onDragStartObservable.add(function (e) {
            if (_this.attachedMesh) {
                lastDragPosition.copyFrom(e.dragPlanePoint);
            }
        });
        var rotationMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        var planeNormalTowardsCamera = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var localPlaneNormalTowardsCamera = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var tmpSnapEvent = { snapDistance: 0 };
        var currentSnapDragDistance = 0;
        var tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        var tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"]();
        var amountToRotate = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        _this.dragBehavior.onDragObservable.add(function (event) {
            if (_this.attachedMesh) {
                if (!_this.attachedMesh.rotationQuaternion || useEulerRotation) {
                    _this.attachedMesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].RotationYawPitchRoll(_this.attachedMesh.rotation.y, _this.attachedMesh.rotation.x, _this.attachedMesh.rotation.z);
                }
                // Remove parent priort to rotating
                var attachedMeshParent = _this.attachedMesh.parent;
                if (attachedMeshParent) {
                    _this.attachedMesh.setParent(null);
                }
                // Calc angle over full 360 degree (https://stackoverflow.com/questions/43493711/the-angle-between-two-3d-vectors-with-a-result-range-0-360)
                var newVector = event.dragPlanePoint.subtract(_this.attachedMesh.absolutePosition).normalize();
                var originalVector = lastDragPosition.subtract(_this.attachedMesh.absolutePosition).normalize();
                var cross = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Cross(newVector, originalVector);
                var dot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Dot(newVector, originalVector);
                var angle = Math.atan2(cross.length(), dot);
                planeNormalTowardsCamera.copyFrom(planeNormal);
                localPlaneNormalTowardsCamera.copyFrom(planeNormal);
                if (_this.updateGizmoRotationToMatchAttachedMesh) {
                    _this.attachedMesh.rotationQuaternion.toRotationMatrix(rotationMatrix);
                    localPlaneNormalTowardsCamera = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinates(planeNormalTowardsCamera, rotationMatrix);
                }
                // Flip up vector depending on which side the camera is on
                if (gizmoLayer.utilityLayerScene.activeCamera) {
                    var camVec = gizmoLayer.utilityLayerScene.activeCamera.position.subtract(_this.attachedMesh.position);
                    if (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Dot(camVec, localPlaneNormalTowardsCamera) > 0) {
                        planeNormalTowardsCamera.scaleInPlace(-1);
                        localPlaneNormalTowardsCamera.scaleInPlace(-1);
                    }
                }
                var halfCircleSide = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Dot(localPlaneNormalTowardsCamera, cross) > 0.0;
                if (halfCircleSide) {
                    angle = -angle;
                }
                // Snapping logic
                var snapped = false;
                if (_this.snapDistance != 0) {
                    currentSnapDragDistance += angle;
                    if (Math.abs(currentSnapDragDistance) > _this.snapDistance) {
                        var dragSteps = Math.floor(Math.abs(currentSnapDragDistance) / _this.snapDistance);
                        if (currentSnapDragDistance < 0) {
                            dragSteps *= -1;
                        }
                        currentSnapDragDistance = currentSnapDragDistance % _this.snapDistance;
                        angle = _this.snapDistance * dragSteps;
                        snapped = true;
                    }
                    else {
                        angle = 0;
                    }
                }
                // If the mesh has a parent, convert needed world rotation to local rotation
                tmpMatrix.reset();
                if (_this.attachedMesh.parent) {
                    _this.attachedMesh.parent.computeWorldMatrix().invertToRef(tmpMatrix);
                    tmpMatrix.getRotationMatrixToRef(tmpMatrix);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(planeNormalTowardsCamera, tmpMatrix, planeNormalTowardsCamera);
                }
                // Convert angle and axis to quaternion (http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm)
                var quaternionCoefficient = Math.sin(angle / 2);
                amountToRotate.set(planeNormalTowardsCamera.x * quaternionCoefficient, planeNormalTowardsCamera.y * quaternionCoefficient, planeNormalTowardsCamera.z * quaternionCoefficient, Math.cos(angle / 2));
                // If the meshes local scale is inverted (eg. loaded gltf file parent with z scale of -1) the rotation needs to be inverted on the y axis
                if (tmpMatrix.determinant() > 0) {
                    amountToRotate.toEulerAnglesToRef(tmpVector);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].RotationYawPitchRollToRef(tmpVector.y, -tmpVector.x, -tmpVector.z, amountToRotate);
                }
                if (_this.updateGizmoRotationToMatchAttachedMesh) {
                    // Rotate selected mesh quaternion over fixed axis
                    _this.attachedMesh.rotationQuaternion.multiplyToRef(amountToRotate, _this.attachedMesh.rotationQuaternion);
                }
                else {
                    // Rotate selected mesh quaternion over rotated axis
                    amountToRotate.multiplyToRef(_this.attachedMesh.rotationQuaternion, _this.attachedMesh.rotationQuaternion);
                }
                if (useEulerRotation) {
                    _this.attachedMesh.rotationQuaternion.toEulerAnglesToRef(tmpVector);
                    _this.attachedMesh.rotationQuaternion = null;
                    _this.attachedMesh.rotation.copyFrom(tmpVector);
                }
                lastDragPosition.copyFrom(event.dragPlanePoint);
                if (snapped) {
                    tmpSnapEvent.snapDistance = angle;
                    _this.onSnapObservable.notifyObservers(tmpSnapEvent);
                }
                // Restore parent
                if (attachedMeshParent) {
                    _this.attachedMesh.setParent(attachedMeshParent);
                }
            }
        });
        _this._pointerObserver = gizmoLayer.utilityLayerScene.onPointerObservable.add(function (pointerInfo) {
            if (_this._customMeshSet) {
                return;
            }
            var isHovered = pointerInfo.pickInfo && (_this._rootMesh.getChildMeshes().indexOf(pointerInfo.pickInfo.pickedMesh) != -1);
            var material = isHovered ? hoverMaterial : coloredMaterial;
            _this._rootMesh.getChildMeshes().forEach(function (m) {
                m.material = material;
                if (m.color) {
                    m.color = material.diffuseColor;
                }
            });
        });
        var light = gizmoLayer._getSharedGizmoLight();
        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(_this._rootMesh.getChildMeshes(false));
        return _this;
    }
    PlaneRotationGizmo.prototype._attachedMeshChanged = function (value) {
        if (this.dragBehavior) {
            this.dragBehavior.enabled = value ? true : false;
        }
    };
    Object.defineProperty(PlaneRotationGizmo.prototype, "isEnabled", {
        get: function () {
            return this._isEnabled;
        },
        /**
             * If the gizmo is enabled
             */
        set: function (value) {
            this._isEnabled = value;
            if (!value) {
                this.attachedMesh = null;
            }
            else {
                if (this._parent) {
                    this.attachedMesh = this._parent.attachedMesh;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    PlaneRotationGizmo.prototype.dispose = function () {
        this.onSnapObservable.clear();
        this.gizmoLayer.utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
        this.dragBehavior.detach();
        _super.prototype.dispose.call(this);
    };
    return PlaneRotationGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_7__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/positionGizmo.ts":
/*!*********************************!*\
  !*** ./Gizmos/positionGizmo.ts ***!
  \*********************************/
/*! exports provided: PositionGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PositionGizmo", function() { return PositionGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _axisDragGizmo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./axisDragGizmo */ "./Gizmos/axisDragGizmo.ts");
/* harmony import */ var _planeDragGizmo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./planeDragGizmo */ "./Gizmos/planeDragGizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");









/**
 * Gizmo that enables dragging a mesh along 3 axis
 */
var PositionGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PositionGizmo, _super);
    /**
     * Creates a PositionGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     */
    function PositionGizmo(gizmoLayer) {
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        var _this = _super.call(this, gizmoLayer) || this;
        /**
         * private variables
         */
        _this._meshAttached = null;
        /** Fires an event when any of it's sub gizmos are dragged */
        _this.onDragStartObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /** Fires an event when any of it's sub gizmos are released from dragging */
        _this.onDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * If set to true, planar drag is enabled
         */
        _this._planarGizmoEnabled = false;
        _this.xGizmo = new _axisDragGizmo__WEBPACK_IMPORTED_MODULE_6__["AxisDragGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 0, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Red().scale(0.5), gizmoLayer, _this);
        _this.yGizmo = new _axisDragGizmo__WEBPACK_IMPORTED_MODULE_6__["AxisDragGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 1, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Green().scale(0.5), gizmoLayer, _this);
        _this.zGizmo = new _axisDragGizmo__WEBPACK_IMPORTED_MODULE_6__["AxisDragGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 1), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Blue().scale(0.5), gizmoLayer, _this);
        _this.xPlaneGizmo = new _planeDragGizmo__WEBPACK_IMPORTED_MODULE_7__["PlaneDragGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 0, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Red().scale(0.5), _this.gizmoLayer, _this);
        _this.yPlaneGizmo = new _planeDragGizmo__WEBPACK_IMPORTED_MODULE_7__["PlaneDragGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 1, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Green().scale(0.5), _this.gizmoLayer, _this);
        _this.zPlaneGizmo = new _planeDragGizmo__WEBPACK_IMPORTED_MODULE_7__["PlaneDragGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 1), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Blue().scale(0.5), _this.gizmoLayer, _this);
        // Relay drag events
        [_this.xGizmo, _this.yGizmo, _this.zGizmo, _this.xPlaneGizmo, _this.yPlaneGizmo, _this.zPlaneGizmo].forEach(function (gizmo) {
            gizmo.dragBehavior.onDragStartObservable.add(function () {
                _this.onDragStartObservable.notifyObservers({});
            });
            gizmo.dragBehavior.onDragEndObservable.add(function () {
                _this.onDragEndObservable.notifyObservers({});
            });
        });
        _this.attachedMesh = null;
        return _this;
    }
    Object.defineProperty(PositionGizmo.prototype, "attachedMesh", {
        get: function () {
            return this._meshAttached;
        },
        set: function (mesh) {
            this._meshAttached = mesh;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo].forEach(function (gizmo) {
                if (gizmo.isEnabled) {
                    gizmo.attachedMesh = mesh;
                }
                else {
                    gizmo.attachedMesh = null;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PositionGizmo.prototype, "planarGizmoEnabled", {
        get: function () {
            return this._planarGizmoEnabled;
        },
        /**
         * If the planar drag gizmo is enabled
         * setting this will enable/disable XY, XZ and YZ planes regardless of individual gizmo settings.
         */
        set: function (value) {
            var _this = this;
            this._planarGizmoEnabled = value;
            [this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo].forEach(function (gizmo) {
                if (gizmo) {
                    gizmo.isEnabled = value;
                    if (value) {
                        gizmo.attachedMesh = _this.attachedMesh;
                    }
                }
            }, this);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PositionGizmo.prototype, "updateGizmoRotationToMatchAttachedMesh", {
        get: function () {
            return this._updateGizmoRotationToMatchAttachedMesh;
        },
        set: function (value) {
            this._updateGizmoRotationToMatchAttachedMesh = value;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo].forEach(function (gizmo) {
                if (gizmo) {
                    gizmo.updateGizmoRotationToMatchAttachedMesh = value;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PositionGizmo.prototype, "snapDistance", {
        get: function () {
            return this._snapDistance;
        },
        /**
         * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)
         */
        set: function (value) {
            this._snapDistance = value;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo].forEach(function (gizmo) {
                if (gizmo) {
                    gizmo.snapDistance = value;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PositionGizmo.prototype, "scaleRatio", {
        get: function () {
            return this._scaleRatio;
        },
        /**
         * Ratio for the scale of the gizmo (Default: 1)
         */
        set: function (value) {
            this._scaleRatio = value;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo].forEach(function (gizmo) {
                if (gizmo) {
                    gizmo.scaleRatio = value;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    PositionGizmo.prototype.dispose = function () {
        [this.xGizmo, this.yGizmo, this.zGizmo, this.xPlaneGizmo, this.yPlaneGizmo, this.zPlaneGizmo].forEach(function (gizmo) {
            if (gizmo) {
                gizmo.dispose();
            }
        });
        this.onDragStartObservable.clear();
        this.onDragEndObservable.clear();
    };
    /**
     * CustomMeshes are not supported by this gizmo
     * @param mesh The mesh to replace the default mesh of the gizmo
     */
    PositionGizmo.prototype.setCustomMesh = function (mesh) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Custom meshes are not supported on this gizmo, please set the custom meshes on the gizmos contained within this one (gizmo.xGizmo, gizmo.yGizmo, gizmo.zGizmo,gizmo.xPlaneGizmo, gizmo.yPlaneGizmo, gizmo.zPlaneGizmo)");
    };
    return PositionGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_5__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/rotationGizmo.ts":
/*!*********************************!*\
  !*** ./Gizmos/rotationGizmo.ts ***!
  \*********************************/
/*! exports provided: RotationGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RotationGizmo", function() { return RotationGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _planeRotationGizmo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./planeRotationGizmo */ "./Gizmos/planeRotationGizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");








/**
 * Gizmo that enables rotating a mesh along 3 axis
 */
var RotationGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RotationGizmo, _super);
    /**
     * Creates a RotationGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     * @param tessellation Amount of tessellation to be used when creating rotation circles
     * @param useEulerRotation Use and update Euler angle instead of quaternion
     */
    function RotationGizmo(gizmoLayer, tessellation, useEulerRotation) {
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_7__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        if (tessellation === void 0) { tessellation = 32; }
        if (useEulerRotation === void 0) { useEulerRotation = false; }
        var _this = _super.call(this, gizmoLayer) || this;
        /** Fires an event when any of it's sub gizmos are dragged */
        _this.onDragStartObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /** Fires an event when any of it's sub gizmos are released from dragging */
        _this.onDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this.xGizmo = new _planeRotationGizmo__WEBPACK_IMPORTED_MODULE_6__["PlaneRotationGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 0, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Red().scale(0.5), gizmoLayer, tessellation, _this, useEulerRotation);
        _this.yGizmo = new _planeRotationGizmo__WEBPACK_IMPORTED_MODULE_6__["PlaneRotationGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 1, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Green().scale(0.5), gizmoLayer, tessellation, _this, useEulerRotation);
        _this.zGizmo = new _planeRotationGizmo__WEBPACK_IMPORTED_MODULE_6__["PlaneRotationGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 1), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Blue().scale(0.5), gizmoLayer, tessellation, _this, useEulerRotation);
        // Relay drag events
        [_this.xGizmo, _this.yGizmo, _this.zGizmo].forEach(function (gizmo) {
            gizmo.dragBehavior.onDragStartObservable.add(function () {
                _this.onDragStartObservable.notifyObservers({});
            });
            gizmo.dragBehavior.onDragEndObservable.add(function () {
                _this.onDragEndObservable.notifyObservers({});
            });
        });
        _this.attachedMesh = null;
        return _this;
    }
    Object.defineProperty(RotationGizmo.prototype, "attachedMesh", {
        get: function () {
            return this._meshAttached;
        },
        set: function (mesh) {
            this._meshAttached = mesh;
            [this.xGizmo, this.yGizmo, this.zGizmo].forEach(function (gizmo) {
                if (gizmo.isEnabled) {
                    gizmo.attachedMesh = mesh;
                }
                else {
                    gizmo.attachedMesh = null;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RotationGizmo.prototype, "updateGizmoRotationToMatchAttachedMesh", {
        get: function () {
            return this.xGizmo.updateGizmoRotationToMatchAttachedMesh;
        },
        set: function (value) {
            if (this.xGizmo) {
                this.xGizmo.updateGizmoRotationToMatchAttachedMesh = value;
                this.yGizmo.updateGizmoRotationToMatchAttachedMesh = value;
                this.zGizmo.updateGizmoRotationToMatchAttachedMesh = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RotationGizmo.prototype, "snapDistance", {
        get: function () {
            return this.xGizmo.snapDistance;
        },
        /**
         * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)
         */
        set: function (value) {
            if (this.xGizmo) {
                this.xGizmo.snapDistance = value;
                this.yGizmo.snapDistance = value;
                this.zGizmo.snapDistance = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RotationGizmo.prototype, "scaleRatio", {
        get: function () {
            return this.xGizmo.scaleRatio;
        },
        /**
         * Ratio for the scale of the gizmo (Default: 1)
         */
        set: function (value) {
            if (this.xGizmo) {
                this.xGizmo.scaleRatio = value;
                this.yGizmo.scaleRatio = value;
                this.zGizmo.scaleRatio = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    RotationGizmo.prototype.dispose = function () {
        this.xGizmo.dispose();
        this.yGizmo.dispose();
        this.zGizmo.dispose();
        this.onDragStartObservable.clear();
        this.onDragEndObservable.clear();
    };
    /**
     * CustomMeshes are not supported by this gizmo
     * @param mesh The mesh to replace the default mesh of the gizmo
     */
    RotationGizmo.prototype.setCustomMesh = function (mesh) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Custom meshes are not supported on this gizmo, please set the custom meshes on the gizmos contained within this one (gizmo.xGizmo, gizmo.yGizmo, gizmo.zGizmo)");
    };
    return RotationGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_5__["Gizmo"]));



/***/ }),

/***/ "./Gizmos/scaleGizmo.ts":
/*!******************************!*\
  !*** ./Gizmos/scaleGizmo.ts ***!
  \******************************/
/*! exports provided: ScaleGizmo */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScaleGizmo", function() { return ScaleGizmo; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_Builders_polyhedronBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/Builders/polyhedronBuilder */ "./Meshes/Builders/polyhedronBuilder.ts");
/* harmony import */ var _gizmo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./gizmo */ "./Gizmos/gizmo.ts");
/* harmony import */ var _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./axisScaleGizmo */ "./Gizmos/axisScaleGizmo.ts");
/* harmony import */ var _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Rendering/utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");









/**
 * Gizmo that enables scaling a mesh along 3 axis
 */
var ScaleGizmo = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ScaleGizmo, _super);
    /**
     * Creates a ScaleGizmo
     * @param gizmoLayer The utility layer the gizmo will be added to
     */
    function ScaleGizmo(gizmoLayer) {
        if (gizmoLayer === void 0) { gizmoLayer = _Rendering_utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_8__["UtilityLayerRenderer"].DefaultUtilityLayer; }
        var _this = _super.call(this, gizmoLayer) || this;
        _this._meshAttached = null;
        /** Fires an event when any of it's sub gizmos are dragged */
        _this.onDragStartObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /** Fires an event when any of it's sub gizmos are released from dragging */
        _this.onDragEndObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this.xGizmo = new _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_7__["AxisScaleGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 0, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Red().scale(0.5), gizmoLayer, _this);
        _this.yGizmo = new _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_7__["AxisScaleGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 1, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Green().scale(0.5), gizmoLayer, _this);
        _this.zGizmo = new _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_7__["AxisScaleGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 1), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Blue().scale(0.5), gizmoLayer, _this);
        // Create uniform scale gizmo
        _this.uniformScaleGizmo = new _axisScaleGizmo__WEBPACK_IMPORTED_MODULE_7__["AxisScaleGizmo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 1, 0), _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"].Yellow().scale(0.5), gizmoLayer, _this);
        _this.uniformScaleGizmo.updateGizmoRotationToMatchAttachedMesh = false;
        _this.uniformScaleGizmo.uniformScaling = true;
        _this._uniformScalingMesh = _Meshes_Builders_polyhedronBuilder__WEBPACK_IMPORTED_MODULE_5__["PolyhedronBuilder"].CreatePolyhedron("", { type: 1 }, _this.uniformScaleGizmo.gizmoLayer.utilityLayerScene);
        _this._uniformScalingMesh.scaling.scaleInPlace(0.02);
        _this._uniformScalingMesh.visibility = 0;
        _this._octahedron = _Meshes_Builders_polyhedronBuilder__WEBPACK_IMPORTED_MODULE_5__["PolyhedronBuilder"].CreatePolyhedron("", { type: 1 }, _this.uniformScaleGizmo.gizmoLayer.utilityLayerScene);
        _this._octahedron.scaling.scaleInPlace(0.007);
        _this._uniformScalingMesh.addChild(_this._octahedron);
        _this.uniformScaleGizmo.setCustomMesh(_this._uniformScalingMesh, true);
        var light = gizmoLayer._getSharedGizmoLight();
        light.includedOnlyMeshes = light.includedOnlyMeshes.concat(_this._octahedron);
        // Relay drag events
        [_this.xGizmo, _this.yGizmo, _this.zGizmo, _this.uniformScaleGizmo].forEach(function (gizmo) {
            gizmo.dragBehavior.onDragStartObservable.add(function () {
                _this.onDragStartObservable.notifyObservers({});
            });
            gizmo.dragBehavior.onDragEndObservable.add(function () {
                _this.onDragEndObservable.notifyObservers({});
            });
        });
        _this.attachedMesh = null;
        return _this;
    }
    Object.defineProperty(ScaleGizmo.prototype, "attachedMesh", {
        get: function () {
            return this._meshAttached;
        },
        set: function (mesh) {
            this._meshAttached = mesh;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach(function (gizmo) {
                if (gizmo.isEnabled) {
                    gizmo.attachedMesh = mesh;
                }
                else {
                    gizmo.attachedMesh = null;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ScaleGizmo.prototype, "updateGizmoRotationToMatchAttachedMesh", {
        get: function () {
            return this._updateGizmoRotationToMatchAttachedMesh;
        },
        set: function (value) {
            if (!value) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Setting updateGizmoRotationToMatchAttachedMesh = false on scaling gizmo is not supported.");
            }
            else {
                this._updateGizmoRotationToMatchAttachedMesh = value;
                [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach(function (gizmo) {
                    if (gizmo) {
                        gizmo.updateGizmoRotationToMatchAttachedMesh = value;
                    }
                });
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ScaleGizmo.prototype, "snapDistance", {
        get: function () {
            return this._snapDistance;
        },
        /**
         * Drag distance in babylon units that the gizmo will snap to when dragged (Default: 0)
         */
        set: function (value) {
            this._snapDistance = value;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach(function (gizmo) {
                if (gizmo) {
                    gizmo.snapDistance = value;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ScaleGizmo.prototype, "scaleRatio", {
        get: function () {
            return this._scaleRatio;
        },
        /**
         * Ratio for the scale of the gizmo (Default: 1)
         */
        set: function (value) {
            this._scaleRatio = value;
            [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach(function (gizmo) {
                if (gizmo) {
                    gizmo.scaleRatio = value;
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes of the gizmo
     */
    ScaleGizmo.prototype.dispose = function () {
        [this.xGizmo, this.yGizmo, this.zGizmo, this.uniformScaleGizmo].forEach(function (gizmo) {
            if (gizmo) {
                gizmo.dispose();
            }
        });
        this.onDragStartObservable.clear();
        this.onDragEndObservable.clear();
        [this._uniformScalingMesh, this._octahedron].forEach(function (msh) {
            if (msh) {
                msh.dispose();
            }
        });
    };
    return ScaleGizmo;
}(_gizmo__WEBPACK_IMPORTED_MODULE_6__["Gizmo"]));



/***/ }),

/***/ "./Helpers/environmentHelper.ts":
/*!**************************************!*\
  !*** ./Helpers/environmentHelper.ts ***!
  \**************************************/
/*! exports provided: EnvironmentHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EnvironmentHelper", function() { return EnvironmentHelper; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Cameras/arcRotateCamera */ "./Cameras/arcRotateCamera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_mirrorTexture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/Textures/mirrorTexture */ "./Materials/Textures/mirrorTexture.ts");
/* harmony import */ var _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/Textures/cubeTexture */ "./Materials/Textures/cubeTexture.ts");
/* harmony import */ var _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Materials/Background/backgroundMaterial */ "./Materials/Background/backgroundMaterial.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Meshes_Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Meshes/Builders/planeBuilder */ "./Meshes/Builders/planeBuilder.ts");
/* harmony import */ var _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Meshes/Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Maths_math_plane__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Maths/math.plane */ "./Maths/math.plane.ts");















/**
 * The Environment helper class can be used to add a fully featuread none expensive background to your scene.
 * It includes by default a skybox and a ground relying on the BackgroundMaterial.
 * It also helps with the default setup of your imageProcessing configuration.
 */
var EnvironmentHelper = /** @class */ (function () {
    /**
     * constructor
     * @param options Defines the options we want to customize the helper
     * @param scene The scene to add the material to
     */
    function EnvironmentHelper(options, scene) {
        var _this = this;
        this._errorHandler = function (message, exception) {
            _this.onErrorObservable.notifyObservers({ message: message, exception: exception });
        };
        this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, EnvironmentHelper._getDefaultOptions(), options);
        this._scene = scene;
        this.onErrorObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._setupBackground();
        this._setupImageProcessing();
    }
    /**
     * Creates the default options for the helper.
     */
    EnvironmentHelper._getDefaultOptions = function () {
        return {
            createGround: true,
            groundSize: 15,
            groundTexture: this._groundTextureCDNUrl,
            groundColor: new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"](0.2, 0.2, 0.3).toLinearSpace().scale(3),
            groundOpacity: 0.9,
            enableGroundShadow: true,
            groundShadowLevel: 0.5,
            enableGroundMirror: false,
            groundMirrorSizeRatio: 0.3,
            groundMirrorBlurKernel: 64,
            groundMirrorAmount: 1,
            groundMirrorFresnelWeight: 1,
            groundMirrorFallOffDistance: 0,
            groundMirrorTextureType: _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT,
            groundYBias: 0.00001,
            createSkybox: true,
            skyboxSize: 20,
            skyboxTexture: this._skyboxTextureCDNUrl,
            skyboxColor: new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color3"](0.2, 0.2, 0.3).toLinearSpace().scale(3),
            backgroundYRotation: 0,
            sizeAuto: true,
            rootPosition: _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(),
            setupImageProcessing: true,
            environmentTexture: this._environmentTextureCDNUrl,
            cameraExposure: 0.8,
            cameraContrast: 1.2,
            toneMappingEnabled: true,
        };
    };
    Object.defineProperty(EnvironmentHelper.prototype, "rootMesh", {
        /**
         * Gets the root mesh created by the helper.
         */
        get: function () {
            return this._rootMesh;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "skybox", {
        /**
         * Gets the skybox created by the helper.
         */
        get: function () {
            return this._skybox;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "skyboxTexture", {
        /**
         * Gets the skybox texture created by the helper.
         */
        get: function () {
            return this._skyboxTexture;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "skyboxMaterial", {
        /**
         * Gets the skybox material created by the helper.
         */
        get: function () {
            return this._skyboxMaterial;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "ground", {
        /**
         * Gets the ground mesh created by the helper.
         */
        get: function () {
            return this._ground;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "groundTexture", {
        /**
         * Gets the ground texture created by the helper.
         */
        get: function () {
            return this._groundTexture;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "groundMirror", {
        /**
         * Gets the ground mirror created by the helper.
         */
        get: function () {
            return this._groundMirror;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "groundMirrorRenderList", {
        /**
         * Gets the ground mirror render list to helps pushing the meshes
         * you wish in the ground reflection.
         */
        get: function () {
            if (this._groundMirror) {
                return this._groundMirror.renderList;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EnvironmentHelper.prototype, "groundMaterial", {
        /**
         * Gets the ground material created by the helper.
         */
        get: function () {
            return this._groundMaterial;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Updates the background according to the new options
     * @param options
     */
    EnvironmentHelper.prototype.updateOptions = function (options) {
        var newOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, this._options, options);
        if (this._ground && !newOptions.createGround) {
            this._ground.dispose();
            this._ground = null;
        }
        if (this._groundMaterial && !newOptions.createGround) {
            this._groundMaterial.dispose();
            this._groundMaterial = null;
        }
        if (this._groundTexture) {
            if (this._options.groundTexture != newOptions.groundTexture) {
                this._groundTexture.dispose();
                this._groundTexture = null;
            }
        }
        if (this._skybox && !newOptions.createSkybox) {
            this._skybox.dispose();
            this._skybox = null;
        }
        if (this._skyboxMaterial && !newOptions.createSkybox) {
            this._skyboxMaterial.dispose();
            this._skyboxMaterial = null;
        }
        if (this._skyboxTexture) {
            if (this._options.skyboxTexture != newOptions.skyboxTexture) {
                this._skyboxTexture.dispose();
                this._skyboxTexture = null;
            }
        }
        if (this._groundMirror && !newOptions.enableGroundMirror) {
            this._groundMirror.dispose();
            this._groundMirror = null;
        }
        if (this._scene.environmentTexture) {
            if (this._options.environmentTexture != newOptions.environmentTexture) {
                this._scene.environmentTexture.dispose();
            }
        }
        this._options = newOptions;
        this._setupBackground();
        this._setupImageProcessing();
    };
    /**
     * Sets the primary color of all the available elements.
     * @param color the main color to affect to the ground and the background
     */
    EnvironmentHelper.prototype.setMainColor = function (color) {
        if (this.groundMaterial) {
            this.groundMaterial.primaryColor = color;
        }
        if (this.skyboxMaterial) {
            this.skyboxMaterial.primaryColor = color;
        }
        if (this.groundMirror) {
            this.groundMirror.clearColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](color.r, color.g, color.b, 1.0);
        }
    };
    /**
     * Setup the image processing according to the specified options.
     */
    EnvironmentHelper.prototype._setupImageProcessing = function () {
        if (this._options.setupImageProcessing) {
            this._scene.imageProcessingConfiguration.contrast = this._options.cameraContrast;
            this._scene.imageProcessingConfiguration.exposure = this._options.cameraExposure;
            this._scene.imageProcessingConfiguration.toneMappingEnabled = this._options.toneMappingEnabled;
            this._setupEnvironmentTexture();
        }
    };
    /**
     * Setup the environment texture according to the specified options.
     */
    EnvironmentHelper.prototype._setupEnvironmentTexture = function () {
        if (this._scene.environmentTexture) {
            return;
        }
        if (this._options.environmentTexture instanceof _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_6__["BaseTexture"]) {
            this._scene.environmentTexture = this._options.environmentTexture;
            return;
        }
        var environmentTexture = _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__["CubeTexture"].CreateFromPrefilteredData(this._options.environmentTexture, this._scene);
        this._scene.environmentTexture = environmentTexture;
    };
    /**
     * Setup the background according to the specified options.
     */
    EnvironmentHelper.prototype._setupBackground = function () {
        if (!this._rootMesh) {
            this._rootMesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"]("BackgroundHelper", this._scene);
        }
        this._rootMesh.rotation.y = this._options.backgroundYRotation;
        var sceneSize = this._getSceneSize();
        if (this._options.createGround) {
            this._setupGround(sceneSize);
            this._setupGroundMaterial();
            this._setupGroundDiffuseTexture();
            if (this._options.enableGroundMirror) {
                this._setupGroundMirrorTexture(sceneSize);
            }
            this._setupMirrorInGroundMaterial();
        }
        if (this._options.createSkybox) {
            this._setupSkybox(sceneSize);
            this._setupSkyboxMaterial();
            this._setupSkyboxReflectionTexture();
        }
        this._rootMesh.position.x = sceneSize.rootPosition.x;
        this._rootMesh.position.z = sceneSize.rootPosition.z;
        this._rootMesh.position.y = sceneSize.rootPosition.y;
    };
    /**
     * Get the scene sizes according to the setup.
     */
    EnvironmentHelper.prototype._getSceneSize = function () {
        var _this = this;
        var groundSize = this._options.groundSize;
        var skyboxSize = this._options.skyboxSize;
        var rootPosition = this._options.rootPosition;
        if (!this._scene.meshes || this._scene.meshes.length === 1) { // 1 only means the root of the helper.
            return { groundSize: groundSize, skyboxSize: skyboxSize, rootPosition: rootPosition };
        }
        var sceneExtends = this._scene.getWorldExtends(function (mesh) {
            return (mesh !== _this._ground && mesh !== _this._rootMesh && mesh !== _this._skybox);
        });
        var sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);
        if (this._options.sizeAuto) {
            if (this._scene.activeCamera instanceof _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_2__["ArcRotateCamera"] &&
                this._scene.activeCamera.upperRadiusLimit) {
                groundSize = this._scene.activeCamera.upperRadiusLimit * 2;
                skyboxSize = groundSize;
            }
            var sceneDiagonalLenght = sceneDiagonal.length();
            if (sceneDiagonalLenght > groundSize) {
                groundSize = sceneDiagonalLenght * 2;
                skyboxSize = groundSize;
            }
            // 10 % bigger.
            groundSize *= 1.1;
            skyboxSize *= 1.5;
            rootPosition = sceneExtends.min.add(sceneDiagonal.scale(0.5));
            rootPosition.y = sceneExtends.min.y - this._options.groundYBias;
        }
        return { groundSize: groundSize, skyboxSize: skyboxSize, rootPosition: rootPosition };
    };
    /**
     * Setup the ground according to the specified options.
     */
    EnvironmentHelper.prototype._setupGround = function (sceneSize) {
        var _this = this;
        if (!this._ground || this._ground.isDisposed()) {
            this._ground = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].CreatePlane("BackgroundPlane", sceneSize.groundSize, this._scene);
            this._ground.rotation.x = Math.PI / 2; // Face up by default.
            this._ground.parent = this._rootMesh;
            this._ground.onDisposeObservable.add(function () { _this._ground = null; });
        }
        this._ground.receiveShadows = this._options.enableGroundShadow;
    };
    /**
     * Setup the ground material according to the specified options.
     */
    EnvironmentHelper.prototype._setupGroundMaterial = function () {
        if (!this._groundMaterial) {
            this._groundMaterial = new _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_10__["BackgroundMaterial"]("BackgroundPlaneMaterial", this._scene);
        }
        this._groundMaterial.alpha = this._options.groundOpacity;
        this._groundMaterial.alphaMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].ALPHA_PREMULTIPLIED_PORTERDUFF;
        this._groundMaterial.shadowLevel = this._options.groundShadowLevel;
        this._groundMaterial.primaryColor = this._options.groundColor;
        this._groundMaterial.useRGBColor = false;
        this._groundMaterial.enableNoise = true;
        if (this._ground) {
            this._ground.material = this._groundMaterial;
        }
    };
    /**
     * Setup the ground diffuse texture according to the specified options.
     */
    EnvironmentHelper.prototype._setupGroundDiffuseTexture = function () {
        if (!this._groundMaterial) {
            return;
        }
        if (this._groundTexture) {
            return;
        }
        if (this._options.groundTexture instanceof _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_6__["BaseTexture"]) {
            this._groundMaterial.diffuseTexture = this._options.groundTexture;
            return;
        }
        var diffuseTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"](this._options.groundTexture, this._scene, undefined, undefined, undefined, undefined, this._errorHandler);
        diffuseTexture.gammaSpace = false;
        diffuseTexture.hasAlpha = true;
        this._groundMaterial.diffuseTexture = diffuseTexture;
    };
    /**
     * Setup the ground mirror texture according to the specified options.
     */
    EnvironmentHelper.prototype._setupGroundMirrorTexture = function (sceneSize) {
        var wrapping = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].CLAMP_ADDRESSMODE;
        if (!this._groundMirror) {
            this._groundMirror = new _Materials_Textures_mirrorTexture__WEBPACK_IMPORTED_MODULE_8__["MirrorTexture"]("BackgroundPlaneMirrorTexture", { ratio: this._options.groundMirrorSizeRatio }, this._scene, false, this._options.groundMirrorTextureType, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE, true);
            this._groundMirror.mirrorPlane = new _Maths_math_plane__WEBPACK_IMPORTED_MODULE_14__["Plane"](0, -1, 0, sceneSize.rootPosition.y);
            this._groundMirror.anisotropicFilteringLevel = 1;
            this._groundMirror.wrapU = wrapping;
            this._groundMirror.wrapV = wrapping;
            this._groundMirror.gammaSpace = false;
            if (this._groundMirror.renderList) {
                for (var i = 0; i < this._scene.meshes.length; i++) {
                    var mesh = this._scene.meshes[i];
                    if (mesh !== this._ground &&
                        mesh !== this._skybox &&
                        mesh !== this._rootMesh) {
                        this._groundMirror.renderList.push(mesh);
                    }
                }
            }
        }
        this._groundMirror.clearColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](this._options.groundColor.r, this._options.groundColor.g, this._options.groundColor.b, 1);
        this._groundMirror.adaptiveBlurKernel = this._options.groundMirrorBlurKernel;
    };
    /**
     * Setup the ground to receive the mirror texture.
     */
    EnvironmentHelper.prototype._setupMirrorInGroundMaterial = function () {
        if (this._groundMaterial) {
            this._groundMaterial.reflectionTexture = this._groundMirror;
            this._groundMaterial.reflectionFresnel = true;
            this._groundMaterial.reflectionAmount = this._options.groundMirrorAmount;
            this._groundMaterial.reflectionStandardFresnelWeight = this._options.groundMirrorFresnelWeight;
            this._groundMaterial.reflectionFalloffDistance = this._options.groundMirrorFallOffDistance;
        }
    };
    /**
     * Setup the skybox according to the specified options.
     */
    EnvironmentHelper.prototype._setupSkybox = function (sceneSize) {
        var _this = this;
        if (!this._skybox || this._skybox.isDisposed()) {
            this._skybox = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].CreateBox("BackgroundSkybox", sceneSize.skyboxSize, this._scene, undefined, _Meshes_mesh__WEBPACK_IMPORTED_MODULE_5__["Mesh"].BACKSIDE);
            this._skybox.onDisposeObservable.add(function () { _this._skybox = null; });
        }
        this._skybox.parent = this._rootMesh;
    };
    /**
     * Setup the skybox material according to the specified options.
     */
    EnvironmentHelper.prototype._setupSkyboxMaterial = function () {
        if (!this._skybox) {
            return;
        }
        if (!this._skyboxMaterial) {
            this._skyboxMaterial = new _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_10__["BackgroundMaterial"]("BackgroundSkyboxMaterial", this._scene);
        }
        this._skyboxMaterial.useRGBColor = false;
        this._skyboxMaterial.primaryColor = this._options.skyboxColor;
        this._skyboxMaterial.enableNoise = true;
        this._skybox.material = this._skyboxMaterial;
    };
    /**
     * Setup the skybox reflection texture according to the specified options.
     */
    EnvironmentHelper.prototype._setupSkyboxReflectionTexture = function () {
        if (!this._skyboxMaterial) {
            return;
        }
        if (this._skyboxTexture) {
            return;
        }
        if (this._options.skyboxTexture instanceof _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_6__["BaseTexture"]) {
            this._skyboxMaterial.reflectionTexture = this._options.skyboxTexture;
            return;
        }
        this._skyboxTexture = new _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__["CubeTexture"](this._options.skyboxTexture, this._scene, undefined, undefined, undefined, undefined, this._errorHandler);
        this._skyboxTexture.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].SKYBOX_MODE;
        this._skyboxTexture.gammaSpace = false;
        this._skyboxMaterial.reflectionTexture = this._skyboxTexture;
    };
    /**
     * Dispose all the elements created by the Helper.
     */
    EnvironmentHelper.prototype.dispose = function () {
        if (this._groundMaterial) {
            this._groundMaterial.dispose(true, true);
        }
        if (this._skyboxMaterial) {
            this._skyboxMaterial.dispose(true, true);
        }
        this._rootMesh.dispose(false);
    };
    /**
     * Default ground texture URL.
     */
    EnvironmentHelper._groundTextureCDNUrl = "https://assets.babylonjs.com/environments/backgroundGround.png";
    /**
     * Default skybox texture URL.
     */
    EnvironmentHelper._skyboxTextureCDNUrl = "https://assets.babylonjs.com/environments/backgroundSkybox.dds";
    /**
     * Default environment texture URL.
     */
    EnvironmentHelper._environmentTextureCDNUrl = "https://assets.babylonjs.com/environments/environmentSpecular.env";
    return EnvironmentHelper;
}());



/***/ }),

/***/ "./Helpers/index.ts":
/*!**************************!*\
  !*** ./Helpers/index.ts ***!
  \**************************/
/*! exports provided: EnvironmentHelper, PhotoDome, _forceSceneHelpersToBundle, VideoDome */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _environmentHelper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./environmentHelper */ "./Helpers/environmentHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EnvironmentHelper", function() { return _environmentHelper__WEBPACK_IMPORTED_MODULE_0__["EnvironmentHelper"]; });

/* harmony import */ var _photoDome__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./photoDome */ "./Helpers/photoDome.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhotoDome", function() { return _photoDome__WEBPACK_IMPORTED_MODULE_1__["PhotoDome"]; });

/* harmony import */ var _sceneHelpers__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sceneHelpers */ "./Helpers/sceneHelpers.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceSceneHelpersToBundle", function() { return _sceneHelpers__WEBPACK_IMPORTED_MODULE_2__["_forceSceneHelpersToBundle"]; });

/* harmony import */ var _videoDome__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./videoDome */ "./Helpers/videoDome.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoDome", function() { return _videoDome__WEBPACK_IMPORTED_MODULE_3__["VideoDome"]; });







/***/ }),

/***/ "./Helpers/photoDome.ts":
/*!******************************!*\
  !*** ./Helpers/photoDome.ts ***!
  \******************************/
/*! exports provided: PhotoDome */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhotoDome", function() { return PhotoDome; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Background/backgroundMaterial */ "./Materials/Background/backgroundMaterial.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");








/**
 * Display a 360 degree photo on an approximately spherical surface, useful for VR applications or skyboxes.
 * As a subclass of TransformNode, this allow parenting to the camera with different locations in the scene.
 * This class achieves its effect with a Texture and a correctly configured BackgroundMaterial on an inverted sphere.
 * Potential additions to this helper include zoom and and non-infinite distance rendering effects.
 */
var PhotoDome = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PhotoDome, _super);
    /**
     * Create an instance of this class and pass through the parameters to the relevant classes, Texture, StandardMaterial, and Mesh.
     * @param name Element's name, child elements will append suffixes for their own names.
     * @param urlsOfPhoto defines the url of the photo to display
     * @param options defines an object containing optional or exposed sub element properties
     * @param onError defines a callback called when an error occured while loading the texture
     */
    function PhotoDome(name, urlOfPhoto, options, scene, onError) {
        if (onError === void 0) { onError = null; }
        var _this = _super.call(this, name, scene) || this;
        _this._useDirectMapping = false;
        /**
         * Observable raised when an error occured while loading the 360 image
         */
        _this.onLoadErrorObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._imageMode = PhotoDome.MODE_MONOSCOPIC;
        _this._onBeforeCameraRenderObserver = null;
        // set defaults and manage values
        name = name || "photoDome";
        options.resolution = (Math.abs(options.resolution) | 0) || 32;
        options.size = Math.abs(options.size) || (scene.activeCamera ? scene.activeCamera.maxZ * 0.48 : 1000);
        if (options.useDirectMapping === undefined) {
            _this._useDirectMapping = true;
        }
        else {
            _this._useDirectMapping = options.useDirectMapping;
        }
        if (options.faceForward === undefined) {
            options.faceForward = true;
        }
        _this._setReady(false);
        // create
        var material = _this._material = new _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_5__["BackgroundMaterial"](name + "_material", scene);
        _this._mesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"].CreateSphere(name + "_mesh", options.resolution, options.size, scene, false, _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"].BACKSIDE);
        // configure material
        material.opacityFresnel = false;
        material.useEquirectangularFOV = true;
        material.fovMultiplier = 1.0;
        _this.photoTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"](urlOfPhoto, scene, true, !_this._useDirectMapping, undefined, undefined, function (message, exception) {
            _this.onLoadErrorObservable.notifyObservers(message || "Unknown error occured");
            if (onError) {
                onError(message, exception);
            }
        });
        _this.photoTexture.onLoadObservable.addOnce(function () {
            _this._setReady(true);
        });
        // configure mesh
        _this._mesh.material = material;
        _this._mesh.parent = _this;
        // Initial rotation
        if (options.faceForward && scene.activeCamera) {
            var camera = scene.activeCamera;
            var forward = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].Forward();
            var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].TransformNormal(forward, camera.getViewMatrix());
            direction.normalize();
            _this.rotation.y = Math.acos(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].Dot(forward, direction));
        }
        return _this;
    }
    Object.defineProperty(PhotoDome.prototype, "photoTexture", {
        /**
         * Gets or sets the texture being displayed on the sphere
         */
        get: function () {
            return this._photoTexture;
        },
        set: function (value) {
            if (this._photoTexture === value) {
                return;
            }
            this._photoTexture = value;
            if (this._useDirectMapping) {
                this._photoTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
                this._photoTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
                this._material.diffuseTexture = this._photoTexture;
            }
            else {
                this._photoTexture.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].FIXED_EQUIRECTANGULAR_MIRRORED_MODE; // matches orientation
                this._photoTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
                this._material.reflectionTexture = this._photoTexture;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhotoDome.prototype, "fovMultiplier", {
        /**
         * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values "zoom in" and higher values "zoom out".
         * Also see the options.resolution property.
         */
        get: function () {
            return this._material.fovMultiplier;
        },
        set: function (value) {
            this._material.fovMultiplier = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhotoDome.prototype, "imageMode", {
        /**
         * Gets or set the current video mode for the video. It can be:
         * * PhotoDome.MODE_MONOSCOPIC : Define the image as a Monoscopic panoramic 360 image.
         * * PhotoDome.MODE_TOPBOTTOM  : Define the image as a Stereoscopic TopBottom/OverUnder panoramic 360 image.
         * * PhotoDome.MODE_SIDEBYSIDE : Define the image as a Stereoscopic Side by Side panoramic 360 image.
         */
        get: function () {
            return this._imageMode;
        },
        set: function (value) {
            if (this._imageMode === value) {
                return;
            }
            this._changeImageMode(value);
        },
        enumerable: true,
        configurable: true
    });
    PhotoDome.prototype._changeImageMode = function (value) {
        var _this = this;
        this._scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
        this._imageMode = value;
        // Default Setup and Reset.
        this._photoTexture.uScale = 1;
        this._photoTexture.vScale = 1;
        this._photoTexture.uOffset = 0;
        this._photoTexture.vOffset = 0;
        switch (value) {
            case PhotoDome.MODE_SIDEBYSIDE:
                this._photoTexture.uScale = 0.5;
                this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add(function (camera) {
                    _this._photoTexture.uOffset = camera.isRightCamera ? 0.5 : 0.0;
                });
                break;
            case PhotoDome.MODE_TOPBOTTOM:
                this._photoTexture.vScale = 0.5;
                this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add(function (camera) {
                    _this._photoTexture.vOffset = camera.isRightCamera ? 0.5 : 0.0;
                });
                break;
        }
    };
    /**
     * Releases resources associated with this node.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    PhotoDome.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        this._photoTexture.dispose();
        this._mesh.dispose();
        this._material.dispose();
        this.onLoadErrorObservable.clear();
        this._scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    /**
     * Define the image as a Monoscopic panoramic 360 image.
     */
    PhotoDome.MODE_MONOSCOPIC = 0;
    /**
     * Define the image as a Stereoscopic TopBottom/OverUnder panoramic 360 image.
     */
    PhotoDome.MODE_TOPBOTTOM = 1;
    /**
     * Define the image as a Stereoscopic Side by Side panoramic 360 image.
     */
    PhotoDome.MODE_SIDEBYSIDE = 2;
    return PhotoDome;
}(_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_2__["TransformNode"]));



/***/ }),

/***/ "./Helpers/sceneHelpers.ts":
/*!*********************************!*\
  !*** ./Helpers/sceneHelpers.ts ***!
  \*********************************/
/*! exports provided: _forceSceneHelpersToBundle */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_forceSceneHelpersToBundle", function() { return _forceSceneHelpersToBundle; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/PBR/pbrMaterial */ "./Materials/PBR/pbrMaterial.ts");
/* harmony import */ var _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Lights/hemisphericLight */ "./Lights/hemisphericLight.ts");
/* harmony import */ var _environmentHelper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./environmentHelper */ "./Helpers/environmentHelper.ts");
/* harmony import */ var _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Cameras/freeCamera */ "./Cameras/freeCamera.ts");
/* harmony import */ var _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Cameras/arcRotateCamera */ "./Cameras/arcRotateCamera.ts");
/* harmony import */ var _Cameras_VR_vrExperienceHelper__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Cameras/VR/vrExperienceHelper */ "./Cameras/VR/vrExperienceHelper.ts");
/* harmony import */ var _Materials_Textures_Loaders_ddsTextureLoader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Materials/Textures/Loaders/ddsTextureLoader */ "./Materials/Textures/Loaders/ddsTextureLoader.ts");
/* harmony import */ var _Materials_Textures_Loaders_envTextureLoader__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Materials/Textures/Loaders/envTextureLoader */ "./Materials/Textures/Loaders/envTextureLoader.ts");
/* harmony import */ var _Materials_Textures_Loaders_ktxTextureLoader__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Materials/Textures/Loaders/ktxTextureLoader */ "./Materials/Textures/Loaders/ktxTextureLoader.ts");
/* harmony import */ var _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Meshes/Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Cameras_XR_webXRDefaultExperience__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Cameras/XR/webXRDefaultExperience */ "./Cameras/XR/webXRDefaultExperience.ts");

















/** @hidden */
var _forceSceneHelpersToBundle = true;
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultLight = function (replace) {
    if (replace === void 0) { replace = false; }
    // Dispose existing light in replace mode.
    if (replace) {
        if (this.lights) {
            for (var i = 0; i < this.lights.length; i++) {
                this.lights[i].dispose();
            }
        }
    }
    // Light
    if (this.lights.length === 0) {
        new _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_7__["HemisphericLight"]("default light", _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Up(), this);
    }
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultCamera = function (createArcRotateCamera, replace, attachCameraControls) {
    if (createArcRotateCamera === void 0) { createArcRotateCamera = false; }
    if (replace === void 0) { replace = false; }
    if (attachCameraControls === void 0) { attachCameraControls = false; }
    // Dispose existing camera in replace mode.
    if (replace) {
        if (this.activeCamera) {
            this.activeCamera.dispose();
            this.activeCamera = null;
        }
    }
    // Camera
    if (!this.activeCamera) {
        var worldExtends = this.getWorldExtends();
        var worldSize = worldExtends.max.subtract(worldExtends.min);
        var worldCenter = worldExtends.min.add(worldSize.scale(0.5));
        var camera;
        var radius = worldSize.length() * 1.5;
        // empty scene scenario!
        if (!isFinite(radius)) {
            radius = 1;
            worldCenter.copyFromFloats(0, 0, 0);
        }
        if (createArcRotateCamera) {
            var arcRotateCamera = new _Cameras_arcRotateCamera__WEBPACK_IMPORTED_MODULE_10__["ArcRotateCamera"]("default camera", -(Math.PI / 2), Math.PI / 2, radius, worldCenter, this);
            arcRotateCamera.lowerRadiusLimit = radius * 0.01;
            arcRotateCamera.wheelPrecision = 100 / radius;
            camera = arcRotateCamera;
        }
        else {
            var freeCamera = new _Cameras_freeCamera__WEBPACK_IMPORTED_MODULE_9__["FreeCamera"]("default camera", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](worldCenter.x, worldCenter.y, -radius), this);
            freeCamera.setTarget(worldCenter);
            camera = freeCamera;
        }
        camera.minZ = radius * 0.01;
        camera.maxZ = radius * 1000;
        camera.speed = radius * 0.2;
        this.activeCamera = camera;
        var canvas = this.getEngine().getRenderingCanvas();
        if (attachCameraControls && canvas) {
            camera.attachControl(canvas);
        }
    }
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultCameraOrLight = function (createArcRotateCamera, replace, attachCameraControls) {
    if (createArcRotateCamera === void 0) { createArcRotateCamera = false; }
    if (replace === void 0) { replace = false; }
    if (attachCameraControls === void 0) { attachCameraControls = false; }
    this.createDefaultLight(replace);
    this.createDefaultCamera(createArcRotateCamera, replace, attachCameraControls);
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultSkybox = function (environmentTexture, pbr, scale, blur, setGlobalEnvTexture) {
    if (pbr === void 0) { pbr = false; }
    if (scale === void 0) { scale = 1000; }
    if (blur === void 0) { blur = 0; }
    if (setGlobalEnvTexture === void 0) { setGlobalEnvTexture = true; }
    if (!environmentTexture) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Can not create default skybox without environment texture.");
        return null;
    }
    if (setGlobalEnvTexture) {
        if (environmentTexture) {
            this.environmentTexture = environmentTexture;
        }
    }
    // Skybox
    var hdrSkybox = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"].CreateBox("hdrSkyBox", scale, this);
    if (pbr) {
        var hdrSkyboxMaterial = new _Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_6__["PBRMaterial"]("skyBox", this);
        hdrSkyboxMaterial.backFaceCulling = false;
        hdrSkyboxMaterial.reflectionTexture = environmentTexture.clone();
        if (hdrSkyboxMaterial.reflectionTexture) {
            hdrSkyboxMaterial.reflectionTexture.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].SKYBOX_MODE;
        }
        hdrSkyboxMaterial.microSurface = 1.0 - blur;
        hdrSkyboxMaterial.disableLighting = true;
        hdrSkyboxMaterial.twoSidedLighting = true;
        hdrSkybox.infiniteDistance = true;
        hdrSkybox.material = hdrSkyboxMaterial;
    }
    else {
        var skyboxMaterial = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_5__["StandardMaterial"]("skyBox", this);
        skyboxMaterial.backFaceCulling = false;
        skyboxMaterial.reflectionTexture = environmentTexture.clone();
        if (skyboxMaterial.reflectionTexture) {
            skyboxMaterial.reflectionTexture.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].SKYBOX_MODE;
        }
        skyboxMaterial.disableLighting = true;
        hdrSkybox.infiniteDistance = true;
        hdrSkybox.material = skyboxMaterial;
    }
    hdrSkybox.isPickable = false;
    return hdrSkybox;
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultEnvironment = function (options) {
    if (_environmentHelper__WEBPACK_IMPORTED_MODULE_8__["EnvironmentHelper"]) {
        return new _environmentHelper__WEBPACK_IMPORTED_MODULE_8__["EnvironmentHelper"](options, this);
    }
    return null;
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultVRExperience = function (webVROptions) {
    if (webVROptions === void 0) { webVROptions = {}; }
    return new _Cameras_VR_vrExperienceHelper__WEBPACK_IMPORTED_MODULE_11__["VRExperienceHelper"](this, webVROptions);
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.createDefaultXRExperienceAsync = function (options) {
    return _Cameras_XR_webXRDefaultExperience__WEBPACK_IMPORTED_MODULE_16__["WebXRDefaultExperience"].CreateAsync(this, options).then(function (helper) {
        return helper;
    });
};


/***/ }),

/***/ "./Helpers/videoDome.ts":
/*!******************************!*\
  !*** ./Helpers/videoDome.ts ***!
  \******************************/
/*! exports provided: VideoDome */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VideoDome", function() { return VideoDome; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_videoTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/videoTexture */ "./Materials/Textures/videoTexture.ts");
/* harmony import */ var _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Background/backgroundMaterial */ "./Materials/Background/backgroundMaterial.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Maths/math */ "./Maths/math.ts");










/**
 * Display a 360/180 degree video on an approximately spherical surface, useful for VR applications or skyboxes.
 * As a subclass of TransformNode, this allow parenting to the camera or multiple videos with different locations in the scene.
 * This class achieves its effect with a VideoTexture and a correctly configured BackgroundMaterial on an inverted sphere.
 * Potential additions to this helper include zoom and and non-infinite distance rendering effects.
 */
var VideoDome = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VideoDome, _super);
    /**
     * Create an instance of this class and pass through the parameters to the relevant classes, VideoTexture, StandardMaterial, and Mesh.
     * @param name Element's name, child elements will append suffixes for their own names.
     * @param urlsOrVideo defines the url(s) or the video element to use
     * @param options An object containing optional or exposed sub element properties
     */
    function VideoDome(name, urlsOrVideo, options, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._halfDome = false;
        _this._useDirectMapping = false;
        _this._videoMode = VideoDome.MODE_MONOSCOPIC;
        /**
         * Oberserver used in Stereoscopic VR Mode.
         */
        _this._onBeforeCameraRenderObserver = null;
        scene = _this.getScene();
        // set defaults and manage values
        name = name || "videoDome";
        options.resolution = (Math.abs(options.resolution) | 0) || 32;
        options.clickToPlay = Boolean(options.clickToPlay);
        options.autoPlay = options.autoPlay === undefined ? true : Boolean(options.autoPlay);
        options.loop = options.loop === undefined ? true : Boolean(options.loop);
        options.size = Math.abs(options.size) || (scene.activeCamera ? scene.activeCamera.maxZ * 0.48 : 1000);
        if (options.useDirectMapping === undefined) {
            _this._useDirectMapping = true;
        }
        else {
            _this._useDirectMapping = options.useDirectMapping;
        }
        if (options.faceForward === undefined) {
            options.faceForward = true;
        }
        _this._setReady(false);
        // create
        var tempOptions = { loop: options.loop, autoPlay: options.autoPlay, autoUpdateTexture: true, poster: options.poster };
        var material = _this._material = new _Materials_Background_backgroundMaterial__WEBPACK_IMPORTED_MODULE_5__["BackgroundMaterial"](name + "_material", scene);
        var texture = _this._videoTexture = new _Materials_Textures_videoTexture__WEBPACK_IMPORTED_MODULE_4__["VideoTexture"](name + "_texture", urlsOrVideo, scene, false, _this._useDirectMapping, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].TRILINEAR_SAMPLINGMODE, tempOptions);
        _this._mesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreateSphere(name + "_mesh", options.resolution, options.size, scene, false, _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].BACKSIDE);
        texture.onLoadObservable.addOnce(function () {
            _this._setReady(true);
        });
        // configure material
        material.useEquirectangularFOV = true;
        material.fovMultiplier = 1.0;
        material.opacityFresnel = false;
        if (_this._useDirectMapping) {
            texture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].CLAMP_ADDRESSMODE;
            texture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].CLAMP_ADDRESSMODE;
            material.diffuseTexture = texture;
        }
        else {
            texture.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].FIXED_EQUIRECTANGULAR_MIRRORED_MODE; // matches orientation
            texture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].CLAMP_ADDRESSMODE;
            material.reflectionTexture = texture;
        }
        // configure mesh
        _this._mesh.material = material;
        _this._mesh.parent = _this;
        // create a (disabled until needed) mask to cover unneeded segments of 180 videos.
        _this._halfDomeMask = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_6__["SphereBuilder"].CreateSphere("", { slice: 0.5, diameter: options.size * 0.99, segments: options.resolution, sideOrientation: _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].BACKSIDE }, scene);
        _this._halfDomeMask.rotate(_Maths_math__WEBPACK_IMPORTED_MODULE_8__["Axis"].X, -Math.PI / 2);
        // set the parent, so it will always be positioned correctly AND will be disposed when the main sphere is disposed
        _this._halfDomeMask.parent = _this._mesh;
        _this._halfDome = !!options.halfDomeMode;
        // enable or disable according to the settings
        _this._halfDomeMask.setEnabled(_this._halfDome);
        // optional configuration
        if (options.clickToPlay) {
            scene.onPointerUp = function () {
                _this._videoTexture.video.play();
            };
        }
        // Initial rotation
        if (options.faceForward && scene.activeCamera) {
            var camera = scene.activeCamera;
            var forward = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].Forward();
            var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].TransformNormal(forward, camera.getViewMatrix());
            direction.normalize();
            _this.rotation.y = Math.acos(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].Dot(forward, direction));
        }
        return _this;
    }
    Object.defineProperty(VideoDome.prototype, "videoTexture", {
        /**
         * Gets the video texture being displayed on the sphere
         */
        get: function () {
            return this._videoTexture;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VideoDome.prototype, "fovMultiplier", {
        /**
         * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values "zoom in" and higher values "zoom out".
         * Also see the options.resolution property.
         */
        get: function () {
            return this._material.fovMultiplier;
        },
        set: function (value) {
            this._material.fovMultiplier = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VideoDome.prototype, "videoMode", {
        /**
         * Gets or set the current video mode for the video. It can be:
         * * VideoDome.MODE_MONOSCOPIC : Define the video source as a Monoscopic panoramic 360 video.
         * * VideoDome.MODE_TOPBOTTOM  : Define the video source as a Stereoscopic TopBottom/OverUnder panoramic 360 video.
         * * VideoDome.MODE_SIDEBYSIDE : Define the video source as a Stereoscopic Side by Side panoramic 360 video.
         */
        get: function () {
            return this._videoMode;
        },
        set: function (value) {
            if (this._videoMode === value) {
                return;
            }
            this._changeVideoMode(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VideoDome.prototype, "halfDome", {
        /**
         * Is the video a 180 degrees video (half dome) or 360 video (full dome)
         *
         */
        get: function () {
            return this._halfDome;
        },
        /**
         * Set the halfDome mode. If set, only the front (180 degrees) will be displayed and the back will be blacked out.
         */
        set: function (enabled) {
            this._halfDome = enabled;
            this._halfDomeMask.setEnabled(enabled);
        },
        enumerable: true,
        configurable: true
    });
    VideoDome.prototype._changeVideoMode = function (value) {
        var _this = this;
        this._scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
        this._videoMode = value;
        // Default Setup and Reset.
        this._videoTexture.uScale = 1;
        this._videoTexture.vScale = 1;
        this._videoTexture.uOffset = 0;
        this._videoTexture.vOffset = 0;
        switch (value) {
            case VideoDome.MODE_SIDEBYSIDE:
                // in half-dome mode the uScale should be double of 360 videos
                // Use 0.99999 to boost perf by not switching program
                this._videoTexture.uScale = this._halfDome ? 0.99999 : 0.5;
                var rightOffset_1 = this._halfDome ? 0.0 : 0.5;
                var leftOffset_1 = this._halfDome ? 0.5 : 0.0;
                this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add(function (camera) {
                    _this._videoTexture.uOffset = camera.isRightCamera ? rightOffset_1 : leftOffset_1;
                });
                break;
            case VideoDome.MODE_TOPBOTTOM:
                // in half-dome mode the vScale should be double of 360 videos
                // Use 0.99999 to boost perf by not switching program
                this._videoTexture.vScale = this._halfDome ? 0.99999 : 0.5;
                this._onBeforeCameraRenderObserver = this._scene.onBeforeCameraRenderObservable.add(function (camera) {
                    _this._videoTexture.vOffset = camera.isRightCamera ? 0.5 : 0.0;
                });
                break;
        }
    };
    /**
     * Releases resources associated with this node.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    VideoDome.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        this._videoTexture.dispose();
        this._mesh.dispose();
        this._material.dispose();
        this._scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    /**
     * Define the video source as a Monoscopic panoramic 360 video.
     */
    VideoDome.MODE_MONOSCOPIC = 0;
    /**
     * Define the video source as a Stereoscopic TopBottom/OverUnder panoramic 360 video.
     */
    VideoDome.MODE_TOPBOTTOM = 1;
    /**
     * Define the video source as a Stereoscopic Side by Side panoramic 360 video.
     */
    VideoDome.MODE_SIDEBYSIDE = 2;
    return VideoDome;
}(_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]));



/***/ }),

/***/ "./Inputs/scene.inputManager.ts":
/*!**************************************!*\
  !*** ./Inputs/scene.inputManager.ts ***!
  \**************************************/
/*! exports provided: InputManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputManager", function() { return InputManager; });
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Actions_abstractActionManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Actions/abstractActionManager */ "./Actions/abstractActionManager.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Actions/actionEvent */ "./Actions/actionEvent.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Events/keyboardEvents */ "./Events/keyboardEvents.ts");







/** @hidden */
var _ClickInfo = /** @class */ (function () {
    function _ClickInfo() {
        this._singleClick = false;
        this._doubleClick = false;
        this._hasSwiped = false;
        this._ignore = false;
    }
    Object.defineProperty(_ClickInfo.prototype, "singleClick", {
        get: function () {
            return this._singleClick;
        },
        set: function (b) {
            this._singleClick = b;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_ClickInfo.prototype, "doubleClick", {
        get: function () {
            return this._doubleClick;
        },
        set: function (b) {
            this._doubleClick = b;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_ClickInfo.prototype, "hasSwiped", {
        get: function () {
            return this._hasSwiped;
        },
        set: function (b) {
            this._hasSwiped = b;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_ClickInfo.prototype, "ignore", {
        get: function () {
            return this._ignore;
        },
        set: function (b) {
            this._ignore = b;
        },
        enumerable: true,
        configurable: true
    });
    return _ClickInfo;
}());
/**
 * Class used to manage all inputs for the scene.
 */
var InputManager = /** @class */ (function () {
    /**
     * Creates a new InputManager
     * @param scene defines the hosting scene
     */
    function InputManager(scene) {
        // Pointers
        this._wheelEventName = "";
        this._meshPickProceed = false;
        this._currentPickResult = null;
        this._previousPickResult = null;
        this._totalPointersPressed = 0;
        this._doubleClickOccured = false;
        this._pointerX = 0;
        this._pointerY = 0;
        this._startingPointerPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](0, 0);
        this._previousStartingPointerPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](0, 0);
        this._startingPointerTime = 0;
        this._previousStartingPointerTime = 0;
        this._pointerCaptures = {};
        this._scene = scene;
    }
    Object.defineProperty(InputManager.prototype, "meshUnderPointer", {
        /**
        * Gets the mesh that is currently under the pointer
        */
        get: function () {
            return this._pointerOverMesh;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputManager.prototype, "unTranslatedPointer", {
        /**
         * Gets the pointer coordinates in 2D without any translation (ie. straight out of the pointer event)
         */
        get: function () {
            return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](this._unTranslatedPointerX, this._unTranslatedPointerY);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputManager.prototype, "pointerX", {
        /**
         * Gets or sets the current on-screen X position of the pointer
         */
        get: function () {
            return this._pointerX;
        },
        set: function (value) {
            this._pointerX = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputManager.prototype, "pointerY", {
        /**
         * Gets or sets the current on-screen Y position of the pointer
         */
        get: function () {
            return this._pointerY;
        },
        set: function (value) {
            this._pointerY = value;
        },
        enumerable: true,
        configurable: true
    });
    InputManager.prototype._updatePointerPosition = function (evt) {
        var canvasRect = this._scene.getEngine().getRenderingCanvasClientRect();
        if (!canvasRect) {
            return;
        }
        this._pointerX = evt.clientX - canvasRect.left;
        this._pointerY = evt.clientY - canvasRect.top;
        this._unTranslatedPointerX = this._pointerX;
        this._unTranslatedPointerY = this._pointerY;
    };
    InputManager.prototype._processPointerMove = function (pickResult, evt) {
        var scene = this._scene;
        var canvas = scene.getEngine().getRenderingCanvas();
        if (!canvas) {
            return;
        }
        canvas.tabIndex = 1;
        // Restore pointer
        canvas.style.cursor = scene.defaultCursor;
        var isMeshPicked = (pickResult && pickResult.hit && pickResult.pickedMesh) ? true : false;
        if (isMeshPicked) {
            scene.setPointerOverMesh(pickResult.pickedMesh);
            if (this._pointerOverMesh && this._pointerOverMesh.actionManager && this._pointerOverMesh.actionManager.hasPointerTriggers) {
                if (this._pointerOverMesh.actionManager.hoverCursor) {
                    canvas.style.cursor = this._pointerOverMesh.actionManager.hoverCursor;
                }
                else {
                    canvas.style.cursor = scene.hoverCursor;
                }
            }
        }
        else {
            scene.setPointerOverMesh(null);
        }
        for (var _i = 0, _a = scene._pointerMoveStage; _i < _a.length; _i++) {
            var step = _a[_i];
            pickResult = step.action(this._unTranslatedPointerX, this._unTranslatedPointerY, pickResult, isMeshPicked, canvas);
        }
        if (pickResult) {
            var type = evt.type === this._wheelEventName ? _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERWHEEL : _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERMOVE;
            if (scene.onPointerMove) {
                scene.onPointerMove(evt, pickResult, type);
            }
            if (scene.onPointerObservable.hasObservers()) {
                var pi = new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerInfo"](type, evt, pickResult);
                this._setRayOnPointerInfo(pi);
                scene.onPointerObservable.notifyObservers(pi, type);
            }
        }
    };
    // Pointers handling
    InputManager.prototype._setRayOnPointerInfo = function (pointerInfo) {
        var scene = this._scene;
        if (pointerInfo.pickInfo && !pointerInfo.pickInfo._pickingUnavailable) {
            if (!pointerInfo.pickInfo.ray) {
                pointerInfo.pickInfo.ray = scene.createPickingRay(pointerInfo.event.offsetX, pointerInfo.event.offsetY, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Identity(), scene.activeCamera);
            }
        }
    };
    InputManager.prototype._checkPrePointerObservable = function (pickResult, evt, type) {
        var scene = this._scene;
        var pi = new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerInfoPre"](type, evt, this._unTranslatedPointerX, this._unTranslatedPointerY);
        if (pickResult) {
            pi.ray = pickResult.ray;
        }
        scene.onPrePointerObservable.notifyObservers(pi, type);
        if (pi.skipOnPointerObservable) {
            return true;
        }
        else {
            return false;
        }
    };
    /**
     * Use this method to simulate a pointer move on a mesh
     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay
     * @param pickResult pickingInfo of the object wished to simulate pointer event on
     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)
     */
    InputManager.prototype.simulatePointerMove = function (pickResult, pointerEventInit) {
        var evt = new PointerEvent("pointermove", pointerEventInit);
        if (this._checkPrePointerObservable(pickResult, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERMOVE)) {
            return;
        }
        this._processPointerMove(pickResult, evt);
    };
    /**
     * Use this method to simulate a pointer down on a mesh
     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay
     * @param pickResult pickingInfo of the object wished to simulate pointer event on
     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)
     */
    InputManager.prototype.simulatePointerDown = function (pickResult, pointerEventInit) {
        var evt = new PointerEvent("pointerdown", pointerEventInit);
        if (this._checkPrePointerObservable(pickResult, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOWN)) {
            return;
        }
        this._processPointerDown(pickResult, evt);
    };
    InputManager.prototype._processPointerDown = function (pickResult, evt) {
        var _this = this;
        var scene = this._scene;
        if (pickResult && pickResult.hit && pickResult.pickedMesh) {
            this._pickedDownMesh = pickResult.pickedMesh;
            var actionManager = pickResult.pickedMesh._getActionManagerForTrigger();
            if (actionManager) {
                if (actionManager.hasPickTriggers) {
                    actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPickDownTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                    switch (evt.button) {
                        case 0:
                            actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnLeftPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                            break;
                        case 1:
                            actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnCenterPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                            break;
                        case 2:
                            actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnRightPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                            break;
                    }
                }
                if (actionManager.hasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnLongPressTrigger)) {
                    window.setTimeout(function () {
                        var pickResult = scene.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, function (mesh) { return (mesh.isPickable && mesh.isVisible && mesh.isReady() && mesh.actionManager && mesh.actionManager.hasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnLongPressTrigger) && mesh == _this._pickedDownMesh); }, false, scene.cameraToUseForPointers);
                        if (pickResult && pickResult.hit && pickResult.pickedMesh && actionManager) {
                            if (_this._totalPointersPressed !== 0 &&
                                ((Date.now() - _this._startingPointerTime) > InputManager.LongPressDelay) &&
                                !_this._isPointerSwiping()) {
                                _this._startingPointerTime = 0;
                                actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnLongPressTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                            }
                        }
                    }, InputManager.LongPressDelay);
                }
            }
        }
        else {
            for (var _i = 0, _a = scene._pointerDownStage; _i < _a.length; _i++) {
                var step = _a[_i];
                pickResult = step.action(this._unTranslatedPointerX, this._unTranslatedPointerY, pickResult, evt);
            }
        }
        if (pickResult) {
            var type = _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOWN;
            if (scene.onPointerDown) {
                scene.onPointerDown(evt, pickResult, type);
            }
            if (scene.onPointerObservable.hasObservers()) {
                var pi = new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerInfo"](type, evt, pickResult);
                this._setRayOnPointerInfo(pi);
                scene.onPointerObservable.notifyObservers(pi, type);
            }
        }
    };
    /** @hidden */
    InputManager.prototype._isPointerSwiping = function () {
        return Math.abs(this._startingPointerPosition.x - this._pointerX) > InputManager.DragMovementThreshold ||
            Math.abs(this._startingPointerPosition.y - this._pointerY) > InputManager.DragMovementThreshold;
    };
    /**
     * Use this method to simulate a pointer up on a mesh
     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay
     * @param pickResult pickingInfo of the object wished to simulate pointer event on
     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)
     * @param doubleTap indicates that the pointer up event should be considered as part of a double click (false by default)
     */
    InputManager.prototype.simulatePointerUp = function (pickResult, pointerEventInit, doubleTap) {
        var evt = new PointerEvent("pointerup", pointerEventInit);
        var clickInfo = new _ClickInfo();
        if (doubleTap) {
            clickInfo.doubleClick = true;
        }
        else {
            clickInfo.singleClick = true;
        }
        if (this._checkPrePointerObservable(pickResult, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERUP)) {
            return;
        }
        this._processPointerUp(pickResult, evt, clickInfo);
    };
    InputManager.prototype._processPointerUp = function (pickResult, evt, clickInfo) {
        var scene = this._scene;
        if (pickResult && pickResult && pickResult.pickedMesh) {
            this._pickedUpMesh = pickResult.pickedMesh;
            if (this._pickedDownMesh === this._pickedUpMesh) {
                if (scene.onPointerPick) {
                    scene.onPointerPick(evt, pickResult);
                }
                if (clickInfo.singleClick && !clickInfo.ignore && scene.onPointerObservable.hasObservers()) {
                    var type_1 = _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERPICK;
                    var pi = new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerInfo"](type_1, evt, pickResult);
                    this._setRayOnPointerInfo(pi);
                    scene.onPointerObservable.notifyObservers(pi, type_1);
                }
            }
            var actionManager = pickResult.pickedMesh._getActionManagerForTrigger();
            if (actionManager && !clickInfo.ignore) {
                actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPickUpTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                if (!clickInfo.hasSwiped && clickInfo.singleClick) {
                    actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                }
                var doubleClickActionManager = pickResult.pickedMesh._getActionManagerForTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnDoublePickTrigger);
                if (clickInfo.doubleClick && doubleClickActionManager) {
                    doubleClickActionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnDoublePickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(pickResult.pickedMesh, evt));
                }
            }
        }
        else {
            if (!clickInfo.ignore) {
                for (var _i = 0, _a = scene._pointerUpStage; _i < _a.length; _i++) {
                    var step = _a[_i];
                    pickResult = step.action(this._unTranslatedPointerX, this._unTranslatedPointerY, pickResult, evt);
                }
            }
        }
        if (this._pickedDownMesh && this._pickedDownMesh !== this._pickedUpMesh) {
            var pickedDownActionManager = this._pickedDownMesh._getActionManagerForTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPickOutTrigger);
            if (pickedDownActionManager) {
                pickedDownActionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPickOutTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(this._pickedDownMesh, evt));
            }
        }
        var type = 0;
        if (scene.onPointerObservable.hasObservers()) {
            if (!clickInfo.ignore && !clickInfo.hasSwiped) {
                if (clickInfo.singleClick && scene.onPointerObservable.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERTAP)) {
                    type = _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERTAP;
                }
                else if (clickInfo.doubleClick && scene.onPointerObservable.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP)) {
                    type = _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP;
                }
                if (type) {
                    var pi = new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerInfo"](type, evt, pickResult);
                    this._setRayOnPointerInfo(pi);
                    scene.onPointerObservable.notifyObservers(pi, type);
                }
            }
            if (!clickInfo.ignore) {
                type = _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERUP;
                var pi = new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerInfo"](type, evt, pickResult);
                this._setRayOnPointerInfo(pi);
                scene.onPointerObservable.notifyObservers(pi, type);
            }
        }
        if (scene.onPointerUp && !clickInfo.ignore) {
            scene.onPointerUp(evt, pickResult, type);
        }
    };
    /**
     * Gets a boolean indicating if the current pointer event is captured (meaning that the scene has already handled the pointer down)
     * @param pointerId defines the pointer id to use in a multi-touch scenario (0 by default)
     * @returns true if the pointer was captured
     */
    InputManager.prototype.isPointerCaptured = function (pointerId) {
        if (pointerId === void 0) { pointerId = 0; }
        return this._pointerCaptures[pointerId];
    };
    /**
    * Attach events to the canvas (To handle actionManagers triggers and raise onPointerMove, onPointerDown and onPointerUp
    * @param attachUp defines if you want to attach events to pointerup
    * @param attachDown defines if you want to attach events to pointerdown
    * @param attachMove defines if you want to attach events to pointermove
    */
    InputManager.prototype.attachControl = function (attachUp, attachDown, attachMove) {
        var _this = this;
        if (attachUp === void 0) { attachUp = true; }
        if (attachDown === void 0) { attachDown = true; }
        if (attachMove === void 0) { attachMove = true; }
        var scene = this._scene;
        var canvas = scene.getEngine().getRenderingCanvas();
        if (!canvas) {
            return;
        }
        var engine = scene.getEngine();
        this._initActionManager = function (act, clickInfo) {
            if (!_this._meshPickProceed) {
                var pickResult = scene.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, scene.pointerDownPredicate, false, scene.cameraToUseForPointers);
                _this._currentPickResult = pickResult;
                if (pickResult) {
                    act = (pickResult.hit && pickResult.pickedMesh) ? pickResult.pickedMesh._getActionManagerForTrigger() : null;
                }
                _this._meshPickProceed = true;
            }
            return act;
        };
        this._delayedSimpleClick = function (btn, clickInfo, cb) {
            // double click delay is over and that no double click has been raised since, or the 2 consecutive keys pressed are different
            if ((Date.now() - _this._previousStartingPointerTime > InputManager.DoubleClickDelay && !_this._doubleClickOccured) ||
                btn !== _this._previousButtonPressed) {
                _this._doubleClickOccured = false;
                clickInfo.singleClick = true;
                clickInfo.ignore = false;
                cb(clickInfo, _this._currentPickResult);
            }
        };
        this._initClickEvent = function (obs1, obs2, evt, cb) {
            var clickInfo = new _ClickInfo();
            _this._currentPickResult = null;
            var act = null;
            var checkPicking = obs1.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERPICK) || obs2.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERPICK)
                || obs1.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERTAP) || obs2.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERTAP)
                || obs1.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP) || obs2.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP);
            if (!checkPicking && _Actions_abstractActionManager__WEBPACK_IMPORTED_MODULE_1__["AbstractActionManager"]) {
                act = _this._initActionManager(act, clickInfo);
                if (act) {
                    checkPicking = act.hasPickTriggers;
                }
            }
            var needToIgnoreNext = false;
            if (checkPicking) {
                var btn = evt.button;
                clickInfo.hasSwiped = _this._isPointerSwiping();
                if (!clickInfo.hasSwiped) {
                    var checkSingleClickImmediately = !InputManager.ExclusiveDoubleClickMode;
                    if (!checkSingleClickImmediately) {
                        checkSingleClickImmediately = !obs1.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP) &&
                            !obs2.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP);
                        if (checkSingleClickImmediately && !_Actions_abstractActionManager__WEBPACK_IMPORTED_MODULE_1__["AbstractActionManager"].HasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnDoublePickTrigger)) {
                            act = _this._initActionManager(act, clickInfo);
                            if (act) {
                                checkSingleClickImmediately = !act.hasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnDoublePickTrigger);
                            }
                        }
                    }
                    if (checkSingleClickImmediately) {
                        // single click detected if double click delay is over or two different successive keys pressed without exclusive double click or no double click required
                        if (Date.now() - _this._previousStartingPointerTime > InputManager.DoubleClickDelay ||
                            btn !== _this._previousButtonPressed) {
                            clickInfo.singleClick = true;
                            cb(clickInfo, _this._currentPickResult);
                            needToIgnoreNext = true;
                        }
                    }
                    // at least one double click is required to be check and exclusive double click is enabled
                    else {
                        // wait that no double click has been raised during the double click delay
                        _this._previousDelayedSimpleClickTimeout = _this._delayedSimpleClickTimeout;
                        _this._delayedSimpleClickTimeout = window.setTimeout(_this._delayedSimpleClick.bind(_this, btn, clickInfo, cb), InputManager.DoubleClickDelay);
                    }
                    var checkDoubleClick = obs1.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP) ||
                        obs2.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP);
                    if (!checkDoubleClick && _Actions_abstractActionManager__WEBPACK_IMPORTED_MODULE_1__["AbstractActionManager"].HasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnDoublePickTrigger)) {
                        act = _this._initActionManager(act, clickInfo);
                        if (act) {
                            checkDoubleClick = act.hasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnDoublePickTrigger);
                        }
                    }
                    if (checkDoubleClick) {
                        // two successive keys pressed are equal, double click delay is not over and double click has not just occurred
                        if (btn === _this._previousButtonPressed &&
                            Date.now() - _this._previousStartingPointerTime < InputManager.DoubleClickDelay &&
                            !_this._doubleClickOccured) {
                            // pointer has not moved for 2 clicks, it's a double click
                            if (!clickInfo.hasSwiped &&
                                !_this._isPointerSwiping()) {
                                _this._previousStartingPointerTime = 0;
                                _this._doubleClickOccured = true;
                                clickInfo.doubleClick = true;
                                clickInfo.ignore = false;
                                if (InputManager.ExclusiveDoubleClickMode && _this._previousDelayedSimpleClickTimeout) {
                                    clearTimeout(_this._previousDelayedSimpleClickTimeout);
                                }
                                _this._previousDelayedSimpleClickTimeout = _this._delayedSimpleClickTimeout;
                                cb(clickInfo, _this._currentPickResult);
                            }
                            // if the two successive clicks are too far, it's just two simple clicks
                            else {
                                _this._doubleClickOccured = false;
                                _this._previousStartingPointerTime = _this._startingPointerTime;
                                _this._previousStartingPointerPosition.x = _this._startingPointerPosition.x;
                                _this._previousStartingPointerPosition.y = _this._startingPointerPosition.y;
                                _this._previousButtonPressed = btn;
                                if (InputManager.ExclusiveDoubleClickMode) {
                                    if (_this._previousDelayedSimpleClickTimeout) {
                                        clearTimeout(_this._previousDelayedSimpleClickTimeout);
                                    }
                                    _this._previousDelayedSimpleClickTimeout = _this._delayedSimpleClickTimeout;
                                    cb(clickInfo, _this._previousPickResult);
                                }
                                else {
                                    cb(clickInfo, _this._currentPickResult);
                                }
                            }
                            needToIgnoreNext = true;
                        }
                        // just the first click of the double has been raised
                        else {
                            _this._doubleClickOccured = false;
                            _this._previousStartingPointerTime = _this._startingPointerTime;
                            _this._previousStartingPointerPosition.x = _this._startingPointerPosition.x;
                            _this._previousStartingPointerPosition.y = _this._startingPointerPosition.y;
                            _this._previousButtonPressed = btn;
                        }
                    }
                }
            }
            if (!needToIgnoreNext) {
                cb(clickInfo, _this._currentPickResult);
            }
        };
        this._onPointerMove = function (evt) {
            _this._updatePointerPosition(evt);
            // PreObservable support
            if (_this._checkPrePointerObservable(null, evt, evt.type === _this._wheelEventName ? _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERWHEEL : _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERMOVE)) {
                return;
            }
            if (!scene.cameraToUseForPointers && !scene.activeCamera) {
                return;
            }
            if (!scene.pointerMovePredicate) {
                scene.pointerMovePredicate = function (mesh) { return (mesh.isPickable && mesh.isVisible && mesh.isReady() && mesh.isEnabled() && (mesh.enablePointerMoveEvents || scene.constantlyUpdateMeshUnderPointer || (mesh._getActionManagerForTrigger() != null)) && (!scene.cameraToUseForPointers || (scene.cameraToUseForPointers.layerMask & mesh.layerMask) !== 0)); };
            }
            // Meshes
            var pickResult = scene.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, scene.pointerMovePredicate, false, scene.cameraToUseForPointers);
            _this._processPointerMove(pickResult, evt);
        };
        this._onPointerDown = function (evt) {
            _this._totalPointersPressed++;
            _this._pickedDownMesh = null;
            _this._meshPickProceed = false;
            _this._updatePointerPosition(evt);
            if (scene.preventDefaultOnPointerDown && canvas) {
                evt.preventDefault();
                canvas.focus();
            }
            _this._startingPointerPosition.x = _this._pointerX;
            _this._startingPointerPosition.y = _this._pointerY;
            _this._startingPointerTime = Date.now();
            // PreObservable support
            if (_this._checkPrePointerObservable(null, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOWN)) {
                return;
            }
            if (!scene.cameraToUseForPointers && !scene.activeCamera) {
                return;
            }
            _this._pointerCaptures[evt.pointerId] = true;
            if (!scene.pointerDownPredicate) {
                scene.pointerDownPredicate = function (mesh) {
                    return mesh.isPickable && mesh.isVisible && mesh.isReady() && mesh.isEnabled() && (!scene.cameraToUseForPointers || (scene.cameraToUseForPointers.layerMask & mesh.layerMask) !== 0);
                };
            }
            // Meshes
            _this._pickedDownMesh = null;
            var pickResult = scene.pick(_this._unTranslatedPointerX, _this._unTranslatedPointerY, scene.pointerDownPredicate, false, scene.cameraToUseForPointers);
            _this._processPointerDown(pickResult, evt);
        };
        this._onPointerUp = function (evt) {
            if (_this._totalPointersPressed === 0) { // We are attaching the pointer up to windows because of a bug in FF
                return; // So we need to test it the pointer down was pressed before.
            }
            _this._totalPointersPressed--;
            _this._pickedUpMesh = null;
            _this._meshPickProceed = false;
            _this._updatePointerPosition(evt);
            if (scene.preventDefaultOnPointerUp && canvas) {
                evt.preventDefault();
                canvas.focus();
            }
            _this._initClickEvent(scene.onPrePointerObservable, scene.onPointerObservable, evt, function (clickInfo, pickResult) {
                // PreObservable support
                if (scene.onPrePointerObservable.hasObservers()) {
                    if (!clickInfo.ignore) {
                        if (!clickInfo.hasSwiped) {
                            if (clickInfo.singleClick && scene.onPrePointerObservable.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERTAP)) {
                                if (_this._checkPrePointerObservable(null, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERTAP)) {
                                    return;
                                }
                            }
                            if (clickInfo.doubleClick && scene.onPrePointerObservable.hasSpecificMask(_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP)) {
                                if (_this._checkPrePointerObservable(null, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP)) {
                                    return;
                                }
                            }
                        }
                        if (_this._checkPrePointerObservable(null, evt, _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERUP)) {
                            return;
                        }
                    }
                }
                if (!_this._pointerCaptures[evt.pointerId]) {
                    return;
                }
                _this._pointerCaptures[evt.pointerId] = false;
                if (!scene.cameraToUseForPointers && !scene.activeCamera) {
                    return;
                }
                if (!scene.pointerUpPredicate) {
                    scene.pointerUpPredicate = function (mesh) {
                        return mesh.isPickable && mesh.isVisible && mesh.isReady() && mesh.isEnabled() && (!scene.cameraToUseForPointers || (scene.cameraToUseForPointers.layerMask & mesh.layerMask) !== 0);
                    };
                }
                // Meshes
                if (!_this._meshPickProceed && (_Actions_abstractActionManager__WEBPACK_IMPORTED_MODULE_1__["AbstractActionManager"] && _Actions_abstractActionManager__WEBPACK_IMPORTED_MODULE_1__["AbstractActionManager"].HasTriggers || scene.onPointerObservable.hasObservers())) {
                    _this._initActionManager(null, clickInfo);
                }
                if (!pickResult) {
                    pickResult = _this._currentPickResult;
                }
                _this._processPointerUp(pickResult, evt, clickInfo);
                _this._previousPickResult = _this._currentPickResult;
            });
        };
        this._onKeyDown = function (evt) {
            var type = _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__["KeyboardEventTypes"].KEYDOWN;
            if (scene.onPreKeyboardObservable.hasObservers()) {
                var pi = new _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__["KeyboardInfoPre"](type, evt);
                scene.onPreKeyboardObservable.notifyObservers(pi, type);
                if (pi.skipOnPointerObservable) {
                    return;
                }
            }
            if (scene.onKeyboardObservable.hasObservers()) {
                var pi = new _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__["KeyboardInfo"](type, evt);
                scene.onKeyboardObservable.notifyObservers(pi, type);
            }
            if (scene.actionManager) {
                scene.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnKeyDownTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNewFromScene(scene, evt));
            }
        };
        this._onKeyUp = function (evt) {
            var type = _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__["KeyboardEventTypes"].KEYUP;
            if (scene.onPreKeyboardObservable.hasObservers()) {
                var pi = new _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__["KeyboardInfoPre"](type, evt);
                scene.onPreKeyboardObservable.notifyObservers(pi, type);
                if (pi.skipOnPointerObservable) {
                    return;
                }
            }
            if (scene.onKeyboardObservable.hasObservers()) {
                var pi = new _Events_keyboardEvents__WEBPACK_IMPORTED_MODULE_6__["KeyboardInfo"](type, evt);
                scene.onKeyboardObservable.notifyObservers(pi, type);
            }
            if (scene.actionManager) {
                scene.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnKeyUpTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNewFromScene(scene, evt));
            }
        };
        // Keyboard events
        this._onCanvasFocusObserver = engine.onCanvasFocusObservable.add((function () {
            var fn = function () {
                if (!canvas) {
                    return;
                }
                canvas.addEventListener("keydown", _this._onKeyDown, false);
                canvas.addEventListener("keyup", _this._onKeyUp, false);
            };
            if (document.activeElement === canvas) {
                fn();
            }
            return fn;
        })());
        this._onCanvasBlurObserver = engine.onCanvasBlurObservable.add(function () {
            if (!canvas) {
                return;
            }
            canvas.removeEventListener("keydown", _this._onKeyDown);
            canvas.removeEventListener("keyup", _this._onKeyUp);
        });
        // Pointer events
        var eventPrefix = _Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].GetPointerPrefix();
        if (attachMove) {
            canvas.addEventListener(eventPrefix + "move", this._onPointerMove, false);
            // Wheel
            this._wheelEventName = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
                document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
                    "DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
            canvas.addEventListener(this._wheelEventName, this._onPointerMove, false);
        }
        if (attachDown) {
            canvas.addEventListener(eventPrefix + "down", this._onPointerDown, false);
        }
        if (attachUp) {
            var hostWindow = scene.getEngine().getHostWindow();
            hostWindow.addEventListener(eventPrefix + "up", this._onPointerUp, false);
        }
    };
    /**
     * Detaches all event handlers
     */
    InputManager.prototype.detachControl = function () {
        var eventPrefix = _Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].GetPointerPrefix();
        var canvas = this._scene.getEngine().getRenderingCanvas();
        var engine = this._scene.getEngine();
        if (!canvas) {
            return;
        }
        // Pointer
        canvas.removeEventListener(eventPrefix + "move", this._onPointerMove);
        canvas.removeEventListener(this._wheelEventName, this._onPointerMove);
        canvas.removeEventListener(eventPrefix + "down", this._onPointerDown);
        window.removeEventListener(eventPrefix + "up", this._onPointerUp);
        // Blur / Focus
        if (this._onCanvasBlurObserver) {
            engine.onCanvasBlurObservable.remove(this._onCanvasBlurObserver);
        }
        if (this._onCanvasFocusObserver) {
            engine.onCanvasFocusObservable.remove(this._onCanvasFocusObserver);
        }
        // Keyboard
        canvas.removeEventListener("keydown", this._onKeyDown);
        canvas.removeEventListener("keyup", this._onKeyUp);
        // Cursor
        canvas.style.cursor = this._scene.defaultCursor;
    };
    /**
     * Force the value of meshUnderPointer
     * @param mesh defines the mesh to use
     */
    InputManager.prototype.setPointerOverMesh = function (mesh) {
        if (this._pointerOverMesh === mesh) {
            return;
        }
        var actionManager;
        if (this._pointerOverMesh) {
            actionManager = this._pointerOverMesh._getActionManagerForTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPointerOutTrigger);
            if (actionManager) {
                actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPointerOutTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(this._pointerOverMesh));
            }
        }
        this._pointerOverMesh = mesh;
        if (this._pointerOverMesh) {
            actionManager = this._pointerOverMesh._getActionManagerForTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPointerOverTrigger);
            if (actionManager) {
                actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ACTION_OnPointerOverTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_4__["ActionEvent"].CreateNew(this._pointerOverMesh));
            }
        }
    };
    /**
     * Gets the mesh under the pointer
     * @returns a Mesh or null if no mesh is under the pointer
     */
    InputManager.prototype.getPointerOverMesh = function () {
        return this._pointerOverMesh;
    };
    /** The distance in pixel that you have to move to prevent some events */
    InputManager.DragMovementThreshold = 10; // in pixels
    /** Time in milliseconds to wait to raise long press events if button is still pressed */
    InputManager.LongPressDelay = 500; // in milliseconds
    /** Time in milliseconds with two consecutive clicks will be considered as a double click */
    InputManager.DoubleClickDelay = 300; // in milliseconds
    /** If you need to check double click without raising a single click at first click, enable this flag */
    InputManager.ExclusiveDoubleClickMode = false;
    return InputManager;
}());



/***/ }),

/***/ "./Instrumentation/engineInstrumentation.ts":
/*!**************************************************!*\
  !*** ./Instrumentation/engineInstrumentation.ts ***!
  \**************************************************/
/*! exports provided: EngineInstrumentation */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EngineInstrumentation", function() { return EngineInstrumentation; });
/* harmony import */ var _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/perfCounter */ "./Misc/perfCounter.ts");

/**
 * This class can be used to get instrumentation data from a Babylon engine
 * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#engineinstrumentation
 */
var EngineInstrumentation = /** @class */ (function () {
    /**
     * Instantiates a new engine instrumentation.
     * This class can be used to get instrumentation data from a Babylon engine
     * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#engineinstrumentation
     * @param engine Defines the engine to instrument
     */
    function EngineInstrumentation(
    /**
     * Define the instrumented engine.
     */
    engine) {
        this.engine = engine;
        this._captureGPUFrameTime = false;
        this._gpuFrameTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]();
        this._captureShaderCompilationTime = false;
        this._shaderCompilationTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]();
        // Observers
        this._onBeginFrameObserver = null;
        this._onEndFrameObserver = null;
        this._onBeforeShaderCompilationObserver = null;
        this._onAfterShaderCompilationObserver = null;
    }
    Object.defineProperty(EngineInstrumentation.prototype, "gpuFrameTimeCounter", {
        // Properties
        /**
         * Gets the perf counter used for GPU frame time
         */
        get: function () {
            return this._gpuFrameTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EngineInstrumentation.prototype, "captureGPUFrameTime", {
        /**
         * Gets the GPU frame time capture status
         */
        get: function () {
            return this._captureGPUFrameTime;
        },
        /**
         * Enable or disable the GPU frame time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureGPUFrameTime) {
                return;
            }
            this._captureGPUFrameTime = value;
            if (value) {
                this._onBeginFrameObserver = this.engine.onBeginFrameObservable.add(function () {
                    if (!_this._gpuFrameTimeToken) {
                        _this._gpuFrameTimeToken = _this.engine.startTimeQuery();
                    }
                });
                this._onEndFrameObserver = this.engine.onEndFrameObservable.add(function () {
                    if (!_this._gpuFrameTimeToken) {
                        return;
                    }
                    var time = _this.engine.endTimeQuery(_this._gpuFrameTimeToken);
                    if (time > -1) {
                        _this._gpuFrameTimeToken = null;
                        _this._gpuFrameTime.fetchNewFrame();
                        _this._gpuFrameTime.addCount(time, true);
                    }
                });
            }
            else {
                this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);
                this._onBeginFrameObserver = null;
                this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);
                this._onEndFrameObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EngineInstrumentation.prototype, "shaderCompilationTimeCounter", {
        /**
         * Gets the perf counter used for shader compilation time
         */
        get: function () {
            return this._shaderCompilationTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EngineInstrumentation.prototype, "captureShaderCompilationTime", {
        /**
         * Gets the shader compilation time capture status
         */
        get: function () {
            return this._captureShaderCompilationTime;
        },
        /**
         * Enable or disable the shader compilation time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureShaderCompilationTime) {
                return;
            }
            this._captureShaderCompilationTime = value;
            if (value) {
                this._onBeforeShaderCompilationObserver = this.engine.onBeforeShaderCompilationObservable.add(function () {
                    _this._shaderCompilationTime.fetchNewFrame();
                    _this._shaderCompilationTime.beginMonitoring();
                });
                this._onAfterShaderCompilationObserver = this.engine.onAfterShaderCompilationObservable.add(function () {
                    _this._shaderCompilationTime.endMonitoring();
                });
            }
            else {
                this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);
                this._onBeforeShaderCompilationObserver = null;
                this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);
                this._onAfterShaderCompilationObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Dispose and release associated resources.
     */
    EngineInstrumentation.prototype.dispose = function () {
        this.engine.onBeginFrameObservable.remove(this._onBeginFrameObserver);
        this._onBeginFrameObserver = null;
        this.engine.onEndFrameObservable.remove(this._onEndFrameObserver);
        this._onEndFrameObserver = null;
        this.engine.onBeforeShaderCompilationObservable.remove(this._onBeforeShaderCompilationObserver);
        this._onBeforeShaderCompilationObserver = null;
        this.engine.onAfterShaderCompilationObservable.remove(this._onAfterShaderCompilationObserver);
        this._onAfterShaderCompilationObserver = null;
        this.engine = null;
    };
    return EngineInstrumentation;
}());



/***/ }),

/***/ "./Instrumentation/index.ts":
/*!**********************************!*\
  !*** ./Instrumentation/index.ts ***!
  \**********************************/
/*! exports provided: EngineInstrumentation, SceneInstrumentation, _TimeToken */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _engineInstrumentation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./engineInstrumentation */ "./Instrumentation/engineInstrumentation.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineInstrumentation", function() { return _engineInstrumentation__WEBPACK_IMPORTED_MODULE_0__["EngineInstrumentation"]; });

/* harmony import */ var _sceneInstrumentation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./sceneInstrumentation */ "./Instrumentation/sceneInstrumentation.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneInstrumentation", function() { return _sceneInstrumentation__WEBPACK_IMPORTED_MODULE_1__["SceneInstrumentation"]; });

/* harmony import */ var _timeToken__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./timeToken */ "./Instrumentation/timeToken.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TimeToken", function() { return _timeToken__WEBPACK_IMPORTED_MODULE_2__["_TimeToken"]; });






/***/ }),

/***/ "./Instrumentation/sceneInstrumentation.ts":
/*!*************************************************!*\
  !*** ./Instrumentation/sceneInstrumentation.ts ***!
  \*************************************************/
/*! exports provided: SceneInstrumentation */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneInstrumentation", function() { return SceneInstrumentation; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/perfCounter */ "./Misc/perfCounter.ts");


/**
 * This class can be used to get instrumentation data from a Babylon engine
 * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#sceneinstrumentation
 */
var SceneInstrumentation = /** @class */ (function () {
    /**
     * Instantiates a new scene instrumentation.
     * This class can be used to get instrumentation data from a Babylon engine
     * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#sceneinstrumentation
     * @param scene Defines the scene to instrument
     */
    function SceneInstrumentation(
    /**
     * Defines the scene to instrument
     */
    scene) {
        var _this = this;
        this.scene = scene;
        this._captureActiveMeshesEvaluationTime = false;
        this._activeMeshesEvaluationTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureRenderTargetsRenderTime = false;
        this._renderTargetsRenderTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureFrameTime = false;
        this._frameTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureRenderTime = false;
        this._renderTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureInterFrameTime = false;
        this._interFrameTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureParticlesRenderTime = false;
        this._particlesRenderTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureSpritesRenderTime = false;
        this._spritesRenderTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._capturePhysicsTime = false;
        this._physicsTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureAnimationsTime = false;
        this._animationsTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        this._captureCameraRenderTime = false;
        this._cameraRenderTime = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_1__["PerfCounter"]();
        // Observers
        this._onBeforeActiveMeshesEvaluationObserver = null;
        this._onAfterActiveMeshesEvaluationObserver = null;
        this._onBeforeRenderTargetsRenderObserver = null;
        this._onAfterRenderTargetsRenderObserver = null;
        this._onAfterRenderObserver = null;
        this._onBeforeDrawPhaseObserver = null;
        this._onAfterDrawPhaseObserver = null;
        this._onBeforeAnimationsObserver = null;
        this._onBeforeParticlesRenderingObserver = null;
        this._onAfterParticlesRenderingObserver = null;
        this._onBeforeSpritesRenderingObserver = null;
        this._onAfterSpritesRenderingObserver = null;
        this._onBeforePhysicsObserver = null;
        this._onAfterPhysicsObserver = null;
        this._onAfterAnimationsObserver = null;
        this._onBeforeCameraRenderObserver = null;
        this._onAfterCameraRenderObserver = null;
        // Before render
        this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(function () {
            if (_this._captureActiveMeshesEvaluationTime) {
                _this._activeMeshesEvaluationTime.fetchNewFrame();
            }
            if (_this._captureRenderTargetsRenderTime) {
                _this._renderTargetsRenderTime.fetchNewFrame();
            }
            if (_this._captureFrameTime) {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Scene rendering");
                _this._frameTime.beginMonitoring();
            }
            if (_this._captureInterFrameTime) {
                _this._interFrameTime.endMonitoring();
            }
            if (_this._captureParticlesRenderTime) {
                _this._particlesRenderTime.fetchNewFrame();
            }
            if (_this._captureSpritesRenderTime) {
                _this._spritesRenderTime.fetchNewFrame();
            }
            if (_this._captureAnimationsTime) {
                _this._animationsTime.beginMonitoring();
            }
            _this.scene.getEngine()._drawCalls.fetchNewFrame();
        });
        // After render
        this._onAfterRenderObserver = scene.onAfterRenderObservable.add(function () {
            if (_this._captureFrameTime) {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Scene rendering");
                _this._frameTime.endMonitoring();
            }
            if (_this._captureRenderTime) {
                _this._renderTime.endMonitoring(false);
            }
            if (_this._captureInterFrameTime) {
                _this._interFrameTime.beginMonitoring();
            }
        });
    }
    Object.defineProperty(SceneInstrumentation.prototype, "activeMeshesEvaluationTimeCounter", {
        // Properties
        /**
         * Gets the perf counter used for active meshes evaluation time
         */
        get: function () {
            return this._activeMeshesEvaluationTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureActiveMeshesEvaluationTime", {
        /**
         * Gets the active meshes evaluation time capture status
         */
        get: function () {
            return this._captureActiveMeshesEvaluationTime;
        },
        /**
         * Enable or disable the active meshes evaluation time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureActiveMeshesEvaluationTime) {
                return;
            }
            this._captureActiveMeshesEvaluationTime = value;
            if (value) {
                this._onBeforeActiveMeshesEvaluationObserver = this.scene.onBeforeActiveMeshesEvaluationObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Active meshes evaluation");
                    _this._activeMeshesEvaluationTime.beginMonitoring();
                });
                this._onAfterActiveMeshesEvaluationObserver = this.scene.onAfterActiveMeshesEvaluationObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Active meshes evaluation");
                    _this._activeMeshesEvaluationTime.endMonitoring();
                });
            }
            else {
                this.scene.onBeforeActiveMeshesEvaluationObservable.remove(this._onBeforeActiveMeshesEvaluationObserver);
                this._onBeforeActiveMeshesEvaluationObserver = null;
                this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);
                this._onAfterActiveMeshesEvaluationObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "renderTargetsRenderTimeCounter", {
        /**
         * Gets the perf counter used for render targets render time
         */
        get: function () {
            return this._renderTargetsRenderTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureRenderTargetsRenderTime", {
        /**
         * Gets the render targets render time capture status
         */
        get: function () {
            return this._captureRenderTargetsRenderTime;
        },
        /**
         * Enable or disable the render targets render time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureRenderTargetsRenderTime) {
                return;
            }
            this._captureRenderTargetsRenderTime = value;
            if (value) {
                this._onBeforeRenderTargetsRenderObserver = this.scene.onBeforeRenderTargetsRenderObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Render targets rendering");
                    _this._renderTargetsRenderTime.beginMonitoring();
                });
                this._onAfterRenderTargetsRenderObserver = this.scene.onAfterRenderTargetsRenderObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Render targets rendering");
                    _this._renderTargetsRenderTime.endMonitoring(false);
                });
            }
            else {
                this.scene.onBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
                this._onBeforeRenderTargetsRenderObserver = null;
                this.scene.onAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
                this._onAfterRenderTargetsRenderObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "particlesRenderTimeCounter", {
        /**
         * Gets the perf counter used for particles render time
         */
        get: function () {
            return this._particlesRenderTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureParticlesRenderTime", {
        /**
         * Gets the particles render time capture status
         */
        get: function () {
            return this._captureParticlesRenderTime;
        },
        /**
         * Enable or disable the particles render time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureParticlesRenderTime) {
                return;
            }
            this._captureParticlesRenderTime = value;
            if (value) {
                this._onBeforeParticlesRenderingObserver = this.scene.onBeforeParticlesRenderingObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Particles");
                    _this._particlesRenderTime.beginMonitoring();
                });
                this._onAfterParticlesRenderingObserver = this.scene.onAfterParticlesRenderingObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Particles");
                    _this._particlesRenderTime.endMonitoring(false);
                });
            }
            else {
                this.scene.onBeforeParticlesRenderingObservable.remove(this._onBeforeParticlesRenderingObserver);
                this._onBeforeParticlesRenderingObserver = null;
                this.scene.onAfterParticlesRenderingObservable.remove(this._onAfterParticlesRenderingObserver);
                this._onAfterParticlesRenderingObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "spritesRenderTimeCounter", {
        /**
         * Gets the perf counter used for sprites render time
         */
        get: function () {
            return this._spritesRenderTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureSpritesRenderTime", {
        /**
         * Gets the sprites render time capture status
         */
        get: function () {
            return this._captureSpritesRenderTime;
        },
        /**
         * Enable or disable the sprites render time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureSpritesRenderTime) {
                return;
            }
            this._captureSpritesRenderTime = value;
            if (!this.scene.spriteManagers) {
                return;
            }
            if (value) {
                this._onBeforeSpritesRenderingObserver = this.scene.onBeforeSpritesRenderingObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Sprites");
                    _this._spritesRenderTime.beginMonitoring();
                });
                this._onAfterSpritesRenderingObserver = this.scene.onAfterSpritesRenderingObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Sprites");
                    _this._spritesRenderTime.endMonitoring(false);
                });
            }
            else {
                this.scene.onBeforeSpritesRenderingObservable.remove(this._onBeforeSpritesRenderingObserver);
                this._onBeforeSpritesRenderingObserver = null;
                this.scene.onAfterSpritesRenderingObservable.remove(this._onAfterSpritesRenderingObserver);
                this._onAfterSpritesRenderingObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "physicsTimeCounter", {
        /**
         * Gets the perf counter used for physics time
         */
        get: function () {
            return this._physicsTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "capturePhysicsTime", {
        /**
         * Gets the physics time capture status
         */
        get: function () {
            return this._capturePhysicsTime;
        },
        /**
         * Enable or disable the physics time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._capturePhysicsTime) {
                return;
            }
            if (!this.scene.onBeforePhysicsObservable) {
                return;
            }
            this._capturePhysicsTime = value;
            if (value) {
                this._onBeforePhysicsObserver = this.scene.onBeforePhysicsObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Physics");
                    _this._physicsTime.beginMonitoring();
                });
                this._onAfterPhysicsObserver = this.scene.onAfterPhysicsObservable.add(function () {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Physics");
                    _this._physicsTime.endMonitoring();
                });
            }
            else {
                this.scene.onBeforePhysicsObservable.remove(this._onBeforePhysicsObserver);
                this._onBeforePhysicsObserver = null;
                this.scene.onAfterPhysicsObservable.remove(this._onAfterPhysicsObserver);
                this._onAfterPhysicsObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "animationsTimeCounter", {
        /**
         * Gets the perf counter used for animations time
         */
        get: function () {
            return this._animationsTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureAnimationsTime", {
        /**
         * Gets the animations time capture status
         */
        get: function () {
            return this._captureAnimationsTime;
        },
        /**
         * Enable or disable the animations time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureAnimationsTime) {
                return;
            }
            this._captureAnimationsTime = value;
            if (value) {
                this._onAfterAnimationsObserver = this.scene.onAfterAnimationsObservable.add(function () {
                    _this._animationsTime.endMonitoring();
                });
            }
            else {
                this.scene.onAfterAnimationsObservable.remove(this._onAfterAnimationsObserver);
                this._onAfterAnimationsObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "frameTimeCounter", {
        /**
         * Gets the perf counter used for frame time capture
         */
        get: function () {
            return this._frameTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureFrameTime", {
        /**
         * Gets the frame time capture status
         */
        get: function () {
            return this._captureFrameTime;
        },
        /**
         * Enable or disable the frame time capture
         */
        set: function (value) {
            this._captureFrameTime = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "interFrameTimeCounter", {
        /**
         * Gets the perf counter used for inter-frames time capture
         */
        get: function () {
            return this._interFrameTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureInterFrameTime", {
        /**
         * Gets the inter-frames time capture status
         */
        get: function () {
            return this._captureInterFrameTime;
        },
        /**
         * Enable or disable the inter-frames time capture
         */
        set: function (value) {
            this._captureInterFrameTime = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "renderTimeCounter", {
        /**
         * Gets the perf counter used for render time capture
         */
        get: function () {
            return this._renderTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureRenderTime", {
        /**
         * Gets the render time capture status
         */
        get: function () {
            return this._captureRenderTime;
        },
        /**
         * Enable or disable the render time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureRenderTime) {
                return;
            }
            this._captureRenderTime = value;
            if (value) {
                this._onBeforeDrawPhaseObserver = this.scene.onBeforeDrawPhaseObservable.add(function () {
                    _this._renderTime.beginMonitoring();
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Main render");
                });
                this._onAfterDrawPhaseObserver = this.scene.onAfterDrawPhaseObservable.add(function () {
                    _this._renderTime.endMonitoring(false);
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Main render");
                });
            }
            else {
                this.scene.onBeforeDrawPhaseObservable.remove(this._onBeforeDrawPhaseObserver);
                this._onBeforeDrawPhaseObserver = null;
                this.scene.onAfterDrawPhaseObservable.remove(this._onAfterDrawPhaseObserver);
                this._onAfterDrawPhaseObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "cameraRenderTimeCounter", {
        /**
         * Gets the perf counter used for camera render time capture
         */
        get: function () {
            return this._cameraRenderTime;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "captureCameraRenderTime", {
        /**
         * Gets the camera render time capture status
         */
        get: function () {
            return this._captureCameraRenderTime;
        },
        /**
         * Enable or disable the camera render time capture
         */
        set: function (value) {
            var _this = this;
            if (value === this._captureCameraRenderTime) {
                return;
            }
            this._captureCameraRenderTime = value;
            if (value) {
                this._onBeforeCameraRenderObserver = this.scene.onBeforeCameraRenderObservable.add(function (camera) {
                    _this._cameraRenderTime.beginMonitoring();
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Rendering camera " + camera.name);
                });
                this._onAfterCameraRenderObserver = this.scene.onAfterCameraRenderObservable.add(function (camera) {
                    _this._cameraRenderTime.endMonitoring(false);
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Rendering camera " + camera.name);
                });
            }
            else {
                this.scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
                this._onBeforeCameraRenderObserver = null;
                this.scene.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);
                this._onAfterCameraRenderObserver = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneInstrumentation.prototype, "drawCallsCounter", {
        /**
         * Gets the perf counter used for draw calls
         */
        get: function () {
            return this.scene.getEngine()._drawCalls;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Dispose and release associated resources.
     */
    SceneInstrumentation.prototype.dispose = function () {
        this.scene.onAfterRenderObservable.remove(this._onAfterRenderObserver);
        this._onAfterRenderObserver = null;
        this.scene.onBeforeActiveMeshesEvaluationObservable.remove(this._onBeforeActiveMeshesEvaluationObserver);
        this._onBeforeActiveMeshesEvaluationObserver = null;
        this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);
        this._onAfterActiveMeshesEvaluationObserver = null;
        this.scene.onBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
        this._onBeforeRenderTargetsRenderObserver = null;
        this.scene.onAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
        this._onAfterRenderTargetsRenderObserver = null;
        this.scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);
        this._onBeforeAnimationsObserver = null;
        this.scene.onBeforeParticlesRenderingObservable.remove(this._onBeforeParticlesRenderingObserver);
        this._onBeforeParticlesRenderingObserver = null;
        this.scene.onAfterParticlesRenderingObservable.remove(this._onAfterParticlesRenderingObserver);
        this._onAfterParticlesRenderingObserver = null;
        if (this._onBeforeSpritesRenderingObserver) {
            this.scene.onBeforeSpritesRenderingObservable.remove(this._onBeforeSpritesRenderingObserver);
            this._onBeforeSpritesRenderingObserver = null;
        }
        if (this._onAfterSpritesRenderingObserver) {
            this.scene.onAfterSpritesRenderingObservable.remove(this._onAfterSpritesRenderingObserver);
            this._onAfterSpritesRenderingObserver = null;
        }
        this.scene.onBeforeDrawPhaseObservable.remove(this._onBeforeDrawPhaseObserver);
        this._onBeforeDrawPhaseObserver = null;
        this.scene.onAfterDrawPhaseObservable.remove(this._onAfterDrawPhaseObserver);
        this._onAfterDrawPhaseObserver = null;
        if (this._onBeforePhysicsObserver) {
            this.scene.onBeforePhysicsObservable.remove(this._onBeforePhysicsObserver);
            this._onBeforePhysicsObserver = null;
        }
        if (this._onAfterPhysicsObserver) {
            this.scene.onAfterPhysicsObservable.remove(this._onAfterPhysicsObserver);
            this._onAfterPhysicsObserver = null;
        }
        this.scene.onAfterAnimationsObservable.remove(this._onAfterAnimationsObserver);
        this._onAfterAnimationsObserver = null;
        this.scene.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
        this._onBeforeCameraRenderObserver = null;
        this.scene.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);
        this._onAfterCameraRenderObserver = null;
        this.scene = null;
    };
    return SceneInstrumentation;
}());



/***/ }),

/***/ "./Instrumentation/timeToken.ts":
/*!**************************************!*\
  !*** ./Instrumentation/timeToken.ts ***!
  \**************************************/
/*! exports provided: _TimeToken */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_TimeToken", function() { return _TimeToken; });
/**
 * @hidden
 **/
var _TimeToken = /** @class */ (function () {
    function _TimeToken() {
        this._timeElapsedQueryEnded = false;
    }
    return _TimeToken;
}());



/***/ }),

/***/ "./Layers/effectLayer.ts":
/*!*******************************!*\
  !*** ./Layers/effectLayer.ts ***!
  \*******************************/
/*! exports provided: EffectLayer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EffectLayer", function() { return EffectLayer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_glowMapGeneration_fragment__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Shaders/glowMapGeneration.fragment */ "./Shaders/glowMapGeneration.fragment.ts");
/* harmony import */ var _Shaders_glowMapGeneration_vertex__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Shaders/glowMapGeneration.vertex */ "./Shaders/glowMapGeneration.vertex.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");

















/**
 * The effect layer Helps adding post process effect blended with the main pass.
 *
 * This can be for instance use to generate glow or higlight effects on the scene.
 *
 * The effect layer class can not be used directly and is intented to inherited from to be
 * customized per effects.
 */
var EffectLayer = /** @class */ (function () {
    /**
     * Instantiates a new effect Layer and references it in the scene.
     * @param name The name of the layer
     * @param scene The scene to use the layer in
     */
    function EffectLayer(
    /** The Friendly of the effect in the scene */
    name, scene) {
        this._vertexBuffers = {};
        this._maxSize = 0;
        this._mainTextureDesiredSize = { width: 0, height: 0 };
        this._shouldRender = true;
        this._postProcesses = [];
        this._textures = [];
        this._emissiveTextureAndColor = { texture: null, color: new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"]() };
        /**
         * The clear color of the texture used to generate the glow map.
         */
        this.neutralColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"]();
        /**
         * Specifies wether the highlight layer is enabled or not.
         */
        this.isEnabled = true;
        /**
         * An event triggered when the effect layer has been disposed.
         */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An event triggered when the effect layer is about rendering the main texture with the glowy parts.
         */
        this.onBeforeRenderMainTextureObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An event triggered when the generated texture is being merged in the scene.
         */
        this.onBeforeComposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An event triggered when the generated texture has been merged in the scene.
         */
        this.onAfterComposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An event triggered when the efffect layer changes its size.
         */
        this.onSizeChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        this.name = name;
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__["EngineStore"].LastCreatedScene;
        EffectLayer._SceneComponentInitialization(this._scene);
        this._engine = this._scene.getEngine();
        this._maxSize = this._engine.getCaps().maxTextureSize;
        this._scene.effectLayers.push(this);
        // Generate Buffers
        this._generateIndexBuffer();
        this._generateVertexBuffer();
    }
    Object.defineProperty(EffectLayer.prototype, "camera", {
        /**
         * Gets the camera attached to the layer.
         */
        get: function () {
            return this._effectLayerOptions.camera;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(EffectLayer.prototype, "renderingGroupId", {
        /**
         * Gets the rendering group id the layer should render in.
         */
        get: function () {
            return this._effectLayerOptions.renderingGroupId;
        },
        set: function (renderingGroupId) {
            this._effectLayerOptions.renderingGroupId = renderingGroupId;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Initializes the effect layer with the required options.
     * @param options Sets of none mandatory options to use with the layer (see IEffectLayerOptions for more information)
     */
    EffectLayer.prototype._init = function (options) {
        // Adapt options
        this._effectLayerOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ mainTextureRatio: 0.5, alphaBlendingMode: _Engines_constants__WEBPACK_IMPORTED_MODULE_13__["Constants"].ALPHA_COMBINE, camera: null, renderingGroupId: -1 }, options);
        this._setMainTextureSize();
        this._createMainTexture();
        this._createTextureAndPostProcesses();
        this._mergeEffect = this._createMergeEffect();
    };
    /**
     * Generates the index buffer of the full screen quad blending to the main canvas.
     */
    EffectLayer.prototype._generateIndexBuffer = function () {
        // Indices
        var indices = [];
        indices.push(0);
        indices.push(1);
        indices.push(2);
        indices.push(0);
        indices.push(2);
        indices.push(3);
        this._indexBuffer = this._engine.createIndexBuffer(indices);
    };
    /**
     * Generates the vertex buffer of the full screen quad blending to the main canvas.
     */
    EffectLayer.prototype._generateVertexBuffer = function () {
        // VBO
        var vertices = [];
        vertices.push(1, 1);
        vertices.push(-1, 1);
        vertices.push(-1, -1);
        vertices.push(1, -1);
        var vertexBuffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"](this._engine, vertices, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind, false, false, 2);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind] = vertexBuffer;
    };
    /**
     * Sets the main texture desired size which is the closest power of two
     * of the engine canvas size.
     */
    EffectLayer.prototype._setMainTextureSize = function () {
        if (this._effectLayerOptions.mainTextureFixedSize) {
            this._mainTextureDesiredSize.width = this._effectLayerOptions.mainTextureFixedSize;
            this._mainTextureDesiredSize.height = this._effectLayerOptions.mainTextureFixedSize;
        }
        else {
            this._mainTextureDesiredSize.width = this._engine.getRenderWidth() * this._effectLayerOptions.mainTextureRatio;
            this._mainTextureDesiredSize.height = this._engine.getRenderHeight() * this._effectLayerOptions.mainTextureRatio;
            this._mainTextureDesiredSize.width = this._engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].GetExponentOfTwo(this._mainTextureDesiredSize.width, this._maxSize) : this._mainTextureDesiredSize.width;
            this._mainTextureDesiredSize.height = this._engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].GetExponentOfTwo(this._mainTextureDesiredSize.height, this._maxSize) : this._mainTextureDesiredSize.height;
        }
        this._mainTextureDesiredSize.width = Math.floor(this._mainTextureDesiredSize.width);
        this._mainTextureDesiredSize.height = Math.floor(this._mainTextureDesiredSize.height);
    };
    /**
     * Creates the main texture for the effect layer.
     */
    EffectLayer.prototype._createMainTexture = function () {
        var _this = this;
        this._mainTexture = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_9__["RenderTargetTexture"]("HighlightLayerMainRTT", {
            width: this._mainTextureDesiredSize.width,
            height: this._mainTextureDesiredSize.height
        }, this._scene, false, true, _Engines_constants__WEBPACK_IMPORTED_MODULE_13__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this._mainTexture.activeCamera = this._effectLayerOptions.camera;
        this._mainTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].CLAMP_ADDRESSMODE;
        this._mainTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].CLAMP_ADDRESSMODE;
        this._mainTexture.anisotropicFilteringLevel = 1;
        this._mainTexture.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE);
        this._mainTexture.renderParticles = false;
        this._mainTexture.renderList = null;
        this._mainTexture.ignoreCameraViewport = true;
        // Custom render function
        this._mainTexture.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes) {
            _this.onBeforeRenderMainTextureObservable.notifyObservers(_this);
            var index;
            var engine = _this._scene.getEngine();
            if (depthOnlySubMeshes.length) {
                engine.setColorWrite(false);
                for (index = 0; index < depthOnlySubMeshes.length; index++) {
                    _this._renderSubMesh(depthOnlySubMeshes.data[index]);
                }
                engine.setColorWrite(true);
            }
            for (index = 0; index < opaqueSubMeshes.length; index++) {
                _this._renderSubMesh(opaqueSubMeshes.data[index]);
            }
            for (index = 0; index < alphaTestSubMeshes.length; index++) {
                _this._renderSubMesh(alphaTestSubMeshes.data[index]);
            }
            var previousAlphaMode = engine.getAlphaMode();
            for (index = 0; index < transparentSubMeshes.length; index++) {
                _this._renderSubMesh(transparentSubMeshes.data[index], true);
            }
            engine.setAlphaMode(previousAlphaMode);
        };
        this._mainTexture.onClearObservable.add(function (engine) {
            engine.clear(_this.neutralColor, true, true, true);
        });
    };
    /**
     * Adds specific effects defines.
     * @param defines The defines to add specifics to.
     */
    EffectLayer.prototype._addCustomEffectDefines = function (defines) {
        // Nothing to add by default.
    };
    /**
     * Checks for the readiness of the element composing the layer.
     * @param subMesh the mesh to check for
     * @param useInstances specify wether or not to use instances to render the mesh
     * @param emissiveTexture the associated emissive texture used to generate the glow
     * @return true if ready otherwise, false
     */
    EffectLayer.prototype._isReady = function (subMesh, useInstances, emissiveTexture) {
        var material = subMesh.getMaterial();
        if (!material) {
            return false;
        }
        if (!material.isReadyForSubMesh(subMesh.getMesh(), subMesh, useInstances)) {
            return false;
        }
        var defines = [];
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind];
        var mesh = subMesh.getMesh();
        var uv1 = false;
        var uv2 = false;
        // Diffuse
        if (material) {
            var needAlphaTest = material.needAlphaTesting();
            var diffuseTexture = material.getAlphaTestTexture();
            var needAlphaBlendFromDiffuse = diffuseTexture && diffuseTexture.hasAlpha &&
                (material.useAlphaFromDiffuseTexture || material._useAlphaFromAlbedoTexture);
            if (diffuseTexture && (needAlphaTest || needAlphaBlendFromDiffuse)) {
                defines.push("#define DIFFUSE");
                if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UV2Kind) &&
                    diffuseTexture.coordinatesIndex === 1) {
                    defines.push("#define DIFFUSEUV2");
                    uv2 = true;
                }
                else if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UVKind)) {
                    defines.push("#define DIFFUSEUV1");
                    uv1 = true;
                }
                if (needAlphaTest) {
                    defines.push("#define ALPHATEST");
                    defines.push("#define ALPHATESTVALUE 0.4");
                }
            }
            var opacityTexture = material.opacityTexture;
            if (opacityTexture) {
                defines.push("#define OPACITY");
                if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UV2Kind) &&
                    opacityTexture.coordinatesIndex === 1) {
                    defines.push("#define OPACITYUV2");
                    uv2 = true;
                }
                else if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UVKind)) {
                    defines.push("#define OPACITYUV1");
                    uv1 = true;
                }
            }
        }
        // Emissive
        if (emissiveTexture) {
            defines.push("#define EMISSIVE");
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UV2Kind) &&
                emissiveTexture.coordinatesIndex === 1) {
                defines.push("#define EMISSIVEUV2");
                uv2 = true;
            }
            else if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UVKind)) {
                defines.push("#define EMISSIVEUV1");
                uv1 = true;
            }
        }
        // Vertex
        if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].ColorKind) && mesh.hasVertexAlpha) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].ColorKind);
            defines.push("#define VERTEXALPHA");
        }
        if (uv1) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UVKind);
            defines.push("#define UV1");
        }
        if (uv2) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UV2Kind);
            defines.push("#define UV2");
        }
        // Bones
        var fallbacks = new _Materials_effect__WEBPACK_IMPORTED_MODULE_10__["EffectFallbacks"]();
        if (mesh.useBones && mesh.computeBonesUsingShaders) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].MatricesWeightsKind);
            if (mesh.numBoneInfluencers > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].MatricesWeightsExtraKind);
            }
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            var skeleton = mesh.skeleton;
            if (skeleton && skeleton.isUsingTextureForMatrices) {
                defines.push("#define BONETEXTURE");
            }
            else {
                defines.push("#define BonesPerMesh " + (skeleton ? (skeleton.bones.length + 1) : 0));
            }
            if (mesh.numBoneInfluencers > 0) {
                fallbacks.addCPUSkinningFallback(0, mesh);
            }
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Morph targets
        var manager = mesh.morphTargetManager;
        var morphInfluencers = 0;
        if (manager) {
            if (manager.numInfluencers > 0) {
                defines.push("#define MORPHTARGETS");
                morphInfluencers = manager.numInfluencers;
                defines.push("#define NUM_MORPH_INFLUENCERS " + morphInfluencers);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_12__["MaterialHelper"].PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, morphInfluencers);
            }
        }
        // Instances
        if (useInstances) {
            defines.push("#define INSTANCES");
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_12__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        this._addCustomEffectDefines(defines);
        // Get correct effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            this._effectLayerMapGenerationEffect = this._scene.getEngine().createEffect("glowMapGeneration", attribs, ["world", "mBones", "viewProjection",
                "glowColor", "morphTargetInfluences", "boneTextureWidth",
                "diffuseMatrix", "emissiveMatrix", "opacityMatrix", "opacityIntensity"], ["diffuseSampler", "emissiveSampler", "opacitySampler", "boneSampler"], join, fallbacks, undefined, undefined, { maxSimultaneousMorphTargets: morphInfluencers });
        }
        return this._effectLayerMapGenerationEffect.isReady();
    };
    /**
     * Renders the glowing part of the scene by blending the blurred glowing meshes on top of the rendered scene.
     */
    EffectLayer.prototype.render = function () {
        var currentEffect = this._mergeEffect;
        // Check
        if (!currentEffect.isReady()) {
            return;
        }
        for (var i = 0; i < this._postProcesses.length; i++) {
            if (!this._postProcesses[i].isReady()) {
                return;
            }
        }
        var engine = this._scene.getEngine();
        this.onBeforeComposeObservable.notifyObservers(this);
        // Render
        engine.enableEffect(currentEffect);
        engine.setState(false);
        // VBOs
        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, currentEffect);
        // Cache
        var previousAlphaMode = engine.getAlphaMode();
        // Go Blend.
        engine.setAlphaMode(this._effectLayerOptions.alphaBlendingMode);
        // Blends the map on the main canvas.
        this._internalRender(currentEffect);
        // Restore Alpha
        engine.setAlphaMode(previousAlphaMode);
        this.onAfterComposeObservable.notifyObservers(this);
        // Handle size changes.
        var size = this._mainTexture.getSize();
        this._setMainTextureSize();
        if (size.width !== this._mainTextureDesiredSize.width || size.height !== this._mainTextureDesiredSize.height) {
            // Recreate RTT and post processes on size change.
            this.onSizeChangedObservable.notifyObservers(this);
            this._disposeTextureAndPostProcesses();
            this._createMainTexture();
            this._createTextureAndPostProcesses();
        }
    };
    /**
     * Determine if a given mesh will be used in the current effect.
     * @param mesh mesh to test
     * @returns true if the mesh will be used
     */
    EffectLayer.prototype.hasMesh = function (mesh) {
        if (this.renderingGroupId === -1 || mesh.renderingGroupId === this.renderingGroupId) {
            return true;
        }
        return false;
    };
    /**
     * Returns true if the layer contains information to display, otherwise false.
     * @returns true if the glow layer should be rendered
     */
    EffectLayer.prototype.shouldRender = function () {
        return this.isEnabled && this._shouldRender;
    };
    /**
     * Returns true if the mesh should render, otherwise false.
     * @param mesh The mesh to render
     * @returns true if it should render otherwise false
     */
    EffectLayer.prototype._shouldRenderMesh = function (mesh) {
        return true;
    };
    /**
     * Returns true if the mesh can be rendered, otherwise false.
     * @param mesh The mesh to render
     * @param material The material used on the mesh
     * @returns true if it can be rendered otherwise false
     */
    EffectLayer.prototype._canRenderMesh = function (mesh, material) {
        return !material.needAlphaBlendingForMesh(mesh);
    };
    /**
     * Returns true if the mesh should render, otherwise false.
     * @param mesh The mesh to render
     * @returns true if it should render otherwise false
     */
    EffectLayer.prototype._shouldRenderEmissiveTextureForMesh = function () {
        return true;
    };
    /**
     * Renders the submesh passed in parameter to the generation map.
     */
    EffectLayer.prototype._renderSubMesh = function (subMesh, enableAlphaMode) {
        var _this = this;
        if (enableAlphaMode === void 0) { enableAlphaMode = false; }
        if (!this.shouldRender()) {
            return;
        }
        var material = subMesh.getMaterial();
        var mesh = subMesh.getRenderingMesh();
        var scene = this._scene;
        var engine = scene.getEngine();
        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
        if (!material) {
            return;
        }
        // Do not block in blend mode.
        if (!this._canRenderMesh(mesh, material)) {
            return;
        }
        // Culling
        engine.setState(material.backFaceCulling);
        // Managing instances
        var batch = mesh._getInstancesRenderList(subMesh._id);
        if (batch.mustReturn) {
            return;
        }
        // Early Exit per mesh
        if (!this._shouldRenderMesh(mesh)) {
            return;
        }
        var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
        this._setEmissiveTextureAndColor(mesh, subMesh, material);
        if (this._isReady(subMesh, hardwareInstancedRendering, this._emissiveTextureAndColor.texture)) {
            engine.enableEffect(this._effectLayerMapGenerationEffect);
            mesh._bind(subMesh, this._effectLayerMapGenerationEffect, _Materials_material__WEBPACK_IMPORTED_MODULE_11__["Material"].TriangleFillMode);
            this._effectLayerMapGenerationEffect.setMatrix("viewProjection", scene.getTransformMatrix());
            this._effectLayerMapGenerationEffect.setFloat4("glowColor", this._emissiveTextureAndColor.color.r, this._emissiveTextureAndColor.color.g, this._emissiveTextureAndColor.color.b, this._emissiveTextureAndColor.color.a);
            var needAlphaTest = material.needAlphaTesting();
            var diffuseTexture = material.getAlphaTestTexture();
            var needAlphaBlendFromDiffuse = diffuseTexture && diffuseTexture.hasAlpha &&
                (material.useAlphaFromDiffuseTexture || material._useAlphaFromAlbedoTexture);
            if (diffuseTexture && (needAlphaTest || needAlphaBlendFromDiffuse)) {
                this._effectLayerMapGenerationEffect.setTexture("diffuseSampler", diffuseTexture);
                var textureMatrix = diffuseTexture.getTextureMatrix();
                if (textureMatrix) {
                    this._effectLayerMapGenerationEffect.setMatrix("diffuseMatrix", textureMatrix);
                }
            }
            var opacityTexture = material.opacityTexture;
            if (opacityTexture) {
                this._effectLayerMapGenerationEffect.setTexture("opacitySampler", opacityTexture);
                this._effectLayerMapGenerationEffect.setFloat("opacityIntensity", opacityTexture.level);
                var textureMatrix = opacityTexture.getTextureMatrix();
                if (textureMatrix) {
                    this._effectLayerMapGenerationEffect.setMatrix("opacityMatrix", textureMatrix);
                }
            }
            // Glow emissive only
            if (this._emissiveTextureAndColor.texture) {
                this._effectLayerMapGenerationEffect.setTexture("emissiveSampler", this._emissiveTextureAndColor.texture);
                this._effectLayerMapGenerationEffect.setMatrix("emissiveMatrix", this._emissiveTextureAndColor.texture.getTextureMatrix());
            }
            // Bones
            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                var skeleton = mesh.skeleton;
                if (skeleton.isUsingTextureForMatrices) {
                    var boneTexture = skeleton.getTransformMatrixTexture(mesh);
                    if (!boneTexture) {
                        return;
                    }
                    this._effectLayerMapGenerationEffect.setTexture("boneSampler", boneTexture);
                    this._effectLayerMapGenerationEffect.setFloat("boneTextureWidth", 4.0 * (skeleton.bones.length + 1));
                }
                else {
                    this._effectLayerMapGenerationEffect.setMatrices("mBones", skeleton.getTransformMatrices((mesh)));
                }
            }
            // Morph targets
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_12__["MaterialHelper"].BindMorphTargetParameters(mesh, this._effectLayerMapGenerationEffect);
            // Alpha mode
            if (enableAlphaMode) {
                engine.setAlphaMode(material.alphaMode);
            }
            // Draw
            mesh._processRendering(subMesh, this._effectLayerMapGenerationEffect, _Materials_material__WEBPACK_IMPORTED_MODULE_11__["Material"].TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._effectLayerMapGenerationEffect.setMatrix("world", world); });
        }
        else {
            // Need to reset refresh rate of the main map
            this._mainTexture.resetRefreshCounter();
        }
    };
    /**
     * Rebuild the required buffers.
     * @hidden Internal use only.
     */
    EffectLayer.prototype._rebuild = function () {
        var vb = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind];
        if (vb) {
            vb._rebuild();
        }
        this._generateIndexBuffer();
    };
    /**
     * Dispose only the render target textures and post process.
     */
    EffectLayer.prototype._disposeTextureAndPostProcesses = function () {
        this._mainTexture.dispose();
        for (var i = 0; i < this._postProcesses.length; i++) {
            if (this._postProcesses[i]) {
                this._postProcesses[i].dispose();
            }
        }
        this._postProcesses = [];
        for (var i = 0; i < this._textures.length; i++) {
            if (this._textures[i]) {
                this._textures[i].dispose();
            }
        }
        this._textures = [];
    };
    /**
     * Dispose the highlight layer and free resources.
     */
    EffectLayer.prototype.dispose = function () {
        var vertexBuffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind];
        if (vertexBuffer) {
            vertexBuffer.dispose();
            this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind] = null;
        }
        if (this._indexBuffer) {
            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
            this._indexBuffer = null;
        }
        // Clean textures and post processes
        this._disposeTextureAndPostProcesses();
        // Remove from scene
        var index = this._scene.effectLayers.indexOf(this, 0);
        if (index > -1) {
            this._scene.effectLayers.splice(index, 1);
        }
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
        this.onBeforeRenderMainTextureObservable.clear();
        this.onBeforeComposeObservable.clear();
        this.onAfterComposeObservable.clear();
        this.onSizeChangedObservable.clear();
    };
    /**
      * Gets the class name of the effect layer
      * @returns the string with the class name of the effect layer
      */
    EffectLayer.prototype.getClassName = function () {
        return "EffectLayer";
    };
    /**
     * Creates an effect layer from parsed effect layer data
     * @param parsedEffectLayer defines effect layer data
     * @param scene defines the current scene
     * @param rootUrl defines the root URL containing the effect layer information
     * @returns a parsed effect Layer
     */
    EffectLayer.Parse = function (parsedEffectLayer, scene, rootUrl) {
        var effectLayerType = _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].Instantiate(parsedEffectLayer.customType);
        return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);
    };
    /** @hidden */
    EffectLayer._SceneComponentInitialization = function (_) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_16__["_DevTools"].WarnImport("EffectLayerSceneComponent");
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], EffectLayer.prototype, "name", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor4"])()
    ], EffectLayer.prototype, "neutralColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], EffectLayer.prototype, "isEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsCameraReference"])()
    ], EffectLayer.prototype, "camera", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], EffectLayer.prototype, "renderingGroupId", null);
    return EffectLayer;
}());



/***/ }),

/***/ "./Layers/effectLayerSceneComponent.ts":
/*!*********************************************!*\
  !*** ./Layers/effectLayerSceneComponent.ts ***!
  \*********************************************/
/*! exports provided: EffectLayerSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EffectLayerSceneComponent", function() { return EffectLayerSceneComponent; });
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _effectLayer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./effectLayer */ "./Layers/effectLayer.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");




// Adds the parser to the scene parsers.
_abstractScene__WEBPACK_IMPORTED_MODULE_3__["AbstractScene"].AddParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_EFFECTLAYER, function (parsedData, scene, container, rootUrl) {
    if (parsedData.effectLayers) {
        if (!container.effectLayers) {
            container.effectLayers = new Array();
        }
        for (var index = 0; index < parsedData.effectLayers.length; index++) {
            var effectLayer = _effectLayer__WEBPACK_IMPORTED_MODULE_2__["EffectLayer"].Parse(parsedData.effectLayers[index], scene, rootUrl);
            container.effectLayers.push(effectLayer);
        }
    }
});
_abstractScene__WEBPACK_IMPORTED_MODULE_3__["AbstractScene"].prototype.removeEffectLayer = function (toRemove) {
    var index = this.effectLayers.indexOf(toRemove);
    if (index !== -1) {
        this.effectLayers.splice(index, 1);
    }
    return index;
};
_abstractScene__WEBPACK_IMPORTED_MODULE_3__["AbstractScene"].prototype.addEffectLayer = function (newEffectLayer) {
    this.effectLayers.push(newEffectLayer);
};
/**
 * Defines the layer scene component responsible to manage any effect layers
 * in a given scene.
 */
var EffectLayerSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function EffectLayerSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_EFFECTLAYER;
        this._renderEffects = false;
        this._needStencil = false;
        this._previousStencilState = false;
        this.scene = scene;
        this._engine = scene.getEngine();
        scene.effectLayers = new Array();
    }
    /**
     * Registers the component in a given scene
     */
    EffectLayerSceneComponent.prototype.register = function () {
        this.scene._isReadyForMeshStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_ISREADYFORMESH_EFFECTLAYER, this, this._isReadyForMesh);
        this.scene._cameraDrawRenderTargetStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER, this, this._renderMainTexture);
        this.scene._beforeCameraDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_BEFORECAMERADRAW_EFFECTLAYER, this, this._setStencil);
        this.scene._afterRenderingGroupDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW, this, this._drawRenderingGroup);
        this.scene._afterCameraDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_AFTERCAMERADRAW_EFFECTLAYER, this, this._setStencilBack);
        this.scene._afterCameraDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW, this, this._drawCamera);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    EffectLayerSceneComponent.prototype.rebuild = function () {
        var layers = this.scene.effectLayers;
        for (var _i = 0, layers_1 = layers; _i < layers_1.length; _i++) {
            var effectLayer = layers_1[_i];
            effectLayer._rebuild();
        }
    };
    /**
     * Serializes the component data to the specified json object
     * @param serializationObject The object to serialize to
     */
    EffectLayerSceneComponent.prototype.serialize = function (serializationObject) {
        // Effect layers
        serializationObject.effectLayers = [];
        var layers = this.scene.effectLayers;
        for (var _i = 0, layers_2 = layers; _i < layers_2.length; _i++) {
            var effectLayer = layers_2[_i];
            if (effectLayer.serialize) {
                serializationObject.effectLayers.push(effectLayer.serialize());
            }
        }
    };
    /**
     * Adds all the elements from the container to the scene
     * @param container the container holding the elements
     */
    EffectLayerSceneComponent.prototype.addFromContainer = function (container) {
        var _this = this;
        if (!container.effectLayers) {
            return;
        }
        container.effectLayers.forEach(function (o) {
            _this.scene.addEffectLayer(o);
        });
    };
    /**
     * Removes all the elements in the container from the scene
     * @param container contains the elements to remove
     * @param dispose if the removed element should be disposed (default: false)
     */
    EffectLayerSceneComponent.prototype.removeFromContainer = function (container, dispose) {
        var _this = this;
        if (!container.effectLayers) {
            return;
        }
        container.effectLayers.forEach(function (o) {
            _this.scene.removeEffectLayer(o);
            if (dispose) {
                o.dispose();
            }
        });
    };
    /**
     * Disposes the component and the associated ressources.
     */
    EffectLayerSceneComponent.prototype.dispose = function () {
        var layers = this.scene.effectLayers;
        while (layers.length) {
            layers[0].dispose();
        }
    };
    EffectLayerSceneComponent.prototype._isReadyForMesh = function (mesh, hardwareInstancedRendering) {
        var layers = this.scene.effectLayers;
        for (var _i = 0, layers_3 = layers; _i < layers_3.length; _i++) {
            var layer = layers_3[_i];
            if (!layer.hasMesh(mesh)) {
                continue;
            }
            for (var _a = 0, _b = mesh.subMeshes; _a < _b.length; _a++) {
                var subMesh = _b[_a];
                if (!layer.isReady(subMesh, hardwareInstancedRendering)) {
                    return false;
                }
            }
        }
        return true;
    };
    EffectLayerSceneComponent.prototype._renderMainTexture = function (camera) {
        this._renderEffects = false;
        this._needStencil = false;
        var needRebind = false;
        var layers = this.scene.effectLayers;
        if (layers && layers.length > 0) {
            this._previousStencilState = this._engine.getStencilBuffer();
            for (var _i = 0, layers_4 = layers; _i < layers_4.length; _i++) {
                var effectLayer = layers_4[_i];
                if (effectLayer.shouldRender() &&
                    (!effectLayer.camera ||
                        (effectLayer.camera.cameraRigMode === _Cameras_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].RIG_MODE_NONE && camera === effectLayer.camera) ||
                        (effectLayer.camera.cameraRigMode !== _Cameras_camera__WEBPACK_IMPORTED_MODULE_0__["Camera"].RIG_MODE_NONE && effectLayer.camera._rigCameras.indexOf(camera) > -1))) {
                    this._renderEffects = true;
                    this._needStencil = this._needStencil || effectLayer.needStencil();
                    var renderTarget = effectLayer._mainTexture;
                    if (renderTarget._shouldRender()) {
                        this.scene.incrementRenderId();
                        renderTarget.render(false, false);
                        needRebind = true;
                    }
                }
            }
            this.scene.incrementRenderId();
        }
        return needRebind;
    };
    EffectLayerSceneComponent.prototype._setStencil = function () {
        // Activate effect Layer stencil
        if (this._needStencil) {
            this._engine.setStencilBuffer(true);
        }
    };
    EffectLayerSceneComponent.prototype._setStencilBack = function () {
        // Restore effect Layer stencil
        if (this._needStencil) {
            this._engine.setStencilBuffer(this._previousStencilState);
        }
    };
    EffectLayerSceneComponent.prototype._draw = function (renderingGroupId) {
        if (this._renderEffects) {
            this._engine.setDepthBuffer(false);
            var layers = this.scene.effectLayers;
            for (var i = 0; i < layers.length; i++) {
                var effectLayer = layers[i];
                if (effectLayer.renderingGroupId === renderingGroupId) {
                    if (effectLayer.shouldRender()) {
                        effectLayer.render();
                    }
                }
            }
            this._engine.setDepthBuffer(true);
        }
    };
    EffectLayerSceneComponent.prototype._drawCamera = function () {
        if (this._renderEffects) {
            this._draw(-1);
        }
    };
    EffectLayerSceneComponent.prototype._drawRenderingGroup = function (index) {
        if (!this.scene._isInIntermediateRendering() && this._renderEffects) {
            this._draw(index);
        }
    };
    return EffectLayerSceneComponent;
}());

_effectLayer__WEBPACK_IMPORTED_MODULE_2__["EffectLayer"]._SceneComponentInitialization = function (scene) {
    var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_EFFECTLAYER);
    if (!component) {
        component = new EffectLayerSceneComponent(scene);
        scene._addComponent(component);
    }
};


/***/ }),

/***/ "./Layers/glowLayer.ts":
/*!*****************************!*\
  !*** ./Layers/glowLayer.ts ***!
  \*****************************/
/*! exports provided: GlowLayer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GlowLayer", function() { return GlowLayer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../PostProcesses/blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _effectLayer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./effectLayer */ "./Layers/effectLayer.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Shaders_glowMapMerge_fragment__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Shaders/glowMapMerge.fragment */ "./Shaders/glowMapMerge.fragment.ts");
/* harmony import */ var _Shaders_glowMapMerge_vertex__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Shaders/glowMapMerge.vertex */ "./Shaders/glowMapMerge.vertex.ts");
/* harmony import */ var _Layers_effectLayerSceneComponent__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Layers/effectLayerSceneComponent */ "./Layers/effectLayerSceneComponent.ts");

















_abstractScene__WEBPACK_IMPORTED_MODULE_9__["AbstractScene"].prototype.getGlowLayerByName = function (name) {
    for (var index = 0; index < this.effectLayers.length; index++) {
        if (this.effectLayers[index].name === name && this.effectLayers[index].getEffectName() === GlowLayer.EffectName) {
            return this.effectLayers[index];
        }
    }
    return null;
};
/**
 * The glow layer Helps adding a glow effect around the emissive parts of a mesh.
 *
 * Once instantiated in a scene, simply use the pushMesh or removeMesh method to add or remove
 * glowy meshes to your scene.
 *
 * Documentation: https://doc.babylonjs.com/how_to/glow_layer
 */
var GlowLayer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GlowLayer, _super);
    /**
     * Instantiates a new glow Layer and references it to the scene.
     * @param name The name of the layer
     * @param scene The scene to use the layer in
     * @param options Sets of none mandatory options to use with the layer (see IGlowLayerOptions for more information)
     */
    function GlowLayer(name, scene, options) {
        var _this = _super.call(this, name, scene) || this;
        _this._intensity = 1.0;
        _this._includedOnlyMeshes = [];
        _this._excludedMeshes = [];
        _this.neutralColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color4"](0, 0, 0, 1);
        // Adapt options
        _this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ mainTextureRatio: GlowLayer.DefaultTextureRatio, blurKernelSize: 32, mainTextureFixedSize: undefined, camera: null, mainTextureSamples: 1, renderingGroupId: -1 }, options);
        // Initialize the layer
        _this._init({
            alphaBlendingMode: _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].ALPHA_ADD,
            camera: _this._options.camera,
            mainTextureFixedSize: _this._options.mainTextureFixedSize,
            mainTextureRatio: _this._options.mainTextureRatio,
            renderingGroupId: _this._options.renderingGroupId
        });
        return _this;
    }
    Object.defineProperty(GlowLayer.prototype, "blurKernelSize", {
        /**
         * Gets the kernel size of the blur.
         */
        get: function () {
            return this._horizontalBlurPostprocess1.kernel;
        },
        /**
         * Sets the kernel size of the blur.
         */
        set: function (value) {
            this._horizontalBlurPostprocess1.kernel = value;
            this._verticalBlurPostprocess1.kernel = value;
            this._horizontalBlurPostprocess2.kernel = value;
            this._verticalBlurPostprocess2.kernel = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GlowLayer.prototype, "intensity", {
        /**
         * Gets the glow intensity.
         */
        get: function () {
            return this._intensity;
        },
        /**
         * Sets the glow intensity.
         */
        set: function (value) {
            this._intensity = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the effect name of the layer.
     * @return The effect name
     */
    GlowLayer.prototype.getEffectName = function () {
        return GlowLayer.EffectName;
    };
    /**
     * Create the merge effect. This is the shader use to blit the information back
     * to the main canvas at the end of the scene rendering.
     */
    GlowLayer.prototype._createMergeEffect = function () {
        // Effect
        return this._engine.createEffect("glowMapMerge", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind], ["offset"], ["textureSampler", "textureSampler2"], "#define EMISSIVE \n");
    };
    /**
     * Creates the render target textures and post processes used in the glow layer.
     */
    GlowLayer.prototype._createTextureAndPostProcesses = function () {
        var _this = this;
        var blurTextureWidth = this._mainTextureDesiredSize.width;
        var blurTextureHeight = this._mainTextureDesiredSize.height;
        blurTextureWidth = this._engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_12__["Engine"].GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
        blurTextureHeight = this._engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_12__["Engine"].GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
        var textureType = 0;
        if (this._engine.getCaps().textureHalfFloatRender) {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].TEXTURETYPE_HALF_FLOAT;
        }
        else {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        }
        this._blurTexture1 = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_5__["RenderTargetTexture"]("GlowLayerBlurRTT", {
            width: blurTextureWidth,
            height: blurTextureHeight
        }, this._scene, false, true, textureType);
        this._blurTexture1.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
        this._blurTexture1.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
        this._blurTexture1.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE);
        this._blurTexture1.renderParticles = false;
        this._blurTexture1.ignoreCameraViewport = true;
        var blurTextureWidth2 = Math.floor(blurTextureWidth / 2);
        var blurTextureHeight2 = Math.floor(blurTextureHeight / 2);
        this._blurTexture2 = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_5__["RenderTargetTexture"]("GlowLayerBlurRTT2", {
            width: blurTextureWidth2,
            height: blurTextureHeight2
        }, this._scene, false, true, textureType);
        this._blurTexture2.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
        this._blurTexture2.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
        this._blurTexture2.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE);
        this._blurTexture2.renderParticles = false;
        this._blurTexture2.ignoreCameraViewport = true;
        this._textures = [this._blurTexture1, this._blurTexture2];
        this._horizontalBlurPostprocess1 = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_7__["BlurPostProcess"]("GlowLayerHBP1", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](1.0, 0), this._options.blurKernelSize / 2, {
            width: blurTextureWidth,
            height: blurTextureHeight
        }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
        this._horizontalBlurPostprocess1.width = blurTextureWidth;
        this._horizontalBlurPostprocess1.height = blurTextureHeight;
        this._horizontalBlurPostprocess1.onApplyObservable.add(function (effect) {
            effect.setTexture("textureSampler", _this._mainTexture);
        });
        this._verticalBlurPostprocess1 = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_7__["BlurPostProcess"]("GlowLayerVBP1", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](0, 1.0), this._options.blurKernelSize / 2, {
            width: blurTextureWidth,
            height: blurTextureHeight
        }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
        this._horizontalBlurPostprocess2 = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_7__["BlurPostProcess"]("GlowLayerHBP2", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](1.0, 0), this._options.blurKernelSize / 2, {
            width: blurTextureWidth2,
            height: blurTextureHeight2
        }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
        this._horizontalBlurPostprocess2.width = blurTextureWidth2;
        this._horizontalBlurPostprocess2.height = blurTextureHeight2;
        this._horizontalBlurPostprocess2.onApplyObservable.add(function (effect) {
            effect.setTexture("textureSampler", _this._blurTexture1);
        });
        this._verticalBlurPostprocess2 = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_7__["BlurPostProcess"]("GlowLayerVBP2", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](0, 1.0), this._options.blurKernelSize / 2, {
            width: blurTextureWidth2,
            height: blurTextureHeight2
        }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
        this._postProcesses = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1, this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];
        this._postProcesses1 = [this._horizontalBlurPostprocess1, this._verticalBlurPostprocess1];
        this._postProcesses2 = [this._horizontalBlurPostprocess2, this._verticalBlurPostprocess2];
        this._mainTexture.samples = this._options.mainTextureSamples;
        this._mainTexture.onAfterUnbindObservable.add(function () {
            var internalTexture = _this._blurTexture1.getInternalTexture();
            if (internalTexture) {
                _this._scene.postProcessManager.directRender(_this._postProcesses1, internalTexture, true);
                internalTexture = _this._blurTexture2.getInternalTexture();
                if (internalTexture) {
                    _this._scene.postProcessManager.directRender(_this._postProcesses2, internalTexture, true);
                }
            }
        });
        // Prevent autoClear.
        this._postProcesses.map(function (pp) { pp.autoClear = false; });
    };
    /**
     * Checks for the readiness of the element composing the layer.
     * @param subMesh the mesh to check for
     * @param useInstances specify wether or not to use instances to render the mesh
     * @param emissiveTexture the associated emissive texture used to generate the glow
     * @return true if ready otherwise, false
     */
    GlowLayer.prototype.isReady = function (subMesh, useInstances) {
        var material = subMesh.getMaterial();
        var mesh = subMesh.getRenderingMesh();
        if (!material || !mesh) {
            return false;
        }
        var emissiveTexture = material.emissiveTexture;
        return _super.prototype._isReady.call(this, subMesh, useInstances, emissiveTexture);
    };
    /**
     * Returns wether or nood the layer needs stencil enabled during the mesh rendering.
     */
    GlowLayer.prototype.needStencil = function () {
        return false;
    };
    /**
     * Returns true if the mesh can be rendered, otherwise false.
     * @param mesh The mesh to render
     * @param material The material used on the mesh
     * @returns true if it can be rendered otherwise false
     */
    GlowLayer.prototype._canRenderMesh = function (mesh, material) {
        return true;
    };
    /**
     * Implementation specific of rendering the generating effect on the main canvas.
     * @param effect The effect used to render through
     */
    GlowLayer.prototype._internalRender = function (effect) {
        // Texture
        effect.setTexture("textureSampler", this._blurTexture1);
        effect.setTexture("textureSampler2", this._blurTexture2);
        effect.setFloat("offset", this._intensity);
        // Cache
        var engine = this._engine;
        var previousStencilBuffer = engine.getStencilBuffer();
        // Draw order
        engine.setStencilBuffer(false);
        engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_6__["Material"].TriangleFillMode, 0, 6);
        // Draw order
        engine.setStencilBuffer(previousStencilBuffer);
    };
    /**
     * Sets the required values for both the emissive texture and and the main color.
     */
    GlowLayer.prototype._setEmissiveTextureAndColor = function (mesh, subMesh, material) {
        var textureLevel = 1.0;
        if (this.customEmissiveTextureSelector) {
            this._emissiveTextureAndColor.texture = this.customEmissiveTextureSelector(mesh, subMesh, material);
        }
        else {
            if (material) {
                this._emissiveTextureAndColor.texture = material.emissiveTexture;
                if (this._emissiveTextureAndColor.texture) {
                    textureLevel = this._emissiveTextureAndColor.texture.level;
                }
            }
            else {
                this._emissiveTextureAndColor.texture = null;
            }
        }
        if (this.customEmissiveColorSelector) {
            this.customEmissiveColorSelector(mesh, subMesh, material, this._emissiveTextureAndColor.color);
        }
        else {
            if (material.emissiveColor) {
                this._emissiveTextureAndColor.color.set(material.emissiveColor.r * textureLevel, material.emissiveColor.g * textureLevel, material.emissiveColor.b * textureLevel, material.alpha);
            }
            else {
                this._emissiveTextureAndColor.color.set(this.neutralColor.r, this.neutralColor.g, this.neutralColor.b, this.neutralColor.a);
            }
        }
    };
    /**
     * Returns true if the mesh should render, otherwise false.
     * @param mesh The mesh to render
     * @returns true if it should render otherwise false
     */
    GlowLayer.prototype._shouldRenderMesh = function (mesh) {
        return this.hasMesh(mesh);
    };
    /**
     * Adds specific effects defines.
     * @param defines The defines to add specifics to.
     */
    GlowLayer.prototype._addCustomEffectDefines = function (defines) {
        defines.push("#define GLOW");
    };
    /**
     * Add a mesh in the exclusion list to prevent it to impact or being impacted by the glow layer.
     * @param mesh The mesh to exclude from the glow layer
     */
    GlowLayer.prototype.addExcludedMesh = function (mesh) {
        if (this._excludedMeshes.indexOf(mesh.uniqueId) === -1) {
            this._excludedMeshes.push(mesh.uniqueId);
        }
    };
    /**
      * Remove a mesh from the exclusion list to let it impact or being impacted by the glow layer.
      * @param mesh The mesh to remove
      */
    GlowLayer.prototype.removeExcludedMesh = function (mesh) {
        var index = this._excludedMeshes.indexOf(mesh.uniqueId);
        if (index !== -1) {
            this._excludedMeshes.splice(index, 1);
        }
    };
    /**
     * Add a mesh in the inclusion list to impact or being impacted by the glow layer.
     * @param mesh The mesh to include in the glow layer
     */
    GlowLayer.prototype.addIncludedOnlyMesh = function (mesh) {
        if (this._includedOnlyMeshes.indexOf(mesh.uniqueId) === -1) {
            this._includedOnlyMeshes.push(mesh.uniqueId);
        }
    };
    /**
      * Remove a mesh from the Inclusion list to prevent it to impact or being impacted by the glow layer.
      * @param mesh The mesh to remove
      */
    GlowLayer.prototype.removeIncludedOnlyMesh = function (mesh) {
        var index = this._includedOnlyMeshes.indexOf(mesh.uniqueId);
        if (index !== -1) {
            this._includedOnlyMeshes.splice(index, 1);
        }
    };
    /**
     * Determine if a given mesh will be used in the glow layer
     * @param mesh The mesh to test
     * @returns true if the mesh will be highlighted by the current glow layer
     */
    GlowLayer.prototype.hasMesh = function (mesh) {
        if (!_super.prototype.hasMesh.call(this, mesh)) {
            return false;
        }
        // Included Mesh
        if (this._includedOnlyMeshes.length) {
            return this._includedOnlyMeshes.indexOf(mesh.uniqueId) !== -1;
        }
        // Excluded Mesh
        if (this._excludedMeshes.length) {
            return this._excludedMeshes.indexOf(mesh.uniqueId) === -1;
        }
        return true;
    };
    /**
     * Free any resources and references associated to a mesh.
     * Internal use
     * @param mesh The mesh to free.
     * @hidden
     */
    GlowLayer.prototype._disposeMesh = function (mesh) {
        this.removeIncludedOnlyMesh(mesh);
        this.removeExcludedMesh(mesh);
    };
    /**
      * Gets the class name of the effect layer
      * @returns the string with the class name of the effect layer
      */
    GlowLayer.prototype.getClassName = function () {
        return "GlowLayer";
    };
    /**
     * Serializes this glow layer
     * @returns a serialized glow layer object
     */
    GlowLayer.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.GlowLayer";
        var index;
        // Included meshes
        serializationObject.includedMeshes = [];
        if (this._includedOnlyMeshes.length) {
            for (index = 0; index < this._includedOnlyMeshes.length; index++) {
                var mesh = this._scene.getMeshByUniqueID(this._includedOnlyMeshes[index]);
                if (mesh) {
                    serializationObject.includedMeshes.push(mesh.id);
                }
            }
        }
        // Excluded meshes
        serializationObject.excludedMeshes = [];
        if (this._excludedMeshes.length) {
            for (index = 0; index < this._excludedMeshes.length; index++) {
                var mesh = this._scene.getMeshByUniqueID(this._excludedMeshes[index]);
                if (mesh) {
                    serializationObject.excludedMeshes.push(mesh.id);
                }
            }
        }
        return serializationObject;
    };
    /**
     * Creates a Glow Layer from parsed glow layer data
     * @param parsedGlowLayer defines glow layer data
     * @param scene defines the current scene
     * @param rootUrl defines the root URL containing the glow layer information
     * @returns a parsed Glow Layer
     */
    GlowLayer.Parse = function (parsedGlowLayer, scene, rootUrl) {
        var gl = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new GlowLayer(parsedGlowLayer.name, scene, parsedGlowLayer.options); }, parsedGlowLayer, scene, rootUrl);
        var index;
        // Excluded meshes
        for (index = 0; index < parsedGlowLayer.excludedMeshes.length; index++) {
            var mesh = scene.getMeshByID(parsedGlowLayer.excludedMeshes[index]);
            if (mesh) {
                gl.addExcludedMesh(mesh);
            }
        }
        // Included meshes
        for (index = 0; index < parsedGlowLayer.includedMeshes.length; index++) {
            var mesh = scene.getMeshByID(parsedGlowLayer.includedMeshes[index]);
            if (mesh) {
                gl.addIncludedOnlyMesh(mesh);
            }
        }
        return gl;
    };
    /**
     * Effect Name of the layer.
     */
    GlowLayer.EffectName = "GlowLayer";
    /**
     * The default blur kernel size used for the glow.
     */
    GlowLayer.DefaultBlurKernelSize = 32;
    /**
     * The default texture size ratio used for the glow.
     */
    GlowLayer.DefaultTextureRatio = 0.5;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], GlowLayer.prototype, "blurKernelSize", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], GlowLayer.prototype, "intensity", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("options")
    ], GlowLayer.prototype, "_options", void 0);
    return GlowLayer;
}(_effectLayer__WEBPACK_IMPORTED_MODULE_8__["EffectLayer"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_11__["_TypeStore"].RegisteredTypes["BABYLON.GlowLayer"] = GlowLayer;


/***/ }),

/***/ "./Layers/highlightLayer.ts":
/*!**********************************!*\
  !*** ./Layers/highlightLayer.ts ***!
  \**********************************/
/*! exports provided: HighlightLayer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HighlightLayer", function() { return HighlightLayer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../PostProcesses/passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony import */ var _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../PostProcesses/blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _effectLayer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./effectLayer */ "./Layers/effectLayer.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Shaders_glowMapMerge_fragment__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../Shaders/glowMapMerge.fragment */ "./Shaders/glowMapMerge.fragment.ts");
/* harmony import */ var _Shaders_glowMapMerge_vertex__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../Shaders/glowMapMerge.vertex */ "./Shaders/glowMapMerge.vertex.ts");
/* harmony import */ var _Shaders_glowBlurPostProcess_fragment__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../Shaders/glowBlurPostProcess.fragment */ "./Shaders/glowBlurPostProcess.fragment.ts");





















_abstractScene__WEBPACK_IMPORTED_MODULE_13__["AbstractScene"].prototype.getHighlightLayerByName = function (name) {
    for (var index = 0; index < this.effectLayers.length; index++) {
        if (this.effectLayers[index].name === name && this.effectLayers[index].getEffectName() === HighlightLayer.EffectName) {
            return this.effectLayers[index];
        }
    }
    return null;
};
/**
 * Special Glow Blur post process only blurring the alpha channel
 * It enforces keeping the most luminous color in the color channel.
 */
var GlowBlurPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GlowBlurPostProcess, _super);
    function GlowBlurPostProcess(name, direction, kernel, options, camera, samplingMode, engine, reusable) {
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE; }
        var _this = _super.call(this, name, "glowBlurPostProcess", ["screenSize", "direction", "blurWidth"], null, options, camera, samplingMode, engine, reusable) || this;
        _this.direction = direction;
        _this.kernel = kernel;
        _this.onApplyObservable.add(function (effect) {
            effect.setFloat2("screenSize", _this.width, _this.height);
            effect.setVector2("direction", _this.direction);
            effect.setFloat("blurWidth", _this.kernel);
        });
        return _this;
    }
    return GlowBlurPostProcess;
}(_PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_9__["PostProcess"]));
/**
 * The highlight layer Helps adding a glow effect around a mesh.
 *
 * Once instantiated in a scene, simply use the pushMesh or removeMesh method to add or remove
 * glowy meshes to your scene.
 *
 * !!! THIS REQUIRES AN ACTIVE STENCIL BUFFER ON THE CANVAS !!!
 */
var HighlightLayer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HighlightLayer, _super);
    /**
     * Instantiates a new highlight Layer and references it to the scene..
     * @param name The name of the layer
     * @param scene The scene to use the layer in
     * @param options Sets of none mandatory options to use with the layer (see IHighlightLayerOptions for more information)
     */
    function HighlightLayer(name, scene, options) {
        var _this = _super.call(this, name, scene) || this;
        _this.name = name;
        /**
         * Specifies whether or not the inner glow is ACTIVE in the layer.
         */
        _this.innerGlow = true;
        /**
         * Specifies whether or not the outer glow is ACTIVE in the layer.
         */
        _this.outerGlow = true;
        /**
         * An event triggered when the highlight layer is being blurred.
         */
        _this.onBeforeBlurObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * An event triggered when the highlight layer has been blurred.
         */
        _this.onAfterBlurObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this._instanceGlowingMeshStencilReference = HighlightLayer.GlowingMeshStencilReference++;
        _this._meshes = {};
        _this._excludedMeshes = {};
        _this.neutralColor = HighlightLayer.NeutralColor;
        // Warn on stencil
        if (!_this._engine.isStencilEnable) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_15__["Logger"].Warn("Rendering the Highlight Layer requires the stencil to be active on the canvas. var engine = new Engine(canvas, antialias, { stencil: true }");
        }
        // Adapt options
        _this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ mainTextureRatio: 0.5, blurTextureSizeRatio: 0.5, blurHorizontalSize: 1.0, blurVerticalSize: 1.0, alphaBlendingMode: _Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].ALPHA_COMBINE, camera: null, renderingGroupId: -1 }, options);
        // Initialize the layer
        _this._init({
            alphaBlendingMode: _this._options.alphaBlendingMode,
            camera: _this._options.camera,
            mainTextureFixedSize: _this._options.mainTextureFixedSize,
            mainTextureRatio: _this._options.mainTextureRatio,
            renderingGroupId: _this._options.renderingGroupId
        });
        // Do not render as long as no meshes have been added
        _this._shouldRender = false;
        return _this;
    }
    Object.defineProperty(HighlightLayer.prototype, "blurHorizontalSize", {
        /**
         * Gets the horizontal size of the blur.
         */
        get: function () {
            return this._horizontalBlurPostprocess.kernel;
        },
        /**
         * Specifies the horizontal size of the blur.
         */
        set: function (value) {
            this._horizontalBlurPostprocess.kernel = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HighlightLayer.prototype, "blurVerticalSize", {
        /**
         * Gets the vertical size of the blur.
         */
        get: function () {
            return this._verticalBlurPostprocess.kernel;
        },
        /**
         * Specifies the vertical size of the blur.
         */
        set: function (value) {
            this._verticalBlurPostprocess.kernel = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the effect name of the layer.
     * @return The effect name
     */
    HighlightLayer.prototype.getEffectName = function () {
        return HighlightLayer.EffectName;
    };
    /**
     * Create the merge effect. This is the shader use to blit the information back
     * to the main canvas at the end of the scene rendering.
     */
    HighlightLayer.prototype._createMergeEffect = function () {
        // Effect
        return this._engine.createEffect("glowMapMerge", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind], ["offset"], ["textureSampler"], this._options.isStroke ? "#define STROKE \n" : undefined);
    };
    /**
     * Creates the render target textures and post processes used in the highlight layer.
     */
    HighlightLayer.prototype._createTextureAndPostProcesses = function () {
        var _this = this;
        var blurTextureWidth = this._mainTextureDesiredSize.width * this._options.blurTextureSizeRatio;
        var blurTextureHeight = this._mainTextureDesiredSize.height * this._options.blurTextureSizeRatio;
        blurTextureWidth = this._engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
        blurTextureHeight = this._engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
        var textureType = 0;
        if (this._engine.getCaps().textureHalfFloatRender) {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].TEXTURETYPE_HALF_FLOAT;
        }
        else {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        }
        this._blurTexture = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_8__["RenderTargetTexture"]("HighlightLayerBlurRTT", {
            width: blurTextureWidth,
            height: blurTextureHeight
        }, this._scene, false, true, textureType);
        this._blurTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].CLAMP_ADDRESSMODE;
        this._blurTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].CLAMP_ADDRESSMODE;
        this._blurTexture.anisotropicFilteringLevel = 16;
        this._blurTexture.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].TRILINEAR_SAMPLINGMODE);
        this._blurTexture.renderParticles = false;
        this._blurTexture.ignoreCameraViewport = true;
        this._textures = [this._blurTexture];
        if (this._options.alphaBlendingMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].ALPHA_COMBINE) {
            this._downSamplePostprocess = new _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_10__["PassPostProcess"]("HighlightLayerPPP", this._options.blurTextureSizeRatio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine());
            this._downSamplePostprocess.onApplyObservable.add(function (effect) {
                effect.setTexture("textureSampler", _this._mainTexture);
            });
            this._horizontalBlurPostprocess = new GlowBlurPostProcess("HighlightLayerHBP", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](1.0, 0), this._options.blurHorizontalSize, 1, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine());
            this._horizontalBlurPostprocess.onApplyObservable.add(function (effect) {
                effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
            });
            this._verticalBlurPostprocess = new GlowBlurPostProcess("HighlightLayerVBP", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](0, 1.0), this._options.blurVerticalSize, 1, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine());
            this._verticalBlurPostprocess.onApplyObservable.add(function (effect) {
                effect.setFloat2("screenSize", blurTextureWidth, blurTextureHeight);
            });
            this._postProcesses = [this._downSamplePostprocess, this._horizontalBlurPostprocess, this._verticalBlurPostprocess];
        }
        else {
            this._horizontalBlurPostprocess = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_11__["BlurPostProcess"]("HighlightLayerHBP", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](1.0, 0), this._options.blurHorizontalSize / 2, {
                width: blurTextureWidth,
                height: blurTextureHeight
            }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
            this._horizontalBlurPostprocess.width = blurTextureWidth;
            this._horizontalBlurPostprocess.height = blurTextureHeight;
            this._horizontalBlurPostprocess.onApplyObservable.add(function (effect) {
                effect.setTexture("textureSampler", _this._mainTexture);
            });
            this._verticalBlurPostprocess = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_11__["BlurPostProcess"]("HighlightLayerVBP", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](0, 1.0), this._options.blurVerticalSize / 2, {
                width: blurTextureWidth,
                height: blurTextureHeight
            }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_7__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, textureType);
            this._postProcesses = [this._horizontalBlurPostprocess, this._verticalBlurPostprocess];
        }
        this._mainTexture.onAfterUnbindObservable.add(function () {
            _this.onBeforeBlurObservable.notifyObservers(_this);
            var internalTexture = _this._blurTexture.getInternalTexture();
            if (internalTexture) {
                _this._scene.postProcessManager.directRender(_this._postProcesses, internalTexture, true);
            }
            _this.onAfterBlurObservable.notifyObservers(_this);
        });
        // Prevent autoClear.
        this._postProcesses.map(function (pp) { pp.autoClear = false; });
    };
    /**
     * Returns wether or nood the layer needs stencil enabled during the mesh rendering.
     */
    HighlightLayer.prototype.needStencil = function () {
        return true;
    };
    /**
     * Checks for the readiness of the element composing the layer.
     * @param subMesh the mesh to check for
     * @param useInstances specify wether or not to use instances to render the mesh
     * @param emissiveTexture the associated emissive texture used to generate the glow
     * @return true if ready otherwise, false
     */
    HighlightLayer.prototype.isReady = function (subMesh, useInstances) {
        var material = subMesh.getMaterial();
        var mesh = subMesh.getRenderingMesh();
        if (!material || !mesh || !this._meshes) {
            return false;
        }
        var emissiveTexture = null;
        var highlightLayerMesh = this._meshes[mesh.uniqueId];
        if (highlightLayerMesh && highlightLayerMesh.glowEmissiveOnly && material) {
            emissiveTexture = material.emissiveTexture;
        }
        return _super.prototype._isReady.call(this, subMesh, useInstances, emissiveTexture);
    };
    /**
     * Implementation specific of rendering the generating effect on the main canvas.
     * @param effect The effect used to render through
     */
    HighlightLayer.prototype._internalRender = function (effect) {
        // Texture
        effect.setTexture("textureSampler", this._blurTexture);
        // Cache
        var engine = this._engine;
        engine.cacheStencilState();
        // Stencil operations
        engine.setStencilOperationPass(_Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].REPLACE);
        engine.setStencilOperationFail(_Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].KEEP);
        engine.setStencilOperationDepthFail(_Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].KEEP);
        // Draw order
        engine.setStencilMask(0x00);
        engine.setStencilBuffer(true);
        engine.setStencilFunctionReference(this._instanceGlowingMeshStencilReference);
        // 2 passes inner outer
        if (this.outerGlow) {
            effect.setFloat("offset", 0);
            engine.setStencilFunction(_Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].NOTEQUAL);
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_6__["Material"].TriangleFillMode, 0, 6);
        }
        if (this.innerGlow) {
            effect.setFloat("offset", 1);
            engine.setStencilFunction(_Engines_constants__WEBPACK_IMPORTED_MODULE_14__["Constants"].EQUAL);
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_6__["Material"].TriangleFillMode, 0, 6);
        }
        // Restore Cache
        engine.restoreStencilState();
    };
    /**
     * Returns true if the layer contains information to display, otherwise false.
     */
    HighlightLayer.prototype.shouldRender = function () {
        if (_super.prototype.shouldRender.call(this)) {
            return this._meshes ? true : false;
        }
        return false;
    };
    /**
     * Returns true if the mesh should render, otherwise false.
     * @param mesh The mesh to render
     * @returns true if it should render otherwise false
     */
    HighlightLayer.prototype._shouldRenderMesh = function (mesh) {
        // Excluded Mesh
        if (this._excludedMeshes && this._excludedMeshes[mesh.uniqueId]) {
            return false;
        }
        if (!_super.prototype.hasMesh.call(this, mesh)) {
            return false;
        }
        return true;
    };
    /**
     * Sets the required values for both the emissive texture and and the main color.
     */
    HighlightLayer.prototype._setEmissiveTextureAndColor = function (mesh, subMesh, material) {
        var highlightLayerMesh = this._meshes[mesh.uniqueId];
        if (highlightLayerMesh) {
            this._emissiveTextureAndColor.color.set(highlightLayerMesh.color.r, highlightLayerMesh.color.g, highlightLayerMesh.color.b, 1.0);
        }
        else {
            this._emissiveTextureAndColor.color.set(this.neutralColor.r, this.neutralColor.g, this.neutralColor.b, this.neutralColor.a);
        }
        if (highlightLayerMesh && highlightLayerMesh.glowEmissiveOnly && material) {
            this._emissiveTextureAndColor.texture = material.emissiveTexture;
            this._emissiveTextureAndColor.color.set(1.0, 1.0, 1.0, 1.0);
        }
        else {
            this._emissiveTextureAndColor.texture = null;
        }
    };
    /**
     * Add a mesh in the exclusion list to prevent it to impact or being impacted by the highlight layer.
     * @param mesh The mesh to exclude from the highlight layer
     */
    HighlightLayer.prototype.addExcludedMesh = function (mesh) {
        if (!this._excludedMeshes) {
            return;
        }
        var meshExcluded = this._excludedMeshes[mesh.uniqueId];
        if (!meshExcluded) {
            this._excludedMeshes[mesh.uniqueId] = {
                mesh: mesh,
                beforeBind: mesh.onBeforeBindObservable.add(function (mesh) {
                    mesh.getEngine().setStencilBuffer(false);
                }),
                afterRender: mesh.onAfterRenderObservable.add(function (mesh) {
                    mesh.getEngine().setStencilBuffer(true);
                }),
            };
        }
    };
    /**
      * Remove a mesh from the exclusion list to let it impact or being impacted by the highlight layer.
      * @param mesh The mesh to highlight
      */
    HighlightLayer.prototype.removeExcludedMesh = function (mesh) {
        if (!this._excludedMeshes) {
            return;
        }
        var meshExcluded = this._excludedMeshes[mesh.uniqueId];
        if (meshExcluded) {
            if (meshExcluded.beforeBind) {
                mesh.onBeforeBindObservable.remove(meshExcluded.beforeBind);
            }
            if (meshExcluded.afterRender) {
                mesh.onAfterRenderObservable.remove(meshExcluded.afterRender);
            }
        }
        this._excludedMeshes[mesh.uniqueId] = null;
    };
    /**
     * Determine if a given mesh will be highlighted by the current HighlightLayer
     * @param mesh mesh to test
     * @returns true if the mesh will be highlighted by the current HighlightLayer
     */
    HighlightLayer.prototype.hasMesh = function (mesh) {
        if (!this._meshes) {
            return false;
        }
        if (!_super.prototype.hasMesh.call(this, mesh)) {
            return false;
        }
        return this._meshes[mesh.uniqueId] !== undefined && this._meshes[mesh.uniqueId] !== null;
    };
    /**
     * Add a mesh in the highlight layer in order to make it glow with the chosen color.
     * @param mesh The mesh to highlight
     * @param color The color of the highlight
     * @param glowEmissiveOnly Extract the glow from the emissive texture
     */
    HighlightLayer.prototype.addMesh = function (mesh, color, glowEmissiveOnly) {
        var _this = this;
        if (glowEmissiveOnly === void 0) { glowEmissiveOnly = false; }
        if (!this._meshes) {
            return;
        }
        var meshHighlight = this._meshes[mesh.uniqueId];
        if (meshHighlight) {
            meshHighlight.color = color;
        }
        else {
            this._meshes[mesh.uniqueId] = {
                mesh: mesh,
                color: color,
                // Lambda required for capture due to Observable this context
                observerHighlight: mesh.onBeforeBindObservable.add(function (mesh) {
                    if (_this.isEnabled) {
                        if (_this._excludedMeshes && _this._excludedMeshes[mesh.uniqueId]) {
                            _this._defaultStencilReference(mesh);
                        }
                        else {
                            mesh.getScene().getEngine().setStencilFunctionReference(_this._instanceGlowingMeshStencilReference);
                        }
                    }
                }),
                observerDefault: mesh.onAfterRenderObservable.add(function (mesh) {
                    if (_this.isEnabled) {
                        _this._defaultStencilReference(mesh);
                    }
                }),
                glowEmissiveOnly: glowEmissiveOnly
            };
            mesh.onDisposeObservable.add(function () {
                _this._disposeMesh(mesh);
            });
        }
        this._shouldRender = true;
    };
    /**
     * Remove a mesh from the highlight layer in order to make it stop glowing.
     * @param mesh The mesh to highlight
     */
    HighlightLayer.prototype.removeMesh = function (mesh) {
        if (!this._meshes) {
            return;
        }
        var meshHighlight = this._meshes[mesh.uniqueId];
        if (meshHighlight) {
            if (meshHighlight.observerHighlight) {
                mesh.onBeforeBindObservable.remove(meshHighlight.observerHighlight);
            }
            if (meshHighlight.observerDefault) {
                mesh.onAfterRenderObservable.remove(meshHighlight.observerDefault);
            }
            delete this._meshes[mesh.uniqueId];
        }
        this._shouldRender = false;
        for (var meshHighlightToCheck in this._meshes) {
            if (this._meshes[meshHighlightToCheck]) {
                this._shouldRender = true;
                break;
            }
        }
    };
    /**
     * Force the stencil to the normal expected value for none glowing parts
     */
    HighlightLayer.prototype._defaultStencilReference = function (mesh) {
        mesh.getScene().getEngine().setStencilFunctionReference(HighlightLayer.NormalMeshStencilReference);
    };
    /**
     * Free any resources and references associated to a mesh.
     * Internal use
     * @param mesh The mesh to free.
     * @hidden
     */
    HighlightLayer.prototype._disposeMesh = function (mesh) {
        this.removeMesh(mesh);
        this.removeExcludedMesh(mesh);
    };
    /**
     * Dispose the highlight layer and free resources.
     */
    HighlightLayer.prototype.dispose = function () {
        if (this._meshes) {
            // Clean mesh references
            for (var id in this._meshes) {
                var meshHighlight = this._meshes[id];
                if (meshHighlight && meshHighlight.mesh) {
                    if (meshHighlight.observerHighlight) {
                        meshHighlight.mesh.onBeforeBindObservable.remove(meshHighlight.observerHighlight);
                    }
                    if (meshHighlight.observerDefault) {
                        meshHighlight.mesh.onAfterRenderObservable.remove(meshHighlight.observerDefault);
                    }
                }
            }
            this._meshes = null;
        }
        if (this._excludedMeshes) {
            for (var id in this._excludedMeshes) {
                var meshHighlight = this._excludedMeshes[id];
                if (meshHighlight) {
                    if (meshHighlight.beforeBind) {
                        meshHighlight.mesh.onBeforeBindObservable.remove(meshHighlight.beforeBind);
                    }
                    if (meshHighlight.afterRender) {
                        meshHighlight.mesh.onAfterRenderObservable.remove(meshHighlight.afterRender);
                    }
                }
            }
            this._excludedMeshes = null;
        }
        _super.prototype.dispose.call(this);
    };
    /**
      * Gets the class name of the effect layer
      * @returns the string with the class name of the effect layer
      */
    HighlightLayer.prototype.getClassName = function () {
        return "HighlightLayer";
    };
    /**
     * Serializes this Highlight layer
     * @returns a serialized Highlight layer object
     */
    HighlightLayer.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.HighlightLayer";
        // Highlighted meshes
        serializationObject.meshes = [];
        if (this._meshes) {
            for (var m in this._meshes) {
                var mesh = this._meshes[m];
                if (mesh) {
                    serializationObject.meshes.push({
                        glowEmissiveOnly: mesh.glowEmissiveOnly,
                        color: mesh.color.asArray(),
                        meshId: mesh.mesh.id
                    });
                }
            }
        }
        // Excluded meshes
        serializationObject.excludedMeshes = [];
        if (this._excludedMeshes) {
            for (var e in this._excludedMeshes) {
                var excludedMesh = this._excludedMeshes[e];
                if (excludedMesh) {
                    serializationObject.excludedMeshes.push(excludedMesh.mesh.id);
                }
            }
        }
        return serializationObject;
    };
    /**
     * Creates a Highlight layer from parsed Highlight layer data
     * @param parsedHightlightLayer defines the Highlight layer data
     * @param scene defines the current scene
     * @param rootUrl defines the root URL containing the Highlight layer information
     * @returns a parsed Highlight layer
     */
    HighlightLayer.Parse = function (parsedHightlightLayer, scene, rootUrl) {
        var hl = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new HighlightLayer(parsedHightlightLayer.name, scene, parsedHightlightLayer.options); }, parsedHightlightLayer, scene, rootUrl);
        var index;
        // Excluded meshes
        for (index = 0; index < parsedHightlightLayer.excludedMeshes.length; index++) {
            var mesh = scene.getMeshByID(parsedHightlightLayer.excludedMeshes[index]);
            if (mesh) {
                hl.addExcludedMesh(mesh);
            }
        }
        // Included meshes
        for (index = 0; index < parsedHightlightLayer.meshes.length; index++) {
            var highlightedMesh = parsedHightlightLayer.meshes[index];
            var mesh = scene.getMeshByID(highlightedMesh.meshId);
            if (mesh) {
                hl.addMesh(mesh, _Maths_math_color__WEBPACK_IMPORTED_MODULE_17__["Color3"].FromArray(highlightedMesh.color), highlightedMesh.glowEmissiveOnly);
            }
        }
        return hl;
    };
    /**
     * Effect Name of the highlight layer.
     */
    HighlightLayer.EffectName = "HighlightLayer";
    /**
     * The neutral color used during the preparation of the glow effect.
     * This is black by default as the blend operation is a blend operation.
     */
    HighlightLayer.NeutralColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_17__["Color4"](0, 0, 0, 0);
    /**
     * Stencil value used for glowing meshes.
     */
    HighlightLayer.GlowingMeshStencilReference = 0x02;
    /**
     * Stencil value used for the other meshes in the scene.
     */
    HighlightLayer.NormalMeshStencilReference = 0x01;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], HighlightLayer.prototype, "innerGlow", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], HighlightLayer.prototype, "outerGlow", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], HighlightLayer.prototype, "blurHorizontalSize", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], HighlightLayer.prototype, "blurVerticalSize", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("options")
    ], HighlightLayer.prototype, "_options", void 0);
    return HighlightLayer;
}(_effectLayer__WEBPACK_IMPORTED_MODULE_12__["EffectLayer"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_16__["_TypeStore"].RegisteredTypes["BABYLON.HighlightLayer"] = HighlightLayer;


/***/ }),

/***/ "./Layers/index.ts":
/*!*************************!*\
  !*** ./Layers/index.ts ***!
  \*************************/
/*! exports provided: EffectLayer, EffectLayerSceneComponent, GlowLayer, HighlightLayer, Layer, LayerSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _effectLayer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./effectLayer */ "./Layers/effectLayer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectLayer", function() { return _effectLayer__WEBPACK_IMPORTED_MODULE_0__["EffectLayer"]; });

/* harmony import */ var _effectLayerSceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./effectLayerSceneComponent */ "./Layers/effectLayerSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectLayerSceneComponent", function() { return _effectLayerSceneComponent__WEBPACK_IMPORTED_MODULE_1__["EffectLayerSceneComponent"]; });

/* harmony import */ var _glowLayer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glowLayer */ "./Layers/glowLayer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GlowLayer", function() { return _glowLayer__WEBPACK_IMPORTED_MODULE_2__["GlowLayer"]; });

/* harmony import */ var _highlightLayer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./highlightLayer */ "./Layers/highlightLayer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HighlightLayer", function() { return _highlightLayer__WEBPACK_IMPORTED_MODULE_3__["HighlightLayer"]; });

/* harmony import */ var _layer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./layer */ "./Layers/layer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Layer", function() { return _layer__WEBPACK_IMPORTED_MODULE_4__["Layer"]; });

/* harmony import */ var _layerSceneComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./layerSceneComponent */ "./Layers/layerSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LayerSceneComponent", function() { return _layerSceneComponent__WEBPACK_IMPORTED_MODULE_5__["LayerSceneComponent"]; });









/***/ }),

/***/ "./Layers/layer.ts":
/*!*************************!*\
  !*** ./Layers/layer.ts ***!
  \*************************/
/*! exports provided: Layer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Layer", function() { return Layer; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _layerSceneComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./layerSceneComponent */ "./Layers/layerSceneComponent.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_layer_fragment__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Shaders/layer.fragment */ "./Shaders/layer.fragment.ts");
/* harmony import */ var _Shaders_layer_vertex__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Shaders/layer.vertex */ "./Shaders/layer.vertex.ts");












/**
 * This represents a full screen 2d layer.
 * This can be useful to display a picture in the  background of your scene for instance.
 * @see https://www.babylonjs-playground.com/#08A2BS#1
 */
var Layer = /** @class */ (function () {
    /**
     * Instantiates a new layer.
     * This represents a full screen 2d layer.
     * This can be useful to display a picture in the  background of your scene for instance.
     * @see https://www.babylonjs-playground.com/#08A2BS#1
     * @param name Define the name of the layer in the scene
     * @param imgUrl Define the url of the texture to display in the layer
     * @param scene Define the scene the layer belongs to
     * @param isBackground Defines whether the layer is displayed in front or behind the scene
     * @param color Defines a color for the layer
     */
    function Layer(
    /**
     * Define the name of the layer.
     */
    name, imgUrl, scene, isBackground, color) {
        this.name = name;
        /**
         * Define the scale of the layer in order to zoom in out of the texture.
         */
        this.scale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1, 1);
        /**
         * Define an offset for the layer in order to shift the texture.
         */
        this.offset = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0, 0);
        /**
         * Define the alpha blending mode used in the layer in case the texture or color has an alpha.
         */
        this.alphaBlendingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_9__["Constants"].ALPHA_COMBINE;
        /**
         * Define a mask to restrict the layer to only some of the scene cameras.
         */
        this.layerMask = 0x0FFFFFFF;
        /**
         * Define the list of render target the layer is visible into.
         */
        this.renderTargetTextures = [];
        /**
         * Define if the layer is only used in renderTarget or if it also
         * renders in the main frame buffer of the canvas.
         */
        this.renderOnlyInRenderTargetTextures = false;
        this._vertexBuffers = {};
        /**
         * An event triggered when the layer is disposed.
         */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /**
        * An event triggered before rendering the scene
        */
        this.onBeforeRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /**
        * An event triggered after rendering the scene
        */
        this.onAfterRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this.texture = imgUrl ? new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"](imgUrl, scene, true) : null;
        this.isBackground = isBackground === undefined ? true : isBackground;
        this.color = color === undefined ? new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](1, 1, 1, 1) : color;
        this._scene = (scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__["EngineStore"].LastCreatedScene);
        var layerComponent = this._scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_7__["SceneComponentConstants"].NAME_LAYER);
        if (!layerComponent) {
            layerComponent = new _layerSceneComponent__WEBPACK_IMPORTED_MODULE_8__["LayerSceneComponent"](this._scene);
            this._scene._addComponent(layerComponent);
        }
        this._scene.layers.push(this);
        var engine = this._scene.getEngine();
        // VBO
        var vertices = [];
        vertices.push(1, 1);
        vertices.push(-1, 1);
        vertices.push(-1, -1);
        vertices.push(1, -1);
        var vertexBuffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"](engine, vertices, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind, false, false, 2);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind] = vertexBuffer;
        this._createIndexBuffer();
        // Effects
        this._effect = engine.createEffect("layer", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind], ["textureMatrix", "color", "scale", "offset"], ["textureSampler"], "");
        this._alphaTestEffect = engine.createEffect("layer", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind], ["textureMatrix", "color", "scale", "offset"], ["textureSampler"], "#define ALPHATEST");
    }
    Object.defineProperty(Layer.prototype, "onDispose", {
        /**
         * Back compatibility with callback before the onDisposeObservable existed.
         * The set callback will be triggered when the layer has been disposed.
         */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Layer.prototype, "onBeforeRender", {
        /**
         * Back compatibility with callback before the onBeforeRenderObservable existed.
         * The set callback will be triggered just before rendering the layer.
         */
        set: function (callback) {
            if (this._onBeforeRenderObserver) {
                this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
            }
            this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Layer.prototype, "onAfterRender", {
        /**
         * Back compatibility with callback before the onAfterRenderObservable existed.
         * The set callback will be triggered just after rendering the layer.
         */
        set: function (callback) {
            if (this._onAfterRenderObserver) {
                this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
            }
            this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Layer.prototype._createIndexBuffer = function () {
        var engine = this._scene.getEngine();
        // Indices
        var indices = [];
        indices.push(0);
        indices.push(1);
        indices.push(2);
        indices.push(0);
        indices.push(2);
        indices.push(3);
        this._indexBuffer = engine.createIndexBuffer(indices);
    };
    /** @hidden */
    Layer.prototype._rebuild = function () {
        var vb = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind];
        if (vb) {
            vb._rebuild();
        }
        this._createIndexBuffer();
    };
    /**
     * Renders the layer in the scene.
     */
    Layer.prototype.render = function () {
        var currentEffect = this.alphaTest ? this._alphaTestEffect : this._effect;
        // Check
        if (!currentEffect.isReady() || !this.texture || !this.texture.isReady()) {
            return;
        }
        var engine = this._scene.getEngine();
        this.onBeforeRenderObservable.notifyObservers(this);
        // Render
        engine.enableEffect(currentEffect);
        engine.setState(false);
        // Texture
        currentEffect.setTexture("textureSampler", this.texture);
        currentEffect.setMatrix("textureMatrix", this.texture.getTextureMatrix());
        // Color
        currentEffect.setFloat4("color", this.color.r, this.color.g, this.color.b, this.color.a);
        // Scale / offset
        currentEffect.setVector2("offset", this.offset);
        currentEffect.setVector2("scale", this.scale);
        // VBOs
        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, currentEffect);
        // Draw order
        if (!this.alphaTest) {
            engine.setAlphaMode(this.alphaBlendingMode);
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, 0, 6);
            engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_9__["Constants"].ALPHA_DISABLE);
        }
        else {
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, 0, 6);
        }
        this.onAfterRenderObservable.notifyObservers(this);
    };
    /**
     * Disposes and releases the associated ressources.
     */
    Layer.prototype.dispose = function () {
        var vertexBuffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind];
        if (vertexBuffer) {
            vertexBuffer.dispose();
            this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind] = null;
        }
        if (this._indexBuffer) {
            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
            this._indexBuffer = null;
        }
        if (this.texture) {
            this.texture.dispose();
            this.texture = null;
        }
        // Clean RTT list
        this.renderTargetTextures = [];
        // Remove from scene
        var index = this._scene.layers.indexOf(this);
        this._scene.layers.splice(index, 1);
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
        this.onAfterRenderObservable.clear();
        this.onBeforeRenderObservable.clear();
    };
    return Layer;
}());



/***/ }),

/***/ "./Layers/layerSceneComponent.ts":
/*!***************************************!*\
  !*** ./Layers/layerSceneComponent.ts ***!
  \***************************************/
/*! exports provided: LayerSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LayerSceneComponent", function() { return LayerSceneComponent; });
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");

/**
 * Defines the layer scene component responsible to manage any layers
 * in a given scene.
 */
var LayerSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function LayerSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].NAME_LAYER;
        this.scene = scene;
        this._engine = scene.getEngine();
        scene.layers = new Array();
    }
    /**
     * Registers the component in a given scene
     */
    LayerSceneComponent.prototype.register = function () {
        this.scene._beforeCameraDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].STEP_BEFORECAMERADRAW_LAYER, this, this._drawCameraBackground);
        this.scene._afterCameraDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].STEP_AFTERCAMERADRAW_LAYER, this, this._drawCameraForeground);
        this.scene._beforeRenderTargetDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].STEP_BEFORERENDERTARGETDRAW_LAYER, this, this._drawRenderTargetBackground);
        this.scene._afterRenderTargetDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].STEP_AFTERRENDERTARGETDRAW_LAYER, this, this._drawRenderTargetForeground);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    LayerSceneComponent.prototype.rebuild = function () {
        var layers = this.scene.layers;
        for (var _i = 0, layers_1 = layers; _i < layers_1.length; _i++) {
            var layer = layers_1[_i];
            layer._rebuild();
        }
    };
    /**
     * Disposes the component and the associated ressources.
     */
    LayerSceneComponent.prototype.dispose = function () {
        var layers = this.scene.layers;
        while (layers.length) {
            layers[0].dispose();
        }
    };
    LayerSceneComponent.prototype._draw = function (predicate) {
        var layers = this.scene.layers;
        if (layers.length) {
            this._engine.setDepthBuffer(false);
            for (var _i = 0, layers_2 = layers; _i < layers_2.length; _i++) {
                var layer = layers_2[_i];
                if (predicate(layer)) {
                    layer.render();
                }
            }
            this._engine.setDepthBuffer(true);
        }
    };
    LayerSceneComponent.prototype._drawCameraPredicate = function (layer, isBackground, cameraLayerMask) {
        return !layer.renderOnlyInRenderTargetTextures &&
            layer.isBackground === isBackground &&
            ((layer.layerMask & cameraLayerMask) !== 0);
    };
    LayerSceneComponent.prototype._drawCameraBackground = function (camera) {
        var _this = this;
        this._draw(function (layer) {
            return _this._drawCameraPredicate(layer, true, camera.layerMask);
        });
    };
    LayerSceneComponent.prototype._drawCameraForeground = function (camera) {
        var _this = this;
        this._draw(function (layer) {
            return _this._drawCameraPredicate(layer, false, camera.layerMask);
        });
    };
    LayerSceneComponent.prototype._drawRenderTargetPredicate = function (layer, isBackground, cameraLayerMask, renderTargetTexture) {
        return (layer.renderTargetTextures.length > 0) &&
            layer.isBackground === isBackground &&
            (layer.renderTargetTextures.indexOf(renderTargetTexture) > -1) &&
            ((layer.layerMask & cameraLayerMask) !== 0);
    };
    LayerSceneComponent.prototype._drawRenderTargetBackground = function (renderTarget) {
        var _this = this;
        this._draw(function (layer) {
            return _this._drawRenderTargetPredicate(layer, true, _this.scene.activeCamera.layerMask, renderTarget);
        });
    };
    LayerSceneComponent.prototype._drawRenderTargetForeground = function (renderTarget) {
        var _this = this;
        this._draw(function (layer) {
            return _this._drawRenderTargetPredicate(layer, false, _this.scene.activeCamera.layerMask, renderTarget);
        });
    };
    /**
     * Adds all the elements from the container to the scene
     * @param container the container holding the elements
     */
    LayerSceneComponent.prototype.addFromContainer = function (container) {
        var _this = this;
        if (!container.layers) {
            return;
        }
        container.layers.forEach(function (layer) {
            _this.scene.layers.push(layer);
        });
    };
    /**
     * Removes all the elements in the container from the scene
     * @param container contains the elements to remove
     * @param dispose if the removed element should be disposed (default: false)
     */
    LayerSceneComponent.prototype.removeFromContainer = function (container, dispose) {
        var _this = this;
        if (dispose === void 0) { dispose = false; }
        if (!container.layers) {
            return;
        }
        container.layers.forEach(function (layer) {
            var index = _this.scene.layers.indexOf(layer);
            if (index !== -1) {
                _this.scene.layers.splice(index, 1);
            }
            if (dispose) {
                layer.dispose();
            }
        });
    };
    return LayerSceneComponent;
}());



/***/ }),

/***/ "./Legacy/legacy.ts":
/*!**************************!*\
  !*** ./Legacy/legacy.ts ***!
  \**************************/
/*! exports provided: Debug, AbstractScene, KeepAssets, AssetContainer, Node, Scene, SceneComponentConstants, Stage, AbstractActionManager, Action, ActionEvent, ActionManager, Condition, ValueCondition, PredicateCondition, StateCondition, SwitchBooleanAction, SetStateAction, SetValueAction, IncrementValueAction, PlayAnimationAction, StopAnimationAction, DoNothingAction, CombineAction, ExecuteCodeAction, SetParentAction, PlaySoundAction, StopSoundAction, InterpolateValueAction, Animatable, _IAnimationState, Animation, TargetedAnimation, AnimationGroup, AnimationPropertiesOverride, EasingFunction, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase, BezierCurveEase, RuntimeAnimation, AnimationEvent, AnimationKeyInterpolation, AnimationRange, Analyser, AudioEngine, AudioSceneComponent, Sound, SoundTrack, WeightedSound, Bone, BoneIKController, BoneLookController, Skeleton, CameraInputTypes, CameraInputsManager, Camera, TargetCamera, FreeCamera, FreeCameraInputsManager, TouchCamera, ArcRotateCamera, ArcRotateCameraInputsManager, DeviceOrientationCamera, FlyCamera, FlyCameraInputsManager, FollowCamera, ArcFollowCamera, FollowCameraInputsManager, GamepadCamera, UniversalCamera, VirtualJoysticksCamera, Collider, DefaultCollisionCoordinator, PickingInfo, IntersectionInfo, _MeshCollisionData, BoundingBox, BoundingInfo, BoundingSphere, Ray, AxesViewer, BoneAxesViewer, DebugLayer, PhysicsViewer, RayHelper, SkeletonViewer, Constants, InstancingAttributeInfo, DepthTextureCreationOptions, EngineCapabilities, Engine, EngineStore, NullEngineOptions, NullEngine, WebGLPipelineContext, WebGPUConstants, WebGPUEngine, WebGL2ShaderProcessor, NativeEngine, KeyboardEventTypes, KeyboardInfo, KeyboardInfoPre, PointerEventTypes, PointerInfoBase, PointerInfoPre, PointerInfo, ClipboardEventTypes, ClipboardInfo, StickValues, Gamepad, GenericPad, GamepadManager, GamepadSystemSceneComponent, Xbox360Button, Xbox360Dpad, Xbox360Pad, DualShockButton, DualShockDpad, DualShockPad, AxisDragGizmo, AxisScaleGizmo, BoundingBoxGizmo, Gizmo, GizmoManager, PlaneRotationGizmo, PositionGizmo, RotationGizmo, ScaleGizmo, LightGizmo, PlaneDragGizmo, EnvironmentHelper, PhotoDome, _forceSceneHelpersToBundle, VideoDome, EngineInstrumentation, SceneInstrumentation, _TimeToken, EffectLayer, EffectLayerSceneComponent, GlowLayer, HighlightLayer, Layer, LayerSceneComponent, LensFlare, LensFlareSystem, LensFlareSystemSceneComponent, Light, ShadowLight, DirectionalLight, HemisphericLight, PointLight, SpotLight, DefaultLoadingScreen, SceneLoaderProgressEvent, SceneLoader, SceneLoaderFlags, ColorCurves, EffectFallbacks, EffectCreationOptions, Effect, FresnelParameters, ImageProcessingConfigurationDefines, ImageProcessingConfiguration, Material, MaterialDefines, MaterialHelper, MultiMaterial, PushMaterial, ShaderMaterial, StandardMaterialDefines, StandardMaterial, BaseTexture, CubeTexture, DynamicTexture, EquiRectangularCubeTexture, HDRCubeTexture, InternalTexture, MirrorTexture, MultiRenderTarget, RawTexture, RenderTargetTexture, Texture, UniformBuffer, MaterialFlags, EffectRenderer, EffectWrapper, Scalar, Space, Axis, Color3, Color4, TmpColors, ToGammaSpace, ToLinearSpace, Epsilon, Frustum, Plane, Size, Vector2, Vector3, Vector4, Quaternion, Matrix, TmpVectors, Viewport, SphericalHarmonics, SphericalPolynomial, AbstractMesh, Buffer, VertexBuffer, CSG, Geometry, GroundMesh, TrailMesh, InstancedMesh, LinesMesh, InstancedLinesMesh, _CreationDataStorage, _InstancesBatch, Mesh, VertexData, MeshBuilder, SimplificationSettings, SimplificationQueue, SimplificationType, SimplicationQueueSceneComponent, Polygon, PolygonMeshBuilder, BaseSubMesh, SubMesh, MeshLODLevel, TransformNode, BoxBuilder, SphereBuilder, CylinderBuilder, TorusBuilder, LinesBuilder, PlaneBuilder, GroundBuilder, DataBuffer, WebGLDataBuffer, WebGPUDataBuffer, MorphTarget, MorphTargetManager, Database, BaseParticleSystem, GPUParticleSystem, Particle, ParticleHelper, ParticleSystem, _IDoNeedToBeInTheBuild, ParticleSystemSet, SolidParticle, ModelShape, DepthSortedParticle, SolidParticleSystem, SubEmitterType, SubEmitter, PhysicsEngine, PhysicsEngineSceneComponent, PhysicsHelper, PhysicsRadialExplosionEventOptions, PhysicsUpdraftEventOptions, PhysicsVortexEventOptions, PhysicsRadialImpulseFalloff, PhysicsUpdraftMode, PhysicsImpostor, PhysicsJoint, DistanceJoint, MotorEnabledJoint, HingeJoint, Hinge2Joint, AnaglyphPostProcess, BlackAndWhitePostProcess, BloomEffect, BloomMergePostProcess, BlurPostProcess, ChromaticAberrationPostProcess, CircleOfConfusionPostProcess, ColorCorrectionPostProcess, ConvolutionPostProcess, DepthOfFieldBlurPostProcess, DepthOfFieldEffectBlurLevel, DepthOfFieldEffect, DepthOfFieldMergePostProcessOptions, DepthOfFieldMergePostProcess, DisplayPassPostProcess, ExtractHighlightsPostProcess, FilterPostProcess, FxaaPostProcess, GrainPostProcess, HighlightsPostProcess, ImageProcessingPostProcess, MotionBlurPostProcess, PassPostProcess, PassCubePostProcess, PostProcess, PostProcessManager, RefractionPostProcess, SharpenPostProcess, StereoscopicInterlacePostProcess, TonemappingOperator, TonemapPostProcess, VolumetricLightScatteringPostProcess, VRDistortionCorrectionPostProcess, VRMultiviewToSingleviewPostProcess, ReflectionProbe, BoundingBoxRenderer, DepthRenderer, DepthRendererSceneComponent, EdgesRenderer, LineEdgesRenderer, GeometryBufferRenderer, GeometryBufferRendererSceneComponent, OutlineRenderer, RenderingGroup, RenderingGroupInfo, RenderingManager, UtilityLayerRenderer, Sprite, SpriteManager, SpritePackedManager, SpriteSceneComponent, _AlphaState, _DepthCullingState, _StencilState, AndOrNotEvaluator, AssetTaskState, AbstractAssetTask, AssetsProgressEvent, MeshAssetTask, TextFileAssetTask, BinaryFileAssetTask, ImageAssetTask, TextureAssetTask, CubeTextureAssetTask, HDRCubeTextureAssetTask, EquiRectangularCubeTextureAssetTask, AssetsManager, DDSTools, expandToProperty, serialize, serializeAsTexture, serializeAsColor3, serializeAsFresnelParameters, serializeAsVector2, serializeAsVector3, serializeAsMeshReference, serializeAsColorCurves, serializeAsColor4, serializeAsImageProcessingConfiguration, serializeAsQuaternion, serializeAsMatrix, serializeAsCameraReference, SerializationHelper, Deferred, EnvironmentTextureTools, MeshExploder, FilesInput, CubeMapToSphericalPolynomialTools, KhronosTextureContainer, EventState, Observer, MultiObserver, Observable, PerformanceMonitor, RollingAverage, PromisePolyfill, SceneOptimization, TextureOptimization, HardwareScalingOptimization, ShadowsOptimization, PostProcessesOptimization, LensFlaresOptimization, CustomOptimization, ParticlesOptimization, RenderTargetsOptimization, MergeMeshesOptimization, SceneOptimizerOptions, SceneOptimizer, SceneSerializer, SmartArray, SmartArrayNoDuplicate, StringDictionary, Tags, TextureTools, TGATools, Tools, className, AsyncLoop, VideoRecorder, JoystickAxis, VirtualJoystick, WorkerPool, Logger, _TypeStore, FilesInputStore, DeepCopier, PivotTools, PrecisionDate, ScreenshotTools, WebRequest, InspectableType, BRDFTextureTools, RGBDTextureTools, ColorGradient, Color3Gradient, FactorGradient, GradientHelper, PerfCounter, RetryStrategy, LoadFileError, AutoRotationBehavior, BouncingBehavior, FramingBehavior, AttachToBoxBehavior, FadeInOutBehavior, MultiPointerScaleBehavior, PointerDragBehavior, SixDofDragBehavior, ArcRotateCameraGamepadInput, ArcRotateCameraKeyboardMoveInput, ArcRotateCameraMouseWheelInput, ArcRotateCameraPointersInput, ArcRotateCameraVRDeviceOrientationInput, FlyCameraKeyboardInput, FlyCameraMouseInput, FollowCameraKeyboardMoveInput, FollowCameraMouseWheelInput, FollowCameraPointersInput, FreeCameraDeviceOrientationInput, FreeCameraGamepadInput, FreeCameraKeyboardMoveInput, FreeCameraMouseInput, FreeCameraTouchInput, FreeCameraVirtualJoystickInput, AnaglyphArcRotateCamera, AnaglyphFreeCamera, AnaglyphGamepadCamera, AnaglyphUniversalCamera, StereoscopicArcRotateCamera, StereoscopicFreeCamera, StereoscopicGamepadCamera, StereoscopicUniversalCamera, VRCameraMetrics, VRDeviceOrientationArcRotateCamera, VRDeviceOrientationFreeCamera, VRDeviceOrientationGamepadCamera, OnAfterEnteringVRObservableEvent, VRExperienceHelper, WebVRFreeCamera, WebXRCamera, WebXREnterExitUIButton, WebXREnterExitUIOptions, WebXREnterExitUI, WebXRState, WebXRExperienceHelper, WebXRInput, WebXRControllerTeleportation, WebXRControllerPointerSelection, WebXRControllerModelLoader, WebXRController, WebXRManagedOutputCanvas, WebXRSessionManager, Octree, OctreeBlock, OctreeSceneComponent, _OcclusionDataStorage, _forceTransformFeedbackToBundle, DaydreamController, GearVRController, GenericController, OculusTouchController, PoseEnabledControllerType, PoseEnabledControllerHelper, PoseEnabledController, ViveController, WebVRController, WindowsMotionController, ShadowGenerator, ShadowGeneratorSceneComponent, _BabylonLoaderRegistered, BackgroundMaterial, PBRMaterialDefines, PBRBaseMaterial, PBRBaseSimpleMaterial, PBRMaterial, PBRMetallicRoughnessMaterial, PBRSpecularGlossinessMaterial, ColorGradingTexture, RawCubeTexture, RawTexture3D, RefractionTexture, VideoTexture, HtmlElementTexture, NodeMaterialBlockTargets, NodeMaterialBlockConnectionPointTypes, NodeMaterialConnectionPoint, NodeMaterialBlock, NodeMaterialDefines, NodeMaterial, NodeMaterialSystemValues, Orientation, BezierCurve, Angle, Arc2, Path2, Path3D, Curve3, PositionNormalVertex, PositionNormalTextureVertex, DracoCompression, TiledBoxBuilder, DiscBuilder, RibbonBuilder, HemisphereBuilder, TorusKnotBuilder, PolygonBuilder, ShapeBuilder, LatheBuilder, TiledPlaneBuilder, TubeBuilder, PolyhedronBuilder, IcoSphereBuilder, DecalBuilder, RecastJSPlugin, RecastJSCrowd, BoxParticleEmitter, ConeParticleEmitter, CylinderParticleEmitter, CylinderDirectedParticleEmitter, HemisphericParticleEmitter, PointParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter, CannonJSPlugin, AmmoJSPlugin, OimoJSPlugin, PostProcessRenderEffect, PostProcessRenderPipeline, PostProcessRenderPipelineManager, PostProcessRenderPipelineManagerSceneComponent, HDRTools, PanoramaToCubeMapTools, _DDSTextureLoader, _ENVTextureLoader, _KTXTextureLoader, _TGATextureLoader, _BasisTextureLoader, CustomProceduralTexture, NoiseProceduralTexture, ProceduralTexture, ProceduralTextureSceneComponent, MultiplyBlock, AddBlock, ScaleBlock, ClampBlock, CrossBlock, DotBlock, TransformBlock, RemapBlock, NormalizeBlock, TrigonometryBlockOperations, TrigonometryBlock, ColorMergerBlock, VectorMergerBlock, ColorSplitterBlock, VectorSplitterBlock, LerpBlock, DivideBlock, SubtractBlock, StepBlock, OppositeBlock, ViewDirectionBlock, FresnelBlock, MaxBlock, MinBlock, NodeMaterialOptimizer, DefaultRenderingPipeline, LensRenderingPipeline, SSAO2RenderingPipeline, SSAORenderingPipeline, StandardRenderingPipeline, VertexOutputBlock, BonesBlock, InstancesBlock, MorphTargetsBlock, LightInformationBlock, FragmentOutputBlock, AlphaTestBlock, ImageProcessingBlock, PerturbNormalBlock, FogBlock, LightBlock, TextureBlock, ReflectionTextureBlock, InputBlock, AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Debug", function() { return Debug; });
/* harmony import */ var _index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../index */ "./index.ts");
/* harmony import */ var _Debug_index__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Debug/index */ "./Debug/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractScene", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AbstractScene"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeepAssets", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["KeepAssets"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetContainer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Node", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Node"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scene", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Scene"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneComponentConstants", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Stage", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Stage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractActionManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AbstractActionManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Action", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Action"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ActionEvent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ActionEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ActionManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ActionManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Condition", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Condition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ValueCondition", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ValueCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PredicateCondition", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PredicateCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StateCondition", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StateCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SwitchBooleanAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SwitchBooleanAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetStateAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SetStateAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetValueAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SetValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IncrementValueAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["IncrementValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlayAnimationAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PlayAnimationAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StopAnimationAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StopAnimationAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DoNothingAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DoNothingAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CombineAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CombineAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExecuteCodeAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ExecuteCodeAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetParentAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SetParentAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaySoundAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PlaySoundAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StopSoundAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StopSoundAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InterpolateValueAction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InterpolateValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Animatable", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Animatable"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_IAnimationState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_IAnimationState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Animation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Animation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TargetedAnimation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TargetedAnimation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationGroup", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnimationGroup"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationPropertiesOverride", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnimationPropertiesOverride"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EasingFunction", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EasingFunction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CircleEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CircleEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BackEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BounceEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BounceEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubicEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CubicEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ElasticEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ElasticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExponentialEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ExponentialEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PowerEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PowerEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuadraticEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["QuadraticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuarticEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["QuarticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuinticEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["QuinticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SineEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SineEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurveEase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BezierCurveEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RuntimeAnimation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RuntimeAnimation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationEvent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnimationEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationKeyInterpolation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnimationKeyInterpolation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationRange", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnimationRange"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Analyser", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Analyser"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AudioEngine", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AudioEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AudioSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AudioSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sound", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Sound"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SoundTrack", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SoundTrack"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WeightedSound", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WeightedSound"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Bone", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Bone"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneIKController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoneIKController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneLookController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoneLookController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Skeleton", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Skeleton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CameraInputTypes", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CameraInputTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CameraInputsManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Camera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TargetCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TargetCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraInputsManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TouchCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TouchCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraInputsManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DeviceOrientationCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DeviceOrientationCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FlyCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraInputsManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FlyCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FollowCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcFollowCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcFollowCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraInputsManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UniversalCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["UniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualJoysticksCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VirtualJoysticksCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Collider", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Collider"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultCollisionCoordinator", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DefaultCollisionCoordinator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PickingInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PickingInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IntersectionInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["IntersectionInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_MeshCollisionData", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_MeshCollisionData"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBox", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoundingBox"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoundingInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingSphere", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoundingSphere"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Ray", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Ray"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxesViewer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AxesViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneAxesViewer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoneAxesViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DebugLayer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DebugLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsViewer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RayHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RayHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SkeletonViewer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SkeletonViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Constants", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Constants"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancingAttributeInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InstancingAttributeInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthTextureCreationOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthTextureCreationOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineCapabilities", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EngineCapabilities"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Engine", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Engine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineStore", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EngineStore"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NullEngineOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NullEngineOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NullEngine", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NullEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGLPipelineContext", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebGLPipelineContext"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUConstants", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebGPUConstants"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUEngine", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebGPUEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGL2ShaderProcessor", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebGL2ShaderProcessor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NativeEngine", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NativeEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardEventTypes", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["KeyboardEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["KeyboardInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfoPre", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["KeyboardInfoPre"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerEventTypes", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfoBase", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointerInfoBase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfoPre", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointerInfoPre"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointerInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardEventTypes", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ClipboardEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ClipboardInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StickValues", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StickValues"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Gamepad", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Gamepad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericPad", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GenericPad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GamepadManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadSystemSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GamepadSystemSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Button", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Xbox360Button"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Dpad", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Xbox360Dpad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Pad", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Xbox360Pad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockButton", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DualShockButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockDpad", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DualShockDpad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockPad", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DualShockPad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxisDragGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AxisDragGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxisScaleGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AxisScaleGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoundingBoxGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Gizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Gizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GizmoManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GizmoManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneRotationGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PlaneRotationGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PositionGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RotationGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RotationGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ScaleGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LightGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneDragGizmo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PlaneDragGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EnvironmentHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EnvironmentHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhotoDome", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhotoDome"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceSceneHelpersToBundle", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_forceSceneHelpersToBundle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoDome", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VideoDome"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineInstrumentation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EngineInstrumentation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneInstrumentation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneInstrumentation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TimeToken", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_TimeToken"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectLayer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EffectLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectLayerSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EffectLayerSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GlowLayer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GlowLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HighlightLayer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HighlightLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Layer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Layer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LayerSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LayerSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlare", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LensFlare"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystem", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LensFlareSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystemSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LensFlareSystemSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Light", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Light"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowLight", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ShadowLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DirectionalLight", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DirectionalLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericLight", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HemisphericLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointLight", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpotLight", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SpotLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultLoadingScreen", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DefaultLoadingScreen"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderProgressEvent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneLoaderProgressEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderFlags", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneLoaderFlags"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorCurves", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ColorCurves"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectFallbacks", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EffectFallbacks"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectCreationOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EffectCreationOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Effect", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Effect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelParameters", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FresnelParameters"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfigurationDefines", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ImageProcessingConfigurationDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfiguration", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ImageProcessingConfiguration"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Material", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Material"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialDefines", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MaterialHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MultiMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PushMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PushMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShaderMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ShaderMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardMaterialDefines", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StandardMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StandardMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BaseTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DynamicTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DynamicTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EquiRectangularCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HDRCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InternalTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InternalTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MirrorTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MirrorTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiRenderTarget", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MultiRenderTarget"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RawTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RenderTargetTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Texture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Texture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UniformBuffer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["UniformBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialFlags", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MaterialFlags"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EffectRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectWrapper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EffectWrapper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scalar", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Scalar"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Space", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Space"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Axis", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Axis"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Color3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color4", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Color4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpColors", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TmpColors"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToGammaSpace", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ToGammaSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToLinearSpace", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ToLinearSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Epsilon", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Epsilon"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Frustum"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Plane", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Plane"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Size", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Size"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector2", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Vector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector3", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Vector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector4", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Vector4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quaternion", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Quaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Matrix", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Matrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpVectors", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Viewport", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Viewport"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphericalHarmonics", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SphericalHarmonics"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphericalPolynomial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SphericalPolynomial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AbstractMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Buffer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Buffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexBuffer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CSG", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CSG"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Geometry", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Geometry"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GroundMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrailMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TrailMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancedMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InstancedMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LinesMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancedLinesMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InstancedLinesMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_CreationDataStorage", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_CreationDataStorage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_InstancesBatch", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_InstancesBatch"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Mesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Mesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexData", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VertexData"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationSettings", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SimplificationSettings"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationQueue", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SimplificationQueue"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationType", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SimplificationType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplicationQueueSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SimplicationQueueSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Polygon", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Polygon"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonMeshBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PolygonMeshBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseSubMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BaseSubMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubMesh", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SubMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshLODLevel", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MeshLODLevel"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformNode", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoxBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CylinderBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TorusBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LinesBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PlaneBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GroundBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DataBuffer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DataBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGLDataBuffer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebGLDataBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUDataBuffer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebGPUDataBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTarget", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MorphTargetManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Database", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Database"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseParticleSystem", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BaseParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GPUParticleSystem", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GPUParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Particle", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Particle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ParticleHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleSystem", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_IDoNeedToBeInTheBuild", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_IDoNeedToBeInTheBuild"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleSystemSet", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ParticleSystemSet"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SolidParticle", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SolidParticle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModelShape", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ModelShape"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthSortedParticle", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthSortedParticle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SolidParticleSystem", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SolidParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubEmitterType", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SubEmitterType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SubEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngine", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngineSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsEngineSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialExplosionEventOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsRadialExplosionEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftEventOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsUpdraftEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsVortexEventOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsVortexEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialImpulseFalloff", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsRadialImpulseFalloff"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftMode", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsUpdraftMode"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsImpostor", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsImpostor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsJoint", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PhysicsJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DistanceJoint", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DistanceJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotorEnabledJoint", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MotorEnabledJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HingeJoint", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HingeJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Hinge2Joint", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Hinge2Joint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnaglyphPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BlackAndWhitePostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BlackAndWhitePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BloomEffect", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BloomEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BloomMergePostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BloomMergePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BlurPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BlurPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ChromaticAberrationPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ChromaticAberrationPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CircleOfConfusionPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CircleOfConfusionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorCorrectionPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ColorCorrectionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConvolutionPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ConvolutionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldBlurPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthOfFieldBlurPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffectBlurLevel", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthOfFieldEffectBlurLevel"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffect", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthOfFieldEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcessOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthOfFieldMergePostProcessOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthOfFieldMergePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DisplayPassPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DisplayPassPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtractHighlightsPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ExtractHighlightsPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilterPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FilterPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FxaaPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FxaaPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GrainPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GrainPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HighlightsPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HighlightsPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ImageProcessingPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotionBlurPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MotionBlurPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PassPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PassPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PassCubePostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PassCubePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcessManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RefractionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SharpenPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SharpenPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicInterlacePostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StereoscopicInterlacePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TonemappingOperator", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TonemappingOperator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TonemapPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TonemapPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VolumetricLightScatteringPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VolumetricLightScatteringPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDistortionCorrectionPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRDistortionCorrectionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRMultiviewToSingleviewPostProcess", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRMultiviewToSingleviewPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionProbe", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ReflectionProbe"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoundingBoxRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthRendererSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DepthRendererSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EdgesRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EdgesRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LineEdgesRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LineEdgesRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GeometryBufferRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRendererSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GeometryBufferRendererSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OutlineRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OutlineRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingGroup", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RenderingGroup"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingGroupInfo", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RenderingGroupInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RenderingManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UtilityLayerRenderer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["UtilityLayerRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Sprite"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpriteManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SpriteManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpritePackedManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SpritePackedManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpriteSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SpriteSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_AlphaState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_AlphaState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DepthCullingState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_DepthCullingState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_StencilState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_StencilState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AndOrNotEvaluator", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AndOrNotEvaluator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetTaskState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AssetTaskState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AbstractAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetsProgressEvent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AssetsProgressEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MeshAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextFileAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TextFileAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BinaryFileAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BinaryFileAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ImageAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTextureAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTextureAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HDRCubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTextureAssetTask", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EquiRectangularCubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetsManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AssetsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DDSTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DDSTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expandToProperty", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["expandToProperty"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serialize", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serialize"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor3", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsColor3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsFresnelParameters", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsFresnelParameters"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector2", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsVector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector3", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsVector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsMeshReference", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsMeshReference"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColorCurves", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsColorCurves"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor4", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsColor4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsImageProcessingConfiguration", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsImageProcessingConfiguration"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsQuaternion", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsQuaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsMatrix", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsMatrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsCameraReference", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["serializeAsCameraReference"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SerializationHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SerializationHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Deferred", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Deferred"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EnvironmentTextureTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EnvironmentTextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshExploder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MeshExploder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilesInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FilesInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeMapToSphericalPolynomialTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CubeMapToSphericalPolynomialTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KhronosTextureContainer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["KhronosTextureContainer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EventState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["EventState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Observer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiObserver", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MultiObserver"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Observable"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerformanceMonitor", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PerformanceMonitor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RollingAverage", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RollingAverage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PromisePolyfill", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PromisePolyfill"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TextureOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HardwareScalingOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HardwareScalingOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowsOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ShadowsOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessesOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcessesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlaresOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LensFlaresOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CustomOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticlesOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ParticlesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetsOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RenderTargetsOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MergeMeshesOptimization", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MergeMeshesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizerOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneOptimizerOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneOptimizer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneSerializer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SceneSerializer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SmartArray", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SmartArray"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SmartArrayNoDuplicate", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SmartArrayNoDuplicate"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StringDictionary", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StringDictionary"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Tags", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Tags"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TGATools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TGATools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Tools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Tools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "className", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["className"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AsyncLoop", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AsyncLoop"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoRecorder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VideoRecorder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "JoystickAxis", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["JoystickAxis"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualJoystick", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VirtualJoystick"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WorkerPool", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WorkerPool"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Logger", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Logger"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TypeStore", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_TypeStore"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilesInputStore", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FilesInputStore"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DeepCopier", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DeepCopier"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PivotTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PivotTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PrecisionDate", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PrecisionDate"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScreenshotTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ScreenshotTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebRequest", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebRequest"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InspectableType", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InspectableType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BRDFTextureTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BRDFTextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RGBDTextureTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RGBDTextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradient", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ColorGradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3Gradient", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Color3Gradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FactorGradient", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FactorGradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GradientHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GradientHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerfCounter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RetryStrategy", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RetryStrategy"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LoadFileError", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LoadFileError"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AutoRotationBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AutoRotationBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BouncingBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BouncingBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FramingBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FramingBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AttachToBoxBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AttachToBoxBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FadeInOutBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FadeInOutBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiPointerScaleBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MultiPointerScaleBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerDragBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointerDragBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SixDofDragBehavior", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SixDofDragBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraGamepadInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraGamepadInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraKeyboardMoveInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraMouseWheelInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraMouseWheelInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraPointersInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraPointersInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraVRDeviceOrientationInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ArcRotateCameraVRDeviceOrientationInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraKeyboardInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FlyCameraKeyboardInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraMouseInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FlyCameraMouseInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraKeyboardMoveInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraMouseWheelInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraMouseWheelInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraPointersInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FollowCameraPointersInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraDeviceOrientationInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraDeviceOrientationInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraGamepadInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraGamepadInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraKeyboardMoveInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraMouseInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraMouseInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraTouchInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraTouchInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraVirtualJoystickInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FreeCameraVirtualJoystickInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphArcRotateCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnaglyphArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphFreeCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnaglyphFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphGamepadCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnaglyphGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphUniversalCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnaglyphUniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicArcRotateCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StereoscopicArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicFreeCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StereoscopicFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicGamepadCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StereoscopicGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicUniversalCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StereoscopicUniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRCameraMetrics", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRCameraMetrics"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationArcRotateCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRDeviceOrientationArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationFreeCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRDeviceOrientationFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationGamepadCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRDeviceOrientationGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OnAfterEnteringVRObservableEvent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OnAfterEnteringVRObservableEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRExperienceHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VRExperienceHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRFreeCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebVRFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRCamera", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIButton", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXREnterExitUIButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIOptions", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXREnterExitUIOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUI", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXREnterExitUI"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRState", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRExperienceHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRExperienceHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRInput", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerTeleportation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRControllerTeleportation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerPointerSelection", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRControllerPointerSelection"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerModelLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRControllerModelLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRManagedOutputCanvas", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRManagedOutputCanvas"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRSessionManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebXRSessionManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Octree", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Octree"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OctreeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OctreeSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_OcclusionDataStorage", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_OcclusionDataStorage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceTransformFeedbackToBundle", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_forceTransformFeedbackToBundle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DaydreamController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DaydreamController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GearVRController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GearVRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["GenericController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OculusTouchController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OculusTouchController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerType", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PoseEnabledControllerType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerHelper", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PoseEnabledControllerHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PoseEnabledController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViveController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ViveController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WebVRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WindowsMotionController", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["WindowsMotionController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGenerator", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ShadowGenerator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGeneratorSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ShadowGeneratorSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BabylonLoaderRegistered", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_BabylonLoaderRegistered"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackgroundMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BackgroundMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterialDefines", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PBRMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PBRBaseMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseSimpleMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PBRBaseSimpleMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PBRMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMetallicRoughnessMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PBRMetallicRoughnessMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRSpecularGlossinessMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PBRSpecularGlossinessMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradingTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ColorGradingTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawCubeTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RawCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture3D", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RawTexture3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RefractionTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VideoTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HtmlElementTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HtmlElementTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockTargets", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockTargets"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockConnectionPointTypes", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialConnectionPoint", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialConnectionPoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialDefines", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterial", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialSystemValues", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialSystemValues"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Orientation", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Orientation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurve", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BezierCurve"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Angle", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Angle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Arc2", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Arc2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path2", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Path2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path3D", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Path3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Curve3", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["Curve3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalVertex", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PositionNormalVertex"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalTextureVertex", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PositionNormalTextureVertex"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DracoCompression", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DracoCompression"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledBoxBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TiledBoxBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DiscBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DiscBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RibbonBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RibbonBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphereBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HemisphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusKnotBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TorusKnotBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PolygonBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShapeBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ShapeBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LatheBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LatheBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledPlaneBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TiledPlaneBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TubeBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TubeBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolyhedronBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PolyhedronBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IcoSphereBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["IcoSphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DecalBuilder", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DecalBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSPlugin", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RecastJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSCrowd", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RecastJSCrowd"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BoxParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConeParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ConeParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CylinderParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderDirectedParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CylinderDirectedParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HemisphericParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PointParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SphereParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereDirectedParticleEmitter", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SphereDirectedParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CannonJSPlugin", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CannonJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AmmoJSPlugin", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AmmoJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OimoJSPlugin", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OimoJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderEffect", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcessRenderEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipeline", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcessRenderPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManager", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcessRenderPipelineManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManagerSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PostProcessRenderPipelineManagerSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["HDRTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PanoramaToCubeMapTools", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PanoramaToCubeMapTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DDSTextureLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_DDSTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_ENVTextureLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_ENVTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_KTXTextureLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_KTXTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TGATextureLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_TGATextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BasisTextureLoader", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["_BasisTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomProceduralTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CustomProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NoiseProceduralTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NoiseProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTexture", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTextureSceneComponent", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ProceduralTextureSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MultiplyBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AddBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AddBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ScaleBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClampBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ClampBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CrossBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["CrossBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DotBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DotBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TransformBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RemapBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["RemapBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NormalizeBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NormalizeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlockOperations", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TrigonometryBlockOperations"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TrigonometryBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorMergerBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ColorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorMergerBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VectorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorSplitterBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ColorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorSplitterBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VectorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LerpBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LerpBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DivideBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DivideBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubtractBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SubtractBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StepBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StepBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OppositeBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["OppositeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViewDirectionBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ViewDirectionBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FresnelBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaxBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MaxBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MinBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MinBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialOptimizer", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialOptimizer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultRenderingPipeline", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["DefaultRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensRenderingPipeline", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LensRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAO2RenderingPipeline", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SSAO2RenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAORenderingPipeline", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["SSAORenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardRenderingPipeline", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["StandardRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["VertexOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["BonesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InstancesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["MorphTargetsBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LightInformationBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FragmentOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AlphaTestBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ImageProcessingBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["PerturbNormalBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["FogBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["LightBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["TextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["ReflectionTextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["InputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return _index__WEBPACK_IMPORTED_MODULE_0__["AnimatedInputBlockTypes"]; });



/**
 * Legacy support, defining window.BABYLON (global variable).
 *
 * This is the entry point for the UMD module.
 * The entry point for a future ESM package should be index.ts
 */
var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
if (typeof globalObject !== "undefined") {
    globalObject.BABYLON = BABYLON;
    globalObject.BABYLON = globalObject.BABYLON || {};
    var BABYLON = globalObject.BABYLON;
    BABYLON.Debug = BABYLON.Debug || {};
    var keys = [];
    for (var key in _Debug_index__WEBPACK_IMPORTED_MODULE_1__) {
        BABYLON.Debug[key] = _Debug_index__WEBPACK_IMPORTED_MODULE_1__[key];
        keys.push(key);
    }
    for (var key in _index__WEBPACK_IMPORTED_MODULE_0__) {
        BABYLON[key] = _index__WEBPACK_IMPORTED_MODULE_0__[key];
    }
}

var Debug = {
    AxesViewer: _Debug_index__WEBPACK_IMPORTED_MODULE_1__["AxesViewer"],
    BoneAxesViewer: _Debug_index__WEBPACK_IMPORTED_MODULE_1__["BoneAxesViewer"],
    PhysicsViewer: _Debug_index__WEBPACK_IMPORTED_MODULE_1__["PhysicsViewer"],
    SkeletonViewer: _Debug_index__WEBPACK_IMPORTED_MODULE_1__["SkeletonViewer"],
};

/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/webpack/buildin/global.js */ "../node_modules/webpack/buildin/global.js")))

/***/ }),

/***/ "./LensFlares/index.ts":
/*!*****************************!*\
  !*** ./LensFlares/index.ts ***!
  \*****************************/
/*! exports provided: LensFlare, LensFlareSystem, LensFlareSystemSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _lensFlare__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lensFlare */ "./LensFlares/lensFlare.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlare", function() { return _lensFlare__WEBPACK_IMPORTED_MODULE_0__["LensFlare"]; });

/* harmony import */ var _lensFlareSystem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lensFlareSystem */ "./LensFlares/lensFlareSystem.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystem", function() { return _lensFlareSystem__WEBPACK_IMPORTED_MODULE_1__["LensFlareSystem"]; });

/* harmony import */ var _lensFlareSystemSceneComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lensFlareSystemSceneComponent */ "./LensFlares/lensFlareSystemSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystemSceneComponent", function() { return _lensFlareSystemSceneComponent__WEBPACK_IMPORTED_MODULE_2__["LensFlareSystemSceneComponent"]; });






/***/ }),

/***/ "./LensFlares/lensFlare.ts":
/*!*********************************!*\
  !*** ./LensFlares/lensFlare.ts ***!
  \*********************************/
/*! exports provided: LensFlare */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LensFlare", function() { return LensFlare; });
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");



/**
 * This represents one of the lens effect in a `lensFlareSystem`.
 * It controls one of the indiviual texture used in the effect.
 * @see http://doc.babylonjs.com/how_to/how_to_use_lens_flares
 */
var LensFlare = /** @class */ (function () {
    /**
     * Instantiates a new Lens Flare.
     * This represents one of the lens effect in a `lensFlareSystem`.
     * It controls one of the indiviual texture used in the effect.
     * @see http://doc.babylonjs.com/how_to/how_to_use_lens_flares
     * @param size Define the size of the lens flare in the system (a floating value between 0 and 1)
     * @param position Define the position of the lens flare in the system. (a floating value between -1 and 1). A value of 0 is located on the emitter. A value greater than 0 is beyond the emitter and a value lesser than 0 is behind.
     * @param color Define the lens color
     * @param imgUrl Define the lens texture url
     * @param system Define the `lensFlareSystem` this flare is part of
     */
    function LensFlare(
    /**
     * Define the size of the lens flare in the system (a floating value between 0 and 1)
     */
    size,
    /**
     * Define the position of the lens flare in the system. (a floating value between -1 and 1). A value of 0 is located on the emitter. A value greater than 0 is beyond the emitter and a value lesser than 0 is behind.
     */
    position, color, imgUrl, system) {
        this.size = size;
        this.position = position;
        /**
         * Define the alpha mode to render this particular lens.
         */
        this.alphaMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].ALPHA_ONEONE;
        this.color = color || new _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__["Color3"](1, 1, 1);
        this.texture = imgUrl ? new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"](imgUrl, system.getScene(), true) : null;
        this._system = system;
        system.lensFlares.push(this);
    }
    /**
     * Creates a new Lens Flare.
     * This represents one of the lens effect in a `lensFlareSystem`.
     * It controls one of the indiviual texture used in the effect.
     * @see http://doc.babylonjs.com/how_to/how_to_use_lens_flares
     * @param size Define the size of the lens flare (a floating value between 0 and 1)
     * @param position Define the position of the lens flare in the system. (a floating value between -1 and 1). A value of 0 is located on the emitter. A value greater than 0 is beyond the emitter and a value lesser than 0 is behind.
     * @param color Define the lens color
     * @param imgUrl Define the lens texture url
     * @param system Define the `lensFlareSystem` this flare is part of
     * @returns The newly created Lens Flare
     */
    LensFlare.AddFlare = function (size, position, color, imgUrl, system) {
        return new LensFlare(size, position, color, imgUrl, system);
    };
    /**
     * Dispose and release the lens flare with its associated resources.
     */
    LensFlare.prototype.dispose = function () {
        if (this.texture) {
            this.texture.dispose();
        }
        // Remove from scene
        var index = this._system.lensFlares.indexOf(this);
        this._system.lensFlares.splice(index, 1);
    };
    return LensFlare;
}());



/***/ }),

/***/ "./LensFlares/lensFlareSystem.ts":
/*!***************************************!*\
  !*** ./LensFlares/lensFlareSystem.ts ***!
  \***************************************/
/*! exports provided: LensFlareSystem */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystem", function() { return LensFlareSystem; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _lensFlare__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./lensFlare */ "./LensFlares/lensFlare.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_lensFlare_fragment__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Shaders/lensFlare.fragment */ "./Shaders/lensFlare.fragment.ts");
/* harmony import */ var _Shaders_lensFlare_vertex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Shaders/lensFlare.vertex */ "./Shaders/lensFlare.vertex.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");













/**
 * This represents a Lens Flare System or the shiny effect created by the light reflection on the  camera lenses.
 * It is usually composed of several `lensFlare`.
 * @see http://doc.babylonjs.com/how_to/how_to_use_lens_flares
 */
var LensFlareSystem = /** @class */ (function () {
    /**
     * Instantiates a lens flare system.
     * This represents a Lens Flare System or the shiny effect created by the light reflection on the  camera lenses.
     * It is usually composed of several `lensFlare`.
     * @see http://doc.babylonjs.com/how_to/how_to_use_lens_flares
     * @param name Define the name of the lens flare system in the scene
     * @param emitter Define the source (the emitter) of the lens flares (it can be a camera, a light or a mesh).
     * @param scene Define the scene the lens flare system belongs to
     */
    function LensFlareSystem(
    /**
     * Define the name of the lens flare system
     */
    name, emitter, scene) {
        this.name = name;
        /**
         * List of lens flares used in this system.
         */
        this.lensFlares = new Array();
        /**
         * Define a limit from the border the lens flare can be visible.
         */
        this.borderLimit = 300;
        /**
         * Define a viewport border we do not want to see the lens flare in.
         */
        this.viewportBorder = 0;
        /**
         * Restricts the rendering of the effect to only the camera rendering this layer mask.
         */
        this.layerMask = 0x0FFFFFFF;
        this._vertexBuffers = {};
        this._isEnabled = true;
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__["EngineStore"].LastCreatedScene;
        LensFlareSystem._SceneComponentInitialization(this._scene);
        this._emitter = emitter;
        this.id = name;
        scene.lensFlareSystems.push(this);
        this.meshesSelectionPredicate = function (m) { return (scene.activeCamera && m.material && m.isVisible && m.isEnabled() && m.isBlocker && ((m.layerMask & scene.activeCamera.layerMask) != 0)); };
        var engine = scene.getEngine();
        // VBO
        var vertices = [];
        vertices.push(1, 1);
        vertices.push(-1, 1);
        vertices.push(-1, -1);
        vertices.push(1, -1);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"](engine, vertices, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind, false, false, 2);
        // Indices
        var indices = [];
        indices.push(0);
        indices.push(1);
        indices.push(2);
        indices.push(0);
        indices.push(2);
        indices.push(3);
        this._indexBuffer = engine.createIndexBuffer(indices);
        // Effects
        this._effect = engine.createEffect("lensFlare", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind], ["color", "viewportMatrix"], ["textureSampler"], "");
    }
    Object.defineProperty(LensFlareSystem.prototype, "isEnabled", {
        /**
         * Define if the lens flare system is enabled.
         */
        get: function () {
            return this._isEnabled;
        },
        set: function (value) {
            this._isEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the scene the effects belongs to.
     * @returns the scene holding the lens flare system
     */
    LensFlareSystem.prototype.getScene = function () {
        return this._scene;
    };
    /**
     * Get the emitter of the lens flare system.
     * It defines the source of the lens flares (it can be a camera, a light or a mesh).
     * @returns the emitter of the lens flare system
     */
    LensFlareSystem.prototype.getEmitter = function () {
        return this._emitter;
    };
    /**
     * Set the emitter of the lens flare system.
     * It defines the source of the lens flares (it can be a camera, a light or a mesh).
     * @param newEmitter Define the new emitter of the system
     */
    LensFlareSystem.prototype.setEmitter = function (newEmitter) {
        this._emitter = newEmitter;
    };
    /**
     * Get the lens flare system emitter position.
     * The emitter defines the source of the lens flares (it can be a camera, a light or a mesh).
     * @returns the position
     */
    LensFlareSystem.prototype.getEmitterPosition = function () {
        return this._emitter.getAbsolutePosition ? this._emitter.getAbsolutePosition() : this._emitter.position;
    };
    /**
     * @hidden
     */
    LensFlareSystem.prototype.computeEffectivePosition = function (globalViewport) {
        var position = this.getEmitterPosition();
        position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Project(position, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity(), this._scene.getTransformMatrix(), globalViewport);
        this._positionX = position.x;
        this._positionY = position.y;
        position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinates(this.getEmitterPosition(), this._scene.getViewMatrix());
        if (this.viewportBorder > 0) {
            globalViewport.x -= this.viewportBorder;
            globalViewport.y -= this.viewportBorder;
            globalViewport.width += this.viewportBorder * 2;
            globalViewport.height += this.viewportBorder * 2;
            position.x += this.viewportBorder;
            position.y += this.viewportBorder;
            this._positionX += this.viewportBorder;
            this._positionY += this.viewportBorder;
        }
        if (position.z > 0) {
            if ((this._positionX > globalViewport.x) && (this._positionX < globalViewport.x + globalViewport.width)) {
                if ((this._positionY > globalViewport.y) && (this._positionY < globalViewport.y + globalViewport.height)) {
                    return true;
                }
            }
            return true;
        }
        return false;
    };
    /** @hidden */
    LensFlareSystem.prototype._isVisible = function () {
        if (!this._isEnabled || !this._scene.activeCamera) {
            return false;
        }
        var emitterPosition = this.getEmitterPosition();
        var direction = emitterPosition.subtract(this._scene.activeCamera.globalPosition);
        var distance = direction.length();
        direction.normalize();
        var ray = new _Culling_ray__WEBPACK_IMPORTED_MODULE_5__["Ray"](this._scene.activeCamera.globalPosition, direction);
        var pickInfo = this._scene.pickWithRay(ray, this.meshesSelectionPredicate, true);
        return !pickInfo || !pickInfo.hit || pickInfo.distance > distance;
    };
    /**
     * @hidden
     */
    LensFlareSystem.prototype.render = function () {
        if (!this._effect.isReady() || !this._scene.activeCamera) {
            return false;
        }
        var engine = this._scene.getEngine();
        var viewport = this._scene.activeCamera.viewport;
        var globalViewport = viewport.toGlobal(engine.getRenderWidth(true), engine.getRenderHeight(true));
        // Position
        if (!this.computeEffectivePosition(globalViewport)) {
            return false;
        }
        // Visibility
        if (!this._isVisible()) {
            return false;
        }
        // Intensity
        var awayX;
        var awayY;
        if (this._positionX < this.borderLimit + globalViewport.x) {
            awayX = this.borderLimit + globalViewport.x - this._positionX;
        }
        else if (this._positionX > globalViewport.x + globalViewport.width - this.borderLimit) {
            awayX = this._positionX - globalViewport.x - globalViewport.width + this.borderLimit;
        }
        else {
            awayX = 0;
        }
        if (this._positionY < this.borderLimit + globalViewport.y) {
            awayY = this.borderLimit + globalViewport.y - this._positionY;
        }
        else if (this._positionY > globalViewport.y + globalViewport.height - this.borderLimit) {
            awayY = this._positionY - globalViewport.y - globalViewport.height + this.borderLimit;
        }
        else {
            awayY = 0;
        }
        var away = (awayX > awayY) ? awayX : awayY;
        away -= this.viewportBorder;
        if (away > this.borderLimit) {
            away = this.borderLimit;
        }
        var intensity = 1.0 - _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Clamp(away / this.borderLimit, 0, 1);
        if (intensity < 0) {
            return false;
        }
        if (intensity > 1.0) {
            intensity = 1.0;
        }
        if (this.viewportBorder > 0) {
            globalViewport.x += this.viewportBorder;
            globalViewport.y += this.viewportBorder;
            globalViewport.width -= this.viewportBorder * 2;
            globalViewport.height -= this.viewportBorder * 2;
            this._positionX -= this.viewportBorder;
            this._positionY -= this.viewportBorder;
        }
        // Position
        var centerX = globalViewport.x + globalViewport.width / 2;
        var centerY = globalViewport.y + globalViewport.height / 2;
        var distX = centerX - this._positionX;
        var distY = centerY - this._positionY;
        // Effects
        engine.enableEffect(this._effect);
        engine.setState(false);
        engine.setDepthBuffer(false);
        // VBOs
        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._effect);
        // Flares
        for (var index = 0; index < this.lensFlares.length; index++) {
            var flare = this.lensFlares[index];
            if (flare.texture && !flare.texture.isReady()) {
                continue;
            }
            engine.setAlphaMode(flare.alphaMode);
            var x = centerX - (distX * flare.position);
            var y = centerY - (distY * flare.position);
            var cw = flare.size;
            var ch = flare.size * engine.getAspectRatio(this._scene.activeCamera, true);
            var cx = 2 * (x / (globalViewport.width + globalViewport.x * 2)) - 1.0;
            var cy = 1.0 - 2 * (y / (globalViewport.height + globalViewport.y * 2));
            var viewportMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromValues(cw / 2, 0, 0, 0, 0, ch / 2, 0, 0, 0, 0, 1, 0, cx, cy, 0, 1);
            this._effect.setMatrix("viewportMatrix", viewportMatrix);
            // Texture
            this._effect.setTexture("textureSampler", flare.texture);
            // Color
            this._effect.setFloat4("color", flare.color.r * intensity, flare.color.g * intensity, flare.color.b * intensity, 1.0);
            // Draw order
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_6__["Material"].TriangleFillMode, 0, 6);
        }
        engine.setDepthBuffer(true);
        engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].ALPHA_DISABLE);
        return true;
    };
    /**
     * Dispose and release the lens flare with its associated resources.
     */
    LensFlareSystem.prototype.dispose = function () {
        var vertexBuffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind];
        if (vertexBuffer) {
            vertexBuffer.dispose();
            this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind] = null;
        }
        if (this._indexBuffer) {
            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
            this._indexBuffer = null;
        }
        while (this.lensFlares.length) {
            this.lensFlares[0].dispose();
        }
        // Remove from scene
        var index = this._scene.lensFlareSystems.indexOf(this);
        this._scene.lensFlareSystems.splice(index, 1);
    };
    /**
     * Parse a lens flare system from a JSON repressentation
     * @param parsedLensFlareSystem Define the JSON to parse
     * @param scene Define the scene the parsed system should be instantiated in
     * @param rootUrl Define the rootUrl of the load sequence to easily find a load relative dependencies such as textures
     * @returns the parsed system
     */
    LensFlareSystem.Parse = function (parsedLensFlareSystem, scene, rootUrl) {
        var emitter = scene.getLastEntryByID(parsedLensFlareSystem.emitterId);
        var name = parsedLensFlareSystem.name || "lensFlareSystem#" + parsedLensFlareSystem.emitterId;
        var lensFlareSystem = new LensFlareSystem(name, emitter, scene);
        lensFlareSystem.id = parsedLensFlareSystem.id || name;
        lensFlareSystem.borderLimit = parsedLensFlareSystem.borderLimit;
        for (var index = 0; index < parsedLensFlareSystem.flares.length; index++) {
            var parsedFlare = parsedLensFlareSystem.flares[index];
            _lensFlare__WEBPACK_IMPORTED_MODULE_7__["LensFlare"].AddFlare(parsedFlare.size, parsedFlare.position, _Maths_math_color__WEBPACK_IMPORTED_MODULE_12__["Color3"].FromArray(parsedFlare.color), parsedFlare.textureName ? rootUrl + parsedFlare.textureName : "", lensFlareSystem);
        }
        return lensFlareSystem;
    };
    /**
     * Serialize the current Lens Flare System into a JSON representation.
     * @returns the serialized JSON
     */
    LensFlareSystem.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.id = this.id;
        serializationObject.name = this.name;
        serializationObject.emitterId = this.getEmitter().id;
        serializationObject.borderLimit = this.borderLimit;
        serializationObject.flares = [];
        for (var index = 0; index < this.lensFlares.length; index++) {
            var flare = this.lensFlares[index];
            serializationObject.flares.push({
                size: flare.size,
                position: flare.position,
                color: flare.color.asArray(),
                textureName: _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFilename(flare.texture ? flare.texture.name : "")
            });
        }
        return serializationObject;
    };
    /** @hidden */
    LensFlareSystem._SceneComponentInitialization = function (_) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_11__["_DevTools"].WarnImport("LensFlareSystemSceneComponent");
    };
    return LensFlareSystem;
}());



/***/ }),

/***/ "./LensFlares/lensFlareSystemSceneComponent.ts":
/*!*****************************************************!*\
  !*** ./LensFlares/lensFlareSystemSceneComponent.ts ***!
  \*****************************************************/
/*! exports provided: LensFlareSystemSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystemSceneComponent", function() { return LensFlareSystemSceneComponent; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _lensFlareSystem__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lensFlareSystem */ "./LensFlares/lensFlareSystem.ts");




// Adds the parser to the scene parsers.
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].AddParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_LENSFLARESYSTEM, function (parsedData, scene, container, rootUrl) {
    // Lens flares
    if (parsedData.lensFlareSystems !== undefined && parsedData.lensFlareSystems !== null) {
        if (!container.lensFlareSystems) {
            container.lensFlareSystems = new Array();
        }
        for (var index = 0, cache = parsedData.lensFlareSystems.length; index < cache; index++) {
            var parsedLensFlareSystem = parsedData.lensFlareSystems[index];
            var lf = _lensFlareSystem__WEBPACK_IMPORTED_MODULE_3__["LensFlareSystem"].Parse(parsedLensFlareSystem, scene, rootUrl);
            container.lensFlareSystems.push(lf);
        }
    }
});
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].prototype.getLensFlareSystemByName = function (name) {
    for (var index = 0; index < this.lensFlareSystems.length; index++) {
        if (this.lensFlareSystems[index].name === name) {
            return this.lensFlareSystems[index];
        }
    }
    return null;
};
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].prototype.getLensFlareSystemByID = function (id) {
    for (var index = 0; index < this.lensFlareSystems.length; index++) {
        if (this.lensFlareSystems[index].id === id) {
            return this.lensFlareSystems[index];
        }
    }
    return null;
};
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].prototype.removeLensFlareSystem = function (toRemove) {
    var index = this.lensFlareSystems.indexOf(toRemove);
    if (index !== -1) {
        this.lensFlareSystems.splice(index, 1);
    }
    return index;
};
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].prototype.addLensFlareSystem = function (newLensFlareSystem) {
    this.lensFlareSystems.push(newLensFlareSystem);
};
/**
 * Defines the lens flare scene component responsible to manage any lens flares
 * in a given scene.
 */
var LensFlareSystemSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function LensFlareSystemSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_LENSFLARESYSTEM;
        this.scene = scene;
        scene.lensFlareSystems = new Array();
    }
    /**
     * Registers the component in a given scene
     */
    LensFlareSystemSceneComponent.prototype.register = function () {
        this.scene._afterCameraDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_AFTERCAMERADRAW_LENSFLARESYSTEM, this, this._draw);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    LensFlareSystemSceneComponent.prototype.rebuild = function () {
        // Nothing to do for lens flare
    };
    /**
     * Adds all the elements from the container to the scene
     * @param container the container holding the elements
     */
    LensFlareSystemSceneComponent.prototype.addFromContainer = function (container) {
        var _this = this;
        if (!container.lensFlareSystems) {
            return;
        }
        container.lensFlareSystems.forEach(function (o) {
            _this.scene.addLensFlareSystem(o);
        });
    };
    /**
     * Removes all the elements in the container from the scene
     * @param container contains the elements to remove
     * @param dispose if the removed element should be disposed (default: false)
     */
    LensFlareSystemSceneComponent.prototype.removeFromContainer = function (container, dispose) {
        var _this = this;
        if (!container.lensFlareSystems) {
            return;
        }
        container.lensFlareSystems.forEach(function (o) {
            _this.scene.removeLensFlareSystem(o);
            if (dispose) {
                o.dispose();
            }
        });
    };
    /**
     * Serializes the component data to the specified json object
     * @param serializationObject The object to serialize to
     */
    LensFlareSystemSceneComponent.prototype.serialize = function (serializationObject) {
        // Lens flares
        serializationObject.lensFlareSystems = [];
        var lensFlareSystems = this.scene.lensFlareSystems;
        for (var _i = 0, lensFlareSystems_1 = lensFlareSystems; _i < lensFlareSystems_1.length; _i++) {
            var lensFlareSystem = lensFlareSystems_1[_i];
            serializationObject.lensFlareSystems.push(lensFlareSystem.serialize());
        }
    };
    /**
     * Disposes the component and the associated ressources.
     */
    LensFlareSystemSceneComponent.prototype.dispose = function () {
        var lensFlareSystems = this.scene.lensFlareSystems;
        while (lensFlareSystems.length) {
            lensFlareSystems[0].dispose();
        }
    };
    LensFlareSystemSceneComponent.prototype._draw = function (camera) {
        // Lens flares
        if (this.scene.lensFlaresEnabled) {
            var lensFlareSystems = this.scene.lensFlareSystems;
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Lens flares", lensFlareSystems.length > 0);
            for (var _i = 0, lensFlareSystems_2 = lensFlareSystems; _i < lensFlareSystems_2.length; _i++) {
                var lensFlareSystem = lensFlareSystems_2[_i];
                if ((camera.layerMask & lensFlareSystem.layerMask) !== 0) {
                    lensFlareSystem.render();
                }
            }
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Lens flares", lensFlareSystems.length > 0);
        }
    };
    return LensFlareSystemSceneComponent;
}());

_lensFlareSystem__WEBPACK_IMPORTED_MODULE_3__["LensFlareSystem"]._SceneComponentInitialization = function (scene) {
    var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_LENSFLARESYSTEM);
    if (!component) {
        component = new LensFlareSystemSceneComponent(scene);
        scene._addComponent(component);
    }
};


/***/ }),

/***/ "./Lights/Shadows/index.ts":
/*!*********************************!*\
  !*** ./Lights/Shadows/index.ts ***!
  \*********************************/
/*! exports provided: ShadowGenerator, ShadowGeneratorSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _shadowGenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shadowGenerator */ "./Lights/Shadows/shadowGenerator.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGenerator", function() { return _shadowGenerator__WEBPACK_IMPORTED_MODULE_0__["ShadowGenerator"]; });

/* harmony import */ var _shadowGeneratorSceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shadowGeneratorSceneComponent */ "./Lights/Shadows/shadowGeneratorSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGeneratorSceneComponent", function() { return _shadowGeneratorSceneComponent__WEBPACK_IMPORTED_MODULE_1__["ShadowGeneratorSceneComponent"]; });





/***/ }),

/***/ "./Lights/Shadows/shadowGenerator.ts":
/*!*******************************************!*\
  !*** ./Lights/Shadows/shadowGenerator.ts ***!
  \*******************************************/
/*! exports provided: ShadowGenerator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowGenerator", function() { return ShadowGenerator; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Lights_light__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Lights/light */ "./Lights/light.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../PostProcesses/blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_shadowMap_fragment__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../Shaders/shadowMap.fragment */ "./Shaders/shadowMap.fragment.ts");
/* harmony import */ var _Shaders_shadowMap_vertex__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../Shaders/shadowMap.vertex */ "./Shaders/shadowMap.vertex.ts");
/* harmony import */ var _Shaders_depthBoxBlur_fragment__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../Shaders/depthBoxBlur.fragment */ "./Shaders/depthBoxBlur.fragment.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Misc/devTools */ "./Misc/devTools.ts");


















/**
 * Default implementation IShadowGenerator.
 * This is the main object responsible of generating shadows in the framework.
 * Documentation: https://doc.babylonjs.com/babylon101/shadows
 */
var ShadowGenerator = /** @class */ (function () {
    /**
     * Creates a ShadowGenerator object.
     * A ShadowGenerator is the required tool to use the shadows.
     * Each light casting shadows needs to use its own ShadowGenerator.
     * Documentation : https://doc.babylonjs.com/babylon101/shadows
     * @param mapSize The size of the texture what stores the shadows. Example : 1024.
     * @param light The light object generating the shadows.
     * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
     */
    function ShadowGenerator(mapSize, light, usefulFloatFirst) {
        /**
         * Observable triggered before the shadow is rendered. Can be used to update internal effect state
         */
        this.onBeforeShadowMapRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_16__["Observable"]();
        /**
         * Observable triggered after the shadow is rendered. Can be used to restore internal effect state
         */
        this.onAfterShadowMapRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_16__["Observable"]();
        /**
         * Observable triggered before a mesh is rendered in the shadow map.
         * Can be used to update internal effect state (that you can get from the onBeforeShadowMapRenderObservable)
         */
        this.onBeforeShadowMapRenderMeshObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_16__["Observable"]();
        /**
         * Observable triggered after a mesh is rendered in the shadow map.
         * Can be used to update internal effect state (that you can get from the onAfterShadowMapRenderObservable)
         */
        this.onAfterShadowMapRenderMeshObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_16__["Observable"]();
        this._bias = 0.00005;
        this._normalBias = 0;
        this._blurBoxOffset = 1;
        this._blurScale = 2;
        this._blurKernel = 1;
        this._useKernelBlur = false;
        this._filter = ShadowGenerator.FILTER_NONE;
        this._filteringQuality = ShadowGenerator.QUALITY_HIGH;
        this._contactHardeningLightSizeUVRatio = 0.1;
        this._darkness = 0;
        this._transparencyShadow = false;
        /**
         * Controls the extent to which the shadows fade out at the edge of the frustum
         * Used only by directionals and spots
         */
        this.frustumEdgeFalloff = 0;
        /**
         * If true the shadow map is generated by rendering the back face of the mesh instead of the front face.
         * This can help with self-shadowing as the geometry making up the back of objects is slightly offset.
         * It might on the other hand introduce peter panning.
         */
        this.forceBackFacesOnly = false;
        this._lightDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this._viewMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Zero();
        this._projectionMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Zero();
        this._transformMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Zero();
        this._cachedPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._cachedDirection = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        this._currentFaceIndex = 0;
        this._currentFaceIndexCache = 0;
        this._defaultTextureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        this._mapSize = mapSize;
        this._light = light;
        this._scene = light.getScene();
        light._shadowGenerator = this;
        ShadowGenerator._SceneComponentInitialization(this._scene);
        // Texture type fallback from float to int if not supported.
        var caps = this._scene.getEngine().getCaps();
        if (!usefulFloatFirst) {
            if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                this._textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_HALF_FLOAT;
            }
            else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {
                this._textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_FLOAT;
            }
            else {
                this._textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_UNSIGNED_INT;
            }
        }
        else {
            if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {
                this._textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_FLOAT;
            }
            else if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                this._textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_HALF_FLOAT;
            }
            else {
                this._textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_UNSIGNED_INT;
            }
        }
        this._initializeGenerator();
        this._applyFilterValues();
    }
    Object.defineProperty(ShadowGenerator.prototype, "bias", {
        /**
         * Gets the bias: offset applied on the depth preventing acnea (in light direction).
         */
        get: function () {
            return this._bias;
        },
        /**
         * Sets the bias: offset applied on the depth preventing acnea (in light direction).
         */
        set: function (bias) {
            this._bias = bias;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "normalBias", {
        /**
         * Gets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
         */
        get: function () {
            return this._normalBias;
        },
        /**
         * Sets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
         */
        set: function (normalBias) {
            this._normalBias = normalBias;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "blurBoxOffset", {
        /**
         * Gets the blur box offset: offset applied during the blur pass.
         * Only useful if useKernelBlur = false
         */
        get: function () {
            return this._blurBoxOffset;
        },
        /**
         * Sets the blur box offset: offset applied during the blur pass.
         * Only useful if useKernelBlur = false
         */
        set: function (value) {
            if (this._blurBoxOffset === value) {
                return;
            }
            this._blurBoxOffset = value;
            this._disposeBlurPostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "blurScale", {
        /**
         * Gets the blur scale: scale of the blurred texture compared to the main shadow map.
         * 2 means half of the size.
         */
        get: function () {
            return this._blurScale;
        },
        /**
         * Sets the blur scale: scale of the blurred texture compared to the main shadow map.
         * 2 means half of the size.
         */
        set: function (value) {
            if (this._blurScale === value) {
                return;
            }
            this._blurScale = value;
            this._disposeBlurPostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "blurKernel", {
        /**
         * Gets the blur kernel: kernel size of the blur pass.
         * Only useful if useKernelBlur = true
         */
        get: function () {
            return this._blurKernel;
        },
        /**
         * Sets the blur kernel: kernel size of the blur pass.
         * Only useful if useKernelBlur = true
         */
        set: function (value) {
            if (this._blurKernel === value) {
                return;
            }
            this._blurKernel = value;
            this._disposeBlurPostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "useKernelBlur", {
        /**
         * Gets whether the blur pass is a kernel blur (if true) or box blur.
         * Only useful in filtered mode (useBlurExponentialShadowMap...)
         */
        get: function () {
            return this._useKernelBlur;
        },
        /**
         * Sets whether the blur pass is a kernel blur (if true) or box blur.
         * Only useful in filtered mode (useBlurExponentialShadowMap...)
         */
        set: function (value) {
            if (this._useKernelBlur === value) {
                return;
            }
            this._useKernelBlur = value;
            this._disposeBlurPostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "depthScale", {
        /**
         * Gets the depth scale used in ESM mode.
         */
        get: function () {
            return this._depthScale !== undefined ? this._depthScale : this._light.getDepthScale();
        },
        /**
         * Sets the depth scale used in ESM mode.
         * This can override the scale stored on the light.
         */
        set: function (value) {
            this._depthScale = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "filter", {
        /**
         * Gets the current mode of the shadow generator (normal, PCF, ESM...).
         * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
         */
        get: function () {
            return this._filter;
        },
        /**
         * Sets the current mode of the shadow generator (normal, PCF, ESM...).
         * The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
         */
        set: function (value) {
            // Blurring the cubemap is going to be too expensive. Reverting to unblurred version
            if (this._light.needCube()) {
                if (value === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {
                    this.useExponentialShadowMap = true;
                    return;
                }
                else if (value === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) {
                    this.useCloseExponentialShadowMap = true;
                    return;
                }
                // PCF on cubemap would also be expensive
                else if (value === ShadowGenerator.FILTER_PCF || value === ShadowGenerator.FILTER_PCSS) {
                    this.usePoissonSampling = true;
                    return;
                }
            }
            // Weblg1 fallback for PCF.
            if (value === ShadowGenerator.FILTER_PCF || value === ShadowGenerator.FILTER_PCSS) {
                if (this._scene.getEngine().webGLVersion === 1) {
                    this.usePoissonSampling = true;
                    return;
                }
            }
            if (this._filter === value) {
                return;
            }
            this._filter = value;
            this._disposeBlurPostProcesses();
            this._applyFilterValues();
            this._light._markMeshesAsLightDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "usePoissonSampling", {
        /**
         * Gets if the current filter is set to Poisson Sampling.
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_POISSONSAMPLING;
        },
        /**
         * Sets the current filter to Poisson Sampling.
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_POISSONSAMPLING) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_POISSONSAMPLING : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "useExponentialShadowMap", {
        /**
         * Gets if the current filter is set to ESM.
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP;
        },
        /**
         * Sets the current filter is to ESM.
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "useBlurExponentialShadowMap", {
        /**
         * Gets if the current filter is set to filtered ESM.
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP;
        },
        /**
         * Gets if the current filter is set to filtered  ESM.
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "useCloseExponentialShadowMap", {
        /**
         * Gets if the current filter is set to "close ESM" (using the inverse of the
         * exponential to prevent steep falloff artifacts).
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP;
        },
        /**
         * Sets the current filter to "close ESM" (using the inverse of the
         * exponential to prevent steep falloff artifacts).
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "useBlurCloseExponentialShadowMap", {
        /**
         * Gets if the current filter is set to filtered "close ESM" (using the inverse of the
         * exponential to prevent steep falloff artifacts).
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP;
        },
        /**
         * Sets the current filter to filtered "close ESM" (using the inverse of the
         * exponential to prevent steep falloff artifacts).
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "usePercentageCloserFiltering", {
        /**
         * Gets if the current filter is set to "PCF" (percentage closer filtering).
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_PCF;
        },
        /**
         * Sets the current filter to "PCF" (percentage closer filtering).
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_PCF) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_PCF : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "filteringQuality", {
        /**
         * Gets the PCF or PCSS Quality.
         * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
         */
        get: function () {
            return this._filteringQuality;
        },
        /**
         * Sets the PCF or PCSS Quality.
         * Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
         */
        set: function (filteringQuality) {
            if (this._filteringQuality === filteringQuality) {
                return;
            }
            this._filteringQuality = filteringQuality;
            this._disposeBlurPostProcesses();
            this._applyFilterValues();
            this._light._markMeshesAsLightDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "useContactHardeningShadow", {
        /**
         * Gets if the current filter is set to "PCSS" (contact hardening).
         */
        get: function () {
            return this.filter === ShadowGenerator.FILTER_PCSS;
        },
        /**
         * Sets the current filter to "PCSS" (contact hardening).
         */
        set: function (value) {
            if (!value && this.filter !== ShadowGenerator.FILTER_PCSS) {
                return;
            }
            this.filter = (value ? ShadowGenerator.FILTER_PCSS : ShadowGenerator.FILTER_NONE);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "contactHardeningLightSizeUVRatio", {
        /**
         * Gets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
         * Using a ratio helps keeping shape stability independently of the map size.
         *
         * It does not account for the light projection as it was having too much
         * instability during the light setup or during light position changes.
         *
         * Only valid if useContactHardeningShadow is true.
         */
        get: function () {
            return this._contactHardeningLightSizeUVRatio;
        },
        /**
         * Sets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
         * Using a ratio helps keeping shape stability independently of the map size.
         *
         * It does not account for the light projection as it was having too much
         * instability during the light setup or during light position changes.
         *
         * Only valid if useContactHardeningShadow is true.
         */
        set: function (contactHardeningLightSizeUVRatio) {
            this._contactHardeningLightSizeUVRatio = contactHardeningLightSizeUVRatio;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowGenerator.prototype, "darkness", {
        /** Gets or sets the actual darkness of a shadow */
        get: function () {
            return this._darkness;
        },
        set: function (value) {
            this.setDarkness(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the darkness value (float). This can only decrease the actual darkness of a shadow.
     * 0 means strongest and 1 would means no shadow.
     * @returns the darkness.
     */
    ShadowGenerator.prototype.getDarkness = function () {
        return this._darkness;
    };
    /**
     * Sets the darkness value (float). This can only decrease the actual darkness of a shadow.
     * @param darkness The darkness value 0 means strongest and 1 would means no shadow.
     * @returns the shadow generator allowing fluent coding.
     */
    ShadowGenerator.prototype.setDarkness = function (darkness) {
        if (darkness >= 1.0) {
            this._darkness = 1.0;
        }
        else if (darkness <= 0.0) {
            this._darkness = 0.0;
        }
        else {
            this._darkness = darkness;
        }
        return this;
    };
    Object.defineProperty(ShadowGenerator.prototype, "transparencyShadow", {
        /** Gets or sets the ability to have transparent shadow  */
        get: function () {
            return this._transparencyShadow;
        },
        set: function (value) {
            this.setTransparencyShadow(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets the ability to have transparent shadow (boolean).
     * @param transparent True if transparent else False
     * @returns the shadow generator allowing fluent coding
     */
    ShadowGenerator.prototype.setTransparencyShadow = function (transparent) {
        this._transparencyShadow = transparent;
        return this;
    };
    /**
     * Gets the main RTT containing the shadow map (usually storing depth from the light point of view).
     * @returns The render target texture if present otherwise, null
     */
    ShadowGenerator.prototype.getShadowMap = function () {
        return this._shadowMap;
    };
    /**
     * Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).
     * @returns The render target texture if the shadow map is present otherwise, null
     */
    ShadowGenerator.prototype.getShadowMapForRendering = function () {
        if (this._shadowMap2) {
            return this._shadowMap2;
        }
        return this._shadowMap;
    };
    /**
     * Gets the class name of that object
     * @returns "ShadowGenerator"
     */
    ShadowGenerator.prototype.getClassName = function () {
        return "ShadowGenerator";
    };
    /**
     * Helper function to add a mesh and its descendants to the list of shadow casters.
     * @param mesh Mesh to add
     * @param includeDescendants boolean indicating if the descendants should be added. Default to true
     * @returns the Shadow Generator itself
     */
    ShadowGenerator.prototype.addShadowCaster = function (mesh, includeDescendants) {
        var _a;
        if (includeDescendants === void 0) { includeDescendants = true; }
        if (!this._shadowMap) {
            return this;
        }
        if (!this._shadowMap.renderList) {
            this._shadowMap.renderList = [];
        }
        this._shadowMap.renderList.push(mesh);
        if (includeDescendants) {
            (_a = this._shadowMap.renderList).push.apply(_a, mesh.getChildMeshes());
        }
        return this;
    };
    /**
     * Helper function to remove a mesh and its descendants from the list of shadow casters
     * @param mesh Mesh to remove
     * @param includeDescendants boolean indicating if the descendants should be removed. Default to true
     * @returns the Shadow Generator itself
     */
    ShadowGenerator.prototype.removeShadowCaster = function (mesh, includeDescendants) {
        if (includeDescendants === void 0) { includeDescendants = true; }
        if (!this._shadowMap || !this._shadowMap.renderList) {
            return this;
        }
        var index = this._shadowMap.renderList.indexOf(mesh);
        if (index !== -1) {
            this._shadowMap.renderList.splice(index, 1);
        }
        if (includeDescendants) {
            for (var _i = 0, _a = mesh.getChildren(); _i < _a.length; _i++) {
                var child = _a[_i];
                this.removeShadowCaster(child);
            }
        }
        return this;
    };
    /**
     * Returns the associated light object.
     * @returns the light generating the shadow
     */
    ShadowGenerator.prototype.getLight = function () {
        return this._light;
    };
    ShadowGenerator.prototype._initializeGenerator = function () {
        this._light._markMeshesAsLightDirty();
        this._initializeShadowMap();
    };
    ShadowGenerator.prototype._initializeShadowMap = function () {
        var _this = this;
        // Render target
        var engine = this._scene.getEngine();
        if (engine.webGLVersion > 1) {
            this._shadowMap = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_9__["RenderTargetTexture"](this._light.name + "_shadowMap", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube(), undefined, false, false);
            this._shadowMap.createDepthStencilTexture(_Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].LESS, true);
        }
        else {
            this._shadowMap = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_9__["RenderTargetTexture"](this._light.name + "_shadowMap", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube());
        }
        this._shadowMap.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].CLAMP_ADDRESSMODE;
        this._shadowMap.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].CLAMP_ADDRESSMODE;
        this._shadowMap.anisotropicFilteringLevel = 1;
        this._shadowMap.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE);
        this._shadowMap.renderParticles = false;
        this._shadowMap.ignoreCameraViewport = true;
        // Record Face Index before render.
        this._shadowMap.onBeforeRenderObservable.add(function (faceIndex) {
            _this._currentFaceIndex = faceIndex;
            if (_this._filter === ShadowGenerator.FILTER_PCF) {
                engine.setColorWrite(false);
            }
        });
        // Custom render function.
        this._shadowMap.customRenderFunction = this._renderForShadowMap.bind(this);
        // Blur if required afer render.
        this._shadowMap.onAfterUnbindObservable.add(function () {
            if (_this._filter === ShadowGenerator.FILTER_PCF) {
                engine.setColorWrite(true);
            }
            if (!_this.useBlurExponentialShadowMap && !_this.useBlurCloseExponentialShadowMap) {
                return;
            }
            var shadowMap = _this.getShadowMapForRendering();
            if (shadowMap) {
                _this._scene.postProcessManager.directRender(_this._blurPostProcesses, shadowMap.getInternalTexture(), true);
            }
        });
        // Clear according to the chosen filter.
        var clearZero = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        var clearOne = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](1.0, 1.0, 1.0, 1.0);
        this._shadowMap.onClearObservable.add(function (engine) {
            if (_this._filter === ShadowGenerator.FILTER_PCF) {
                engine.clear(clearOne, false, true, false);
            }
            else if (_this.useExponentialShadowMap || _this.useBlurExponentialShadowMap) {
                engine.clear(clearZero, true, true, false);
            }
            else {
                engine.clear(clearOne, true, true, false);
            }
        });
        this._shadowMap.onResizeObservable.add(function (RTT) {
            _this._mapSize = RTT.getRenderSize();
            _this._light._markMeshesAsLightDirty();
            _this.recreateShadowMap();
        });
    };
    ShadowGenerator.prototype._initializeBlurRTTAndPostProcesses = function () {
        var _this = this;
        var engine = this._scene.getEngine();
        var targetSize = this._mapSize / this.blurScale;
        if (!this.useKernelBlur || this.blurScale !== 1.0) {
            this._shadowMap2 = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_9__["RenderTargetTexture"](this._light.name + "_shadowMap2", targetSize, this._scene, false, true, this._textureType);
            this._shadowMap2.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].CLAMP_ADDRESSMODE;
            this._shadowMap2.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].CLAMP_ADDRESSMODE;
            this._shadowMap2.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE);
        }
        if (this.useKernelBlur) {
            this._kernelBlurXPostprocess = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_11__["BlurPostProcess"](this._light.name + "KernelBlurX", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1, 0), this.blurKernel, 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, this._textureType);
            this._kernelBlurXPostprocess.width = targetSize;
            this._kernelBlurXPostprocess.height = targetSize;
            this._kernelBlurXPostprocess.onApplyObservable.add(function (effect) {
                effect.setTexture("textureSampler", _this._shadowMap);
            });
            this._kernelBlurYPostprocess = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_11__["BlurPostProcess"](this._light.name + "KernelBlurY", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0, 1), this.blurKernel, 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, this._textureType);
            this._kernelBlurXPostprocess.autoClear = false;
            this._kernelBlurYPostprocess.autoClear = false;
            if (this._textureType === _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_UNSIGNED_INT) {
                this._kernelBlurXPostprocess.packedFloat = true;
                this._kernelBlurYPostprocess.packedFloat = true;
            }
            this._blurPostProcesses = [this._kernelBlurXPostprocess, this._kernelBlurYPostprocess];
        }
        else {
            this._boxBlurPostprocess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_10__["PostProcess"](this._light.name + "DepthBoxBlur", "depthBoxBlur", ["screenSize", "boxOffset"], [], 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, "#define OFFSET " + this._blurBoxOffset, this._textureType);
            this._boxBlurPostprocess.onApplyObservable.add(function (effect) {
                effect.setFloat2("screenSize", targetSize, targetSize);
                effect.setTexture("textureSampler", _this._shadowMap);
            });
            this._boxBlurPostprocess.autoClear = false;
            this._blurPostProcesses = [this._boxBlurPostprocess];
        }
    };
    ShadowGenerator.prototype._renderForShadowMap = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes) {
        var index;
        var engine = this._scene.getEngine();
        if (depthOnlySubMeshes.length) {
            engine.setColorWrite(false);
            for (index = 0; index < depthOnlySubMeshes.length; index++) {
                this._renderSubMeshForShadowMap(depthOnlySubMeshes.data[index]);
            }
            engine.setColorWrite(true);
        }
        for (index = 0; index < opaqueSubMeshes.length; index++) {
            this._renderSubMeshForShadowMap(opaqueSubMeshes.data[index]);
        }
        for (index = 0; index < alphaTestSubMeshes.length; index++) {
            this._renderSubMeshForShadowMap(alphaTestSubMeshes.data[index]);
        }
        if (this._transparencyShadow) {
            for (index = 0; index < transparentSubMeshes.length; index++) {
                this._renderSubMeshForShadowMap(transparentSubMeshes.data[index]);
            }
        }
    };
    ShadowGenerator.prototype._renderSubMeshForShadowMap = function (subMesh) {
        var _this = this;
        var mesh = subMesh.getRenderingMesh();
        var scene = this._scene;
        var engine = scene.getEngine();
        var material = subMesh.getMaterial();
        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
        if (!material || subMesh.verticesCount === 0) {
            return;
        }
        // Culling
        engine.setState(material.backFaceCulling);
        // Managing instances
        var batch = mesh._getInstancesRenderList(subMesh._id);
        if (batch.mustReturn) {
            return;
        }
        var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
        if (this.isReady(subMesh, hardwareInstancedRendering)) {
            engine.enableEffect(this._effect);
            mesh._bind(subMesh, this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode);
            this._effect.setFloat3("biasAndScale", this.bias, this.normalBias, this.depthScale);
            this._effect.setMatrix("viewProjection", this.getTransformMatrix());
            if (this.getLight().getTypeID() === _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTTYPEID_DIRECTIONALLIGHT) {
                this._effect.setVector3("lightData", this._cachedDirection);
            }
            else {
                this._effect.setVector3("lightData", this._cachedPosition);
            }
            if (scene.activeCamera) {
                this._effect.setFloat2("depthValues", this.getLight().getDepthMinZ(scene.activeCamera), this.getLight().getDepthMinZ(scene.activeCamera) + this.getLight().getDepthMaxZ(scene.activeCamera));
            }
            // Alpha test
            if (material && material.needAlphaTesting()) {
                var alphaTexture = material.getAlphaTestTexture();
                if (alphaTexture) {
                    this._effect.setTexture("diffuseSampler", alphaTexture);
                    this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix() || this._defaultTextureMatrix);
                }
            }
            // Bones
            if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                var skeleton = mesh.skeleton;
                if (skeleton.isUsingTextureForMatrices) {
                    var boneTexture = skeleton.getTransformMatrixTexture(mesh);
                    if (!boneTexture) {
                        return;
                    }
                    this._effect.setTexture("boneSampler", boneTexture);
                    this._effect.setFloat("boneTextureWidth", 4.0 * (skeleton.bones.length + 1));
                }
                else {
                    this._effect.setMatrices("mBones", skeleton.getTransformMatrices((mesh)));
                }
            }
            // Morph targets
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].BindMorphTargetParameters(mesh, this._effect);
            if (this.forceBackFacesOnly) {
                engine.setState(true, 0, false, true);
            }
            // Observables
            this.onBeforeShadowMapRenderMeshObservable.notifyObservers(mesh);
            this.onBeforeShadowMapRenderObservable.notifyObservers(this._effect);
            // Draw
            mesh._processRendering(subMesh, this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._effect.setMatrix("world", world); });
            if (this.forceBackFacesOnly) {
                engine.setState(true, 0, false, false);
            }
            // Observables
            this.onAfterShadowMapRenderObservable.notifyObservers(this._effect);
            this.onAfterShadowMapRenderMeshObservable.notifyObservers(mesh);
        }
        else {
            // Need to reset refresh rate of the shadowMap
            if (this._shadowMap) {
                this._shadowMap.resetRefreshCounter();
            }
        }
    };
    ShadowGenerator.prototype._applyFilterValues = function () {
        if (!this._shadowMap) {
            return;
        }
        if (this.filter === ShadowGenerator.FILTER_NONE || this.filter === ShadowGenerator.FILTER_PCSS) {
            this._shadowMap.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].NEAREST_SAMPLINGMODE);
        }
        else {
            this._shadowMap.updateSamplingMode(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_8__["Texture"].BILINEAR_SAMPLINGMODE);
        }
    };
    /**
     * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
     * @param onCompiled Callback triggered at the and of the effects compilation
     * @param options Sets of optional options forcing the compilation with different modes
     */
    ShadowGenerator.prototype.forceCompilation = function (onCompiled, options) {
        var _this = this;
        var localOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ useInstances: false }, options);
        var shadowMap = this.getShadowMap();
        if (!shadowMap) {
            if (onCompiled) {
                onCompiled(this);
            }
            return;
        }
        var renderList = shadowMap.renderList;
        if (!renderList) {
            if (onCompiled) {
                onCompiled(this);
            }
            return;
        }
        var subMeshes = new Array();
        for (var _i = 0, renderList_1 = renderList; _i < renderList_1.length; _i++) {
            var mesh = renderList_1[_i];
            subMeshes.push.apply(subMeshes, mesh.subMeshes);
        }
        if (subMeshes.length === 0) {
            if (onCompiled) {
                onCompiled(this);
            }
            return;
        }
        var currentIndex = 0;
        var checkReady = function () {
            if (!_this._scene || !_this._scene.getEngine()) {
                return;
            }
            while (_this.isReady(subMeshes[currentIndex], localOptions.useInstances)) {
                currentIndex++;
                if (currentIndex >= subMeshes.length) {
                    if (onCompiled) {
                        onCompiled(_this);
                    }
                    return;
                }
            }
            setTimeout(checkReady, 16);
        };
        checkReady();
    };
    /**
     * Forces all the attached effect to compile to enable rendering only once ready vs. lazyly compiling effects.
     * @param options Sets of optional options forcing the compilation with different modes
     * @returns A promise that resolves when the compilation completes
     */
    ShadowGenerator.prototype.forceCompilationAsync = function (options) {
        var _this = this;
        return new Promise(function (resolve) {
            _this.forceCompilation(function () {
                resolve();
            }, options);
        });
    };
    /**
     * Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
     * @param subMesh The submesh we want to render in the shadow map
     * @param useInstances Defines wether will draw in the map using instances
     * @returns true if ready otherwise, false
     */
    ShadowGenerator.prototype.isReady = function (subMesh, useInstances) {
        var defines = [];
        if (this._textureType !== _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].TEXTURETYPE_UNSIGNED_INT) {
            defines.push("#define FLOAT");
        }
        if (this.useExponentialShadowMap || this.useBlurExponentialShadowMap) {
            defines.push("#define ESM");
        }
        else if (this.usePercentageCloserFiltering || this.useContactHardeningShadow) {
            defines.push("#define DEPTHTEXTURE");
        }
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind];
        var mesh = subMesh.getMesh();
        var material = subMesh.getMaterial();
        // Normal bias.
        if (this.normalBias && mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind)) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind);
            defines.push("#define NORMAL");
            if (mesh.nonUniformScaling) {
                defines.push("#define NONUNIFORMSCALING");
            }
            if (this.getLight().getTypeID() === _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTTYPEID_DIRECTIONALLIGHT) {
                defines.push("#define DIRECTIONINLIGHTDATA");
            }
        }
        // Alpha test
        if (material && material.needAlphaTesting()) {
            var alphaTexture = material.getAlphaTestTexture();
            if (alphaTexture) {
                defines.push("#define ALPHATEST");
                if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind)) {
                    attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind);
                    defines.push("#define UV1");
                }
                if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind)) {
                    if (alphaTexture.coordinatesIndex === 1) {
                        attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind);
                        defines.push("#define UV2");
                    }
                }
            }
        }
        // Bones
        var fallbacks = new _Materials_effect__WEBPACK_IMPORTED_MODULE_7__["EffectFallbacks"]();
        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind);
            if (mesh.numBoneInfluencers > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsExtraKind);
            }
            var skeleton = mesh.skeleton;
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            if (mesh.numBoneInfluencers > 0) {
                fallbacks.addCPUSkinningFallback(0, mesh);
            }
            if (skeleton.isUsingTextureForMatrices) {
                defines.push("#define BONETEXTURE");
            }
            else {
                defines.push("#define BonesPerMesh " + (skeleton.bones.length + 1));
            }
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Morph targets
        var manager = mesh.morphTargetManager;
        var morphInfluencers = 0;
        if (manager) {
            if (manager.numInfluencers > 0) {
                defines.push("#define MORPHTARGETS");
                morphInfluencers = manager.numInfluencers;
                defines.push("#define NUM_MORPH_INFLUENCERS " + morphInfluencers);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, morphInfluencers);
            }
        }
        // Instances
        if (useInstances) {
            defines.push("#define INSTANCES");
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        if (this.customShaderOptions) {
            if (this.customShaderOptions.defines) {
                for (var _i = 0, _a = this.customShaderOptions.defines; _i < _a.length; _i++) {
                    var define = _a[_i];
                    if (defines.indexOf(define) === -1) {
                        defines.push(define);
                    }
                }
            }
        }
        // Get correct effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            var shaderName = "shadowMap";
            var uniforms = ["world", "mBones", "viewProjection", "diffuseMatrix", "lightData", "depthValues", "biasAndScale", "morphTargetInfluences", "boneTextureWidth"];
            var samplers = ["diffuseSampler", "boneSampler"];
            // Custom shader?
            if (this.customShaderOptions) {
                shaderName = this.customShaderOptions.shaderName;
                if (this.customShaderOptions.attributes) {
                    for (var _b = 0, _c = this.customShaderOptions.attributes; _b < _c.length; _b++) {
                        var attrib = _c[_b];
                        if (attribs.indexOf(attrib) === -1) {
                            attribs.push(attrib);
                        }
                    }
                }
                if (this.customShaderOptions.uniforms) {
                    for (var _d = 0, _e = this.customShaderOptions.uniforms; _d < _e.length; _d++) {
                        var uniform = _e[_d];
                        if (uniforms.indexOf(uniform) === -1) {
                            uniforms.push(uniform);
                        }
                    }
                }
                if (this.customShaderOptions.samplers) {
                    for (var _f = 0, _g = this.customShaderOptions.samplers; _f < _g.length; _f++) {
                        var sampler = _g[_f];
                        if (samplers.indexOf(sampler) === -1) {
                            samplers.push(sampler);
                        }
                    }
                }
            }
            this._effect = this._scene.getEngine().createEffect(shaderName, attribs, uniforms, samplers, join, fallbacks, undefined, undefined, { maxSimultaneousMorphTargets: morphInfluencers });
        }
        if (!this._effect.isReady()) {
            return false;
        }
        if (this.useBlurExponentialShadowMap || this.useBlurCloseExponentialShadowMap) {
            if (!this._blurPostProcesses || !this._blurPostProcesses.length) {
                this._initializeBlurRTTAndPostProcesses();
            }
        }
        if (this._kernelBlurXPostprocess && !this._kernelBlurXPostprocess.isReady()) {
            return false;
        }
        if (this._kernelBlurYPostprocess && !this._kernelBlurYPostprocess.isReady()) {
            return false;
        }
        if (this._boxBlurPostprocess && !this._boxBlurPostprocess.isReady()) {
            return false;
        }
        return true;
    };
    /**
     * Prepare all the defines in a material relying on a shadow map at the specified light index.
     * @param defines Defines of the material we want to update
     * @param lightIndex Index of the light in the enabled light list of the material
     */
    ShadowGenerator.prototype.prepareDefines = function (defines, lightIndex) {
        var scene = this._scene;
        var light = this._light;
        if (!scene.shadowsEnabled || !light.shadowEnabled) {
            return;
        }
        defines["SHADOW" + lightIndex] = true;
        if (this.useContactHardeningShadow) {
            defines["SHADOWPCSS" + lightIndex] = true;
            if (this._filteringQuality === ShadowGenerator.QUALITY_LOW) {
                defines["SHADOWLOWQUALITY" + lightIndex] = true;
            }
            else if (this._filteringQuality === ShadowGenerator.QUALITY_MEDIUM) {
                defines["SHADOWMEDIUMQUALITY" + lightIndex] = true;
            }
            // else default to high.
        }
        if (this.usePercentageCloserFiltering) {
            defines["SHADOWPCF" + lightIndex] = true;
            if (this._filteringQuality === ShadowGenerator.QUALITY_LOW) {
                defines["SHADOWLOWQUALITY" + lightIndex] = true;
            }
            else if (this._filteringQuality === ShadowGenerator.QUALITY_MEDIUM) {
                defines["SHADOWMEDIUMQUALITY" + lightIndex] = true;
            }
            // else default to high.
        }
        else if (this.usePoissonSampling) {
            defines["SHADOWPOISSON" + lightIndex] = true;
        }
        else if (this.useExponentialShadowMap || this.useBlurExponentialShadowMap) {
            defines["SHADOWESM" + lightIndex] = true;
        }
        else if (this.useCloseExponentialShadowMap || this.useBlurCloseExponentialShadowMap) {
            defines["SHADOWCLOSEESM" + lightIndex] = true;
        }
        if (light.needCube()) {
            defines["SHADOWCUBE" + lightIndex] = true;
        }
    };
    /**
     * Binds the shadow related information inside of an effect (information like near, far, darkness...
     * defined in the generator but impacting the effect).
     * @param lightIndex Index of the light in the enabled light list of the material owning the effect
     * @param effect The effect we are binfing the information for
     */
    ShadowGenerator.prototype.bindShadowLight = function (lightIndex, effect) {
        var light = this._light;
        var scene = this._scene;
        if (!scene.shadowsEnabled || !light.shadowEnabled) {
            return;
        }
        var camera = scene.activeCamera;
        if (!camera) {
            return;
        }
        var shadowMap = this.getShadowMap();
        if (!shadowMap) {
            return;
        }
        if (!light.needCube()) {
            effect.setMatrix("lightMatrix" + lightIndex, this.getTransformMatrix());
        }
        // Only PCF uses depth stencil texture.
        if (this._filter === ShadowGenerator.FILTER_PCF) {
            effect.setDepthStencilTexture("shadowSampler" + lightIndex, this.getShadowMapForRendering());
            light._uniformBuffer.updateFloat4("shadowsInfo", this.getDarkness(), shadowMap.getSize().width, 1 / shadowMap.getSize().width, this.frustumEdgeFalloff, lightIndex);
        }
        else if (this._filter === ShadowGenerator.FILTER_PCSS) {
            effect.setDepthStencilTexture("shadowSampler" + lightIndex, this.getShadowMapForRendering());
            effect.setTexture("depthSampler" + lightIndex, this.getShadowMapForRendering());
            light._uniformBuffer.updateFloat4("shadowsInfo", this.getDarkness(), 1 / shadowMap.getSize().width, this._contactHardeningLightSizeUVRatio * shadowMap.getSize().width, this.frustumEdgeFalloff, lightIndex);
        }
        else {
            effect.setTexture("shadowSampler" + lightIndex, this.getShadowMapForRendering());
            light._uniformBuffer.updateFloat4("shadowsInfo", this.getDarkness(), this.blurScale / shadowMap.getSize().width, this.depthScale, this.frustumEdgeFalloff, lightIndex);
        }
        light._uniformBuffer.updateFloat2("depthValues", this.getLight().getDepthMinZ(camera), this.getLight().getDepthMinZ(camera) + this.getLight().getDepthMaxZ(camera), lightIndex);
    };
    /**
     * Gets the transformation matrix used to project the meshes into the map from the light point of view.
     * (eq to shadow prjection matrix * light transform matrix)
     * @returns The transform matrix used to create the shadow map
     */
    ShadowGenerator.prototype.getTransformMatrix = function () {
        var scene = this._scene;
        if (this._currentRenderID === scene.getRenderId() && this._currentFaceIndexCache === this._currentFaceIndex) {
            return this._transformMatrix;
        }
        this._currentRenderID = scene.getRenderId();
        this._currentFaceIndexCache = this._currentFaceIndex;
        var lightPosition = this._light.position;
        if (this._light.computeTransformedInformation()) {
            lightPosition = this._light.transformedPosition;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].NormalizeToRef(this._light.getShadowDirection(this._currentFaceIndex), this._lightDirection);
        if (Math.abs(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Dot(this._lightDirection, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Up())) === 1.0) {
            this._lightDirection.z = 0.0000000000001; // Required to avoid perfectly perpendicular light
        }
        if (this._light.needProjectionMatrixCompute() || !this._cachedPosition || !this._cachedDirection || !lightPosition.equals(this._cachedPosition) || !this._lightDirection.equals(this._cachedDirection)) {
            this._cachedPosition.copyFrom(lightPosition);
            this._cachedDirection.copyFrom(this._lightDirection);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].LookAtLHToRef(lightPosition, lightPosition.add(this._lightDirection), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Up(), this._viewMatrix);
            var shadowMap = this.getShadowMap();
            if (shadowMap) {
                var renderList = shadowMap.renderList;
                if (renderList) {
                    this._light.setShadowProjectionMatrix(this._projectionMatrix, this._viewMatrix, renderList);
                }
            }
            this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
        }
        return this._transformMatrix;
    };
    /**
     * Recreates the shadow map dependencies like RTT and post processes. This can be used during the switch between
     * Cube and 2D textures for instance.
     */
    ShadowGenerator.prototype.recreateShadowMap = function () {
        var shadowMap = this._shadowMap;
        if (!shadowMap) {
            return;
        }
        // Track render list.
        var renderList = shadowMap.renderList;
        // Clean up existing data.
        this._disposeRTTandPostProcesses();
        // Reinitializes.
        this._initializeGenerator();
        // Reaffect the filter to ensure a correct fallback if necessary.
        this.filter = this.filter;
        // Reaffect the filter.
        this._applyFilterValues();
        // Reaffect Render List.
        this._shadowMap.renderList = renderList;
    };
    ShadowGenerator.prototype._disposeBlurPostProcesses = function () {
        if (this._shadowMap2) {
            this._shadowMap2.dispose();
            this._shadowMap2 = null;
        }
        if (this._boxBlurPostprocess) {
            this._boxBlurPostprocess.dispose();
            this._boxBlurPostprocess = null;
        }
        if (this._kernelBlurXPostprocess) {
            this._kernelBlurXPostprocess.dispose();
            this._kernelBlurXPostprocess = null;
        }
        if (this._kernelBlurYPostprocess) {
            this._kernelBlurYPostprocess.dispose();
            this._kernelBlurYPostprocess = null;
        }
        this._blurPostProcesses = [];
    };
    ShadowGenerator.prototype._disposeRTTandPostProcesses = function () {
        if (this._shadowMap) {
            this._shadowMap.dispose();
            this._shadowMap = null;
        }
        this._disposeBlurPostProcesses();
    };
    /**
     * Disposes the ShadowGenerator.
     * Returns nothing.
     */
    ShadowGenerator.prototype.dispose = function () {
        this._disposeRTTandPostProcesses();
        if (this._light) {
            this._light._shadowGenerator = null;
            this._light._markMeshesAsLightDirty();
        }
        this.onBeforeShadowMapRenderMeshObservable.clear();
        this.onBeforeShadowMapRenderObservable.clear();
        this.onAfterShadowMapRenderMeshObservable.clear();
        this.onAfterShadowMapRenderObservable.clear();
    };
    /**
     * Serializes the shadow generator setup to a json object.
     * @returns The serialized JSON object
     */
    ShadowGenerator.prototype.serialize = function () {
        var serializationObject = {};
        var shadowMap = this.getShadowMap();
        if (!shadowMap) {
            return serializationObject;
        }
        serializationObject.lightId = this._light.id;
        serializationObject.mapSize = shadowMap.getRenderSize();
        serializationObject.useExponentialShadowMap = this.useExponentialShadowMap;
        serializationObject.useBlurExponentialShadowMap = this.useBlurExponentialShadowMap;
        serializationObject.useCloseExponentialShadowMap = this.useBlurExponentialShadowMap;
        serializationObject.useBlurCloseExponentialShadowMap = this.useBlurExponentialShadowMap;
        serializationObject.usePoissonSampling = this.usePoissonSampling;
        serializationObject.forceBackFacesOnly = this.forceBackFacesOnly;
        serializationObject.depthScale = this.depthScale;
        serializationObject.darkness = this.getDarkness();
        serializationObject.blurBoxOffset = this.blurBoxOffset;
        serializationObject.blurKernel = this.blurKernel;
        serializationObject.blurScale = this.blurScale;
        serializationObject.useKernelBlur = this.useKernelBlur;
        serializationObject.transparencyShadow = this._transparencyShadow;
        serializationObject.frustumEdgeFalloff = this.frustumEdgeFalloff;
        serializationObject.bias = this.bias;
        serializationObject.normalBias = this.normalBias;
        serializationObject.usePercentageCloserFiltering = this.usePercentageCloserFiltering;
        serializationObject.useContactHardeningShadow = this.useContactHardeningShadow;
        serializationObject.filteringQuality = this.filteringQuality;
        serializationObject.contactHardeningLightSizeUVRatio = this.contactHardeningLightSizeUVRatio;
        serializationObject.renderList = [];
        if (shadowMap.renderList) {
            for (var meshIndex = 0; meshIndex < shadowMap.renderList.length; meshIndex++) {
                var mesh = shadowMap.renderList[meshIndex];
                serializationObject.renderList.push(mesh.id);
            }
        }
        return serializationObject;
    };
    /**
     * Parses a serialized ShadowGenerator and returns a new ShadowGenerator.
     * @param parsedShadowGenerator The JSON object to parse
     * @param scene The scene to create the shadow map for
     * @returns The parsed shadow generator
     */
    ShadowGenerator.Parse = function (parsedShadowGenerator, scene) {
        var light = scene.getLightByID(parsedShadowGenerator.lightId);
        var shadowGenerator = new ShadowGenerator(parsedShadowGenerator.mapSize, light);
        var shadowMap = shadowGenerator.getShadowMap();
        for (var meshIndex = 0; meshIndex < parsedShadowGenerator.renderList.length; meshIndex++) {
            var meshes = scene.getMeshesByID(parsedShadowGenerator.renderList[meshIndex]);
            meshes.forEach(function (mesh) {
                if (!shadowMap) {
                    return;
                }
                if (!shadowMap.renderList) {
                    shadowMap.renderList = [];
                }
                shadowMap.renderList.push(mesh);
            });
        }
        if (parsedShadowGenerator.usePoissonSampling) {
            shadowGenerator.usePoissonSampling = true;
        }
        else if (parsedShadowGenerator.useExponentialShadowMap) {
            shadowGenerator.useExponentialShadowMap = true;
        }
        else if (parsedShadowGenerator.useBlurExponentialShadowMap) {
            shadowGenerator.useBlurExponentialShadowMap = true;
        }
        else if (parsedShadowGenerator.useCloseExponentialShadowMap) {
            shadowGenerator.useCloseExponentialShadowMap = true;
        }
        else if (parsedShadowGenerator.useBlurCloseExponentialShadowMap) {
            shadowGenerator.useBlurCloseExponentialShadowMap = true;
        }
        else if (parsedShadowGenerator.usePercentageCloserFiltering) {
            shadowGenerator.usePercentageCloserFiltering = true;
        }
        else if (parsedShadowGenerator.useContactHardeningShadow) {
            shadowGenerator.useContactHardeningShadow = true;
        }
        if (parsedShadowGenerator.filteringQuality) {
            shadowGenerator.filteringQuality = parsedShadowGenerator.filteringQuality;
        }
        if (parsedShadowGenerator.contactHardeningLightSizeUVRatio) {
            shadowGenerator.contactHardeningLightSizeUVRatio = parsedShadowGenerator.contactHardeningLightSizeUVRatio;
        }
        // Backward compat
        else if (parsedShadowGenerator.useVarianceShadowMap) {
            shadowGenerator.useExponentialShadowMap = true;
        }
        else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
            shadowGenerator.useBlurExponentialShadowMap = true;
        }
        if (parsedShadowGenerator.depthScale) {
            shadowGenerator.depthScale = parsedShadowGenerator.depthScale;
        }
        if (parsedShadowGenerator.blurScale) {
            shadowGenerator.blurScale = parsedShadowGenerator.blurScale;
        }
        if (parsedShadowGenerator.blurBoxOffset) {
            shadowGenerator.blurBoxOffset = parsedShadowGenerator.blurBoxOffset;
        }
        if (parsedShadowGenerator.useKernelBlur) {
            shadowGenerator.useKernelBlur = parsedShadowGenerator.useKernelBlur;
        }
        if (parsedShadowGenerator.blurKernel) {
            shadowGenerator.blurKernel = parsedShadowGenerator.blurKernel;
        }
        if (parsedShadowGenerator.bias !== undefined) {
            shadowGenerator.bias = parsedShadowGenerator.bias;
        }
        if (parsedShadowGenerator.normalBias !== undefined) {
            shadowGenerator.normalBias = parsedShadowGenerator.normalBias;
        }
        if (parsedShadowGenerator.frustumEdgeFalloff !== undefined) {
            shadowGenerator.frustumEdgeFalloff = parsedShadowGenerator.frustumEdgeFalloff;
        }
        if (parsedShadowGenerator.darkness) {
            shadowGenerator.setDarkness(parsedShadowGenerator.darkness);
        }
        if (parsedShadowGenerator.transparencyShadow) {
            shadowGenerator.setTransparencyShadow(true);
        }
        shadowGenerator.forceBackFacesOnly = parsedShadowGenerator.forceBackFacesOnly;
        return shadowGenerator;
    };
    /**
     * Shadow generator mode None: no filtering applied.
     */
    ShadowGenerator.FILTER_NONE = 0;
    /**
     * Shadow generator mode ESM: Exponential Shadow Mapping.
     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)
     */
    ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP = 1;
    /**
     * Shadow generator mode Poisson Sampling: Percentage Closer Filtering.
     * (Multiple Tap around evenly distributed around the pixel are used to evaluate the shadow strength)
     */
    ShadowGenerator.FILTER_POISSONSAMPLING = 2;
    /**
     * Shadow generator mode ESM: Blurred Exponential Shadow Mapping.
     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)
     */
    ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP = 3;
    /**
     * Shadow generator mode ESM: Exponential Shadow Mapping using the inverse of the exponential preventing
     * edge artifacts on steep falloff.
     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)
     */
    ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP = 4;
    /**
     * Shadow generator mode ESM: Blurred Exponential Shadow Mapping using the inverse of the exponential preventing
     * edge artifacts on steep falloff.
     * (http://developer.download.nvidia.com/presentations/2008/GDC/GDC08_SoftShadowMapping.pdf)
     */
    ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP = 5;
    /**
     * Shadow generator mode PCF: Percentage Closer Filtering
     * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1
     * (https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html)
     */
    ShadowGenerator.FILTER_PCF = 6;
    /**
     * Shadow generator mode PCSS: Percentage Closering Soft Shadow.
     * benefits from Webgl 2 shadow samplers. Fallback to Poisson Sampling in Webgl 1
     * Contact Hardening
     */
    ShadowGenerator.FILTER_PCSS = 7;
    /**
     * Reserved for PCF and PCSS
     * Highest Quality.
     *
     * Execute PCF on a 5*5 kernel improving a lot the shadow aliasing artifacts.
     *
     * Execute PCSS with 32 taps blocker search and 64 taps PCF.
     */
    ShadowGenerator.QUALITY_HIGH = 0;
    /**
     * Reserved for PCF and PCSS
     * Good tradeoff for quality/perf cross devices
     *
     * Execute PCF on a 3*3 kernel.
     *
     * Execute PCSS with 16 taps blocker search and 32 taps PCF.
     */
    ShadowGenerator.QUALITY_MEDIUM = 1;
    /**
     * Reserved for PCF and PCSS
     * The lowest quality but the fastest.
     *
     * Execute PCF on a 1*1 kernel.
     *
     * Execute PCSS with 16 taps blocker search and 16 taps PCF.
     */
    ShadowGenerator.QUALITY_LOW = 2;
    /** @hidden */
    ShadowGenerator._SceneComponentInitialization = function (_) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_17__["_DevTools"].WarnImport("ShadowGeneratorSceneComponent");
    };
    return ShadowGenerator;
}());



/***/ }),

/***/ "./Lights/Shadows/shadowGeneratorSceneComponent.ts":
/*!*********************************************************!*\
  !*** ./Lights/Shadows/shadowGeneratorSceneComponent.ts ***!
  \*********************************************************/
/*! exports provided: ShadowGeneratorSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowGeneratorSceneComponent", function() { return ShadowGeneratorSceneComponent; });
/* harmony import */ var _shadowGenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./shadowGenerator */ "./Lights/Shadows/shadowGenerator.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../abstractScene */ "./abstractScene.ts");



// Adds the parser to the scene parsers.
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].AddParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_SHADOWGENERATOR, function (parsedData, scene) {
    // Shadows
    if (parsedData.shadowGenerators !== undefined && parsedData.shadowGenerators !== null) {
        for (var index = 0, cache = parsedData.shadowGenerators.length; index < cache; index++) {
            var parsedShadowGenerator = parsedData.shadowGenerators[index];
            _shadowGenerator__WEBPACK_IMPORTED_MODULE_0__["ShadowGenerator"].Parse(parsedShadowGenerator, scene);
            // SG would be available on their associated lights
        }
    }
});
/**
 * Defines the shadow generator component responsible to manage any shadow generators
 * in a given scene.
 */
var ShadowGeneratorSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function ShadowGeneratorSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_SHADOWGENERATOR;
        this.scene = scene;
    }
    /**
     * Registers the component in a given scene
     */
    ShadowGeneratorSceneComponent.prototype.register = function () {
        this.scene._gatherRenderTargetsStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_GATHERRENDERTARGETS_SHADOWGENERATOR, this, this._gatherRenderTargets);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    ShadowGeneratorSceneComponent.prototype.rebuild = function () {
        // Nothing To Do Here.
    };
    /**
     * Serializes the component data to the specified json object
     * @param serializationObject The object to serialize to
     */
    ShadowGeneratorSceneComponent.prototype.serialize = function (serializationObject) {
        // Shadows
        serializationObject.shadowGenerators = [];
        var lights = this.scene.lights;
        for (var _i = 0, lights_1 = lights; _i < lights_1.length; _i++) {
            var light = lights_1[_i];
            var shadowGenerator = light.getShadowGenerator();
            if (shadowGenerator) {
                serializationObject.shadowGenerators.push(shadowGenerator.serialize());
            }
        }
    };
    /**
     * Adds all the elements from the container to the scene
     * @param container the container holding the elements
     */
    ShadowGeneratorSceneComponent.prototype.addFromContainer = function (container) {
        // Nothing To Do Here. (directly attached to a light)
    };
    /**
     * Removes all the elements in the container from the scene
     * @param container contains the elements to remove
     * @param dispose if the removed element should be disposed (default: false)
     */
    ShadowGeneratorSceneComponent.prototype.removeFromContainer = function (container, dispose) {
        // Nothing To Do Here. (directly attached to a light)
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    ShadowGeneratorSceneComponent.prototype.dispose = function () {
        // Nothing To Do Here.
    };
    ShadowGeneratorSceneComponent.prototype._gatherRenderTargets = function (renderTargets) {
        // Shadows
        var scene = this.scene;
        if (this.scene.shadowsEnabled) {
            for (var lightIndex = 0; lightIndex < scene.lights.length; lightIndex++) {
                var light = scene.lights[lightIndex];
                var shadowGenerator = light.getShadowGenerator();
                if (light.isEnabled() && light.shadowEnabled && shadowGenerator) {
                    var shadowMap = (shadowGenerator.getShadowMap());
                    if (scene.textures.indexOf(shadowMap) !== -1) {
                        renderTargets.push(shadowMap);
                    }
                }
            }
        }
    };
    return ShadowGeneratorSceneComponent;
}());

_shadowGenerator__WEBPACK_IMPORTED_MODULE_0__["ShadowGenerator"]._SceneComponentInitialization = function (scene) {
    var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_SHADOWGENERATOR);
    if (!component) {
        component = new ShadowGeneratorSceneComponent(scene);
        scene._addComponent(component);
    }
};


/***/ }),

/***/ "./Lights/directionalLight.ts":
/*!************************************!*\
  !*** ./Lights/directionalLight.ts ***!
  \************************************/
/*! exports provided: DirectionalLight */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DirectionalLight", function() { return DirectionalLight; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _light__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./light */ "./Lights/light.ts");
/* harmony import */ var _shadowLight__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./shadowLight */ "./Lights/shadowLight.ts");






_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("Light_Type_1", function (name, scene) {
    return function () { return new DirectionalLight(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
/**
 * A directional light is defined by a direction (what a surprise!).
 * The light is emitted from everywhere in the specified direction, and has an infinite range.
 * An example of a directional light is when a distance planet is lit by the apparently parallel lines of light from its sun. Light in a downward direction will light the top of an object.
 * Documentation: https://doc.babylonjs.com/babylon101/lights
 */
var DirectionalLight = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DirectionalLight, _super);
    /**
     * Creates a DirectionalLight object in the scene, oriented towards the passed direction (Vector3).
     * The directional light is emitted from everywhere in the given direction.
     * It can cast shadows.
     * Documentation : https://doc.babylonjs.com/babylon101/lights
     * @param name The friendly name of the light
     * @param direction The direction of the light
     * @param scene The scene the light belongs to
     */
    function DirectionalLight(name, direction, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._shadowFrustumSize = 0;
        _this._shadowOrthoScale = 0.1;
        /**
         * Automatically compute the projection matrix to best fit (including all the casters)
         * on each frame.
         */
        _this.autoUpdateExtends = true;
        // Cache
        _this._orthoLeft = Number.MAX_VALUE;
        _this._orthoRight = Number.MIN_VALUE;
        _this._orthoTop = Number.MIN_VALUE;
        _this._orthoBottom = Number.MAX_VALUE;
        _this.position = direction.scale(-1.0);
        _this.direction = direction;
        return _this;
    }
    Object.defineProperty(DirectionalLight.prototype, "shadowFrustumSize", {
        /**
         * Fix frustum size for the shadow generation. This is disabled if the value is 0.
         */
        get: function () {
            return this._shadowFrustumSize;
        },
        /**
         * Specifies a fix frustum size for the shadow generation.
         */
        set: function (value) {
            this._shadowFrustumSize = value;
            this.forceProjectionMatrixCompute();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DirectionalLight.prototype, "shadowOrthoScale", {
        /**
         * Gets the shadow projection scale against the optimal computed one.
         * 0.1 by default which means that the projection window is increase by 10% from the optimal size.
         * This does not impact in fixed frustum size (shadowFrustumSize being set)
         */
        get: function () {
            return this._shadowOrthoScale;
        },
        /**
         * Sets the shadow projection scale against the optimal computed one.
         * 0.1 by default which means that the projection window is increase by 10% from the optimal size.
         * This does not impact in fixed frustum size (shadowFrustumSize being set)
         */
        set: function (value) {
            this._shadowOrthoScale = value;
            this.forceProjectionMatrixCompute();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the string "DirectionalLight".
     * @return The class name
     */
    DirectionalLight.prototype.getClassName = function () {
        return "DirectionalLight";
    };
    /**
     * Returns the integer 1.
     * @return The light Type id as a constant defines in Light.LIGHTTYPEID_x
     */
    DirectionalLight.prototype.getTypeID = function () {
        return _light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTTYPEID_DIRECTIONALLIGHT;
    };
    /**
     * Sets the passed matrix "matrix" as projection matrix for the shadows cast by the light according to the passed view matrix.
     * Returns the DirectionalLight Shadow projection matrix.
     */
    DirectionalLight.prototype._setDefaultShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
        if (this.shadowFrustumSize > 0) {
            this._setDefaultFixedFrustumShadowProjectionMatrix(matrix);
        }
        else {
            this._setDefaultAutoExtendShadowProjectionMatrix(matrix, viewMatrix, renderList);
        }
    };
    /**
     * Sets the passed matrix "matrix" as fixed frustum projection matrix for the shadows cast by the light according to the passed view matrix.
     * Returns the DirectionalLight Shadow projection matrix.
     */
    DirectionalLight.prototype._setDefaultFixedFrustumShadowProjectionMatrix = function (matrix) {
        var activeCamera = this.getScene().activeCamera;
        if (!activeCamera) {
            return;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].OrthoLHToRef(this.shadowFrustumSize, this.shadowFrustumSize, this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera.minZ, this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera.maxZ, matrix);
    };
    /**
     * Sets the passed matrix "matrix" as auto extend projection matrix for the shadows cast by the light according to the passed view matrix.
     * Returns the DirectionalLight Shadow projection matrix.
     */
    DirectionalLight.prototype._setDefaultAutoExtendShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
        var activeCamera = this.getScene().activeCamera;
        if (!activeCamera) {
            return;
        }
        // Check extends
        if (this.autoUpdateExtends || this._orthoLeft === Number.MAX_VALUE) {
            var tempVector3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
            this._orthoLeft = Number.MAX_VALUE;
            this._orthoRight = Number.MIN_VALUE;
            this._orthoTop = Number.MIN_VALUE;
            this._orthoBottom = Number.MAX_VALUE;
            for (var meshIndex = 0; meshIndex < renderList.length; meshIndex++) {
                var mesh = renderList[meshIndex];
                if (!mesh) {
                    continue;
                }
                var boundingInfo = mesh.getBoundingInfo();
                var boundingBox = boundingInfo.boundingBox;
                for (var index = 0; index < boundingBox.vectorsWorld.length; index++) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(boundingBox.vectorsWorld[index], viewMatrix, tempVector3);
                    if (tempVector3.x < this._orthoLeft) {
                        this._orthoLeft = tempVector3.x;
                    }
                    if (tempVector3.y < this._orthoBottom) {
                        this._orthoBottom = tempVector3.y;
                    }
                    if (tempVector3.x > this._orthoRight) {
                        this._orthoRight = tempVector3.x;
                    }
                    if (tempVector3.y > this._orthoTop) {
                        this._orthoTop = tempVector3.y;
                    }
                }
            }
        }
        var xOffset = this._orthoRight - this._orthoLeft;
        var yOffset = this._orthoTop - this._orthoBottom;
        if (this.getScene().useRightHandedSystem) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].OrthoOffCenterRHToRef(this._orthoLeft - xOffset * this.shadowOrthoScale, this._orthoRight + xOffset * this.shadowOrthoScale, this._orthoBottom - yOffset * this.shadowOrthoScale, this._orthoTop + yOffset * this.shadowOrthoScale, this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera.minZ, this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera.maxZ, matrix);
        }
        else {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].OrthoOffCenterLHToRef(this._orthoLeft - xOffset * this.shadowOrthoScale, this._orthoRight + xOffset * this.shadowOrthoScale, this._orthoBottom - yOffset * this.shadowOrthoScale, this._orthoTop + yOffset * this.shadowOrthoScale, this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera.minZ, this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera.maxZ, matrix);
        }
    };
    DirectionalLight.prototype._buildUniformLayout = function () {
        this._uniformBuffer.addUniform("vLightData", 4);
        this._uniformBuffer.addUniform("vLightDiffuse", 4);
        this._uniformBuffer.addUniform("vLightSpecular", 3);
        this._uniformBuffer.addUniform("shadowsInfo", 3);
        this._uniformBuffer.addUniform("depthValues", 2);
        this._uniformBuffer.create();
    };
    /**
     * Sets the passed Effect object with the DirectionalLight transformed position (or position if not parented) and the passed name.
     * @param effect The effect to update
     * @param lightIndex The index of the light in the effect to update
     * @returns The directional light
     */
    DirectionalLight.prototype.transferToEffect = function (effect, lightIndex) {
        if (this.computeTransformedInformation()) {
            if (this.getScene().useRightHandedSystem) {
                this._uniformBuffer.updateFloat4("vLightData", -this.transformedDirection.x, -this.transformedDirection.y, -this.transformedDirection.z, 1, lightIndex);
            }
            else {
                this._uniformBuffer.updateFloat4("vLightData", this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z, 1, lightIndex);
            }
            return this;
        }
        if (this.getScene().useRightHandedSystem) {
            this._uniformBuffer.updateFloat4("vLightData", -this.direction.x, -this.direction.y, -this.direction.z, 1, lightIndex);
        }
        else {
            this._uniformBuffer.updateFloat4("vLightData", this.direction.x, this.direction.y, this.direction.z, 1, lightIndex);
        }
        return this;
    };
    DirectionalLight.prototype.transferToNodeMaterialEffect = function (effect, lightDataUniformName) {
        if (this.computeTransformedInformation()) {
            if (this.getScene().useRightHandedSystem) {
                effect.setFloat3(lightDataUniformName, -this.transformedDirection.x, -this.transformedDirection.y, -this.transformedDirection.z);
            }
            else {
                effect.setFloat3(lightDataUniformName, this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z);
            }
            return this;
        }
        if (this.getScene().useRightHandedSystem) {
            effect.setFloat3(lightDataUniformName, -this.direction.x, -this.direction.y, -this.direction.z);
        }
        else {
            effect.setFloat3(lightDataUniformName, this.direction.x, this.direction.y, this.direction.z);
        }
        return this;
    };
    /**
     * Gets the minZ used for shadow according to both the scene and the light.
     *
     * Values are fixed on directional lights as it relies on an ortho projection hence the need to convert being
     * -1 and 1 to 0 and 1 doing (depth + min) / (min + max) -> (depth + 1) / (1 + 1) -> (depth * 0.5) + 0.5.
     * @param activeCamera The camera we are returning the min for
     * @returns the depth min z
     */
    DirectionalLight.prototype.getDepthMinZ = function (activeCamera) {
        return 1;
    };
    /**
     * Gets the maxZ used for shadow according to both the scene and the light.
     *
     * Values are fixed on directional lights as it relies on an ortho projection hence the need to convert being
     * -1 and 1 to 0 and 1 doing (depth + min) / (min + max) -> (depth + 1) / (1 + 1) -> (depth * 0.5) + 0.5.
     * @param activeCamera The camera we are returning the max for
     * @returns the depth max z
     */
    DirectionalLight.prototype.getDepthMaxZ = function (activeCamera) {
        return 1;
    };
    /**
     * Prepares the list of defines specific to the light type.
     * @param defines the list of defines
     * @param lightIndex defines the index of the light for the effect
     */
    DirectionalLight.prototype.prepareLightSpecificDefines = function (defines, lightIndex) {
        defines["DIRLIGHT" + lightIndex] = true;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DirectionalLight.prototype, "shadowFrustumSize", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DirectionalLight.prototype, "shadowOrthoScale", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DirectionalLight.prototype, "autoUpdateExtends", void 0);
    return DirectionalLight;
}(_shadowLight__WEBPACK_IMPORTED_MODULE_5__["ShadowLight"]));



/***/ }),

/***/ "./Lights/hemisphericLight.ts":
/*!************************************!*\
  !*** ./Lights/hemisphericLight.ts ***!
  \************************************/
/*! exports provided: HemisphericLight */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HemisphericLight", function() { return HemisphericLight; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _light__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./light */ "./Lights/light.ts");






_node__WEBPACK_IMPORTED_MODULE_4__["Node"].AddNodeConstructor("Light_Type_3", function (name, scene) {
    return function () { return new HemisphericLight(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
/**
 * The HemisphericLight simulates the ambient environment light,
 * so the passed direction is the light reflection direction, not the incoming direction.
 */
var HemisphericLight = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HemisphericLight, _super);
    /**
     * Creates a HemisphericLight object in the scene according to the passed direction (Vector3).
     * The HemisphericLight simulates the ambient environment light, so the passed direction is the light reflection direction, not the incoming direction.
     * The HemisphericLight can't cast shadows.
     * Documentation : https://doc.babylonjs.com/babylon101/lights
     * @param name The friendly name of the light
     * @param direction The direction of the light reflection
     * @param scene The scene the light belongs to
     */
    function HemisphericLight(name, direction, scene) {
        var _this = _super.call(this, name, scene) || this;
        /**
         * The groundColor is the light in the opposite direction to the one specified during creation.
         * You can think of the diffuse and specular light as coming from the centre of the object in the given direction and the groundColor light in the opposite direction.
         */
        _this.groundColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0.0, 0.0, 0.0);
        _this.direction = direction || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Up();
        return _this;
    }
    HemisphericLight.prototype._buildUniformLayout = function () {
        this._uniformBuffer.addUniform("vLightData", 4);
        this._uniformBuffer.addUniform("vLightDiffuse", 4);
        this._uniformBuffer.addUniform("vLightSpecular", 3);
        this._uniformBuffer.addUniform("vLightGround", 3);
        this._uniformBuffer.addUniform("shadowsInfo", 3);
        this._uniformBuffer.addUniform("depthValues", 2);
        this._uniformBuffer.create();
    };
    /**
     * Returns the string "HemisphericLight".
     * @return The class name
     */
    HemisphericLight.prototype.getClassName = function () {
        return "HemisphericLight";
    };
    /**
     * Sets the HemisphericLight direction towards the passed target (Vector3).
     * Returns the updated direction.
     * @param target The target the direction should point to
     * @return The computed direction
     */
    HemisphericLight.prototype.setDirectionToTarget = function (target) {
        this.direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(target.subtract(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero()));
        return this.direction;
    };
    /**
     * Returns the shadow generator associated to the light.
     * @returns Always null for hemispheric lights because it does not support shadows.
     */
    HemisphericLight.prototype.getShadowGenerator = function () {
        return null;
    };
    /**
     * Sets the passed Effect object with the HemisphericLight normalized direction and color and the passed name (string).
     * @param effect The effect to update
     * @param lightIndex The index of the light in the effect to update
     * @returns The hemispheric light
     */
    HemisphericLight.prototype.transferToEffect = function (effect, lightIndex) {
        var normalizeDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(this.direction);
        this._uniformBuffer.updateFloat4("vLightData", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, 0.0, lightIndex);
        this._uniformBuffer.updateColor3("vLightGround", this.groundColor.scale(this.intensity), lightIndex);
        return this;
    };
    HemisphericLight.prototype.transferToNodeMaterialEffect = function (effect, lightDataUniformName) {
        var normalizeDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(this.direction);
        effect.setFloat3(lightDataUniformName, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z);
        return this;
    };
    /**
     * Computes the world matrix of the node
     * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
     * @param useWasUpdatedFlag defines a reserved property
     * @returns the world matrix
     */
    HemisphericLight.prototype.computeWorldMatrix = function () {
        if (!this._worldMatrix) {
            this._worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Identity();
        }
        return this._worldMatrix;
    };
    /**
     * Returns the integer 3.
     * @return The light Type id as a constant defines in Light.LIGHTTYPEID_x
     */
    HemisphericLight.prototype.getTypeID = function () {
        return _light__WEBPACK_IMPORTED_MODULE_5__["Light"].LIGHTTYPEID_HEMISPHERICLIGHT;
    };
    /**
     * Prepares the list of defines specific to the light type.
     * @param defines the list of defines
     * @param lightIndex defines the index of the light for the effect
     */
    HemisphericLight.prototype.prepareLightSpecificDefines = function (defines, lightIndex) {
        defines["HEMILIGHT" + lightIndex] = true;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], HemisphericLight.prototype, "groundColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], HemisphericLight.prototype, "direction", void 0);
    return HemisphericLight;
}(_light__WEBPACK_IMPORTED_MODULE_5__["Light"]));



/***/ }),

/***/ "./Lights/index.ts":
/*!*************************!*\
  !*** ./Lights/index.ts ***!
  \*************************/
/*! exports provided: Light, ShadowLight, DirectionalLight, HemisphericLight, PointLight, SpotLight, ShadowGenerator, ShadowGeneratorSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _light__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./light */ "./Lights/light.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Light", function() { return _light__WEBPACK_IMPORTED_MODULE_0__["Light"]; });

/* harmony import */ var _shadowLight__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./shadowLight */ "./Lights/shadowLight.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowLight", function() { return _shadowLight__WEBPACK_IMPORTED_MODULE_1__["ShadowLight"]; });

/* harmony import */ var _Shadows_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Shadows/index */ "./Lights/Shadows/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGenerator", function() { return _Shadows_index__WEBPACK_IMPORTED_MODULE_2__["ShadowGenerator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGeneratorSceneComponent", function() { return _Shadows_index__WEBPACK_IMPORTED_MODULE_2__["ShadowGeneratorSceneComponent"]; });

/* harmony import */ var _directionalLight__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./directionalLight */ "./Lights/directionalLight.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DirectionalLight", function() { return _directionalLight__WEBPACK_IMPORTED_MODULE_3__["DirectionalLight"]; });

/* harmony import */ var _hemisphericLight__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./hemisphericLight */ "./Lights/hemisphericLight.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericLight", function() { return _hemisphericLight__WEBPACK_IMPORTED_MODULE_4__["HemisphericLight"]; });

/* harmony import */ var _pointLight__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./pointLight */ "./Lights/pointLight.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointLight", function() { return _pointLight__WEBPACK_IMPORTED_MODULE_5__["PointLight"]; });

/* harmony import */ var _spotLight__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./spotLight */ "./Lights/spotLight.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpotLight", function() { return _spotLight__WEBPACK_IMPORTED_MODULE_6__["SpotLight"]; });










/***/ }),

/***/ "./Lights/light.ts":
/*!*************************!*\
  !*** ./Lights/light.ts ***!
  \*************************/
/*! exports provided: Light */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Light", function() { return Light; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/uniformBuffer */ "./Materials/uniformBuffer.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");







/**
 * Base class of all the lights in Babylon. It groups all the generic information about lights.
 * Lights are used, as you would expect, to affect how meshes are seen, in terms of both illumination and colour.
 * All meshes allow light to pass through them unless shadow generation is activated. The default number of lights allowed is four but this can be increased.
 */
var Light = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Light, _super);
    /**
     * Creates a Light object in the scene.
     * Documentation : https://doc.babylonjs.com/babylon101/lights
     * @param name The firendly name of the light
     * @param scene The scene the light belongs too
     */
    function Light(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        /**
         * Diffuse gives the basic color to an object.
         */
        _this.diffuse = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](1.0, 1.0, 1.0);
        /**
         * Specular produces a highlight color on an object.
         * Note: This is note affecting PBR materials.
         */
        _this.specular = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](1.0, 1.0, 1.0);
        /**
         * Defines the falloff type for this light. This lets overrriding how punctual light are
         * falling off base on range or angle.
         * This can be set to any values in Light.FALLOFF_x.
         *
         * Note: This is only useful for PBR Materials at the moment. This could be extended if required to
         * other types of materials.
         */
        _this.falloffType = Light.FALLOFF_DEFAULT;
        /**
         * Strength of the light.
         * Note: By default it is define in the framework own unit.
         * Note: In PBR materials the intensityMode can be use to chose what unit the intensity is defined in.
         */
        _this.intensity = 1.0;
        _this._range = Number.MAX_VALUE;
        _this._inverseSquaredRange = 0;
        /**
         * Cached photometric scale default to 1.0 as the automatic intensity mode defaults to 1.0 for every type
         * of light.
         */
        _this._photometricScale = 1.0;
        _this._intensityMode = Light.INTENSITYMODE_AUTOMATIC;
        _this._radius = 0.00001;
        /**
         * Defines the rendering priority of the lights. It can help in case of fallback or number of lights
         * exceeding the number allowed of the materials.
         */
        _this.renderPriority = 0;
        _this._shadowEnabled = true;
        _this._excludeWithLayerMask = 0;
        _this._includeOnlyWithLayerMask = 0;
        _this._lightmapMode = 0;
        /**
         * @hidden Internal use only.
         */
        _this._excludedMeshesIds = new Array();
        /**
         * @hidden Internal use only.
         */
        _this._includedOnlyMeshesIds = new Array();
        /** @hidden */
        _this._isLight = true;
        _this.getScene().addLight(_this);
        _this._uniformBuffer = new _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_5__["UniformBuffer"](_this.getScene().getEngine());
        _this._buildUniformLayout();
        _this.includedOnlyMeshes = new Array();
        _this.excludedMeshes = new Array();
        _this._resyncMeshes();
        return _this;
    }
    Object.defineProperty(Light.prototype, "range", {
        /**
         * Defines how far from the source the light is impacting in scene units.
         * Note: Unused in PBR material as the distance light falloff is defined following the inverse squared falloff.
         */
        get: function () {
            return this._range;
        },
        /**
         * Defines how far from the source the light is impacting in scene units.
         * Note: Unused in PBR material as the distance light falloff is defined following the inverse squared falloff.
         */
        set: function (value) {
            this._range = value;
            this._inverseSquaredRange = 1.0 / (this.range * this.range);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "intensityMode", {
        /**
         * Gets the photometric scale used to interpret the intensity.
         * This is only relevant with PBR Materials where the light intensity can be defined in a physical way.
         */
        get: function () {
            return this._intensityMode;
        },
        /**
         * Sets the photometric scale used to interpret the intensity.
         * This is only relevant with PBR Materials where the light intensity can be defined in a physical way.
         */
        set: function (value) {
            this._intensityMode = value;
            this._computePhotometricScale();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "radius", {
        /**
         * Gets the light radius used by PBR Materials to simulate soft area lights.
         */
        get: function () {
            return this._radius;
        },
        /**
         * sets the light radius used by PBR Materials to simulate soft area lights.
         */
        set: function (value) {
            this._radius = value;
            this._computePhotometricScale();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "shadowEnabled", {
        /**
         * Gets wether or not the shadows are enabled for this light. This can help turning off/on shadow without detaching
         * the current shadow generator.
         */
        get: function () {
            return this._shadowEnabled;
        },
        /**
         * Sets wether or not the shadows are enabled for this light. This can help turning off/on shadow without detaching
         * the current shadow generator.
         */
        set: function (value) {
            if (this._shadowEnabled === value) {
                return;
            }
            this._shadowEnabled = value;
            this._markMeshesAsLightDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "includedOnlyMeshes", {
        /**
         * Gets the only meshes impacted by this light.
         */
        get: function () {
            return this._includedOnlyMeshes;
        },
        /**
         * Sets the only meshes impacted by this light.
         */
        set: function (value) {
            this._includedOnlyMeshes = value;
            this._hookArrayForIncludedOnly(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "excludedMeshes", {
        /**
         * Gets the meshes not impacted by this light.
         */
        get: function () {
            return this._excludedMeshes;
        },
        /**
         * Sets the meshes not impacted by this light.
         */
        set: function (value) {
            this._excludedMeshes = value;
            this._hookArrayForExcluded(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "excludeWithLayerMask", {
        /**
         * Gets the layer id use to find what meshes are not impacted by the light.
         * Inactive if 0
         */
        get: function () {
            return this._excludeWithLayerMask;
        },
        /**
         * Sets the layer id use to find what meshes are not impacted by the light.
         * Inactive if 0
         */
        set: function (value) {
            this._excludeWithLayerMask = value;
            this._resyncMeshes();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "includeOnlyWithLayerMask", {
        /**
         * Gets the layer id use to find what meshes are impacted by the light.
         * Inactive if 0
         */
        get: function () {
            return this._includeOnlyWithLayerMask;
        },
        /**
         * Sets the layer id use to find what meshes are impacted by the light.
         * Inactive if 0
         */
        set: function (value) {
            this._includeOnlyWithLayerMask = value;
            this._resyncMeshes();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Light.prototype, "lightmapMode", {
        /**
         * Gets the lightmap mode of this light (should be one of the constants defined by Light.LIGHTMAP_x)
         */
        get: function () {
            return this._lightmapMode;
        },
        /**
         * Sets the lightmap mode of this light (should be one of the constants defined by Light.LIGHTMAP_x)
         */
        set: function (value) {
            if (this._lightmapMode === value) {
                return;
            }
            this._lightmapMode = value;
            this._markMeshesAsLightDirty();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the string "Light".
     * @returns the class name
     */
    Light.prototype.getClassName = function () {
        return "Light";
    };
    /**
     * Converts the light information to a readable string for debug purpose.
     * @param fullDetails Supports for multiple levels of logging within scene loading
     * @returns the human readable light info
     */
    Light.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name;
        ret += ", type: " + (["Point", "Directional", "Spot", "Hemispheric"])[this.getTypeID()];
        if (this.animations) {
            for (var i = 0; i < this.animations.length; i++) {
                ret += ", animation[0]: " + this.animations[i].toString(fullDetails);
            }
        }
        if (fullDetails) {
        }
        return ret;
    };
    /** @hidden */
    Light.prototype._syncParentEnabledState = function () {
        _super.prototype._syncParentEnabledState.call(this);
        this._resyncMeshes();
    };
    /**
     * Set the enabled state of this node.
     * @param value - the new enabled state
     */
    Light.prototype.setEnabled = function (value) {
        _super.prototype.setEnabled.call(this, value);
        this._resyncMeshes();
    };
    /**
     * Returns the Light associated shadow generator if any.
     * @return the associated shadow generator.
     */
    Light.prototype.getShadowGenerator = function () {
        return this._shadowGenerator;
    };
    /**
     * Returns a Vector3, the absolute light position in the World.
     * @returns the world space position of the light
     */
    Light.prototype.getAbsolutePosition = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
    };
    /**
     * Specifies if the light will affect the passed mesh.
     * @param mesh The mesh to test against the light
     * @return true the mesh is affected otherwise, false.
     */
    Light.prototype.canAffectMesh = function (mesh) {
        if (!mesh) {
            return true;
        }
        if (this.includedOnlyMeshes && this.includedOnlyMeshes.length > 0 && this.includedOnlyMeshes.indexOf(mesh) === -1) {
            return false;
        }
        if (this.excludedMeshes && this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1) {
            return false;
        }
        if (this.includeOnlyWithLayerMask !== 0 && (this.includeOnlyWithLayerMask & mesh.layerMask) === 0) {
            return false;
        }
        if (this.excludeWithLayerMask !== 0 && this.excludeWithLayerMask & mesh.layerMask) {
            return false;
        }
        return true;
    };
    /**
     * Sort function to order lights for rendering.
     * @param a First Light object to compare to second.
     * @param b Second Light object to compare first.
     * @return -1 to reduce's a's index relative to be, 0 for no change, 1 to increase a's index relative to b.
     */
    Light.CompareLightsPriority = function (a, b) {
        //shadow-casting lights have priority over non-shadow-casting lights
        //the renderPrioirty is a secondary sort criterion
        if (a.shadowEnabled !== b.shadowEnabled) {
            return (b.shadowEnabled ? 1 : 0) - (a.shadowEnabled ? 1 : 0);
        }
        return b.renderPriority - a.renderPriority;
    };
    /**
     * Releases resources associated with this node.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    Light.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        if (this._shadowGenerator) {
            this._shadowGenerator.dispose();
            this._shadowGenerator = null;
        }
        // Animations
        this.getScene().stopAnimation(this);
        // Remove from meshes
        for (var _i = 0, _a = this.getScene().meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            mesh._removeLightSource(this, true);
        }
        this._uniformBuffer.dispose();
        // Remove from scene
        this.getScene().removeLight(this);
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    /**
     * Returns the light type ID (integer).
     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x
     */
    Light.prototype.getTypeID = function () {
        return 0;
    };
    /**
     * Returns the intensity scaled by the Photometric Scale according to the light type and intensity mode.
     * @returns the scaled intensity in intensity mode unit
     */
    Light.prototype.getScaledIntensity = function () {
        return this._photometricScale * this.intensity;
    };
    /**
     * Returns a new Light object, named "name", from the current one.
     * @param name The name of the cloned light
     * @returns the new created light
     */
    Light.prototype.clone = function (name) {
        var constructor = Light.GetConstructorFromName(this.getTypeID(), name, this.getScene());
        if (!constructor) {
            return null;
        }
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(constructor, this);
    };
    /**
     * Serializes the current light into a Serialization object.
     * @returns the serialized object.
     */
    Light.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        // Type
        serializationObject.type = this.getTypeID();
        // Parent
        if (this.parent) {
            serializationObject.parentId = this.parent.id;
        }
        // Inclusion / exclusions
        if (this.excludedMeshes.length > 0) {
            serializationObject.excludedMeshesIds = [];
            this.excludedMeshes.forEach(function (mesh) {
                serializationObject.excludedMeshesIds.push(mesh.id);
            });
        }
        if (this.includedOnlyMeshes.length > 0) {
            serializationObject.includedOnlyMeshesIds = [];
            this.includedOnlyMeshes.forEach(function (mesh) {
                serializationObject.includedOnlyMeshesIds.push(mesh.id);
            });
        }
        // Animations
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].AppendSerializedAnimations(this, serializationObject);
        serializationObject.ranges = this.serializeAnimationRanges();
        return serializationObject;
    };
    /**
     * Creates a new typed light from the passed type (integer) : point light = 0, directional light = 1, spot light = 2, hemispheric light = 3.
     * This new light is named "name" and added to the passed scene.
     * @param type Type according to the types available in Light.LIGHTTYPEID_x
     * @param name The friendly name of the light
     * @param scene The scene the new light will belong to
     * @returns the constructor function
     */
    Light.GetConstructorFromName = function (type, name, scene) {
        var constructorFunc = _node__WEBPACK_IMPORTED_MODULE_4__["Node"].Construct("Light_Type_" + type, name, scene);
        if (constructorFunc) {
            return constructorFunc;
        }
        // Default to no light for none present once.
        return null;
    };
    /**
     * Parses the passed "parsedLight" and returns a new instanced Light from this parsing.
     * @param parsedLight The JSON representation of the light
     * @param scene The scene to create the parsed light in
     * @returns the created light after parsing
     */
    Light.Parse = function (parsedLight, scene) {
        var constructor = Light.GetConstructorFromName(parsedLight.type, parsedLight.name, scene);
        if (!constructor) {
            return null;
        }
        var light = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(constructor, parsedLight, scene);
        // Inclusion / exclusions
        if (parsedLight.excludedMeshesIds) {
            light._excludedMeshesIds = parsedLight.excludedMeshesIds;
        }
        if (parsedLight.includedOnlyMeshesIds) {
            light._includedOnlyMeshesIds = parsedLight.includedOnlyMeshesIds;
        }
        // Parent
        if (parsedLight.parentId) {
            light._waitingParentId = parsedLight.parentId;
        }
        // Falloff
        if (parsedLight.falloffType !== undefined) {
            light.falloffType = parsedLight.falloffType;
        }
        // Lightmaps
        if (parsedLight.lightmapMode !== undefined) {
            light.lightmapMode = parsedLight.lightmapMode;
        }
        // Animations
        if (parsedLight.animations) {
            for (var animationIndex = 0; animationIndex < parsedLight.animations.length; animationIndex++) {
                var parsedAnimation = parsedLight.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_6__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    light.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
            _node__WEBPACK_IMPORTED_MODULE_4__["Node"].ParseAnimationRanges(light, parsedLight, scene);
        }
        if (parsedLight.autoAnimate) {
            scene.beginAnimation(light, parsedLight.autoAnimateFrom, parsedLight.autoAnimateTo, parsedLight.autoAnimateLoop, parsedLight.autoAnimateSpeed || 1.0);
        }
        return light;
    };
    Light.prototype._hookArrayForExcluded = function (array) {
        var _this = this;
        var oldPush = array.push;
        array.push = function () {
            var items = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                items[_i] = arguments[_i];
            }
            var result = oldPush.apply(array, items);
            for (var _a = 0, items_1 = items; _a < items_1.length; _a++) {
                var item = items_1[_a];
                item._resyncLighSource(_this);
            }
            return result;
        };
        var oldSplice = array.splice;
        array.splice = function (index, deleteCount) {
            var deleted = oldSplice.apply(array, [index, deleteCount]);
            for (var _i = 0, deleted_1 = deleted; _i < deleted_1.length; _i++) {
                var item = deleted_1[_i];
                item._resyncLighSource(_this);
            }
            return deleted;
        };
        for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
            var item = array_1[_i];
            item._resyncLighSource(this);
        }
    };
    Light.prototype._hookArrayForIncludedOnly = function (array) {
        var _this = this;
        var oldPush = array.push;
        array.push = function () {
            var items = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                items[_i] = arguments[_i];
            }
            var result = oldPush.apply(array, items);
            _this._resyncMeshes();
            return result;
        };
        var oldSplice = array.splice;
        array.splice = function (index, deleteCount) {
            var deleted = oldSplice.apply(array, [index, deleteCount]);
            _this._resyncMeshes();
            return deleted;
        };
        this._resyncMeshes();
    };
    Light.prototype._resyncMeshes = function () {
        for (var _i = 0, _a = this.getScene().meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            mesh._resyncLighSource(this);
        }
    };
    /**
     * Forces the meshes to update their light related information in their rendering used effects
     * @hidden Internal Use Only
     */
    Light.prototype._markMeshesAsLightDirty = function () {
        for (var _i = 0, _a = this.getScene().meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            if (mesh.lightSources.indexOf(this) !== -1) {
                mesh._markSubMeshesAsLightDirty();
            }
        }
    };
    /**
     * Recomputes the cached photometric scale if needed.
     */
    Light.prototype._computePhotometricScale = function () {
        this._photometricScale = this._getPhotometricScale();
        this.getScene().resetCachedMaterial();
    };
    /**
     * Returns the Photometric Scale according to the light type and intensity mode.
     */
    Light.prototype._getPhotometricScale = function () {
        var photometricScale = 0.0;
        var lightTypeID = this.getTypeID();
        //get photometric mode
        var photometricMode = this.intensityMode;
        if (photometricMode === Light.INTENSITYMODE_AUTOMATIC) {
            if (lightTypeID === Light.LIGHTTYPEID_DIRECTIONALLIGHT) {
                photometricMode = Light.INTENSITYMODE_ILLUMINANCE;
            }
            else {
                photometricMode = Light.INTENSITYMODE_LUMINOUSINTENSITY;
            }
        }
        //compute photometric scale
        switch (lightTypeID) {
            case Light.LIGHTTYPEID_POINTLIGHT:
            case Light.LIGHTTYPEID_SPOTLIGHT:
                switch (photometricMode) {
                    case Light.INTENSITYMODE_LUMINOUSPOWER:
                        photometricScale = 1.0 / (4.0 * Math.PI);
                        break;
                    case Light.INTENSITYMODE_LUMINOUSINTENSITY:
                        photometricScale = 1.0;
                        break;
                    case Light.INTENSITYMODE_LUMINANCE:
                        photometricScale = this.radius * this.radius;
                        break;
                }
                break;
            case Light.LIGHTTYPEID_DIRECTIONALLIGHT:
                switch (photometricMode) {
                    case Light.INTENSITYMODE_ILLUMINANCE:
                        photometricScale = 1.0;
                        break;
                    case Light.INTENSITYMODE_LUMINANCE:
                        // When radius (and therefore solid angle) is non-zero a directional lights brightness can be specified via central (peak) luminance.
                        // For a directional light the 'radius' defines the angular radius (in radians) rather than world-space radius (e.g. in metres).
                        var apexAngleRadians = this.radius;
                        // Impose a minimum light angular size to avoid the light becoming an infinitely small angular light source (i.e. a dirac delta function).
                        apexAngleRadians = Math.max(apexAngleRadians, 0.001);
                        var solidAngle = 2.0 * Math.PI * (1.0 - Math.cos(apexAngleRadians));
                        photometricScale = solidAngle;
                        break;
                }
                break;
            case Light.LIGHTTYPEID_HEMISPHERICLIGHT:
                // No fall off in hemisperic light.
                photometricScale = 1.0;
                break;
        }
        return photometricScale;
    };
    /**
     * Reorder the light in the scene according to their defined priority.
     * @hidden Internal Use Only
     */
    Light.prototype._reorderLightsInScene = function () {
        var scene = this.getScene();
        if (this._renderPriority != 0) {
            scene.requireLightSorting = true;
        }
        this.getScene().sortLightsByPriority();
    };
    /**
     * Falloff Default: light is falling off following the material specification:
     * standard material is using standard falloff whereas pbr material can request special falloff per materials.
     */
    Light.FALLOFF_DEFAULT = 0;
    /**
     * Falloff Physical: light is falling off following the inverse squared distance law.
     */
    Light.FALLOFF_PHYSICAL = 1;
    /**
     * Falloff gltf: light is falling off as described in the gltf moving to PBR document
     * to enhance interoperability with other engines.
     */
    Light.FALLOFF_GLTF = 2;
    /**
     * Falloff Standard: light is falling off like in the standard material
     * to enhance interoperability with other materials.
     */
    Light.FALLOFF_STANDARD = 3;
    //lightmapMode Consts
    /**
     * If every light affecting the material is in this lightmapMode,
     * material.lightmapTexture adds or multiplies
     * (depends on material.useLightmapAsShadowmap)
     * after every other light calculations.
     */
    Light.LIGHTMAP_DEFAULT = 0;
    /**
     * material.lightmapTexture as only diffuse lighting from this light
     * adds only specular lighting from this light
     * adds dynamic shadows
     */
    Light.LIGHTMAP_SPECULAR = 1;
    /**
     * material.lightmapTexture as only lighting
     * no light calculation from this light
     * only adds dynamic shadows from this light
     */
    Light.LIGHTMAP_SHADOWSONLY = 2;
    // Intensity Mode Consts
    /**
     * Each light type uses the default quantity according to its type:
     *      point/spot lights use luminous intensity
     *      directional lights use illuminance
     */
    Light.INTENSITYMODE_AUTOMATIC = 0;
    /**
     * lumen (lm)
     */
    Light.INTENSITYMODE_LUMINOUSPOWER = 1;
    /**
     * candela (lm/sr)
     */
    Light.INTENSITYMODE_LUMINOUSINTENSITY = 2;
    /**
     * lux (lm/m^2)
     */
    Light.INTENSITYMODE_ILLUMINANCE = 3;
    /**
     * nit (cd/m^2)
     */
    Light.INTENSITYMODE_LUMINANCE = 4;
    // Light types ids const.
    /**
     * Light type const id of the point light.
     */
    Light.LIGHTTYPEID_POINTLIGHT = 0;
    /**
     * Light type const id of the directional light.
     */
    Light.LIGHTTYPEID_DIRECTIONALLIGHT = 1;
    /**
     * Light type const id of the spot light.
     */
    Light.LIGHTTYPEID_SPOTLIGHT = 2;
    /**
     * Light type const id of the hemispheric light.
     */
    Light.LIGHTTYPEID_HEMISPHERICLIGHT = 3;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], Light.prototype, "diffuse", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], Light.prototype, "specular", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Light.prototype, "falloffType", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Light.prototype, "intensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Light.prototype, "range", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Light.prototype, "intensityMode", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Light.prototype, "radius", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Light.prototype, "_renderPriority", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_reorderLightsInScene")
    ], Light.prototype, "renderPriority", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("shadowEnabled")
    ], Light.prototype, "_shadowEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("excludeWithLayerMask")
    ], Light.prototype, "_excludeWithLayerMask", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("includeOnlyWithLayerMask")
    ], Light.prototype, "_includeOnlyWithLayerMask", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("lightmapMode")
    ], Light.prototype, "_lightmapMode", void 0);
    return Light;
}(_node__WEBPACK_IMPORTED_MODULE_4__["Node"]));



/***/ }),

/***/ "./Lights/pointLight.ts":
/*!******************************!*\
  !*** ./Lights/pointLight.ts ***!
  \******************************/
/*! exports provided: PointLight */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointLight", function() { return PointLight; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _light__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./light */ "./Lights/light.ts");
/* harmony import */ var _shadowLight__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./shadowLight */ "./Lights/shadowLight.ts");






_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("Light_Type_0", function (name, scene) {
    return function () { return new PointLight(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), scene); };
});
/**
 * A point light is a light defined by an unique point in world space.
 * The light is emitted in every direction from this point.
 * A good example of a point light is a standard light bulb.
 * Documentation: https://doc.babylonjs.com/babylon101/lights
 */
var PointLight = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PointLight, _super);
    /**
     * Creates a PointLight object from the passed name and position (Vector3) and adds it in the scene.
     * A PointLight emits the light in every direction.
     * It can cast shadows.
     * If the scene camera is already defined and you want to set your PointLight at the camera position, just set it :
     * ```javascript
     * var pointLight = new PointLight("pl", camera.position, scene);
     * ```
     * Documentation : https://doc.babylonjs.com/babylon101/lights
     * @param name The light friendly name
     * @param position The position of the point light in the scene
     * @param scene The scene the lights belongs to
     */
    function PointLight(name, position, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._shadowAngle = Math.PI / 2;
        _this.position = position;
        return _this;
    }
    Object.defineProperty(PointLight.prototype, "shadowAngle", {
        /**
         * Getter: In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback
         * This specifies what angle the shadow will use to be created.
         *
         * It default to 90 degrees to work nicely with the cube texture generation for point lights shadow maps.
         */
        get: function () {
            return this._shadowAngle;
        },
        /**
         * Setter: In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback
         * This specifies what angle the shadow will use to be created.
         *
         * It default to 90 degrees to work nicely with the cube texture generation for point lights shadow maps.
         */
        set: function (value) {
            this._shadowAngle = value;
            this.forceProjectionMatrixCompute();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PointLight.prototype, "direction", {
        /**
         * Gets the direction if it has been set.
         * In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback
         */
        get: function () {
            return this._direction;
        },
        /**
         * In case of direction provided, the shadow will not use a cube texture but simulate a spot shadow as a fallback
         */
        set: function (value) {
            var previousNeedCube = this.needCube();
            this._direction = value;
            if (this.needCube() !== previousNeedCube && this._shadowGenerator) {
                this._shadowGenerator.recreateShadowMap();
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the string "PointLight"
     * @returns the class name
     */
    PointLight.prototype.getClassName = function () {
        return "PointLight";
    };
    /**
     * Returns the integer 0.
     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x
     */
    PointLight.prototype.getTypeID = function () {
        return _light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTTYPEID_POINTLIGHT;
    };
    /**
     * Specifies wether or not the shadowmap should be a cube texture.
     * @returns true if the shadowmap needs to be a cube texture.
     */
    PointLight.prototype.needCube = function () {
        return !this.direction;
    };
    /**
     * Returns a new Vector3 aligned with the PointLight cube system according to the passed cube face index (integer).
     * @param faceIndex The index of the face we are computed the direction to generate shadow
     * @returns The set direction in 2d mode otherwise the direction to the cubemap face if needCube() is true
     */
    PointLight.prototype.getShadowDirection = function (faceIndex) {
        if (this.direction) {
            return _super.prototype.getShadowDirection.call(this, faceIndex);
        }
        else {
            switch (faceIndex) {
                case 0:
                    return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](1.0, 0.0, 0.0);
                case 1:
                    return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](-1.0, 0.0, 0.0);
                case 2:
                    return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0.0, -1.0, 0.0);
                case 3:
                    return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0.0, 1.0, 0.0);
                case 4:
                    return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0.0, 0.0, 1.0);
                case 5:
                    return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0.0, 0.0, -1.0);
            }
        }
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
    };
    /**
     * Sets the passed matrix "matrix" as a left-handed perspective projection matrix with the following settings :
     * - fov = PI / 2
     * - aspect ratio : 1.0
     * - z-near and far equal to the active camera minZ and maxZ.
     * Returns the PointLight.
     */
    PointLight.prototype._setDefaultShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
        var activeCamera = this.getScene().activeCamera;
        if (!activeCamera) {
            return;
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].PerspectiveFovLHToRef(this.shadowAngle, 1.0, this.getDepthMinZ(activeCamera), this.getDepthMaxZ(activeCamera), matrix);
    };
    PointLight.prototype._buildUniformLayout = function () {
        this._uniformBuffer.addUniform("vLightData", 4);
        this._uniformBuffer.addUniform("vLightDiffuse", 4);
        this._uniformBuffer.addUniform("vLightSpecular", 3);
        this._uniformBuffer.addUniform("vLightFalloff", 4);
        this._uniformBuffer.addUniform("shadowsInfo", 3);
        this._uniformBuffer.addUniform("depthValues", 2);
        this._uniformBuffer.create();
    };
    /**
     * Sets the passed Effect "effect" with the PointLight transformed position (or position, if none) and passed name (string).
     * @param effect The effect to update
     * @param lightIndex The index of the light in the effect to update
     * @returns The point light
     */
    PointLight.prototype.transferToEffect = function (effect, lightIndex) {
        if (this.computeTransformedInformation()) {
            this._uniformBuffer.updateFloat4("vLightData", this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z, 0.0, lightIndex);
        }
        else {
            this._uniformBuffer.updateFloat4("vLightData", this.position.x, this.position.y, this.position.z, 0, lightIndex);
        }
        this._uniformBuffer.updateFloat4("vLightFalloff", this.range, this._inverseSquaredRange, 0, 0, lightIndex);
        return this;
    };
    PointLight.prototype.transferToNodeMaterialEffect = function (effect, lightDataUniformName) {
        if (this.computeTransformedInformation()) {
            effect.setFloat3(lightDataUniformName, this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z);
        }
        else {
            effect.setFloat3(lightDataUniformName, this.position.x, this.position.y, this.position.z);
        }
        return this;
    };
    /**
     * Prepares the list of defines specific to the light type.
     * @param defines the list of defines
     * @param lightIndex defines the index of the light for the effect
     */
    PointLight.prototype.prepareLightSpecificDefines = function (defines, lightIndex) {
        defines["POINTLIGHT" + lightIndex] = true;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PointLight.prototype, "shadowAngle", null);
    return PointLight;
}(_shadowLight__WEBPACK_IMPORTED_MODULE_5__["ShadowLight"]));



/***/ }),

/***/ "./Lights/shadowLight.ts":
/*!*******************************!*\
  !*** ./Lights/shadowLight.ts ***!
  \*******************************/
/*! exports provided: ShadowLight */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowLight", function() { return ShadowLight; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _light__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./light */ "./Lights/light.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");





/**
 * Base implementation IShadowLight
 * It groups all the common behaviour in order to reduce dupplication and better follow the DRY pattern.
 */
var ShadowLight = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShadowLight, _super);
    function ShadowLight() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._needProjectionMatrixCompute = true;
        return _this;
    }
    ShadowLight.prototype._setPosition = function (value) {
        this._position = value;
    };
    Object.defineProperty(ShadowLight.prototype, "position", {
        /**
         * Sets the position the shadow will be casted from. Also use as the light position for both
         * point and spot lights.
         */
        get: function () {
            return this._position;
        },
        /**
         * Sets the position the shadow will be casted from. Also use as the light position for both
         * point and spot lights.
         */
        set: function (value) {
            this._setPosition(value);
        },
        enumerable: true,
        configurable: true
    });
    ShadowLight.prototype._setDirection = function (value) {
        this._direction = value;
    };
    Object.defineProperty(ShadowLight.prototype, "direction", {
        /**
         * In 2d mode (needCube being false), gets the direction used to cast the shadow.
         * Also use as the light direction on spot and directional lights.
         */
        get: function () {
            return this._direction;
        },
        /**
         * In 2d mode (needCube being false), sets the direction used to cast the shadow.
         * Also use as the light direction on spot and directional lights.
         */
        set: function (value) {
            this._setDirection(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowLight.prototype, "shadowMinZ", {
        /**
         * Gets the shadow projection clipping minimum z value.
         */
        get: function () {
            return this._shadowMinZ;
        },
        /**
         * Sets the shadow projection clipping minimum z value.
         */
        set: function (value) {
            this._shadowMinZ = value;
            this.forceProjectionMatrixCompute();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ShadowLight.prototype, "shadowMaxZ", {
        /**
         * Sets the shadow projection clipping maximum z value.
         */
        get: function () {
            return this._shadowMaxZ;
        },
        /**
         * Gets the shadow projection clipping maximum z value.
         */
        set: function (value) {
            this._shadowMaxZ = value;
            this.forceProjectionMatrixCompute();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Computes the transformed information (transformedPosition and transformedDirection in World space) of the current light
     * @returns true if the information has been computed, false if it does not need to (no parenting)
     */
    ShadowLight.prototype.computeTransformedInformation = function () {
        if (this.parent && this.parent.getWorldMatrix) {
            if (!this.transformedPosition) {
                this.transformedPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
            }
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(this.position, this.parent.getWorldMatrix(), this.transformedPosition);
            // In case the direction is present.
            if (this.direction) {
                if (!this.transformedDirection) {
                    this.transformedDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
                }
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformNormalToRef(this.direction, this.parent.getWorldMatrix(), this.transformedDirection);
            }
            return true;
        }
        return false;
    };
    /**
     * Return the depth scale used for the shadow map.
     * @returns the depth scale.
     */
    ShadowLight.prototype.getDepthScale = function () {
        return 50.0;
    };
    /**
     * Get the direction to use to render the shadow map. In case of cube texture, the face index can be passed.
     * @param faceIndex The index of the face we are computed the direction to generate shadow
     * @returns The set direction in 2d mode otherwise the direction to the cubemap face if needCube() is true
     */
    ShadowLight.prototype.getShadowDirection = function (faceIndex) {
        return this.transformedDirection ? this.transformedDirection : this.direction;
    };
    /**
     * Returns the ShadowLight absolute position in the World.
     * @returns the position vector in world space
     */
    ShadowLight.prototype.getAbsolutePosition = function () {
        return this.transformedPosition ? this.transformedPosition : this.position;
    };
    /**
     * Sets the ShadowLight direction toward the passed target.
     * @param target The point to target in local space
     * @returns the updated ShadowLight direction
     */
    ShadowLight.prototype.setDirectionToTarget = function (target) {
        this.direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(target.subtract(this.position));
        return this.direction;
    };
    /**
     * Returns the light rotation in euler definition.
     * @returns the x y z rotation in local space.
     */
    ShadowLight.prototype.getRotation = function () {
        this.direction.normalize();
        var xaxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Cross(this.direction, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_4__["Axis"].Y);
        var yaxis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Cross(xaxis, this.direction);
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].RotationFromAxis(xaxis, yaxis, this.direction);
    };
    /**
     * Returns whether or not the shadow generation require a cube texture or a 2d texture.
     * @returns true if a cube texture needs to be use
     */
    ShadowLight.prototype.needCube = function () {
        return false;
    };
    /**
     * Detects if the projection matrix requires to be recomputed this frame.
     * @returns true if it requires to be recomputed otherwise, false.
     */
    ShadowLight.prototype.needProjectionMatrixCompute = function () {
        return this._needProjectionMatrixCompute;
    };
    /**
     * Forces the shadow generator to recompute the projection matrix even if position and direction did not changed.
     */
    ShadowLight.prototype.forceProjectionMatrixCompute = function () {
        this._needProjectionMatrixCompute = true;
    };
    /** @hidden */
    ShadowLight.prototype._initCache = function () {
        _super.prototype._initCache.call(this);
        this._cache.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
    };
    /** @hidden */
    ShadowLight.prototype._isSynchronized = function () {
        if (!this._cache.position.equals(this.position)) {
            return false;
        }
        return true;
    };
    /**
     * Computes the world matrix of the node
     * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
     * @returns the world matrix
     */
    ShadowLight.prototype.computeWorldMatrix = function (force) {
        if (!force && this.isSynchronized()) {
            this._currentRenderId = this.getScene().getRenderId();
            return this._worldMatrix;
        }
        this._updateCache();
        this._cache.position.copyFrom(this.position);
        if (!this._worldMatrix) {
            this._worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Identity();
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].TranslationToRef(this.position.x, this.position.y, this.position.z, this._worldMatrix);
        if (this.parent && this.parent.getWorldMatrix) {
            this._worldMatrix.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
            this._markSyncedWithParent();
        }
        // Cache the determinant
        this._worldMatrixDeterminantIsDirty = true;
        return this._worldMatrix;
    };
    /**
     * Gets the minZ used for shadow according to both the scene and the light.
     * @param activeCamera The camera we are returning the min for
     * @returns the depth min z
     */
    ShadowLight.prototype.getDepthMinZ = function (activeCamera) {
        return this.shadowMinZ !== undefined ? this.shadowMinZ : activeCamera.minZ;
    };
    /**
     * Gets the maxZ used for shadow according to both the scene and the light.
     * @param activeCamera The camera we are returning the max for
     * @returns the depth max z
     */
    ShadowLight.prototype.getDepthMaxZ = function (activeCamera) {
        return this.shadowMaxZ !== undefined ? this.shadowMaxZ : activeCamera.maxZ;
    };
    /**
     * Sets the shadow projection matrix in parameter to the generated projection matrix.
     * @param matrix The materix to updated with the projection information
     * @param viewMatrix The transform matrix of the light
     * @param renderList The list of mesh to render in the map
     * @returns The current light
     */
    ShadowLight.prototype.setShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
        if (this.customProjectionMatrixBuilder) {
            this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);
        }
        else {
            this._setDefaultShadowProjectionMatrix(matrix, viewMatrix, renderList);
        }
        return this;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], ShadowLight.prototype, "position", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], ShadowLight.prototype, "direction", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ShadowLight.prototype, "shadowMinZ", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ShadowLight.prototype, "shadowMaxZ", null);
    return ShadowLight;
}(_light__WEBPACK_IMPORTED_MODULE_3__["Light"]));



/***/ }),

/***/ "./Lights/spotLight.ts":
/*!*****************************!*\
  !*** ./Lights/spotLight.ts ***!
  \*****************************/
/*! exports provided: SpotLight */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpotLight", function() { return SpotLight; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _light__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./light */ "./Lights/light.ts");
/* harmony import */ var _shadowLight__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./shadowLight */ "./Lights/shadowLight.ts");






_node__WEBPACK_IMPORTED_MODULE_3__["Node"].AddNodeConstructor("Light_Type_2", function (name, scene) {
    return function () { return new SpotLight(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(), 0, 0, scene); };
});
/**
 * A spot light is defined by a position, a direction, an angle, and an exponent.
 * These values define a cone of light starting from the position, emitting toward the direction.
 * The angle, in radians, defines the size (field of illumination) of the spotlight's conical beam,
 * and the exponent defines the speed of the decay of the light with distance (reach).
 * Documentation: https://doc.babylonjs.com/babylon101/lights
 */
var SpotLight = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SpotLight, _super);
    /**
     * Creates a SpotLight object in the scene. A spot light is a simply light oriented cone.
     * It can cast shadows.
     * Documentation : https://doc.babylonjs.com/babylon101/lights
     * @param name The light friendly name
     * @param position The position of the spot light in the scene
     * @param direction The direction of the light in the scene
     * @param angle The cone angle of the light in Radians
     * @param exponent The light decay speed with the distance from the emission spot
     * @param scene The scene the lights belongs to
     */
    function SpotLight(name, position, direction, angle, exponent, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._innerAngle = 0;
        _this._projectionTextureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Zero();
        _this._projectionTextureLightNear = 1e-6;
        _this._projectionTextureLightFar = 1000.0;
        _this._projectionTextureUpDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Up();
        _this._projectionTextureViewLightDirty = true;
        _this._projectionTextureProjectionLightDirty = true;
        _this._projectionTextureDirty = true;
        _this._projectionTextureViewTargetVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        _this._projectionTextureViewLightMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Zero();
        _this._projectionTextureProjectionLightMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].Zero();
        _this._projectionTextureScalingMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromValues(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0);
        _this.position = position;
        _this.direction = direction;
        _this.angle = angle;
        _this.exponent = exponent;
        return _this;
    }
    Object.defineProperty(SpotLight.prototype, "angle", {
        /**
         * Gets the cone angle of the spot light in Radians.
         */
        get: function () {
            return this._angle;
        },
        /**
         * Sets the cone angle of the spot light in Radians.
         */
        set: function (value) {
            this._angle = value;
            this._cosHalfAngle = Math.cos(value * 0.5);
            this._projectionTextureProjectionLightDirty = true;
            this.forceProjectionMatrixCompute();
            this._computeAngleValues();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "innerAngle", {
        /**
         * Only used in gltf falloff mode, this defines the angle where
         * the directional falloff will start before cutting at angle which could be seen
         * as outer angle.
         */
        get: function () {
            return this._innerAngle;
        },
        /**
         * Only used in gltf falloff mode, this defines the angle where
         * the directional falloff will start before cutting at angle which could be seen
         * as outer angle.
         */
        set: function (value) {
            this._innerAngle = value;
            this._computeAngleValues();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "shadowAngleScale", {
        /**
         * Allows scaling the angle of the light for shadow generation only.
         */
        get: function () {
            return this._shadowAngleScale;
        },
        /**
         * Allows scaling the angle of the light for shadow generation only.
         */
        set: function (value) {
            this._shadowAngleScale = value;
            this.forceProjectionMatrixCompute();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "projectionTextureMatrix", {
        /**
        * Allows reading the projecton texture
        */
        get: function () {
            return this._projectionTextureMatrix;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "projectionTextureLightNear", {
        /**
         * Gets the near clip of the Spotlight for texture projection.
         */
        get: function () {
            return this._projectionTextureLightNear;
        },
        /**
         * Sets the near clip of the Spotlight for texture projection.
         */
        set: function (value) {
            this._projectionTextureLightNear = value;
            this._projectionTextureProjectionLightDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "projectionTextureLightFar", {
        /**
         * Gets the far clip of the Spotlight for texture projection.
         */
        get: function () {
            return this._projectionTextureLightFar;
        },
        /**
         * Sets the far clip of the Spotlight for texture projection.
         */
        set: function (value) {
            this._projectionTextureLightFar = value;
            this._projectionTextureProjectionLightDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "projectionTextureUpDirection", {
        /**
         * Gets the Up vector of the Spotlight for texture projection.
         */
        get: function () {
            return this._projectionTextureUpDirection;
        },
        /**
         * Sets the Up vector of the Spotlight for texture projection.
         */
        set: function (value) {
            this._projectionTextureUpDirection = value;
            this._projectionTextureProjectionLightDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpotLight.prototype, "projectionTexture", {
        /**
         * Gets the projection texture of the light.
        */
        get: function () {
            return this._projectionTexture;
        },
        /**
        * Sets the projection texture of the light.
        */
        set: function (value) {
            var _this = this;
            if (this._projectionTexture === value) {
                return;
            }
            this._projectionTexture = value;
            this._projectionTextureDirty = true;
            if (this._projectionTexture && !this._projectionTexture.isReady()) {
                var texture = this._projectionTexture;
                if (texture.onLoadObservable) {
                    texture.onLoadObservable.addOnce(function () {
                        _this._markMeshesAsLightDirty();
                    });
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the string "SpotLight".
     * @returns the class name
     */
    SpotLight.prototype.getClassName = function () {
        return "SpotLight";
    };
    /**
     * Returns the integer 2.
     * @returns The light Type id as a constant defines in Light.LIGHTTYPEID_x
     */
    SpotLight.prototype.getTypeID = function () {
        return _light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTTYPEID_SPOTLIGHT;
    };
    /**
     * Overrides the direction setter to recompute the projection texture view light Matrix.
     */
    SpotLight.prototype._setDirection = function (value) {
        _super.prototype._setDirection.call(this, value);
        this._projectionTextureViewLightDirty = true;
    };
    /**
     * Overrides the position setter to recompute the projection texture view light Matrix.
     */
    SpotLight.prototype._setPosition = function (value) {
        _super.prototype._setPosition.call(this, value);
        this._projectionTextureViewLightDirty = true;
    };
    /**
     * Sets the passed matrix "matrix" as perspective projection matrix for the shadows and the passed view matrix with the fov equal to the SpotLight angle and and aspect ratio of 1.0.
     * Returns the SpotLight.
     */
    SpotLight.prototype._setDefaultShadowProjectionMatrix = function (matrix, viewMatrix, renderList) {
        var activeCamera = this.getScene().activeCamera;
        if (!activeCamera) {
            return;
        }
        this._shadowAngleScale = this._shadowAngleScale || 1;
        var angle = this._shadowAngleScale * this._angle;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].PerspectiveFovLHToRef(angle, 1.0, this.getDepthMinZ(activeCamera), this.getDepthMaxZ(activeCamera), matrix);
    };
    SpotLight.prototype._computeProjectionTextureViewLightMatrix = function () {
        this._projectionTextureViewLightDirty = false;
        this._projectionTextureDirty = true;
        this.position.addToRef(this.direction, this._projectionTextureViewTargetVector);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].LookAtLHToRef(this.position, this._projectionTextureViewTargetVector, this._projectionTextureUpDirection, this._projectionTextureViewLightMatrix);
    };
    SpotLight.prototype._computeProjectionTextureProjectionLightMatrix = function () {
        this._projectionTextureProjectionLightDirty = false;
        this._projectionTextureDirty = true;
        var light_far = this.projectionTextureLightFar;
        var light_near = this.projectionTextureLightNear;
        var P = light_far / (light_far - light_near);
        var Q = -P * light_near;
        var S = 1.0 / Math.tan(this._angle / 2.0);
        var A = 1.0;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromValuesToRef(S / A, 0.0, 0.0, 0.0, 0.0, S, 0.0, 0.0, 0.0, 0.0, P, 1.0, 0.0, 0.0, Q, 0.0, this._projectionTextureProjectionLightMatrix);
    };
    /**
     * Main function for light texture projection matrix computing.
     */
    SpotLight.prototype._computeProjectionTextureMatrix = function () {
        this._projectionTextureDirty = false;
        this._projectionTextureViewLightMatrix.multiplyToRef(this._projectionTextureProjectionLightMatrix, this._projectionTextureMatrix);
        this._projectionTextureMatrix.multiplyToRef(this._projectionTextureScalingMatrix, this._projectionTextureMatrix);
    };
    SpotLight.prototype._buildUniformLayout = function () {
        this._uniformBuffer.addUniform("vLightData", 4);
        this._uniformBuffer.addUniform("vLightDiffuse", 4);
        this._uniformBuffer.addUniform("vLightSpecular", 3);
        this._uniformBuffer.addUniform("vLightDirection", 3);
        this._uniformBuffer.addUniform("vLightFalloff", 4);
        this._uniformBuffer.addUniform("shadowsInfo", 3);
        this._uniformBuffer.addUniform("depthValues", 2);
        this._uniformBuffer.create();
    };
    SpotLight.prototype._computeAngleValues = function () {
        this._lightAngleScale = 1.0 / Math.max(0.001, (Math.cos(this._innerAngle * 0.5) - this._cosHalfAngle));
        this._lightAngleOffset = -this._cosHalfAngle * this._lightAngleScale;
    };
    /**
     * Sets the passed Effect object with the SpotLight transfomed position (or position if not parented) and normalized direction.
     * @param effect The effect to update
     * @param lightIndex The index of the light in the effect to update
     * @returns The spot light
     */
    SpotLight.prototype.transferToEffect = function (effect, lightIndex) {
        var normalizeDirection;
        if (this.computeTransformedInformation()) {
            this._uniformBuffer.updateFloat4("vLightData", this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z, this.exponent, lightIndex);
            normalizeDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(this.transformedDirection);
        }
        else {
            this._uniformBuffer.updateFloat4("vLightData", this.position.x, this.position.y, this.position.z, this.exponent, lightIndex);
            normalizeDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(this.direction);
        }
        if (this.getScene().useRightHandedSystem) {
            this._uniformBuffer.updateFloat4("vLightDirection", -normalizeDirection.x, -normalizeDirection.y, -normalizeDirection.z, this._cosHalfAngle, lightIndex);
        }
        else {
            this._uniformBuffer.updateFloat4("vLightDirection", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, this._cosHalfAngle, lightIndex);
        }
        this._uniformBuffer.updateFloat4("vLightFalloff", this.range, this._inverseSquaredRange, this._lightAngleScale, this._lightAngleOffset, lightIndex);
        if (this.projectionTexture && this.projectionTexture.isReady()) {
            if (this._projectionTextureViewLightDirty) {
                this._computeProjectionTextureViewLightMatrix();
            }
            if (this._projectionTextureProjectionLightDirty) {
                this._computeProjectionTextureProjectionLightMatrix();
            }
            if (this._projectionTextureDirty) {
                this._computeProjectionTextureMatrix();
            }
            effect.setMatrix("textureProjectionMatrix" + lightIndex, this._projectionTextureMatrix);
            effect.setTexture("projectionLightSampler" + lightIndex, this.projectionTexture);
        }
        return this;
    };
    SpotLight.prototype.transferToNodeMaterialEffect = function (effect, lightDataUniformName) {
        var normalizeDirection;
        if (this.computeTransformedInformation()) {
            normalizeDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(this.transformedDirection);
        }
        else {
            normalizeDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Normalize(this.direction);
        }
        if (this.getScene().useRightHandedSystem) {
            effect.setFloat3(lightDataUniformName, -normalizeDirection.x, -normalizeDirection.y, -normalizeDirection.z);
        }
        else {
            effect.setFloat3(lightDataUniformName, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z);
        }
        return this;
    };
    /**
     * Disposes the light and the associated resources.
     */
    SpotLight.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        if (this._projectionTexture) {
            this._projectionTexture.dispose();
        }
    };
    /**
     * Prepares the list of defines specific to the light type.
     * @param defines the list of defines
     * @param lightIndex defines the index of the light for the effect
     */
    SpotLight.prototype.prepareLightSpecificDefines = function (defines, lightIndex) {
        defines["SPOTLIGHT" + lightIndex] = true;
        defines["PROJECTEDLIGHTTEXTURE" + lightIndex] = this.projectionTexture && this.projectionTexture.isReady() ? true : false;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "angle", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "innerAngle", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "shadowAngleScale", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "exponent", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "projectionTextureLightNear", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "projectionTextureLightFar", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], SpotLight.prototype, "projectionTextureUpDirection", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("projectedLightTexture")
    ], SpotLight.prototype, "_projectionTexture", void 0);
    return SpotLight;
}(_shadowLight__WEBPACK_IMPORTED_MODULE_5__["ShadowLight"]));



/***/ }),

/***/ "./Loading/Plugins/babylonFileLoader.ts":
/*!**********************************************!*\
  !*** ./Loading/Plugins/babylonFileLoader.ts ***!
  \**********************************************/
/*! exports provided: _BabylonLoaderRegistered */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_BabylonLoaderRegistered", function() { return _BabylonLoaderRegistered; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_geometry__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Meshes/geometry */ "./Meshes/geometry.ts");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Materials/multiMaterial */ "./Materials/multiMaterial.ts");
/* harmony import */ var _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Materials/Textures/cubeTexture */ "./Materials/Textures/cubeTexture.ts");
/* harmony import */ var _Materials_Textures_hdrCubeTexture__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Materials/Textures/hdrCubeTexture */ "./Materials/Textures/hdrCubeTexture.ts");
/* harmony import */ var _Animations_animationGroup__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../Animations/animationGroup */ "./Animations/animationGroup.ts");
/* harmony import */ var _Lights_light__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../Lights/light */ "./Lights/light.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _assetContainer__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../assetContainer */ "./assetContainer.ts");
/* harmony import */ var _Actions_actionManager__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Actions/actionManager */ "./Actions/actionManager.ts");
/* harmony import */ var _Bones_skeleton__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../Bones/skeleton */ "./Bones/skeleton.ts");
/* harmony import */ var _Morph_morphTargetManager__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../../Morph/morphTargetManager */ "./Morph/morphTargetManager.ts");
/* harmony import */ var _Physics_Plugins_cannonJSPlugin__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../../Physics/Plugins/cannonJSPlugin */ "./Physics/Plugins/cannonJSPlugin.ts");
/* harmony import */ var _Physics_Plugins_oimoJSPlugin__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../../Physics/Plugins/oimoJSPlugin */ "./Physics/Plugins/oimoJSPlugin.ts");
/* harmony import */ var _Physics_Plugins_ammoJSPlugin__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../../Physics/Plugins/ammoJSPlugin */ "./Physics/Plugins/ammoJSPlugin.ts");
/* harmony import */ var _Probes_reflectionProbe__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../../Probes/reflectionProbe */ "./Probes/reflectionProbe.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_stringTools__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ../../Misc/stringTools */ "./Misc/stringTools.ts");



























/** @hidden */
var _BabylonLoaderRegistered = true;
var parseMaterialById = function (id, parsedData, scene, rootUrl) {
    for (var index = 0, cache = parsedData.materials.length; index < cache; index++) {
        var parsedMaterial = parsedData.materials[index];
        if (parsedMaterial.id === id) {
            return _Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].Parse(parsedMaterial, scene, rootUrl);
        }
    }
    return null;
};
var isDescendantOf = function (mesh, names, hierarchyIds) {
    for (var i in names) {
        if (mesh.name === names[i]) {
            hierarchyIds.push(mesh.id);
            return true;
        }
    }
    if (mesh.parentId && hierarchyIds.indexOf(mesh.parentId) !== -1) {
        hierarchyIds.push(mesh.id);
        return true;
    }
    return false;
};
var logOperation = function (operation, producer) {
    return operation + " of " + (producer ? producer.file + " from " + producer.name + " version: " + producer.version + ", exporter version: " + producer.exporter_version : "unknown");
};
var loadDetailLevels = function (scene, mesh) {
    var mastermesh = mesh;
    // Every value specified in the ids array of the lod data points to another mesh which should be used as the lower LOD level.
    // The distances (or coverages) array values specified are used along with the lod mesh ids as a hint to determine the switching threshold for the various LODs.
    if (mesh._waitingData.lods) {
        if (mesh._waitingData.lods.ids && mesh._waitingData.lods.ids.length > 0) {
            var lodmeshes = mesh._waitingData.lods.ids;
            var wasenabled = mastermesh.isEnabled(false);
            if (mesh._waitingData.lods.distances) {
                var distances = mesh._waitingData.lods.distances;
                if (distances.length >= lodmeshes.length) {
                    var culling = (distances.length > lodmeshes.length) ? distances[distances.length - 1] : 0;
                    mastermesh.setEnabled(false);
                    for (var index = 0; index < lodmeshes.length; index++) {
                        var lodid = lodmeshes[index];
                        var lodmesh = scene.getMeshByID(lodid);
                        if (lodmesh != null) {
                            mastermesh.addLODLevel(distances[index], lodmesh);
                        }
                    }
                    if (culling > 0) {
                        mastermesh.addLODLevel(culling, null);
                    }
                    if (wasenabled === true) {
                        mastermesh.setEnabled(true);
                    }
                }
                else {
                    _Misc_tools__WEBPACK_IMPORTED_MODULE_25__["Tools"].Warn("Invalid level of detail distances for " + mesh.name);
                }
            }
        }
        mesh._waitingData.lods = null;
    }
};
var loadAssetContainer = function (scene, data, rootUrl, onError, addToScene) {
    if (addToScene === void 0) { addToScene = false; }
    var container = new _assetContainer__WEBPACK_IMPORTED_MODULE_16__["AssetContainer"](scene);
    // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details
    // when SceneLoader.debugLogging = true (default), or exception encountered.
    // Everything stored in var log instead of writing separate lines to support only writing in exception,
    // and avoid problems with multiple concurrent .babylon loads.
    var log = "importScene has failed JSON parse";
    try {
        var parsedData = JSON.parse(data);
        log = "";
        var fullDetails = _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel === _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].DETAILED_LOGGING;
        var index;
        var cache;
        // Environment texture
        if (parsedData.environmentTexture !== undefined && parsedData.environmentTexture !== null) {
            // PBR needed for both HDR texture (gamma space) & a sky box
            var isPBR = parsedData.isPBR !== undefined ? parsedData.isPBR : true;
            if (parsedData.environmentTextureType && parsedData.environmentTextureType === "BABYLON.HDRCubeTexture") {
                var hdrSize = (parsedData.environmentTextureSize) ? parsedData.environmentTextureSize : 128;
                var hdrTexture = new _Materials_Textures_hdrCubeTexture__WEBPACK_IMPORTED_MODULE_10__["HDRCubeTexture"]((parsedData.environmentTexture.match(/https?:\/\//g) ? "" : rootUrl) + parsedData.environmentTexture, scene, hdrSize, true, !isPBR);
                if (parsedData.environmentTextureRotationY) {
                    hdrTexture.rotationY = parsedData.environmentTextureRotationY;
                }
                scene.environmentTexture = hdrTexture;
            }
            else {
                if (_Misc_stringTools__WEBPACK_IMPORTED_MODULE_26__["StringTools"].EndsWith(parsedData.environmentTexture, ".env")) {
                    var compressedTexture = new _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__["CubeTexture"]((parsedData.environmentTexture.match(/https?:\/\//g) ? "" : rootUrl) + parsedData.environmentTexture, scene);
                    if (parsedData.environmentTextureRotationY) {
                        compressedTexture.rotationY = parsedData.environmentTextureRotationY;
                    }
                    scene.environmentTexture = compressedTexture;
                }
                else {
                    var cubeTexture = _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__["CubeTexture"].CreateFromPrefilteredData((parsedData.environmentTexture.match(/https?:\/\//g) ? "" : rootUrl) + parsedData.environmentTexture, scene);
                    if (parsedData.environmentTextureRotationY) {
                        cubeTexture.rotationY = parsedData.environmentTextureRotationY;
                    }
                    scene.environmentTexture = cubeTexture;
                }
            }
            if (parsedData.createDefaultSkybox === true) {
                var skyboxScale = (scene.activeCamera !== undefined && scene.activeCamera !== null) ? (scene.activeCamera.maxZ - scene.activeCamera.minZ) / 2 : 1000;
                var skyboxBlurLevel = parsedData.skyboxBlurLevel || 0;
                scene.createDefaultSkybox(scene.environmentTexture, isPBR, skyboxScale, skyboxBlurLevel);
            }
            container.environmentTexture = scene.environmentTexture;
        }
        // Environment Intensity
        if (parsedData.environmentIntensity !== undefined && parsedData.environmentIntensity !== null) {
            scene.environmentIntensity = parsedData.environmentIntensity;
        }
        // Lights
        if (parsedData.lights !== undefined && parsedData.lights !== null) {
            for (index = 0, cache = parsedData.lights.length; index < cache; index++) {
                var parsedLight = parsedData.lights[index];
                var light = _Lights_light__WEBPACK_IMPORTED_MODULE_12__["Light"].Parse(parsedLight, scene);
                if (light) {
                    container.lights.push(light);
                    log += (index === 0 ? "\n\tLights:" : "");
                    log += "\n\t\t" + light.toString(fullDetails);
                }
            }
        }
        // Reflection probes
        if (parsedData.reflectionProbes !== undefined && parsedData.reflectionProbes !== null) {
            for (index = 0, cache = parsedData.reflectionProbes.length; index < cache; index++) {
                var parsedReflectionProbe = parsedData.reflectionProbes[index];
                var reflectionProbe = _Probes_reflectionProbe__WEBPACK_IMPORTED_MODULE_23__["ReflectionProbe"].Parse(parsedReflectionProbe, scene, rootUrl);
                if (reflectionProbe) {
                    container.reflectionProbes.push(reflectionProbe);
                    log += (index === 0 ? "\n\tReflection Probes:" : "");
                    log += "\n\t\t" + reflectionProbe.toString(fullDetails);
                }
            }
        }
        // Animations
        if (parsedData.animations !== undefined && parsedData.animations !== null) {
            for (index = 0, cache = parsedData.animations.length; index < cache; index++) {
                var parsedAnimation = parsedData.animations[index];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_24__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    var animation = internalClass.Parse(parsedAnimation);
                    scene.animations.push(animation);
                    container.animations.push(animation);
                    log += (index === 0 ? "\n\tAnimations:" : "");
                    log += "\n\t\t" + animation.toString(fullDetails);
                }
            }
        }
        // Materials
        if (parsedData.materials !== undefined && parsedData.materials !== null) {
            for (index = 0, cache = parsedData.materials.length; index < cache; index++) {
                var parsedMaterial = parsedData.materials[index];
                var mat = _Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].Parse(parsedMaterial, scene, rootUrl);
                if (mat) {
                    container.materials.push(mat);
                    log += (index === 0 ? "\n\tMaterials:" : "");
                    log += "\n\t\t" + mat.toString(fullDetails);
                    // Textures
                    var textures = mat.getActiveTextures();
                    textures.forEach(function (t) {
                        if (container.textures.indexOf(t) == -1) {
                            container.textures.push(t);
                        }
                    });
                }
            }
        }
        if (parsedData.multiMaterials !== undefined && parsedData.multiMaterials !== null) {
            for (index = 0, cache = parsedData.multiMaterials.length; index < cache; index++) {
                var parsedMultiMaterial = parsedData.multiMaterials[index];
                var mmat = _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_8__["MultiMaterial"].ParseMultiMaterial(parsedMultiMaterial, scene);
                container.multiMaterials.push(mmat);
                log += (index === 0 ? "\n\tMultiMaterials:" : "");
                log += "\n\t\t" + mmat.toString(fullDetails);
                // Textures
                var textures = mmat.getActiveTextures();
                textures.forEach(function (t) {
                    if (container.textures.indexOf(t) == -1) {
                        container.textures.push(t);
                    }
                });
            }
        }
        // Morph targets
        if (parsedData.morphTargetManagers !== undefined && parsedData.morphTargetManagers !== null) {
            for (var _i = 0, _a = parsedData.morphTargetManagers; _i < _a.length; _i++) {
                var managerData = _a[_i];
                container.morphTargetManagers.push(_Morph_morphTargetManager__WEBPACK_IMPORTED_MODULE_19__["MorphTargetManager"].Parse(managerData, scene));
            }
        }
        // Skeletons
        if (parsedData.skeletons !== undefined && parsedData.skeletons !== null) {
            for (index = 0, cache = parsedData.skeletons.length; index < cache; index++) {
                var parsedSkeleton = parsedData.skeletons[index];
                var skeleton = _Bones_skeleton__WEBPACK_IMPORTED_MODULE_18__["Skeleton"].Parse(parsedSkeleton, scene);
                container.skeletons.push(skeleton);
                log += (index === 0 ? "\n\tSkeletons:" : "");
                log += "\n\t\t" + skeleton.toString(fullDetails);
            }
        }
        // Geometries
        var geometries = parsedData.geometries;
        if (geometries !== undefined && geometries !== null) {
            var addedGeometry = new Array();
            // VertexData
            var vertexData = geometries.vertexData;
            if (vertexData !== undefined && vertexData !== null) {
                for (index = 0, cache = vertexData.length; index < cache; index++) {
                    var parsedVertexData = vertexData[index];
                    addedGeometry.push(_Meshes_geometry__WEBPACK_IMPORTED_MODULE_5__["Geometry"].Parse(parsedVertexData, scene, rootUrl));
                }
            }
            addedGeometry.forEach(function (g) {
                if (g) {
                    container.geometries.push(g);
                }
            });
        }
        // Transform nodes
        if (parsedData.transformNodes !== undefined && parsedData.transformNodes !== null) {
            for (index = 0, cache = parsedData.transformNodes.length; index < cache; index++) {
                var parsedTransformNode = parsedData.transformNodes[index];
                var node = _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_6__["TransformNode"].Parse(parsedTransformNode, scene, rootUrl);
                container.transformNodes.push(node);
            }
        }
        // Meshes
        if (parsedData.meshes !== undefined && parsedData.meshes !== null) {
            for (index = 0, cache = parsedData.meshes.length; index < cache; index++) {
                var parsedMesh = parsedData.meshes[index];
                var mesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"].Parse(parsedMesh, scene, rootUrl);
                container.meshes.push(mesh);
                log += (index === 0 ? "\n\tMeshes:" : "");
                log += "\n\t\t" + mesh.toString(fullDetails);
            }
        }
        // Cameras
        if (parsedData.cameras !== undefined && parsedData.cameras !== null) {
            for (index = 0, cache = parsedData.cameras.length; index < cache; index++) {
                var parsedCamera = parsedData.cameras[index];
                var camera = _Cameras_camera__WEBPACK_IMPORTED_MODULE_1__["Camera"].Parse(parsedCamera, scene);
                container.cameras.push(camera);
                log += (index === 0 ? "\n\tCameras:" : "");
                log += "\n\t\t" + camera.toString(fullDetails);
            }
        }
        // Animation Groups
        if (parsedData.animationGroups !== undefined && parsedData.animationGroups !== null) {
            for (index = 0, cache = parsedData.animationGroups.length; index < cache; index++) {
                var parsedAnimationGroup = parsedData.animationGroups[index];
                var animationGroup = _Animations_animationGroup__WEBPACK_IMPORTED_MODULE_11__["AnimationGroup"].Parse(parsedAnimationGroup, scene);
                container.animationGroups.push(animationGroup);
                log += (index === 0 ? "\n\tAnimationGroups:" : "");
                log += "\n\t\t" + animationGroup.toString(fullDetails);
            }
        }
        // Browsing all the graph to connect the dots
        for (index = 0, cache = scene.cameras.length; index < cache; index++) {
            var camera = scene.cameras[index];
            if (camera._waitingParentId) {
                camera.parent = scene.getLastEntryByID(camera._waitingParentId);
                camera._waitingParentId = null;
            }
        }
        for (index = 0, cache = scene.lights.length; index < cache; index++) {
            var light_1 = scene.lights[index];
            if (light_1 && light_1._waitingParentId) {
                light_1.parent = scene.getLastEntryByID(light_1._waitingParentId);
                light_1._waitingParentId = null;
            }
        }
        // Connect parents & children and parse actions and lods
        for (index = 0, cache = scene.transformNodes.length; index < cache; index++) {
            var transformNode = scene.transformNodes[index];
            if (transformNode._waitingParentId) {
                transformNode.parent = scene.getLastEntryByID(transformNode._waitingParentId);
                transformNode._waitingParentId = null;
            }
        }
        for (index = 0, cache = scene.meshes.length; index < cache; index++) {
            var mesh = scene.meshes[index];
            if (mesh._waitingParentId) {
                mesh.parent = scene.getLastEntryByID(mesh._waitingParentId);
                mesh._waitingParentId = null;
            }
            if (mesh._waitingData.lods) {
                loadDetailLevels(scene, mesh);
            }
        }
        // link skeleton transform nodes
        for (index = 0, cache = scene.skeletons.length; index < cache; index++) {
            var skeleton = scene.skeletons[index];
            if (skeleton._hasWaitingData) {
                if (skeleton.bones != null) {
                    skeleton.bones.forEach(function (bone) {
                        if (bone._waitingTransformNodeId) {
                            var linkTransformNode = scene.getLastEntryByID(bone._waitingTransformNodeId);
                            if (linkTransformNode) {
                                bone.linkTransformNode(linkTransformNode);
                            }
                            bone._waitingTransformNodeId = null;
                        }
                    });
                }
                skeleton._hasWaitingData = null;
            }
        }
        // freeze world matrix application
        for (index = 0, cache = scene.meshes.length; index < cache; index++) {
            var currentMesh = scene.meshes[index];
            if (currentMesh._waitingData.freezeWorldMatrix) {
                currentMesh.freezeWorldMatrix();
                currentMesh._waitingData.freezeWorldMatrix = null;
            }
            else {
                currentMesh.computeWorldMatrix(true);
            }
        }
        // Lights exclusions / inclusions
        for (index = 0, cache = scene.lights.length; index < cache; index++) {
            var light_2 = scene.lights[index];
            // Excluded check
            if (light_2._excludedMeshesIds.length > 0) {
                for (var excludedIndex = 0; excludedIndex < light_2._excludedMeshesIds.length; excludedIndex++) {
                    var excludedMesh = scene.getMeshByID(light_2._excludedMeshesIds[excludedIndex]);
                    if (excludedMesh) {
                        light_2.excludedMeshes.push(excludedMesh);
                    }
                }
                light_2._excludedMeshesIds = [];
            }
            // Included check
            if (light_2._includedOnlyMeshesIds.length > 0) {
                for (var includedOnlyIndex = 0; includedOnlyIndex < light_2._includedOnlyMeshesIds.length; includedOnlyIndex++) {
                    var includedOnlyMesh = scene.getMeshByID(light_2._includedOnlyMeshesIds[includedOnlyIndex]);
                    if (includedOnlyMesh) {
                        light_2.includedOnlyMeshes.push(includedOnlyMesh);
                    }
                }
                light_2._includedOnlyMeshesIds = [];
            }
        }
        _abstractScene__WEBPACK_IMPORTED_MODULE_15__["AbstractScene"].Parse(parsedData, scene, container, rootUrl);
        // Actions (scene) Done last as it can access other objects.
        for (index = 0, cache = scene.meshes.length; index < cache; index++) {
            var mesh = scene.meshes[index];
            if (mesh._waitingData.actions) {
                _Actions_actionManager__WEBPACK_IMPORTED_MODULE_17__["ActionManager"].Parse(mesh._waitingData.actions, mesh, scene);
                mesh._waitingData.actions = null;
            }
        }
        if (parsedData.actions !== undefined && parsedData.actions !== null) {
            _Actions_actionManager__WEBPACK_IMPORTED_MODULE_17__["ActionManager"].Parse(parsedData.actions, null, scene);
        }
        if (!addToScene) {
            container.removeAllFromScene();
        }
    }
    catch (err) {
        var msg = logOperation("loadAssets", parsedData ? parsedData.producer : "Unknown") + log;
        if (onError) {
            onError(msg, err);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Log(msg);
            throw err;
        }
    }
    finally {
        if (log !== null && _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel !== _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].NO_LOGGING) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Log(logOperation("loadAssets", parsedData ? parsedData.producer : "Unknown") + (_Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel !== _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].MINIMAL_LOGGING ? log : ""));
        }
    }
    return container;
};
_Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].RegisterPlugin({
    name: "babylon.js",
    extensions: ".babylon",
    canDirectLoad: function (data) {
        if (data.indexOf("babylon") !== -1) { // We consider that the producer string is filled
            return true;
        }
        return false;
    },
    importMesh: function (meshesNames, scene, data, rootUrl, meshes, particleSystems, skeletons, onError) {
        // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details
        // when SceneLoader.debugLogging = true (default), or exception encountered.
        // Everything stored in var log instead of writing separate lines to support only writing in exception,
        // and avoid problems with multiple concurrent .babylon loads.
        var log = "importMesh has failed JSON parse";
        try {
            var parsedData = JSON.parse(data);
            log = "";
            var fullDetails = _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel === _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].DETAILED_LOGGING;
            if (!meshesNames) {
                meshesNames = null;
            }
            else if (!Array.isArray(meshesNames)) {
                meshesNames = [meshesNames];
            }
            var hierarchyIds = new Array();
            if (parsedData.meshes !== undefined && parsedData.meshes !== null) {
                var loadedSkeletonsIds = [];
                var loadedMaterialsIds = [];
                var index;
                var cache;
                for (index = 0, cache = parsedData.meshes.length; index < cache; index++) {
                    var parsedMesh = parsedData.meshes[index];
                    if (meshesNames === null || isDescendantOf(parsedMesh, meshesNames, hierarchyIds)) {
                        if (meshesNames !== null) {
                            // Remove found mesh name from list.
                            delete meshesNames[meshesNames.indexOf(parsedMesh.name)];
                        }
                        //Geometry?
                        if (parsedMesh.geometryId !== undefined && parsedMesh.geometryId !== null) {
                            //does the file contain geometries?
                            if (parsedData.geometries !== undefined && parsedData.geometries !== null) {
                                //find the correct geometry and add it to the scene
                                var found = false;
                                ["boxes", "spheres", "cylinders", "toruses", "grounds", "planes", "torusKnots", "vertexData"].forEach(function (geometryType) {
                                    if (found === true || !parsedData.geometries[geometryType] || !(Array.isArray(parsedData.geometries[geometryType]))) {
                                        return;
                                    }
                                    else {
                                        parsedData.geometries[geometryType].forEach(function (parsedGeometryData) {
                                            if (parsedGeometryData.id === parsedMesh.geometryId) {
                                                switch (geometryType) {
                                                    case "vertexData":
                                                        _Meshes_geometry__WEBPACK_IMPORTED_MODULE_5__["Geometry"].Parse(parsedGeometryData, scene, rootUrl);
                                                        break;
                                                }
                                                found = true;
                                            }
                                        });
                                    }
                                });
                                if (found === false) {
                                    _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Geometry not found for mesh " + parsedMesh.id);
                                }
                            }
                        }
                        // Material ?
                        if (parsedMesh.materialId) {
                            var materialFound = (loadedMaterialsIds.indexOf(parsedMesh.materialId) !== -1);
                            if (materialFound === false && parsedData.multiMaterials !== undefined && parsedData.multiMaterials !== null) {
                                for (var multimatIndex = 0, multimatCache = parsedData.multiMaterials.length; multimatIndex < multimatCache; multimatIndex++) {
                                    var parsedMultiMaterial = parsedData.multiMaterials[multimatIndex];
                                    if (parsedMultiMaterial.id === parsedMesh.materialId) {
                                        for (var matIndex = 0, matCache = parsedMultiMaterial.materials.length; matIndex < matCache; matIndex++) {
                                            var subMatId = parsedMultiMaterial.materials[matIndex];
                                            loadedMaterialsIds.push(subMatId);
                                            var mat = parseMaterialById(subMatId, parsedData, scene, rootUrl);
                                            if (mat) {
                                                log += "\n\tMaterial " + mat.toString(fullDetails);
                                            }
                                        }
                                        loadedMaterialsIds.push(parsedMultiMaterial.id);
                                        var mmat = _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_8__["MultiMaterial"].ParseMultiMaterial(parsedMultiMaterial, scene);
                                        if (mmat) {
                                            materialFound = true;
                                            log += "\n\tMulti-Material " + mmat.toString(fullDetails);
                                        }
                                        break;
                                    }
                                }
                            }
                            if (materialFound === false) {
                                loadedMaterialsIds.push(parsedMesh.materialId);
                                var mat = parseMaterialById(parsedMesh.materialId, parsedData, scene, rootUrl);
                                if (!mat) {
                                    _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Material not found for mesh " + parsedMesh.id);
                                }
                                else {
                                    log += "\n\tMaterial " + mat.toString(fullDetails);
                                }
                            }
                        }
                        // Skeleton ?
                        if (parsedMesh.skeletonId > -1 && parsedData.skeletons !== undefined && parsedData.skeletons !== null) {
                            var skeletonAlreadyLoaded = (loadedSkeletonsIds.indexOf(parsedMesh.skeletonId) > -1);
                            if (skeletonAlreadyLoaded === false) {
                                for (var skeletonIndex = 0, skeletonCache = parsedData.skeletons.length; skeletonIndex < skeletonCache; skeletonIndex++) {
                                    var parsedSkeleton = parsedData.skeletons[skeletonIndex];
                                    if (parsedSkeleton.id === parsedMesh.skeletonId) {
                                        var skeleton = _Bones_skeleton__WEBPACK_IMPORTED_MODULE_18__["Skeleton"].Parse(parsedSkeleton, scene);
                                        skeletons.push(skeleton);
                                        loadedSkeletonsIds.push(parsedSkeleton.id);
                                        log += "\n\tSkeleton " + skeleton.toString(fullDetails);
                                    }
                                }
                            }
                        }
                        // Morph targets ?
                        if (parsedData.morphTargetManagers !== undefined && parsedData.morphTargetManagers !== null) {
                            for (var _i = 0, _a = parsedData.morphTargetManagers; _i < _a.length; _i++) {
                                var managerData = _a[_i];
                                _Morph_morphTargetManager__WEBPACK_IMPORTED_MODULE_19__["MorphTargetManager"].Parse(managerData, scene);
                            }
                        }
                        var mesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"].Parse(parsedMesh, scene, rootUrl);
                        meshes.push(mesh);
                        log += "\n\tMesh " + mesh.toString(fullDetails);
                    }
                }
                // Connecting parents and lods
                var currentMesh;
                for (index = 0, cache = scene.meshes.length; index < cache; index++) {
                    currentMesh = scene.meshes[index];
                    if (currentMesh._waitingParentId) {
                        currentMesh.parent = scene.getLastEntryByID(currentMesh._waitingParentId);
                        currentMesh._waitingParentId = null;
                    }
                    if (currentMesh._waitingData.lods) {
                        loadDetailLevels(scene, currentMesh);
                    }
                }
                // link skeleton transform nodes
                for (index = 0, cache = scene.skeletons.length; index < cache; index++) {
                    var skeleton = scene.skeletons[index];
                    if (skeleton._hasWaitingData) {
                        if (skeleton.bones != null) {
                            skeleton.bones.forEach(function (bone) {
                                if (bone._waitingTransformNodeId) {
                                    var linkTransformNode = scene.getLastEntryByID(bone._waitingTransformNodeId);
                                    if (linkTransformNode) {
                                        bone.linkTransformNode(linkTransformNode);
                                    }
                                    bone._waitingTransformNodeId = null;
                                }
                            });
                        }
                        skeleton._hasWaitingData = null;
                    }
                }
                // freeze and compute world matrix application
                for (index = 0, cache = scene.meshes.length; index < cache; index++) {
                    currentMesh = scene.meshes[index];
                    if (currentMesh._waitingData.freezeWorldMatrix) {
                        currentMesh.freezeWorldMatrix();
                        currentMesh._waitingData.freezeWorldMatrix = null;
                    }
                    else {
                        currentMesh.computeWorldMatrix(true);
                    }
                }
            }
            // Particles
            if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {
                var parser = _abstractScene__WEBPACK_IMPORTED_MODULE_15__["AbstractScene"].GetIndividualParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_13__["SceneComponentConstants"].NAME_PARTICLESYSTEM);
                if (parser) {
                    for (index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {
                        var parsedParticleSystem = parsedData.particleSystems[index];
                        if (hierarchyIds.indexOf(parsedParticleSystem.emitterId) !== -1) {
                            particleSystems.push(parser(parsedParticleSystem, scene, rootUrl));
                        }
                    }
                }
            }
            return true;
        }
        catch (err) {
            var msg = logOperation("importMesh", parsedData ? parsedData.producer : "Unknown") + log;
            if (onError) {
                onError(msg, err);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Log(msg);
                throw err;
            }
        }
        finally {
            if (log !== null && _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel !== _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].NO_LOGGING) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Log(logOperation("importMesh", parsedData ? parsedData.producer : "Unknown") + (_Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel !== _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].MINIMAL_LOGGING ? log : ""));
            }
        }
        return false;
    },
    load: function (scene, data, rootUrl, onError) {
        // Entire method running in try block, so ALWAYS logs as far as it got, only actually writes details
        // when SceneLoader.debugLogging = true (default), or exception encountered.
        // Everything stored in var log instead of writing separate lines to support only writing in exception,
        // and avoid problems with multiple concurrent .babylon loads.
        var log = "importScene has failed JSON parse";
        try {
            var parsedData = JSON.parse(data);
            log = "";
            // Scene
            if (parsedData.useDelayedTextureLoading !== undefined && parsedData.useDelayedTextureLoading !== null) {
                scene.useDelayedTextureLoading = parsedData.useDelayedTextureLoading && !_Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].ForceFullSceneLoadingForIncremental;
            }
            if (parsedData.autoClear !== undefined && parsedData.autoClear !== null) {
                scene.autoClear = parsedData.autoClear;
            }
            if (parsedData.clearColor !== undefined && parsedData.clearColor !== null) {
                scene.clearColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color4"].FromArray(parsedData.clearColor);
            }
            if (parsedData.ambientColor !== undefined && parsedData.ambientColor !== null) {
                scene.ambientColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].FromArray(parsedData.ambientColor);
            }
            if (parsedData.gravity !== undefined && parsedData.gravity !== null) {
                scene.gravity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].FromArray(parsedData.gravity);
            }
            // Fog
            if (parsedData.fogMode && parsedData.fogMode !== 0) {
                scene.fogMode = parsedData.fogMode;
                scene.fogColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].FromArray(parsedData.fogColor);
                scene.fogStart = parsedData.fogStart;
                scene.fogEnd = parsedData.fogEnd;
                scene.fogDensity = parsedData.fogDensity;
                log += "\tFog mode for scene:  ";
                switch (scene.fogMode) {
                    // getters not compiling, so using hardcoded
                    case 1:
                        log += "exp\n";
                        break;
                    case 2:
                        log += "exp2\n";
                        break;
                    case 3:
                        log += "linear\n";
                        break;
                }
            }
            //Physics
            if (parsedData.physicsEnabled) {
                var physicsPlugin;
                if (parsedData.physicsEngine === "cannon") {
                    physicsPlugin = new _Physics_Plugins_cannonJSPlugin__WEBPACK_IMPORTED_MODULE_20__["CannonJSPlugin"]();
                }
                else if (parsedData.physicsEngine === "oimo") {
                    physicsPlugin = new _Physics_Plugins_oimoJSPlugin__WEBPACK_IMPORTED_MODULE_21__["OimoJSPlugin"]();
                }
                else if (parsedData.physicsEngine === "ammo") {
                    physicsPlugin = new _Physics_Plugins_ammoJSPlugin__WEBPACK_IMPORTED_MODULE_22__["AmmoJSPlugin"]();
                }
                log = "\tPhysics engine " + (parsedData.physicsEngine ? parsedData.physicsEngine : "oimo") + " enabled\n";
                //else - default engine, which is currently oimo
                var physicsGravity = parsedData.physicsGravity ? _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].FromArray(parsedData.physicsGravity) : null;
                scene.enablePhysics(physicsGravity, physicsPlugin);
            }
            // Metadata
            if (parsedData.metadata !== undefined && parsedData.metadata !== null) {
                scene.metadata = parsedData.metadata;
            }
            //collisions, if defined. otherwise, default is true
            if (parsedData.collisionsEnabled !== undefined && parsedData.collisionsEnabled !== null) {
                scene.collisionsEnabled = parsedData.collisionsEnabled;
            }
            var container = loadAssetContainer(scene, data, rootUrl, onError, true);
            if (!container) {
                return false;
            }
            if (parsedData.autoAnimate) {
                scene.beginAnimation(scene, parsedData.autoAnimateFrom, parsedData.autoAnimateTo, parsedData.autoAnimateLoop, parsedData.autoAnimateSpeed || 1.0);
            }
            if (parsedData.activeCameraID !== undefined && parsedData.activeCameraID !== null) {
                scene.setActiveCameraByID(parsedData.activeCameraID);
            }
            // Environment texture
            if (parsedData.environmentTexture !== undefined && parsedData.environmentTexture !== null) {
                // PBR needed for both HDR texture (gamma space) & a sky box
                var isPBR = parsedData.isPBR !== undefined ? parsedData.isPBR : true;
                if (parsedData.environmentTextureType && parsedData.environmentTextureType === "BABYLON.HDRCubeTexture") {
                    var hdrSize = (parsedData.environmentTextureSize) ? parsedData.environmentTextureSize : 128;
                    var hdrTexture = new _Materials_Textures_hdrCubeTexture__WEBPACK_IMPORTED_MODULE_10__["HDRCubeTexture"](rootUrl + parsedData.environmentTexture, scene, hdrSize, true, !isPBR);
                    if (parsedData.environmentTextureRotationY) {
                        hdrTexture.rotationY = parsedData.environmentTextureRotationY;
                    }
                    scene.environmentTexture = hdrTexture;
                }
                else {
                    if (_Misc_stringTools__WEBPACK_IMPORTED_MODULE_26__["StringTools"].EndsWith(parsedData.environmentTexture, ".env")) {
                        var compressedTexture = new _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__["CubeTexture"](rootUrl + parsedData.environmentTexture, scene);
                        if (parsedData.environmentTextureRotationY) {
                            compressedTexture.rotationY = parsedData.environmentTextureRotationY;
                        }
                        scene.environmentTexture = compressedTexture;
                    }
                    else {
                        var cubeTexture = _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_9__["CubeTexture"].CreateFromPrefilteredData(rootUrl + parsedData.environmentTexture, scene);
                        if (parsedData.environmentTextureRotationY) {
                            cubeTexture.rotationY = parsedData.environmentTextureRotationY;
                        }
                        scene.environmentTexture = cubeTexture;
                    }
                }
                if (parsedData.createDefaultSkybox === true) {
                    var skyboxScale = (scene.activeCamera !== undefined && scene.activeCamera !== null) ? (scene.activeCamera.maxZ - scene.activeCamera.minZ) / 2 : 1000;
                    var skyboxBlurLevel = parsedData.skyboxBlurLevel || 0;
                    scene.createDefaultSkybox(scene.environmentTexture, isPBR, skyboxScale, skyboxBlurLevel);
                }
            }
            // Finish
            return true;
        }
        catch (err) {
            var msg = logOperation("importScene", parsedData ? parsedData.producer : "Unknown") + log;
            if (onError) {
                onError(msg, err);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Log(msg);
                throw err;
            }
        }
        finally {
            if (log !== null && _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel !== _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].NO_LOGGING) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Log(logOperation("importScene", parsedData ? parsedData.producer : "Unknown") + (_Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].loggingLevel !== _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_14__["SceneLoader"].MINIMAL_LOGGING ? log : ""));
            }
        }
        return false;
    },
    loadAssetContainer: function (scene, data, rootUrl, onError) {
        var container = loadAssetContainer(scene, data, rootUrl, onError);
        return container;
    }
});


/***/ }),

/***/ "./Loading/Plugins/index.ts":
/*!**********************************!*\
  !*** ./Loading/Plugins/index.ts ***!
  \**********************************/
/*! exports provided: _BabylonLoaderRegistered */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _babylonFileLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./babylonFileLoader */ "./Loading/Plugins/babylonFileLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BabylonLoaderRegistered", function() { return _babylonFileLoader__WEBPACK_IMPORTED_MODULE_0__["_BabylonLoaderRegistered"]; });




/***/ }),

/***/ "./Loading/index.ts":
/*!**************************!*\
  !*** ./Loading/index.ts ***!
  \**************************/
/*! exports provided: DefaultLoadingScreen, SceneLoaderProgressEvent, SceneLoader, SceneLoaderFlags, _BabylonLoaderRegistered */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _loadingScreen__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./loadingScreen */ "./Loading/loadingScreen.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultLoadingScreen", function() { return _loadingScreen__WEBPACK_IMPORTED_MODULE_0__["DefaultLoadingScreen"]; });

/* harmony import */ var _Plugins_index__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Plugins/index */ "./Loading/Plugins/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BabylonLoaderRegistered", function() { return _Plugins_index__WEBPACK_IMPORTED_MODULE_1__["_BabylonLoaderRegistered"]; });

/* harmony import */ var _sceneLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderProgressEvent", function() { return _sceneLoader__WEBPACK_IMPORTED_MODULE_2__["SceneLoaderProgressEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoader", function() { return _sceneLoader__WEBPACK_IMPORTED_MODULE_2__["SceneLoader"]; });

/* harmony import */ var _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sceneLoaderFlags */ "./Loading/sceneLoaderFlags.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderFlags", function() { return _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_3__["SceneLoaderFlags"]; });







/***/ }),

/***/ "./Loading/loadingScreen.ts":
/*!**********************************!*\
  !*** ./Loading/loadingScreen.ts ***!
  \**********************************/
/*! exports provided: DefaultLoadingScreen */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefaultLoadingScreen", function() { return DefaultLoadingScreen; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");

/**
 * Class used for the default loading screen
 * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
 */
var DefaultLoadingScreen = /** @class */ (function () {
    /**
     * Creates a new default loading screen
     * @param _renderingCanvas defines the canvas used to render the scene
     * @param _loadingText defines the default text to display
     * @param _loadingDivBackgroundColor defines the default background color
     */
    function DefaultLoadingScreen(_renderingCanvas, _loadingText, _loadingDivBackgroundColor) {
        var _this = this;
        if (_loadingText === void 0) { _loadingText = ""; }
        if (_loadingDivBackgroundColor === void 0) { _loadingDivBackgroundColor = "black"; }
        this._renderingCanvas = _renderingCanvas;
        this._loadingText = _loadingText;
        this._loadingDivBackgroundColor = _loadingDivBackgroundColor;
        // Resize
        this._resizeLoadingUI = function () {
            var canvasRect = _this._renderingCanvas.getBoundingClientRect();
            var canvasPositioning = window.getComputedStyle(_this._renderingCanvas).position;
            if (!_this._loadingDiv) {
                return;
            }
            _this._loadingDiv.style.position = (canvasPositioning === "fixed") ? "fixed" : "absolute";
            _this._loadingDiv.style.left = canvasRect.left + "px";
            _this._loadingDiv.style.top = canvasRect.top + "px";
            _this._loadingDiv.style.width = canvasRect.width + "px";
            _this._loadingDiv.style.height = canvasRect.height + "px";
        };
    }
    /**
     * Function called to display the loading screen
     */
    DefaultLoadingScreen.prototype.displayLoadingUI = function () {
        if (this._loadingDiv) {
            // Do not add a loading screen if there is already one
            return;
        }
        this._loadingDiv = document.createElement("div");
        this._loadingDiv.id = "babylonjsLoadingDiv";
        this._loadingDiv.style.opacity = "0";
        this._loadingDiv.style.transition = "opacity 1.5s ease";
        this._loadingDiv.style.pointerEvents = "none";
        // Loading text
        this._loadingTextDiv = document.createElement("div");
        this._loadingTextDiv.style.position = "absolute";
        this._loadingTextDiv.style.left = "0";
        this._loadingTextDiv.style.top = "50%";
        this._loadingTextDiv.style.marginTop = "80px";
        this._loadingTextDiv.style.width = "100%";
        this._loadingTextDiv.style.height = "20px";
        this._loadingTextDiv.style.fontFamily = "Arial";
        this._loadingTextDiv.style.fontSize = "14px";
        this._loadingTextDiv.style.color = "white";
        this._loadingTextDiv.style.textAlign = "center";
        this._loadingTextDiv.innerHTML = "Loading";
        this._loadingDiv.appendChild(this._loadingTextDiv);
        //set the predefined text
        this._loadingTextDiv.innerHTML = this._loadingText;
        // Generating keyframes
        var style = document.createElement('style');
        style.type = 'text/css';
        var keyFrames = "@-webkit-keyframes spin1 {                    0% { -webkit-transform: rotate(0deg);}\n                    100% { -webkit-transform: rotate(360deg);}\n                }                @keyframes spin1 {                    0% { transform: rotate(0deg);}\n                    100% { transform: rotate(360deg);}\n                }";
        style.innerHTML = keyFrames;
        document.getElementsByTagName('head')[0].appendChild(style);
        // Loading img
        var imgBack = new Image();
        if (!DefaultLoadingScreen.DefaultLogoUrl) {
            imgBack.src = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxODAuMTcgMjA4LjA0Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjt9LmNscy0ye2ZpbGw6I2UwNjg0Yjt9LmNscy0ze2ZpbGw6I2JiNDY0Yjt9LmNscy00e2ZpbGw6I2UwZGVkODt9LmNscy01e2ZpbGw6I2Q1ZDJjYTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPkJhYnlsb25Mb2dvPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iUGFnZV9FbGVtZW50cyIgZGF0YS1uYW1lPSJQYWdlIEVsZW1lbnRzIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik05MC4wOSwwLDAsNTJWMTU2bDkwLjA5LDUyLDkwLjA4LTUyVjUyWiIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSIxODAuMTcgNTIuMDEgMTUxLjk3IDM1LjczIDEyNC44NSA1MS4zOSAxNTMuMDUgNjcuNjcgMTgwLjE3IDUyLjAxIi8+PHBvbHlnb24gY2xhc3M9ImNscy0yIiBwb2ludHM9IjI3LjEyIDY3LjY3IDExNy4yMSAxNS42NiA5MC4wOCAwIDAgNTIuMDEgMjcuMTIgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iNjEuODkgMTIwLjMgOTAuMDggMTM2LjU4IDExOC4yOCAxMjAuMyA5MC4wOCAxMDQuMDIgNjEuODkgMTIwLjMiLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDE1My4wNSAxNDAuMzcgOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyAwIDUyLjAxIDAgMTU2LjAzIDkwLjA4IDIwOC4wNCAxODAuMTcgMTU2LjAzIDE4MC4xNyA1Mi4wMSAxNTMuMDUgNjcuNjciLz48cG9seWdvbiBjbGFzcz0iY2xzLTMiIHBvaW50cz0iOTAuMDggNzEuNDYgNjEuODkgODcuNzQgNjEuODkgMTIwLjMgOTAuMDggMTA0LjAyIDExOC4yOCAxMjAuMyAxMTguMjggODcuNzQgOTAuMDggNzEuNDYiLz48cG9seWdvbiBjbGFzcz0iY2xzLTQiIHBvaW50cz0iMTUzLjA1IDY3LjY3IDExOC4yOCA4Ny43NCAxMTguMjggMTIwLjMgOTAuMDggMTM2LjU4IDkwLjA4IDE3Ni43MiAxNTMuMDUgMTQwLjM3IDE1My4wNSA2Ny42NyIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtNSIgcG9pbnRzPSIyNy4xMiA2Ny42NyA2MS44OSA4Ny43NCA2MS44OSAxMjAuMyA5MC4wOCAxMzYuNTggOTAuMDggMTc2LjcyIDI3LjEyIDE0MC4zNyAyNy4xMiA2Ny42NyIvPjwvZz48L2c+PC9zdmc+";
        }
        else {
            imgBack.src = DefaultLoadingScreen.DefaultLogoUrl;
        }
        imgBack.style.position = "absolute";
        imgBack.style.left = "40%";
        imgBack.style.top = "40%";
        imgBack.style.width = "20%";
        imgBack.style.height = "20%";
        // Loading spinner
        var imgSpinner = new Image();
        if (!DefaultLoadingScreen.DefaultSpinnerUrl) {
            imgSpinner.src = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzOTIgMzkyIj48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2UwNjg0Yjt9LmNscy0ye2ZpbGw6bm9uZTt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlNwaW5uZXJJY29uPC90aXRsZT48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iU3Bpbm5lciI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNNDAuMjEsMTI2LjQzYzMuNy03LjMxLDcuNjctMTQuNDQsMTItMjEuMzJsMy4zNi01LjEsMy41Mi01YzEuMjMtMS42MywyLjQxLTMuMjksMy42NS00LjkxczIuNTMtMy4yMSwzLjgyLTQuNzlBMTg1LjIsMTg1LjIsMCwwLDEsODMuNCw2Ny40M2EyMDgsMjA4LDAsMCwxLDE5LTE1LjY2YzMuMzUtMi40MSw2Ljc0LTQuNzgsMTAuMjUtN3M3LjExLTQuMjgsMTAuNzUtNi4zMmM3LjI5LTQsMTQuNzMtOCwyMi41My0xMS40OSwzLjktMS43Miw3Ljg4LTMuMywxMi00LjY0YTEwNC4yMiwxMDQuMjIsMCwwLDEsMTIuNDQtMy4yMyw2Mi40NCw2Mi40NCwwLDAsMSwxMi43OC0xLjM5QTI1LjkyLDI1LjkyLDAsMCwxLDE5NiwyMS40NGE2LjU1LDYuNTUsMCwwLDEsMi4wNSw5LDYuNjYsNi42NiwwLDAsMS0xLjY0LDEuNzhsLS40MS4yOWEyMi4wNywyMi4wNywwLDAsMS01Ljc4LDMsMzAuNDIsMzAuNDIsMCwwLDEtNS42NywxLjYyLDM3LjgyLDM3LjgyLDAsMCwxLTUuNjkuNzFjLTEsMC0xLjkuMTgtMi44NS4yNmwtMi44NS4yNHEtNS43Mi41MS0xMS40OCwxLjFjLTMuODQuNC03LjcxLjgyLTExLjU4LDEuNGExMTIuMzQsMTEyLjM0LDAsMCwwLTIyLjk0LDUuNjFjLTMuNzIsMS4zNS03LjM0LDMtMTAuOTQsNC42NHMtNy4xNCwzLjUxLTEwLjYsNS41MUExNTEuNiwxNTEuNiwwLDAsMCw2OC41Niw4N0M2Ny4yMyw4OC40OCw2Niw5MCw2NC42NCw5MS41NnMtMi41MSwzLjE1LTMuNzUsNC43M2wtMy41NCw0LjljLTEuMTMsMS42Ni0yLjIzLDMuMzUtMy4zMyw1YTEyNywxMjcsMCwwLDAtMTAuOTMsMjEuNDksMS41OCwxLjU4LDAsMSwxLTMtMS4xNVM0MC4xOSwxMjYuNDcsNDAuMjEsMTI2LjQzWiIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgd2lkdGg9IjM5MiIgaGVpZ2h0PSIzOTIiLz48L2c+PC9nPjwvc3ZnPg==";
        }
        else {
            imgSpinner.src = DefaultLoadingScreen.DefaultSpinnerUrl;
        }
        imgSpinner.style.position = "absolute";
        imgSpinner.style.left = "30%";
        imgSpinner.style.top = "30%";
        imgSpinner.style.width = "40%";
        imgSpinner.style.height = "40%";
        imgSpinner.style.animation = "spin1 0.75s infinite linear";
        imgSpinner.style.webkitAnimation = "spin1 0.75s infinite linear";
        imgSpinner.style.transformOrigin = "50% 50%";
        imgSpinner.style.webkitTransformOrigin = "50% 50%";
        this._loadingDiv.appendChild(imgBack);
        this._loadingDiv.appendChild(imgSpinner);
        this._resizeLoadingUI();
        window.addEventListener("resize", this._resizeLoadingUI);
        this._loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;
        document.body.appendChild(this._loadingDiv);
        this._loadingDiv.style.opacity = "1";
    };
    /**
     * Function called to hide the loading screen
     */
    DefaultLoadingScreen.prototype.hideLoadingUI = function () {
        var _this = this;
        if (!this._loadingDiv) {
            return;
        }
        var onTransitionEnd = function () {
            if (!_this._loadingDiv) {
                return;
            }
            if (_this._loadingDiv.parentElement) {
                _this._loadingDiv.parentElement.removeChild(_this._loadingDiv);
            }
            window.removeEventListener("resize", _this._resizeLoadingUI);
            _this._loadingDiv = null;
        };
        this._loadingDiv.style.opacity = "0";
        this._loadingDiv.addEventListener("transitionend", onTransitionEnd);
    };
    Object.defineProperty(DefaultLoadingScreen.prototype, "loadingUIText", {
        get: function () {
            return this._loadingText;
        },
        /**
         * Gets or sets the text to display while loading
         */
        set: function (text) {
            this._loadingText = text;
            if (this._loadingTextDiv) {
                this._loadingTextDiv.innerHTML = this._loadingText;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultLoadingScreen.prototype, "loadingUIBackgroundColor", {
        /**
         * Gets or sets the color to use for the background
         */
        get: function () {
            return this._loadingDivBackgroundColor;
        },
        set: function (color) {
            this._loadingDivBackgroundColor = color;
            if (!this._loadingDiv) {
                return;
            }
            this._loadingDiv.style.backgroundColor = this._loadingDivBackgroundColor;
        },
        enumerable: true,
        configurable: true
    });
    /** Gets or sets the logo url to use for the default loading screen */
    DefaultLoadingScreen.DefaultLogoUrl = "";
    /** Gets or sets the spinner url to use for the default loading screen */
    DefaultLoadingScreen.DefaultSpinnerUrl = "";
    return DefaultLoadingScreen;
}());

_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].DefaultLoadingScreenFactory = function (canvas) { return new DefaultLoadingScreen(canvas); };


/***/ }),

/***/ "./Loading/sceneLoader.ts":
/*!********************************!*\
  !*** ./Loading/sceneLoader.ts ***!
  \********************************/
/*! exports provided: SceneLoaderProgressEvent, SceneLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderProgressEvent", function() { return SceneLoaderProgressEvent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneLoader", function() { return SceneLoader; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_filesInputStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/filesInputStore */ "./Misc/filesInputStore.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sceneLoaderFlags */ "./Loading/sceneLoaderFlags.ts");









/**
 * Class used to represent data loading progression
 */
var SceneLoaderProgressEvent = /** @class */ (function () {
    /**
     * Create a new progress event
     * @param lengthComputable defines if data length to load can be evaluated
     * @param loaded defines the loaded data length
     * @param total defines the data length to load
     */
    function SceneLoaderProgressEvent(
    /** defines if data length to load can be evaluated */
    lengthComputable,
    /** defines the loaded data length */
    loaded,
    /** defines the data length to load */
    total) {
        this.lengthComputable = lengthComputable;
        this.loaded = loaded;
        this.total = total;
    }
    /**
     * Creates a new SceneLoaderProgressEvent from a ProgressEvent
     * @param event defines the source event
     * @returns a new SceneLoaderProgressEvent
     */
    SceneLoaderProgressEvent.FromProgressEvent = function (event) {
        return new SceneLoaderProgressEvent(event.lengthComputable, event.loaded, event.total);
    };
    return SceneLoaderProgressEvent;
}());

/**
 * Class used to load scene from various file formats using registered plugins
 * @see http://doc.babylonjs.com/how_to/load_from_any_file_type
 */
var SceneLoader = /** @class */ (function () {
    function SceneLoader() {
    }
    Object.defineProperty(SceneLoader, "ForceFullSceneLoadingForIncremental", {
        /**
         * Gets or sets a boolean indicating if entire scene must be loaded even if scene contains incremental data
         */
        get: function () {
            return _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].ForceFullSceneLoadingForIncremental;
        },
        set: function (value) {
            _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].ForceFullSceneLoadingForIncremental = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneLoader, "ShowLoadingScreen", {
        /**
         * Gets or sets a boolean indicating if loading screen must be displayed while loading a scene
         */
        get: function () {
            return _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].ShowLoadingScreen;
        },
        set: function (value) {
            _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].ShowLoadingScreen = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneLoader, "loggingLevel", {
        /**
         * Defines the current logging level (while loading the scene)
         * @ignorenaming
         */
        get: function () {
            return _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].loggingLevel;
        },
        set: function (value) {
            _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].loggingLevel = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneLoader, "CleanBoneMatrixWeights", {
        /**
         * Gets or set a boolean indicating if matrix weights must be cleaned upon loading
         */
        get: function () {
            return _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].CleanBoneMatrixWeights;
        },
        set: function (value) {
            _sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_8__["SceneLoaderFlags"].CleanBoneMatrixWeights = value;
        },
        enumerable: true,
        configurable: true
    });
    SceneLoader._getDefaultPlugin = function () {
        return SceneLoader._registeredPlugins[".babylon"];
    };
    SceneLoader._getPluginForExtension = function (extension) {
        var registeredPlugin = SceneLoader._registeredPlugins[extension];
        if (registeredPlugin) {
            return registeredPlugin;
        }
        _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Warn("Unable to find a plugin to load " + extension + " files. Trying to use .babylon default plugin. To load from a specific filetype (eg. gltf) see: http://doc.babylonjs.com/how_to/load_from_any_file_type");
        return SceneLoader._getDefaultPlugin();
    };
    SceneLoader._getPluginForDirectLoad = function (data) {
        for (var extension in SceneLoader._registeredPlugins) {
            var plugin = SceneLoader._registeredPlugins[extension].plugin;
            if (plugin.canDirectLoad && plugin.canDirectLoad(data)) {
                return SceneLoader._registeredPlugins[extension];
            }
        }
        return SceneLoader._getDefaultPlugin();
    };
    SceneLoader._getPluginForFilename = function (sceneFilename) {
        var queryStringPosition = sceneFilename.indexOf("?");
        if (queryStringPosition !== -1) {
            sceneFilename = sceneFilename.substring(0, queryStringPosition);
        }
        var dotPosition = sceneFilename.lastIndexOf(".");
        var extension = sceneFilename.substring(dotPosition, sceneFilename.length).toLowerCase();
        return SceneLoader._getPluginForExtension(extension);
    };
    // use babylon file loader directly if sceneFilename is prefixed with "data:"
    SceneLoader._getDirectLoad = function (sceneFilename) {
        if (sceneFilename.substr(0, 5) === "data:") {
            return sceneFilename.substr(5);
        }
        return null;
    };
    SceneLoader._loadData = function (fileInfo, scene, onSuccess, onProgress, onError, onDispose, pluginExtension) {
        var directLoad = SceneLoader._getDirectLoad(fileInfo.name);
        var registeredPlugin = pluginExtension ? SceneLoader._getPluginForExtension(pluginExtension) : (directLoad ? SceneLoader._getPluginForDirectLoad(fileInfo.name) : SceneLoader._getPluginForFilename(fileInfo.name));
        var plugin;
        if (registeredPlugin.plugin.createPlugin) {
            plugin = registeredPlugin.plugin.createPlugin();
        }
        else {
            plugin = registeredPlugin.plugin;
        }
        if (!plugin) {
            throw "The loader plugin corresponding to the file type you are trying to load has not been found. If using es6, please import the plugin you wish to use before.";
        }
        var useArrayBuffer = registeredPlugin.isBinary;
        var offlineProvider;
        SceneLoader.OnPluginActivatedObservable.notifyObservers(plugin);
        var dataCallback = function (data, responseURL) {
            if (scene.isDisposed) {
                onError("Scene has been disposed");
                return;
            }
            scene.offlineProvider = offlineProvider;
            onSuccess(plugin, data, responseURL);
        };
        var request = null;
        var pluginDisposed = false;
        var onDisposeObservable = plugin.onDisposeObservable;
        if (onDisposeObservable) {
            onDisposeObservable.add(function () {
                pluginDisposed = true;
                if (request) {
                    request.abort();
                    request = null;
                }
                onDispose();
            });
        }
        var manifestChecked = function () {
            if (pluginDisposed) {
                return;
            }
            request = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].LoadFile(fileInfo.url, dataCallback, onProgress ? function (event) {
                onProgress(SceneLoaderProgressEvent.FromProgressEvent(event));
            } : undefined, offlineProvider, useArrayBuffer, function (request, exception) {
                onError("Failed to load scene." + (exception ? " " + exception.message : ""), exception);
            });
        };
        if (directLoad) {
            dataCallback(directLoad);
            return plugin;
        }
        var file = fileInfo.file || _Misc_filesInputStore__WEBPACK_IMPORTED_MODULE_2__["FilesInputStore"].FilesToLoad[fileInfo.name.toLowerCase()];
        if (fileInfo.rootUrl.indexOf("file:") === -1 || (fileInfo.rootUrl.indexOf("file:") !== -1 && !file)) {
            var engine = scene.getEngine();
            var canUseOfflineSupport = engine.enableOfflineSupport;
            if (canUseOfflineSupport) {
                // Also check for exceptions
                var exceptionFound = false;
                for (var _i = 0, _a = scene.disableOfflineSupportExceptionRules; _i < _a.length; _i++) {
                    var regex = _a[_i];
                    if (regex.test(fileInfo.url)) {
                        exceptionFound = true;
                        break;
                    }
                }
                canUseOfflineSupport = !exceptionFound;
            }
            if (canUseOfflineSupport && _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].OfflineProviderFactory) {
                // Checking if a manifest file has been set for this scene and if offline mode has been requested
                offlineProvider = _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].OfflineProviderFactory(fileInfo.url, manifestChecked, engine.disableManifestCheck);
            }
            else {
                manifestChecked();
            }
        }
        // Loading file from disk via input file or drag'n'drop
        else {
            if (file) {
                request = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].ReadFile(file, dataCallback, onProgress, useArrayBuffer);
            }
            else {
                onError("Unable to find file named " + fileInfo.name);
            }
        }
        return plugin;
    };
    SceneLoader._getFileInfo = function (rootUrl, sceneFilename) {
        var url;
        var name;
        var file = null;
        if (!sceneFilename) {
            url = rootUrl;
            name = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFilename(rootUrl);
            rootUrl = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFolderPath(rootUrl);
        }
        else if (sceneFilename.name) {
            var sceneFile = sceneFilename;
            url = rootUrl + sceneFile.name;
            name = sceneFile.name;
            file = sceneFile;
        }
        else {
            var filename = sceneFilename;
            if (filename.substr(0, 1) === "/") {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].Error("Wrong sceneFilename parameter");
                return null;
            }
            url = rootUrl + filename;
            name = filename;
        }
        return {
            url: url,
            rootUrl: rootUrl,
            name: name,
            file: file
        };
    };
    // Public functions
    /**
     * Gets a plugin that can load the given extension
     * @param extension defines the extension to load
     * @returns a plugin or null if none works
     */
    SceneLoader.GetPluginForExtension = function (extension) {
        return SceneLoader._getPluginForExtension(extension).plugin;
    };
    /**
     * Gets a boolean indicating that the given extension can be loaded
     * @param extension defines the extension to load
     * @returns true if the extension is supported
     */
    SceneLoader.IsPluginForExtensionAvailable = function (extension) {
        return !!SceneLoader._registeredPlugins[extension];
    };
    /**
     * Adds a new plugin to the list of registered plugins
     * @param plugin defines the plugin to add
     */
    SceneLoader.RegisterPlugin = function (plugin) {
        if (typeof plugin.extensions === "string") {
            var extension = plugin.extensions;
            SceneLoader._registeredPlugins[extension.toLowerCase()] = {
                plugin: plugin,
                isBinary: false
            };
        }
        else {
            var extensions = plugin.extensions;
            Object.keys(extensions).forEach(function (extension) {
                SceneLoader._registeredPlugins[extension.toLowerCase()] = {
                    plugin: plugin,
                    isBinary: extensions[extension].isBinary
                };
            });
        }
    };
    /**
     * Import meshes into a scene
     * @param meshNames an array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param scene the instance of BABYLON.Scene to append to
     * @param onSuccess a callback with a list of imported meshes, particleSystems, and skeletons when import succeeds
     * @param onProgress a callback with a progress event for each file being loaded
     * @param onError a callback with the scene, a message, and possibly an exception when import fails
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded plugin
     */
    SceneLoader.ImportMesh = function (meshNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene; }
        if (onSuccess === void 0) { onSuccess = null; }
        if (onProgress === void 0) { onProgress = null; }
        if (onError === void 0) { onError = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        if (!scene) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Error("No scene available to import mesh to");
            return null;
        }
        var fileInfo = SceneLoader._getFileInfo(rootUrl, sceneFilename);
        if (!fileInfo) {
            return null;
        }
        var loadingToken = {};
        scene._addPendingData(loadingToken);
        var disposeHandler = function () {
            scene._removePendingData(loadingToken);
        };
        var errorHandler = function (message, exception) {
            var errorMessage = "Unable to import meshes from " + fileInfo.url + ": " + message;
            if (onError) {
                onError(scene, errorMessage, exception);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Error(errorMessage);
                // should the exception be thrown?
            }
            disposeHandler();
        };
        var progressHandler = onProgress ? function (event) {
            try {
                onProgress(event);
            }
            catch (e) {
                errorHandler("Error in onProgress callback: " + e, e);
            }
        } : undefined;
        var successHandler = function (meshes, particleSystems, skeletons, animationGroups) {
            scene.importedMeshesFiles.push(fileInfo.url);
            if (onSuccess) {
                try {
                    onSuccess(meshes, particleSystems, skeletons, animationGroups);
                }
                catch (e) {
                    errorHandler("Error in onSuccess callback: " + e, e);
                }
            }
            scene._removePendingData(loadingToken);
        };
        return SceneLoader._loadData(fileInfo, scene, function (plugin, data, responseURL) {
            if (plugin.rewriteRootURL) {
                fileInfo.rootUrl = plugin.rewriteRootURL(fileInfo.rootUrl, responseURL);
            }
            if (plugin.importMesh) {
                var syncedPlugin = plugin;
                var meshes = new Array();
                var particleSystems = new Array();
                var skeletons = new Array();
                if (!syncedPlugin.importMesh(meshNames, scene, data, fileInfo.rootUrl, meshes, particleSystems, skeletons, errorHandler)) {
                    return;
                }
                scene.loadingPluginName = plugin.name;
                successHandler(meshes, particleSystems, skeletons, []);
            }
            else {
                var asyncedPlugin = plugin;
                asyncedPlugin.importMeshAsync(meshNames, scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name).then(function (result) {
                    scene.loadingPluginName = plugin.name;
                    successHandler(result.meshes, result.particleSystems, result.skeletons, result.animationGroups);
                }).catch(function (error) {
                    errorHandler(error.message, error);
                });
            }
        }, progressHandler, errorHandler, disposeHandler, pluginExtension);
    };
    /**
     * Import meshes into a scene
     * @param meshNames an array of mesh names, a single mesh name, or empty string for all meshes that filter what meshes are imported
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param scene the instance of BABYLON.Scene to append to
     * @param onProgress a callback with a progress event for each file being loaded
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded list of imported meshes, particle systems, skeletons, and animation groups
     */
    SceneLoader.ImportMeshAsync = function (meshNames, rootUrl, sceneFilename, scene, onProgress, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene; }
        if (onProgress === void 0) { onProgress = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        return new Promise(function (resolve, reject) {
            SceneLoader.ImportMesh(meshNames, rootUrl, sceneFilename, scene, function (meshes, particleSystems, skeletons, animationGroups) {
                resolve({
                    meshes: meshes,
                    particleSystems: particleSystems,
                    skeletons: skeletons,
                    animationGroups: animationGroups
                });
            }, onProgress, function (scene, message, exception) {
                reject(exception || new Error(message));
            }, pluginExtension);
        });
    };
    /**
     * Load a scene
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param engine is the instance of BABYLON.Engine to use to create the scene
     * @param onSuccess a callback with the scene when import succeeds
     * @param onProgress a callback with a progress event for each file being loaded
     * @param onError a callback with the scene, a message, and possibly an exception when import fails
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded plugin
     */
    SceneLoader.Load = function (rootUrl, sceneFilename, engine, onSuccess, onProgress, onError, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (engine === void 0) { engine = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedEngine; }
        if (onSuccess === void 0) { onSuccess = null; }
        if (onProgress === void 0) { onProgress = null; }
        if (onError === void 0) { onError = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        if (!engine) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].Error("No engine available");
            return null;
        }
        return SceneLoader.Append(rootUrl, sceneFilename, new _scene__WEBPACK_IMPORTED_MODULE_3__["Scene"](engine), onSuccess, onProgress, onError, pluginExtension);
    };
    /**
     * Load a scene
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param engine is the instance of BABYLON.Engine to use to create the scene
     * @param onProgress a callback with a progress event for each file being loaded
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded scene
     */
    SceneLoader.LoadAsync = function (rootUrl, sceneFilename, engine, onProgress, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (engine === void 0) { engine = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedEngine; }
        if (onProgress === void 0) { onProgress = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        return new Promise(function (resolve, reject) {
            SceneLoader.Load(rootUrl, sceneFilename, engine, function (scene) {
                resolve(scene);
            }, onProgress, function (scene, message, exception) {
                reject(exception || new Error(message));
            }, pluginExtension);
        });
    };
    /**
     * Append a scene
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param scene is the instance of BABYLON.Scene to append to
     * @param onSuccess a callback with the scene when import succeeds
     * @param onProgress a callback with a progress event for each file being loaded
     * @param onError a callback with the scene, a message, and possibly an exception when import fails
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded plugin
     */
    SceneLoader.Append = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene; }
        if (onSuccess === void 0) { onSuccess = null; }
        if (onProgress === void 0) { onProgress = null; }
        if (onError === void 0) { onError = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        if (!scene) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Error("No scene available to append to");
            return null;
        }
        var fileInfo = SceneLoader._getFileInfo(rootUrl, sceneFilename);
        if (!fileInfo) {
            return null;
        }
        if (SceneLoader.ShowLoadingScreen) {
            scene.getEngine().displayLoadingUI();
        }
        var loadingToken = {};
        scene._addPendingData(loadingToken);
        var disposeHandler = function () {
            scene._removePendingData(loadingToken);
            scene.getEngine().hideLoadingUI();
        };
        var errorHandler = function (message, exception) {
            var errorMessage = "Unable to load from " + fileInfo.url + (message ? ": " + message : "");
            if (onError) {
                onError(scene, errorMessage, exception);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Error(errorMessage);
                // should the exception be thrown?
            }
            disposeHandler();
        };
        var progressHandler = onProgress ? function (event) {
            try {
                onProgress(event);
            }
            catch (e) {
                errorHandler("Error in onProgress callback", e);
            }
        } : undefined;
        var successHandler = function () {
            if (onSuccess) {
                try {
                    onSuccess(scene);
                }
                catch (e) {
                    errorHandler("Error in onSuccess callback", e);
                }
            }
            scene._removePendingData(loadingToken);
        };
        return SceneLoader._loadData(fileInfo, scene, function (plugin, data) {
            if (plugin.load) {
                var syncedPlugin = plugin;
                if (!syncedPlugin.load(scene, data, fileInfo.rootUrl, errorHandler)) {
                    return;
                }
                scene.loadingPluginName = plugin.name;
                successHandler();
            }
            else {
                var asyncedPlugin = plugin;
                asyncedPlugin.loadAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name).then(function () {
                    scene.loadingPluginName = plugin.name;
                    successHandler();
                }).catch(function (error) {
                    errorHandler(error.message, error);
                });
            }
            if (SceneLoader.ShowLoadingScreen) {
                scene.executeWhenReady(function () {
                    scene.getEngine().hideLoadingUI();
                });
            }
        }, progressHandler, errorHandler, disposeHandler, pluginExtension);
    };
    /**
     * Append a scene
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param scene is the instance of BABYLON.Scene to append to
     * @param onProgress a callback with a progress event for each file being loaded
     * @param pluginExtension the extension used to determine the plugin
     * @returns The given scene
     */
    SceneLoader.AppendAsync = function (rootUrl, sceneFilename, scene, onProgress, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene; }
        if (onProgress === void 0) { onProgress = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        return new Promise(function (resolve, reject) {
            SceneLoader.Append(rootUrl, sceneFilename, scene, function (scene) {
                resolve(scene);
            }, onProgress, function (scene, message, exception) {
                reject(exception || new Error(message));
            }, pluginExtension);
        });
    };
    /**
     * Load a scene into an asset container
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene or a File object (default: empty string)
     * @param scene is the instance of BABYLON.Scene to append to (default: last created scene)
     * @param onSuccess a callback with the scene when import succeeds
     * @param onProgress a callback with a progress event for each file being loaded
     * @param onError a callback with the scene, a message, and possibly an exception when import fails
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded plugin
     */
    SceneLoader.LoadAssetContainer = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene; }
        if (onSuccess === void 0) { onSuccess = null; }
        if (onProgress === void 0) { onProgress = null; }
        if (onError === void 0) { onError = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        if (!scene) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Error("No scene available to load asset container to");
            return null;
        }
        var fileInfo = SceneLoader._getFileInfo(rootUrl, sceneFilename);
        if (!fileInfo) {
            return null;
        }
        var loadingToken = {};
        scene._addPendingData(loadingToken);
        var disposeHandler = function () {
            scene._removePendingData(loadingToken);
        };
        var errorHandler = function (message, exception) {
            var errorMessage = "Unable to load assets from " + fileInfo.url + (message ? ": " + message : "");
            if (onError) {
                onError(scene, errorMessage, exception);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_6__["Logger"].Error(errorMessage);
                // should the exception be thrown?
            }
            disposeHandler();
        };
        var progressHandler = onProgress ? function (event) {
            try {
                onProgress(event);
            }
            catch (e) {
                errorHandler("Error in onProgress callback", e);
            }
        } : undefined;
        var successHandler = function (assets) {
            if (onSuccess) {
                try {
                    onSuccess(assets);
                }
                catch (e) {
                    errorHandler("Error in onSuccess callback", e);
                }
            }
            scene._removePendingData(loadingToken);
        };
        return SceneLoader._loadData(fileInfo, scene, function (plugin, data) {
            if (plugin.loadAssetContainer) {
                var syncedPlugin = plugin;
                var assetContainer = syncedPlugin.loadAssetContainer(scene, data, fileInfo.rootUrl, errorHandler);
                if (!assetContainer) {
                    return;
                }
                scene.loadingPluginName = plugin.name;
                successHandler(assetContainer);
            }
            else if (plugin.loadAssetContainerAsync) {
                var asyncedPlugin = plugin;
                asyncedPlugin.loadAssetContainerAsync(scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name).then(function (assetContainer) {
                    scene.loadingPluginName = plugin.name;
                    successHandler(assetContainer);
                }).catch(function (error) {
                    errorHandler(error.message, error);
                });
            }
            else {
                errorHandler("LoadAssetContainer is not supported by this plugin. Plugin did not provide a loadAssetContainer or loadAssetContainerAsync method.");
            }
            if (SceneLoader.ShowLoadingScreen) {
                scene.executeWhenReady(function () {
                    scene.getEngine().hideLoadingUI();
                });
            }
        }, progressHandler, errorHandler, disposeHandler, pluginExtension);
    };
    /**
     * Load a scene into an asset container
     * @param rootUrl a string that defines the root url for the scene and resources or the concatenation of rootURL and filename (e.g. http://example.com/test.glb)
     * @param sceneFilename a string that defines the name of the scene file or starts with "data:" following by the stringified version of the scene (default: empty string)
     * @param scene is the instance of Scene to append to
     * @param onProgress a callback with a progress event for each file being loaded
     * @param pluginExtension the extension used to determine the plugin
     * @returns The loaded asset container
     */
    SceneLoader.LoadAssetContainerAsync = function (rootUrl, sceneFilename, scene, onProgress, pluginExtension) {
        if (sceneFilename === void 0) { sceneFilename = ""; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene; }
        if (onProgress === void 0) { onProgress = null; }
        if (pluginExtension === void 0) { pluginExtension = null; }
        return new Promise(function (resolve, reject) {
            SceneLoader.LoadAssetContainer(rootUrl, sceneFilename, scene, function (assetContainer) {
                resolve(assetContainer);
            }, onProgress, function (scene, message, exception) {
                reject(exception || new Error(message));
            }, pluginExtension);
        });
    };
    /**
     * No logging while loading
     */
    SceneLoader.NO_LOGGING = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCENELOADER_NO_LOGGING;
    /**
     * Minimal logging while loading
     */
    SceneLoader.MINIMAL_LOGGING = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCENELOADER_MINIMAL_LOGGING;
    /**
     * Summary logging while loading
     */
    SceneLoader.SUMMARY_LOGGING = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCENELOADER_SUMMARY_LOGGING;
    /**
     * Detailled logging while loading
     */
    SceneLoader.DETAILED_LOGGING = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].SCENELOADER_DETAILED_LOGGING;
    // Members
    /**
     * Event raised when a plugin is used to load a scene
     */
    SceneLoader.OnPluginActivatedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
    SceneLoader._registeredPlugins = {};
    return SceneLoader;
}());



/***/ }),

/***/ "./Loading/sceneLoaderFlags.ts":
/*!*************************************!*\
  !*** ./Loading/sceneLoaderFlags.ts ***!
  \*************************************/
/*! exports provided: SceneLoaderFlags */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderFlags", function() { return SceneLoaderFlags; });
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");

/**
 * Class used to represent data loading progression
 */
var SceneLoaderFlags = /** @class */ (function () {
    function SceneLoaderFlags() {
    }
    Object.defineProperty(SceneLoaderFlags, "ForceFullSceneLoadingForIncremental", {
        /**
         * Gets or sets a boolean indicating if entire scene must be loaded even if scene contains incremental data
         */
        get: function () {
            return SceneLoaderFlags._ForceFullSceneLoadingForIncremental;
        },
        set: function (value) {
            SceneLoaderFlags._ForceFullSceneLoadingForIncremental = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneLoaderFlags, "ShowLoadingScreen", {
        /**
         * Gets or sets a boolean indicating if loading screen must be displayed while loading a scene
         */
        get: function () {
            return SceneLoaderFlags._ShowLoadingScreen;
        },
        set: function (value) {
            SceneLoaderFlags._ShowLoadingScreen = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneLoaderFlags, "loggingLevel", {
        /**
         * Defines the current logging level (while loading the scene)
         * @ignorenaming
         */
        get: function () {
            return SceneLoaderFlags._loggingLevel;
        },
        set: function (value) {
            SceneLoaderFlags._loggingLevel = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneLoaderFlags, "CleanBoneMatrixWeights", {
        /**
         * Gets or set a boolean indicating if matrix weights must be cleaned upon loading
         */
        get: function () {
            return SceneLoaderFlags._CleanBoneMatrixWeights;
        },
        set: function (value) {
            SceneLoaderFlags._CleanBoneMatrixWeights = value;
        },
        enumerable: true,
        configurable: true
    });
    // Flags
    SceneLoaderFlags._ForceFullSceneLoadingForIncremental = false;
    SceneLoaderFlags._ShowLoadingScreen = true;
    SceneLoaderFlags._CleanBoneMatrixWeights = false;
    SceneLoaderFlags._loggingLevel = _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].SCENELOADER_NO_LOGGING;
    return SceneLoaderFlags;
}());



/***/ }),

/***/ "./Materials/Background/backgroundMaterial.ts":
/*!****************************************************!*\
  !*** ./Materials/Background/backgroundMaterial.ts ***!
  \****************************************************/
/*! exports provided: BackgroundMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BackgroundMaterial", function() { return BackgroundMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_materialDefines__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Materials/materialDefines */ "./Materials/materialDefines.ts");
/* harmony import */ var _Materials_pushMaterial__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Materials/pushMaterial */ "./Materials/pushMaterial.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _materialFlags__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Shaders_background_fragment__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../Shaders/background.fragment */ "./Shaders/background.fragment.ts");
/* harmony import */ var _Shaders_background_vertex__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Shaders/background.vertex */ "./Shaders/background.vertex.ts");


















/**
 * Background material defines definition.
 * @hidden Mainly internal Use
 */
var BackgroundMaterialDefines = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BackgroundMaterialDefines, _super);
    /**
     * Constructor of the defines.
     */
    function BackgroundMaterialDefines() {
        var _this = _super.call(this) || this;
        /**
         * True if the diffuse texture is in use.
         */
        _this.DIFFUSE = false;
        /**
         * The direct UV channel to use.
         */
        _this.DIFFUSEDIRECTUV = 0;
        /**
         * True if the diffuse texture is in gamma space.
         */
        _this.GAMMADIFFUSE = false;
        /**
         * True if the diffuse texture has opacity in the alpha channel.
         */
        _this.DIFFUSEHASALPHA = false;
        /**
         * True if you want the material to fade to transparent at grazing angle.
         */
        _this.OPACITYFRESNEL = false;
        /**
         * True if an extra blur needs to be added in the reflection.
         */
        _this.REFLECTIONBLUR = false;
        /**
         * True if you want the material to fade to reflection at grazing angle.
         */
        _this.REFLECTIONFRESNEL = false;
        /**
         * True if you want the material to falloff as far as you move away from the scene center.
         */
        _this.REFLECTIONFALLOFF = false;
        /**
         * False if the current Webgl implementation does not support the texture lod extension.
         */
        _this.TEXTURELODSUPPORT = false;
        /**
         * True to ensure the data are premultiplied.
         */
        _this.PREMULTIPLYALPHA = false;
        /**
         * True if the texture contains cooked RGB values and not gray scaled multipliers.
         */
        _this.USERGBCOLOR = false;
        /**
         * True if highlight and shadow levels have been specified. It can help ensuring the main perceived color
         * stays aligned with the desired configuration.
         */
        _this.USEHIGHLIGHTANDSHADOWCOLORS = false;
        /**
         * True to add noise in order to reduce the banding effect.
         */
        _this.NOISE = false;
        /**
         * is the reflection texture in BGR color scheme?
         * Mainly used to solve a bug in ios10 video tag
         */
        _this.REFLECTIONBGR = false;
        _this.IMAGEPROCESSING = false;
        _this.VIGNETTE = false;
        _this.VIGNETTEBLENDMODEMULTIPLY = false;
        _this.VIGNETTEBLENDMODEOPAQUE = false;
        _this.TONEMAPPING = false;
        _this.TONEMAPPING_ACES = false;
        _this.CONTRAST = false;
        _this.COLORCURVES = false;
        _this.COLORGRADING = false;
        _this.COLORGRADING3D = false;
        _this.SAMPLER3DGREENDEPTH = false;
        _this.SAMPLER3DBGRMAP = false;
        _this.IMAGEPROCESSINGPOSTPROCESS = false;
        _this.EXPOSURE = false;
        _this.MULTIVIEW = false;
        // Reflection.
        _this.REFLECTION = false;
        _this.REFLECTIONMAP_3D = false;
        _this.REFLECTIONMAP_SPHERICAL = false;
        _this.REFLECTIONMAP_PLANAR = false;
        _this.REFLECTIONMAP_CUBIC = false;
        _this.REFLECTIONMAP_PROJECTION = false;
        _this.REFLECTIONMAP_SKYBOX = false;
        _this.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
        _this.REFLECTIONMAP_EXPLICIT = false;
        _this.REFLECTIONMAP_EQUIRECTANGULAR = false;
        _this.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
        _this.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
        _this.INVERTCUBICMAP = false;
        _this.REFLECTIONMAP_OPPOSITEZ = false;
        _this.LODINREFLECTIONALPHA = false;
        _this.GAMMAREFLECTION = false;
        _this.RGBDREFLECTION = false;
        _this.EQUIRECTANGULAR_RELFECTION_FOV = false;
        // Default BJS.
        _this.MAINUV1 = false;
        _this.MAINUV2 = false;
        _this.UV1 = false;
        _this.UV2 = false;
        _this.CLIPPLANE = false;
        _this.CLIPPLANE2 = false;
        _this.CLIPPLANE3 = false;
        _this.CLIPPLANE4 = false;
        _this.POINTSIZE = false;
        _this.FOG = false;
        _this.NORMAL = false;
        _this.NUM_BONE_INFLUENCERS = 0;
        _this.BonesPerMesh = 0;
        _this.INSTANCES = false;
        _this.SHADOWFLOAT = false;
        _this.rebuild();
        return _this;
    }
    return BackgroundMaterialDefines;
}(_Materials_materialDefines__WEBPACK_IMPORTED_MODULE_8__["MaterialDefines"]));
/**
 * Background material used to create an efficient environement around your scene.
 */
var BackgroundMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BackgroundMaterial, _super);
    /**
     * Instantiates a Background Material in the given scene
     * @param name The friendly name of the material
     * @param scene The scene to add the material to
     */
    function BackgroundMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        /**
         * Key light Color (multiply against the environement texture)
         */
        _this.primaryColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color3"].White();
        _this._primaryColorShadowLevel = 0;
        _this._primaryColorHighlightLevel = 0;
        /**
         * Reflection Texture used in the material.
         * Should be author in a specific way for the best result (refer to the documentation).
         */
        _this.reflectionTexture = null;
        /**
         * Reflection Texture level of blur.
         *
         * Can be use to reuse an existing HDR Texture and target a specific LOD to prevent authoring the
         * texture twice.
         */
        _this.reflectionBlur = 0;
        /**
         * Diffuse Texture used in the material.
         * Should be author in a specific way for the best result (refer to the documentation).
         */
        _this.diffuseTexture = null;
        _this._shadowLights = null;
        /**
         * Specify the list of lights casting shadow on the material.
         * All scene shadow lights will be included if null.
         */
        _this.shadowLights = null;
        /**
         * Helps adjusting the shadow to a softer level if required.
         * 0 means black shadows and 1 means no shadows.
         */
        _this.shadowLevel = 0;
        /**
         * In case of opacity Fresnel or reflection falloff, this is use as a scene center.
         * It is usually zero but might be interesting to modify according to your setup.
         */
        _this.sceneCenter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Zero();
        /**
         * This helps specifying that the material is falling off to the sky box at grazing angle.
         * This helps ensuring a nice transition when the camera goes under the ground.
         */
        _this.opacityFresnel = true;
        /**
         * This helps specifying that the material is falling off from diffuse to the reflection texture at grazing angle.
         * This helps adding a mirror texture on the ground.
         */
        _this.reflectionFresnel = false;
        /**
         * This helps specifying the falloff radius off the reflection texture from the sceneCenter.
         * This helps adding a nice falloff effect to the reflection if used as a mirror for instance.
         */
        _this.reflectionFalloffDistance = 0.0;
        /**
         * This specifies the weight of the reflection against the background in case of reflection Fresnel.
         */
        _this.reflectionAmount = 1.0;
        /**
         * This specifies the weight of the reflection at grazing angle.
         */
        _this.reflectionReflectance0 = 0.05;
        /**
         * This specifies the weight of the reflection at a perpendicular point of view.
         */
        _this.reflectionReflectance90 = 0.5;
        /**
         * Helps to directly use the maps channels instead of their level.
         */
        _this.useRGBColor = true;
        /**
         * This helps reducing the banding effect that could occur on the background.
         */
        _this.enableNoise = false;
        _this._fovMultiplier = 1.0;
        /**
         * Enable the FOV adjustment feature controlled by fovMultiplier.
         */
        _this.useEquirectangularFOV = false;
        _this._maxSimultaneousLights = 4;
        /**
         * Number of Simultaneous lights allowed on the material.
         */
        _this.maxSimultaneousLights = 4;
        /**
         * Keep track of the image processing observer to allow dispose and replace.
         */
        _this._imageProcessingObserver = null;
        /**
         * Due to a bug in iOS10, video tags (which are using the background material) are in BGR and not RGB.
         * Setting this flag to true (not done automatically!) will convert it back to RGB.
         */
        _this.switchToBGR = false;
        // Temp values kept as cache in the material.
        _this._renderTargets = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_2__["SmartArray"](16);
        _this._reflectionControls = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector4"].Zero();
        _this._white = _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color3"].White();
        _this._primaryShadowColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color3"].Black();
        _this._primaryHighlightColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color3"].Black();
        // Setup the default processing configuration to the scene.
        _this._attachImageProcessingConfiguration(null);
        _this.getRenderTargetTextures = function () {
            _this._renderTargets.reset();
            if (_this._diffuseTexture && _this._diffuseTexture.isRenderTarget) {
                _this._renderTargets.push(_this._diffuseTexture);
            }
            if (_this._reflectionTexture && _this._reflectionTexture.isRenderTarget) {
                _this._renderTargets.push(_this._reflectionTexture);
            }
            return _this._renderTargets;
        };
        return _this;
    }
    Object.defineProperty(BackgroundMaterial.prototype, "_perceptualColor", {
        /**
         * Experimental Internal Use Only.
         *
         * Key light Color in "perceptual value" meaning the color you would like to see on screen.
         * This acts as a helper to set the primary color to a more "human friendly" value.
         * Conversion to linear space as well as exposure and tone mapping correction will be applied to keep the
         * output color as close as possible from the chosen value.
         * (This does not account for contrast color grading and color curves as they are considered post effect and not directly
         * part of lighting setup.)
         */
        get: function () {
            return this.__perceptualColor;
        },
        set: function (value) {
            this.__perceptualColor = value;
            this._computePrimaryColorFromPerceptualColor();
            this._markAllSubMeshesAsLightsDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "primaryColorShadowLevel", {
        /**
         * Defines the level of the shadows (dark area of the reflection map) in order to help scaling the colors.
         * The color opposite to the primary color is used at the level chosen to define what the black area would look.
         */
        get: function () {
            return this._primaryColorShadowLevel;
        },
        set: function (value) {
            this._primaryColorShadowLevel = value;
            this._computePrimaryColors();
            this._markAllSubMeshesAsLightsDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "primaryColorHighlightLevel", {
        /**
         * Defines the level of the highliights (highlight area of the reflection map) in order to help scaling the colors.
         * The primary color is used at the level chosen to define what the white area would look.
         */
        get: function () {
            return this._primaryColorHighlightLevel;
        },
        set: function (value) {
            this._primaryColorHighlightLevel = value;
            this._computePrimaryColors();
            this._markAllSubMeshesAsLightsDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "reflectionStandardFresnelWeight", {
        /**
         * Sets the reflection reflectance fresnel values according to the default standard
         * empirically know to work well :-)
         */
        set: function (value) {
            var reflectionWeight = value;
            if (reflectionWeight < 0.5) {
                reflectionWeight = reflectionWeight * 2.0;
                this.reflectionReflectance0 = BackgroundMaterial.StandardReflectance0 * reflectionWeight;
                this.reflectionReflectance90 = BackgroundMaterial.StandardReflectance90 * reflectionWeight;
            }
            else {
                reflectionWeight = reflectionWeight * 2.0 - 1.0;
                this.reflectionReflectance0 = BackgroundMaterial.StandardReflectance0 + (1.0 - BackgroundMaterial.StandardReflectance0) * reflectionWeight;
                this.reflectionReflectance90 = BackgroundMaterial.StandardReflectance90 + (1.0 - BackgroundMaterial.StandardReflectance90) * reflectionWeight;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "fovMultiplier", {
        /**
         * The current fov(field of view) multiplier, 0.0 - 2.0. Defaults to 1.0. Lower values "zoom in" and higher values "zoom out".
         * Best used when trying to implement visual zoom effects like fish-eye or binoculars while not adjusting camera fov.
         * Recommended to be keep at 1.0 except for special cases.
         */
        get: function () {
            return this._fovMultiplier;
        },
        set: function (value) {
            if (isNaN(value)) {
                value = 1.0;
            }
            this._fovMultiplier = Math.max(0.0, Math.min(2.0, value));
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attaches a new image processing configuration to the PBR Material.
     * @param configuration (if null the scene configuration will be use)
     */
    BackgroundMaterial.prototype._attachImageProcessingConfiguration = function (configuration) {
        var _this = this;
        if (configuration === this._imageProcessingConfiguration) {
            return;
        }
        // Detaches observer.
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        // Pick the scene configuration if needed.
        if (!configuration) {
            this._imageProcessingConfiguration = this.getScene().imageProcessingConfiguration;
        }
        else {
            this._imageProcessingConfiguration = configuration;
        }
        // Attaches observer.
        if (this._imageProcessingConfiguration) {
            this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(function () {
                _this._computePrimaryColorFromPerceptualColor();
                _this._markAllSubMeshesAsImageProcessingDirty();
            });
        }
    };
    Object.defineProperty(BackgroundMaterial.prototype, "imageProcessingConfiguration", {
        /**
         * Gets the image processing configuration used either in this material.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        /**
         * Sets the Default image processing configuration used either in the this material.
         *
         * If sets to null, the scene one is in use.
         */
        set: function (value) {
            this._attachImageProcessingConfiguration(value);
            // Ensure the effect will be rebuilt.
            this._markAllSubMeshesAsTexturesDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraColorCurvesEnabled", {
        /**
         * Gets wether the color curves effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorCurvesEnabled;
        },
        /**
         * Sets wether the color curves effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorCurvesEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraColorGradingEnabled", {
        /**
         * Gets wether the color grading effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorGradingEnabled;
        },
        /**
         * Gets wether the color grading effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorGradingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraToneMappingEnabled", {
        /**
         * Gets wether tonemapping is enabled or not.
         */
        get: function () {
            return this._imageProcessingConfiguration.toneMappingEnabled;
        },
        /**
         * Sets wether tonemapping is enabled or not
         */
        set: function (value) {
            this._imageProcessingConfiguration.toneMappingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraExposure", {
        /**
         * The camera exposure used on this material.
         * This property is here and not in the camera to allow controlling exposure without full screen post process.
         * This corresponds to a photographic exposure.
         */
        get: function () {
            return this._imageProcessingConfiguration.exposure;
        },
        /**
         * The camera exposure used on this material.
         * This property is here and not in the camera to allow controlling exposure without full screen post process.
         * This corresponds to a photographic exposure.
         */
        set: function (value) {
            this._imageProcessingConfiguration.exposure = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraContrast", {
        /**
         * Gets The camera contrast used on this material.
         */
        get: function () {
            return this._imageProcessingConfiguration.contrast;
        },
        /**
         * Sets The camera contrast used on this material.
         */
        set: function (value) {
            this._imageProcessingConfiguration.contrast = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraColorGradingTexture", {
        /**
         * Gets the Color Grading 2D Lookup Texture.
         */
        get: function () {
            return this._imageProcessingConfiguration.colorGradingTexture;
        },
        /**
         * Sets the Color Grading 2D Lookup Texture.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorGradingTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "cameraColorCurves", {
        /**
         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorCurves;
        },
        /**
         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorCurves = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BackgroundMaterial.prototype, "hasRenderTargetTextures", {
        /**
         * Gets a boolean indicating that current material needs to register RTT
         */
        get: function () {
            if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {
                return true;
            }
            if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                return true;
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * The entire material has been created in order to prevent overdraw.
     * @returns false
     */
    BackgroundMaterial.prototype.needAlphaTesting = function () {
        return true;
    };
    /**
     * The entire material has been created in order to prevent overdraw.
     * @returns true if blending is enable
     */
    BackgroundMaterial.prototype.needAlphaBlending = function () {
        return ((this.alpha < 0) || (this._diffuseTexture != null && this._diffuseTexture.hasAlpha));
    };
    /**
     * Checks wether the material is ready to be rendered for a given mesh.
     * @param mesh The mesh to render
     * @param subMesh The submesh to check against
     * @param useInstances Specify wether or not the material is used with instances
     * @returns true if all the dependencies are ready (Textures, Effects...)
     */
    BackgroundMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        var _this = this;
        if (useInstances === void 0) { useInstances = false; }
        if (subMesh.effect && this.isFrozen) {
            if (this._wasPreviouslyReady) {
                return true;
            }
        }
        if (!subMesh._materialDefines) {
            subMesh._materialDefines = new BackgroundMaterialDefines();
        }
        var scene = this.getScene();
        var defines = subMesh._materialDefines;
        if (!this.checkReadyOnEveryCall && subMesh.effect) {
            if (defines._renderId === scene.getRenderId()) {
                return true;
            }
        }
        var engine = scene.getEngine();
        // Lights
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
        defines._needNormals = true;
        // Multiview
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareDefinesForMultiview(scene, defines);
        // Textures
        if (defines._areTexturesDirty) {
            defines._needUVs = false;
            if (scene.texturesEnabled) {
                if (scene.getEngine().getCaps().textureLOD) {
                    defines.TEXTURELODSUPPORT = true;
                }
                if (this._diffuseTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].DiffuseTextureEnabled) {
                    if (!this._diffuseTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareDefinesForMergedUV(this._diffuseTexture, defines, "DIFFUSE");
                    defines.DIFFUSEHASALPHA = this._diffuseTexture.hasAlpha;
                    defines.GAMMADIFFUSE = this._diffuseTexture.gammaSpace;
                    defines.OPACITYFRESNEL = this._opacityFresnel;
                }
                else {
                    defines.DIFFUSE = false;
                    defines.DIFFUSEHASALPHA = false;
                    defines.GAMMADIFFUSE = false;
                    defines.OPACITYFRESNEL = false;
                }
                var reflectionTexture = this._reflectionTexture;
                if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ReflectionTextureEnabled) {
                    if (!reflectionTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    defines.REFLECTION = true;
                    defines.GAMMAREFLECTION = reflectionTexture.gammaSpace;
                    defines.RGBDREFLECTION = reflectionTexture.isRGBD;
                    defines.REFLECTIONBLUR = this._reflectionBlur > 0;
                    defines.REFLECTIONMAP_OPPOSITEZ = this.getScene().useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ;
                    defines.LODINREFLECTIONALPHA = reflectionTexture.lodLevelInAlpha;
                    defines.EQUIRECTANGULAR_RELFECTION_FOV = this.useEquirectangularFOV;
                    defines.REFLECTIONBGR = this.switchToBGR;
                    if (reflectionTexture.coordinatesMode === _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].INVCUBIC_MODE) {
                        defines.INVERTCUBICMAP = true;
                    }
                    defines.REFLECTIONMAP_3D = reflectionTexture.isCube;
                    switch (reflectionTexture.coordinatesMode) {
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].EXPLICIT_MODE:
                            defines.REFLECTIONMAP_EXPLICIT = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].PLANAR_MODE:
                            defines.REFLECTIONMAP_PLANAR = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].PROJECTION_MODE:
                            defines.REFLECTIONMAP_PROJECTION = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].SKYBOX_MODE:
                            defines.REFLECTIONMAP_SKYBOX = true;
                            defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = !reflectionTexture.getReflectionTextureMatrix().isIdentity();
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].SPHERICAL_MODE:
                            defines.REFLECTIONMAP_SPHERICAL = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].EQUIRECTANGULAR_MODE:
                            defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].FIXED_EQUIRECTANGULAR_MODE:
                            defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
                            defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].CUBIC_MODE:
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_11__["Texture"].INVCUBIC_MODE:
                        default:
                            defines.REFLECTIONMAP_CUBIC = true;
                            break;
                    }
                    if (this.reflectionFresnel) {
                        defines.REFLECTIONFRESNEL = true;
                        defines.REFLECTIONFALLOFF = this.reflectionFalloffDistance > 0;
                        this._reflectionControls.x = this.reflectionAmount;
                        this._reflectionControls.y = this.reflectionReflectance0;
                        this._reflectionControls.z = this.reflectionReflectance90;
                        this._reflectionControls.w = 1 / this.reflectionFalloffDistance;
                    }
                    else {
                        defines.REFLECTIONFRESNEL = false;
                        defines.REFLECTIONFALLOFF = false;
                    }
                }
                else {
                    defines.REFLECTION = false;
                    defines.REFLECTIONFRESNEL = false;
                    defines.REFLECTIONFALLOFF = false;
                    defines.REFLECTIONBLUR = false;
                    defines.REFLECTIONMAP_3D = false;
                    defines.REFLECTIONMAP_SPHERICAL = false;
                    defines.REFLECTIONMAP_PLANAR = false;
                    defines.REFLECTIONMAP_CUBIC = false;
                    defines.REFLECTIONMAP_PROJECTION = false;
                    defines.REFLECTIONMAP_SKYBOX = false;
                    defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
                    defines.REFLECTIONMAP_EXPLICIT = false;
                    defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
                    defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
                    defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
                    defines.INVERTCUBICMAP = false;
                    defines.REFLECTIONMAP_OPPOSITEZ = false;
                    defines.LODINREFLECTIONALPHA = false;
                    defines.GAMMAREFLECTION = false;
                    defines.RGBDREFLECTION = false;
                }
            }
            defines.PREMULTIPLYALPHA = (this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].ALPHA_PREMULTIPLIED || this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_12__["Constants"].ALPHA_PREMULTIPLIED_PORTERDUFF);
            defines.USERGBCOLOR = this._useRGBColor;
            defines.NOISE = this._enableNoise;
        }
        if (defines._areLightsDirty) {
            defines.USEHIGHLIGHTANDSHADOWCOLORS = !this._useRGBColor && (this._primaryColorShadowLevel !== 0 || this._primaryColorHighlightLevel !== 0);
        }
        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
            if (!this._imageProcessingConfiguration.isReady()) {
                return false;
            }
            this._imageProcessingConfiguration.prepareDefines(defines);
        }
        // Misc.
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
        // Values that need to be evaluated on every frame
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
        // Attribs
        if (_Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareDefinesForAttributes(mesh, defines, false, true, false)) {
            if (mesh) {
                if (!scene.getEngine().getCaps().standardDerivatives && !mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind)) {
                    mesh.createNormals(true);
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Warn("BackgroundMaterial: Normals have been created for the mesh: " + mesh.name);
                }
            }
        }
        // Get correct effect
        if (defines.isDirty) {
            defines.markAsProcessed();
            scene.resetCachedMaterial();
            // Fallbacks
            var fallbacks = new _Materials_effect__WEBPACK_IMPORTED_MODULE_6__["EffectFallbacks"]();
            if (defines.FOG) {
                fallbacks.addFallback(0, "FOG");
            }
            if (defines.POINTSIZE) {
                fallbacks.addFallback(1, "POINTSIZE");
            }
            if (defines.MULTIVIEW) {
                fallbacks.addFallback(0, "MULTIVIEW");
            }
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights);
            //Attributes
            var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind];
            if (defines.NORMAL) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind);
            }
            if (defines.UV1) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].UVKind);
            }
            if (defines.UV2) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].UV2Kind);
            }
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareAttributesForInstances(attribs, defines);
            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType",
                "vFogInfos", "vFogColor", "pointSize",
                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "mBones",
                "vPrimaryColor", "vPrimaryColorShadow",
                "vReflectionInfos", "reflectionMatrix", "vReflectionMicrosurfaceInfos", "fFovMultiplier",
                "shadowLevel", "alpha",
                "vBackgroundCenter", "vReflectionControl",
                "vDiffuseInfos", "diffuseMatrix",
            ];
            var samplers = ["diffuseSampler", "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh"];
            var uniformBuffers = ["Material", "Scene"];
            if (_Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_10__["ImageProcessingConfiguration"]) {
                _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_10__["ImageProcessingConfiguration"].PrepareUniforms(uniforms, defines);
                _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_10__["ImageProcessingConfiguration"].PrepareSamplers(samplers, defines);
            }
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].PrepareUniformsAndSamplersList({
                uniformsNames: uniforms,
                uniformBuffersNames: uniformBuffers,
                samplers: samplers,
                defines: defines,
                maxSimultaneousLights: this._maxSimultaneousLights
            });
            var onCompiled = function (effect) {
                if (_this.onCompiled) {
                    _this.onCompiled(effect);
                }
                _this.bindSceneUniformBuffer(effect, scene.getSceneUniformBuffer());
            };
            var join = defines.toString();
            subMesh.setEffect(scene.getEngine().createEffect("background", {
                attributes: attribs,
                uniformsNames: uniforms,
                uniformBuffersNames: uniformBuffers,
                samplers: samplers,
                defines: join,
                fallbacks: fallbacks,
                onCompiled: onCompiled,
                onError: this.onError,
                indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights }
            }, engine), defines);
            this.buildUniformLayout();
        }
        if (!subMesh.effect || !subMesh.effect.isReady()) {
            return false;
        }
        defines._renderId = scene.getRenderId();
        this._wasPreviouslyReady = true;
        return true;
    };
    /**
     * Compute the primary color according to the chosen perceptual color.
     */
    BackgroundMaterial.prototype._computePrimaryColorFromPerceptualColor = function () {
        if (!this.__perceptualColor) {
            return;
        }
        this._primaryColor.copyFrom(this.__perceptualColor);
        // Revert gamma space.
        this._primaryColor.toLinearSpaceToRef(this._primaryColor);
        // Revert image processing configuration.
        if (this._imageProcessingConfiguration) {
            // Revert Exposure.
            this._primaryColor.scaleToRef(1 / this._imageProcessingConfiguration.exposure, this._primaryColor);
        }
        this._computePrimaryColors();
    };
    /**
     * Compute the highlights and shadow colors according to their chosen levels.
     */
    BackgroundMaterial.prototype._computePrimaryColors = function () {
        if (this._primaryColorShadowLevel === 0 && this._primaryColorHighlightLevel === 0) {
            return;
        }
        // Find the highlight color based on the configuration.
        this._primaryColor.scaleToRef(this._primaryColorShadowLevel, this._primaryShadowColor);
        this._primaryColor.subtractToRef(this._primaryShadowColor, this._primaryShadowColor);
        // Find the shadow color based on the configuration.
        this._white.subtractToRef(this._primaryColor, this._primaryHighlightColor);
        this._primaryHighlightColor.scaleToRef(this._primaryColorHighlightLevel, this._primaryHighlightColor);
        this._primaryColor.addToRef(this._primaryHighlightColor, this._primaryHighlightColor);
    };
    /**
     * Build the uniform buffer used in the material.
     */
    BackgroundMaterial.prototype.buildUniformLayout = function () {
        // Order is important !
        this._uniformBuffer.addUniform("vPrimaryColor", 4);
        this._uniformBuffer.addUniform("vPrimaryColorShadow", 4);
        this._uniformBuffer.addUniform("vDiffuseInfos", 2);
        this._uniformBuffer.addUniform("vReflectionInfos", 2);
        this._uniformBuffer.addUniform("diffuseMatrix", 16);
        this._uniformBuffer.addUniform("reflectionMatrix", 16);
        this._uniformBuffer.addUniform("vReflectionMicrosurfaceInfos", 3);
        this._uniformBuffer.addUniform("fFovMultiplier", 1);
        this._uniformBuffer.addUniform("pointSize", 1);
        this._uniformBuffer.addUniform("shadowLevel", 1);
        this._uniformBuffer.addUniform("alpha", 1);
        this._uniformBuffer.addUniform("vBackgroundCenter", 3);
        this._uniformBuffer.addUniform("vReflectionControl", 4);
        this._uniformBuffer.create();
    };
    /**
     * Unbind the material.
     */
    BackgroundMaterial.prototype.unbind = function () {
        if (this._diffuseTexture && this._diffuseTexture.isRenderTarget) {
            this._uniformBuffer.setTexture("diffuseSampler", null);
        }
        if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
            this._uniformBuffer.setTexture("reflectionSampler", null);
        }
        _super.prototype.unbind.call(this);
    };
    /**
     * Bind only the world matrix to the material.
     * @param world The world matrix to bind.
     */
    BackgroundMaterial.prototype.bindOnlyWorldMatrix = function (world) {
        this._activeEffect.setMatrix("world", world);
    };
    /**
     * Bind the material for a dedicated submeh (every used meshes will be considered opaque).
     * @param world The world matrix to bind.
     * @param subMesh The submesh to bind for.
     */
    BackgroundMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
        var scene = this.getScene();
        var defines = subMesh._materialDefines;
        if (!defines) {
            return;
        }
        var effect = subMesh.effect;
        if (!effect) {
            return;
        }
        this._activeEffect = effect;
        // Matrices
        this.bindOnlyWorldMatrix(world);
        // Bones
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindBonesParameters(mesh, this._activeEffect);
        var mustRebind = this._mustRebind(scene, effect, mesh.visibility);
        if (mustRebind) {
            this._uniformBuffer.bindToEffect(effect, "Material");
            this.bindViewProjection(effect);
            var reflectionTexture = this._reflectionTexture;
            if (!this._uniformBuffer.useUbo || !this.isFrozen || !this._uniformBuffer.isSync) {
                // Texture uniforms
                if (scene.texturesEnabled) {
                    if (this._diffuseTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].DiffuseTextureEnabled) {
                        this._uniformBuffer.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindTextureMatrix(this._diffuseTexture, this._uniformBuffer, "diffuse");
                    }
                    if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ReflectionTextureEnabled) {
                        this._uniformBuffer.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
                        this._uniformBuffer.updateFloat2("vReflectionInfos", reflectionTexture.level, this._reflectionBlur);
                        this._uniformBuffer.updateFloat3("vReflectionMicrosurfaceInfos", reflectionTexture.getSize().width, reflectionTexture.lodGenerationScale, reflectionTexture.lodGenerationOffset);
                    }
                }
                if (this.shadowLevel > 0) {
                    this._uniformBuffer.updateFloat("shadowLevel", this.shadowLevel);
                }
                this._uniformBuffer.updateFloat("alpha", this.alpha);
                // Point size
                if (this.pointsCloud) {
                    this._uniformBuffer.updateFloat("pointSize", this.pointSize);
                }
                if (defines.USEHIGHLIGHTANDSHADOWCOLORS) {
                    this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryHighlightColor, 1.0);
                    this._uniformBuffer.updateColor4("vPrimaryColorShadow", this._primaryShadowColor, 1.0);
                }
                else {
                    this._uniformBuffer.updateColor4("vPrimaryColor", this._primaryColor, 1.0);
                }
            }
            this._uniformBuffer.updateFloat("fFovMultiplier", this._fovMultiplier);
            // Textures
            if (scene.texturesEnabled) {
                if (this._diffuseTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].DiffuseTextureEnabled) {
                    this._uniformBuffer.setTexture("diffuseSampler", this._diffuseTexture);
                }
                if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ReflectionTextureEnabled) {
                    if (defines.REFLECTIONBLUR && defines.TEXTURELODSUPPORT) {
                        this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
                    }
                    else if (!defines.REFLECTIONBLUR) {
                        this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture);
                    }
                    else {
                        this._uniformBuffer.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
                        this._uniformBuffer.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
                        this._uniformBuffer.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
                    }
                    if (defines.REFLECTIONFRESNEL) {
                        this._uniformBuffer.updateFloat3("vBackgroundCenter", this.sceneCenter.x, this.sceneCenter.y, this.sceneCenter.z);
                        this._uniformBuffer.updateFloat4("vReflectionControl", this._reflectionControls.x, this._reflectionControls.y, this._reflectionControls.z, this._reflectionControls.w);
                    }
                }
            }
            // Clip plane
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindClipPlane(this._activeEffect, scene);
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindEyePosition(effect, scene);
        }
        if (mustRebind || !this.isFrozen) {
            if (scene.lightsEnabled) {
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights, false);
            }
            // View
            this.bindView(effect);
            // Fog
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindFogParameters(scene, mesh, this._activeEffect, true);
            // image processing
            if (this._imageProcessingConfiguration) {
                this._imageProcessingConfiguration.bind(this._activeEffect);
            }
        }
        this._uniformBuffer.update();
        this._afterBind(mesh, this._activeEffect);
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param texture - Base texture to use.
     * @returns - Boolean specifying if a texture is used in the material.
     */
    BackgroundMaterial.prototype.hasTexture = function (texture) {
        if (_super.prototype.hasTexture.call(this, texture)) {
            return true;
        }
        if (this._reflectionTexture === texture) {
            return true;
        }
        if (this._diffuseTexture === texture) {
            return true;
        }
        return false;
    };
    /**
     * Dispose the material.
     * @param forceDisposeEffect Force disposal of the associated effect.
     * @param forceDisposeTextures Force disposal of the associated textures.
     */
    BackgroundMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
        if (forceDisposeEffect === void 0) { forceDisposeEffect = false; }
        if (forceDisposeTextures === void 0) { forceDisposeTextures = false; }
        if (forceDisposeTextures) {
            if (this.diffuseTexture) {
                this.diffuseTexture.dispose();
            }
            if (this.reflectionTexture) {
                this.reflectionTexture.dispose();
            }
        }
        this._renderTargets.dispose();
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        _super.prototype.dispose.call(this, forceDisposeEffect);
    };
    /**
     * Clones the material.
     * @param name The cloned name.
     * @returns The cloned material.
     */
    BackgroundMaterial.prototype.clone = function (name) {
        var _this = this;
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new BackgroundMaterial(name, _this.getScene()); }, this);
    };
    /**
     * Serializes the current material to its JSON representation.
     * @returns The JSON representation.
     */
    BackgroundMaterial.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.BackgroundMaterial";
        return serializationObject;
    };
    /**
     * Gets the class name of the material
     * @returns "BackgroundMaterial"
     */
    BackgroundMaterial.prototype.getClassName = function () {
        return "BackgroundMaterial";
    };
    /**
     * Parse a JSON input to create back a background material.
     * @param source The JSON data to parse
     * @param scene The scene to create the parsed material in
     * @param rootUrl The root url of the assets the material depends upon
     * @returns the instantiated BackgroundMaterial.
     */
    BackgroundMaterial.Parse = function (source, scene, rootUrl) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new BackgroundMaterial(source.name, scene); }, source, scene, rootUrl);
    };
    /**
     * Standard reflectance value at parallel view angle.
     */
    BackgroundMaterial.StandardReflectance0 = 0.05;
    /**
     * Standard reflectance value at grazing angle.
     */
    BackgroundMaterial.StandardReflectance90 = 0.5;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], BackgroundMaterial.prototype, "_primaryColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], BackgroundMaterial.prototype, "primaryColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], BackgroundMaterial.prototype, "__perceptualColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_primaryColorShadowLevel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_primaryColorHighlightLevel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], BackgroundMaterial.prototype, "primaryColorHighlightLevel", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])()
    ], BackgroundMaterial.prototype, "_reflectionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_reflectionBlur", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionBlur", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])()
    ], BackgroundMaterial.prototype, "_diffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "diffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "shadowLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_shadowLevel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "shadowLevel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], BackgroundMaterial.prototype, "_sceneCenter", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "sceneCenter", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_opacityFresnel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "opacityFresnel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_reflectionFresnel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionFresnel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_reflectionFalloffDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionFalloffDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_reflectionAmount", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionAmount", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_reflectionReflectance0", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionReflectance0", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_reflectionReflectance90", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "reflectionReflectance90", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_useRGBColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "useRGBColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_enableNoise", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "enableNoise", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BackgroundMaterial.prototype, "_maxSimultaneousLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], BackgroundMaterial.prototype, "maxSimultaneousLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsImageProcessingConfiguration"])()
    ], BackgroundMaterial.prototype, "_imageProcessingConfiguration", void 0);
    return BackgroundMaterial;
}(_Materials_pushMaterial__WEBPACK_IMPORTED_MODULE_9__["PushMaterial"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_13__["_TypeStore"].RegisteredTypes["BABYLON.BackgroundMaterial"] = BackgroundMaterial;


/***/ }),

/***/ "./Materials/Background/index.ts":
/*!***************************************!*\
  !*** ./Materials/Background/index.ts ***!
  \***************************************/
/*! exports provided: BackgroundMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _backgroundMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./backgroundMaterial */ "./Materials/Background/backgroundMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackgroundMaterial", function() { return _backgroundMaterial__WEBPACK_IMPORTED_MODULE_0__["BackgroundMaterial"]; });




/***/ }),

/***/ "./Materials/Node/Blocks/Dual/fogBlock.ts":
/*!************************************************!*\
  !*** ./Materials/Node/Blocks/Dual/fogBlock.ts ***!
  \************************************************/
/*! exports provided: FogBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return FogBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");








/**
 * Block used to add support for scene fog
 */
var FogBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FogBlock, _super);
    /**
     * Create a new FogBlock
     * @param name defines the block name
     */
    function FogBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].VertexAndFragment, true) || this;
        // Vertex
        _this.registerInput("worldPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Vertex);
        _this.registerInput("view", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Vertex);
        // Fragment
        _this.registerInput("input", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Fragment);
        _this.registerInput("fogColor", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Fragment);
        _this.input.acceptedConnectionPointTypes.push(_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4);
        _this.fogColor.acceptedConnectionPointTypes.push(_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    FogBlock.prototype.getClassName = function () {
        return "FogBlock";
    };
    Object.defineProperty(FogBlock.prototype, "worldPosition", {
        /**
         * Gets the world position input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FogBlock.prototype, "view", {
        /**
         * Gets the view input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FogBlock.prototype, "input", {
        /**
         * Gets the color input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FogBlock.prototype, "fogColor", {
        /**
         * Gets the fog color input component
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FogBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    FogBlock.prototype.autoConfigure = function (material) {
        if (!this.view.isConnected) {
            var viewInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialSystemValues"].View; });
            if (!viewInput) {
                viewInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("view");
                viewInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialSystemValues"].View);
            }
            viewInput.output.connectTo(this.view);
        }
        if (!this.fogColor.isConnected) {
            var fogColorInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialSystemValues"].FogColor; });
            if (!fogColorInput) {
                fogColorInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("fogColor", undefined, _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3);
                fogColorInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialSystemValues"].FogColor);
            }
            fogColorInput.output.connectTo(this.fogColor);
        }
    };
    FogBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        var scene = mesh.getScene();
        defines.setValue("FOG", nodeMaterial.fogEnabled && _materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].GetFogState(mesh, scene));
    };
    FogBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (!mesh) {
            return;
        }
        var scene = mesh.getScene();
        effect.setFloat4(this._fogParameters, scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
    };
    FogBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        if (state.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Fragment) {
            state.sharedData.blocksWithDefines.push(this);
            state.sharedData.bindableBlocks.push(this);
            state._emitFunctionFromInclude("fogFragmentDeclaration", "//" + this.name, {
                removeUniforms: true,
                removeVaryings: true,
                removeIfDef: false,
                replaceStrings: [{ search: /float CalcFogFactor\(\)/, replace: "float CalcFogFactor(vec3 vFogDistance, vec4 vFogInfos)" }]
            });
            var tempFogVariablename = state._getFreeVariableName("fog");
            var color = this.input;
            var fogColor = this.fogColor;
            this._fogParameters = state._getFreeVariableName("fogParameters");
            var output = this._outputs[0];
            state._emitUniformFromString(this._fogParameters, "vec4");
            state.compilationString += "#ifdef FOG\r\n";
            state.compilationString += "float " + tempFogVariablename + " = CalcFogFactor(" + this._fogDistanceName + ", " + this._fogParameters + ");\r\n";
            state.compilationString += this._declareOutput(output, state) + (" = " + tempFogVariablename + " * " + color.associatedVariableName + ".rgb + (1.0 - " + tempFogVariablename + ") * " + fogColor.associatedVariableName + ".rgb;\r\n");
            state.compilationString += "#else\r\n" + this._declareOutput(output, state) + " =  " + color.associatedVariableName + ".rgb;\r\n";
            state.compilationString += "#endif\r\n";
        }
        else {
            var worldPos = this.worldPosition;
            var view = this.view;
            this._fogDistanceName = state._getFreeVariableName("vFogDistance");
            state._emitVaryingFromString(this._fogDistanceName, "vec3");
            state.compilationString += this._fogDistanceName + " = (" + view.associatedVariableName + " * " + worldPos.associatedVariableName + ").xyz;\r\n";
        }
        return this;
    };
    return FogBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.FogBlock"] = FogBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Dual/index.ts":
/*!*********************************************!*\
  !*** ./Materials/Node/Blocks/Dual/index.ts ***!
  \*********************************************/
/*! exports provided: FogBlock, LightBlock, TextureBlock, ReflectionTextureBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _fogBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./fogBlock */ "./Materials/Node/Blocks/Dual/fogBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return _fogBlock__WEBPACK_IMPORTED_MODULE_0__["FogBlock"]; });

/* harmony import */ var _lightBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lightBlock */ "./Materials/Node/Blocks/Dual/lightBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return _lightBlock__WEBPACK_IMPORTED_MODULE_1__["LightBlock"]; });

/* harmony import */ var _textureBlock__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./textureBlock */ "./Materials/Node/Blocks/Dual/textureBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return _textureBlock__WEBPACK_IMPORTED_MODULE_2__["TextureBlock"]; });

/* harmony import */ var _reflectionTextureBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./reflectionTextureBlock */ "./Materials/Node/Blocks/Dual/reflectionTextureBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return _reflectionTextureBlock__WEBPACK_IMPORTED_MODULE_3__["ReflectionTextureBlock"]; });







/***/ }),

/***/ "./Materials/Node/Blocks/Dual/lightBlock.ts":
/*!**************************************************!*\
  !*** ./Materials/Node/Blocks/Dual/lightBlock.ts ***!
  \**************************************************/
/*! exports provided: LightBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return LightBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");








/**
 * Block used to add light in the fragment shader
 */
var LightBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightBlock, _super);
    /**
     * Create a new LightBlock
     * @param name defines the block name
     */
    function LightBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].VertexAndFragment) || this;
        _this.registerInput("worldPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Vertex);
        _this.registerInput("worldNormal", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Fragment);
        _this.registerInput("cameraPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector3, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("diffuseOutput", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Color3, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("specularOutput", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Color3, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Fragment);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    LightBlock.prototype.getClassName = function () {
        return "LightBlock";
    };
    Object.defineProperty(LightBlock.prototype, "worldPosition", {
        /**
         * Gets the world position input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightBlock.prototype, "worldNormal", {
        /**
         * Gets the world normal input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightBlock.prototype, "cameraPosition", {
        /**
        * Gets the camera (or eye) position component
        */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightBlock.prototype, "diffuseOutput", {
        /**
         * Gets the diffuse output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightBlock.prototype, "specularOutput", {
        /**
         * Gets the specular output component
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    LightBlock.prototype.autoConfigure = function (material) {
        if (!this.cameraPosition.isConnected) {
            var cameraPositionInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialSystemValues"].CameraPosition; });
            if (!cameraPositionInput) {
                cameraPositionInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("cameraPosition");
                cameraPositionInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialSystemValues"].CameraPosition);
            }
            cameraPositionInput.output.connectTo(this.cameraPosition);
        }
    };
    LightBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        if (!defines._areLightsDirty) {
            return;
        }
        var scene = mesh.getScene();
        if (!this.light) {
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForLights(scene, mesh, defines, true, nodeMaterial.maxSimultaneousLights);
        }
        else {
            var state = {
                needNormals: false,
                needRebuild: false,
                lightmapMode: false,
                shadowEnabled: false,
                specularEnabled: false
            };
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForLight(scene, mesh, this.light, this._lightId, defines, true, state);
            if (state.needRebuild) {
                defines.rebuild();
            }
        }
    };
    LightBlock.prototype.updateUniformsAndSamples = function (state, nodeMaterial, defines) {
        for (var lightIndex = 0; lightIndex < nodeMaterial.maxSimultaneousLights; lightIndex++) {
            if (!defines["LIGHT" + lightIndex]) {
                break;
            }
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareUniformsAndSamplersForLight(lightIndex, state.uniforms, state.samplers, false, state.uniformBuffers);
        }
    };
    LightBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (!mesh) {
            return;
        }
        var scene = mesh.getScene();
        if (!this.light) {
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindLights(scene, mesh, effect, true, nodeMaterial.maxSimultaneousLights, false);
        }
        else {
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindLight(this.light, this._lightId, scene, mesh, effect, true, false);
        }
    };
    LightBlock.prototype._injectVertexCode = function (state) {
        var worldPos = this.worldPosition;
        var comments = "//" + this.name;
        // Declaration
        if (!this.light) { // Emit for all lights
            state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                repeatKey: "maxSimultaneousLights"
            });
            this._lightId = 0;
            state.sharedData.dynamicUniformBlocks.push(this);
        }
        else {
            this._lightId = (state.counters["lightCounter"] !== undefined ? state.counters["lightCounter"] : -1) + 1;
            state.counters["lightCounter"] = this._lightId;
            state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }]
            }, this._lightId.toString());
        }
        // Inject code in vertex
        var worldPosVaryingName = "v_" + worldPos.associatedVariableName;
        if (state._emitVaryingFromString(worldPosVaryingName, "vec4")) {
            state.compilationString += worldPosVaryingName + " = " + worldPos.associatedVariableName + ";\r\n";
        }
        if (this.light) {
            state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
                replaceStrings: [
                    { search: /{X}/g, replace: this._lightId.toString() },
                    { search: /worldPos/g, replace: worldPos.associatedVariableName }
                ]
            });
        }
        else {
            state.compilationString += "vec4 worldPos = " + worldPos.associatedVariableName + ";\r\n";
            state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
                repeatKey: "maxSimultaneousLights"
            });
        }
    };
    LightBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        if (state.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Fragment) {
            // Vertex
            this._injectVertexCode(state);
            return;
        }
        // Fragment
        state.sharedData.bindableBlocks.push(this);
        state.sharedData.blocksWithDefines.push(this);
        var comments = "//" + this.name;
        var worldPos = this.worldPosition;
        state._emitFunctionFromInclude("helperFunctions", comments);
        state._emitFunctionFromInclude("lightsFragmentFunctions", comments, {
            replaceStrings: [
                { search: /vPositionW/g, replace: "v_" + worldPos.associatedVariableName + ".xyz" }
            ]
        });
        state._emitFunctionFromInclude("shadowsFragmentFunctions", comments, {
            replaceStrings: [
                { search: /vPositionW/g, replace: "v_" + worldPos.associatedVariableName + ".xyz" }
            ]
        });
        if (!this.light) { // Emit for all lights
            state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                repeatKey: "maxSimultaneousLights"
            });
        }
        else {
            state._emitFunctionFromInclude(state.supportUniformBuffers ? "lightUboDeclaration" : "lightFragmentDeclaration", comments, {
                replaceStrings: [{ search: /{X}/g, replace: this._lightId.toString() }]
            }, this._lightId.toString());
            // Uniforms and samplers
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareUniformsAndSamplersForLight(this._lightId, state.uniforms, state.samplers, undefined, state.uniformBuffers);
        }
        // Code
        if (this._lightId === 0) {
            if (state._registerTempVariable("viewDirectionW")) {
                state.compilationString += "vec3 viewDirectionW = normalize(" + this.cameraPosition.associatedVariableName + " - " + ("v_" + worldPos.associatedVariableName) + ".xyz);\r\n";
            }
            state.compilationString += "lightingInfo info;\r\n";
            state.compilationString += "float shadow = 1.;\r\n";
            state.compilationString += "float glossiness = 0.;\r\n";
            state.compilationString += "vec3 diffuseBase = vec3(0., 0., 0.);\r\n";
            state.compilationString += "vec3 specularBase = vec3(0., 0., 0.);\r\n";
            state.compilationString += "vec3 normalW = " + this.worldNormal.associatedVariableName + ".xyz;\r\n";
        }
        if (this.light) {
            state.compilationString += state._emitCodeFromInclude("lightFragment", comments, {
                replaceStrings: [
                    { search: /{X}/g, replace: this._lightId.toString() }
                ]
            });
        }
        else {
            state.compilationString += state._emitCodeFromInclude("lightFragment", comments, {
                repeatKey: "maxSimultaneousLights"
            });
        }
        var diffuseOutput = this.diffuseOutput;
        var specularOutput = this.specularOutput;
        state.compilationString += this._declareOutput(diffuseOutput, state) + " = diffuseBase;\r\n";
        if (specularOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(specularOutput, state) + " = specularBase;\r\n";
        }
        return this;
    };
    LightBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        if (this.light) {
            serializationObject.lightId = this.light.id;
        }
        return serializationObject;
    };
    LightBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        if (serializationObject.lightId) {
            this.light = scene.getLightByID(serializationObject.lightId);
        }
    };
    return LightBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.LightBlock"] = LightBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Dual/reflectionTextureBlock.ts":
/*!**************************************************************!*\
  !*** ./Materials/Node/Blocks/Dual/reflectionTextureBlock.ts ***!
  \**************************************************************/
/*! exports provided: ReflectionTextureBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return ReflectionTextureBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Textures_texture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../../Engines/constants */ "./Engines/constants.ts");









/**
 * Block used to read a reflection texture from a sampler
 */
var ReflectionTextureBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ReflectionTextureBlock, _super);
    /**
     * Create a new TextureBlock
     * @param name defines the block name
     */
    function ReflectionTextureBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment) || this;
        _this.registerInput("position", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex);
        _this.registerInput("worldPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex);
        _this.registerInput("worldNormal", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex);
        _this.registerInput("world", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex);
        _this.registerInput("cameraPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerInput("view", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("rgb", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("r", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("g", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("b", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ReflectionTextureBlock.prototype.getClassName = function () {
        return "ReflectionTextureBlock";
    };
    Object.defineProperty(ReflectionTextureBlock.prototype, "position", {
        /**
         * Gets the world position input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "worldPosition", {
        /**
         * Gets the world position input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "worldNormal", {
        /**
         * Gets the world normal input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "world", {
        /**
         * Gets the world input component
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "cameraPosition", {
        /**
        * Gets the camera (or eye) position component
        */
        get: function () {
            return this._inputs[4];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "view", {
        /**
         * Gets the view input component
         */
        get: function () {
            return this._inputs[5];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "rgb", {
        /**
         * Gets the rgb output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "r", {
        /**
         * Gets the r output component
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "g", {
        /**
         * Gets the g output component
         */
        get: function () {
            return this._outputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionTextureBlock.prototype, "b", {
        /**
         * Gets the b output component
         */
        get: function () {
            return this._outputs[3];
        },
        enumerable: true,
        configurable: true
    });
    ReflectionTextureBlock.prototype.autoConfigure = function (material) {
        if (!this.position.isConnected) {
            var positionInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "position"; });
            if (!positionInput) {
                positionInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("position");
                positionInput.setAsAttribute();
            }
            positionInput.output.connectTo(this.position);
        }
        if (!this.world.isConnected) {
            var worldInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialSystemValues"].World; });
            if (!worldInput) {
                worldInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("world");
                worldInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialSystemValues"].World);
            }
            worldInput.output.connectTo(this.world);
        }
        if (!this.cameraPosition.isConnected) {
            var cameraPositionInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialSystemValues"].CameraPosition; });
            if (!cameraPositionInput) {
                cameraPositionInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("cameraPosition");
                cameraPositionInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialSystemValues"].CameraPosition);
            }
            cameraPositionInput.output.connectTo(this.cameraPosition);
        }
        if (!this.view.isConnected) {
            var viewInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialSystemValues"].View; });
            if (!viewInput) {
                viewInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("view");
                viewInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialSystemValues"].View);
            }
            viewInput.output.connectTo(this.view);
        }
    };
    ReflectionTextureBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        if (!defines._areTexturesDirty) {
            return;
        }
        if (!this.texture || !this.texture.getTextureMatrix) {
            return;
        }
        defines.setValue(this._define3DName, this.texture.isCube);
        defines.setValue(this._defineLocalCubicName, this.texture.boundingBoxSize ? true : false);
        defines.setValue(this._defineExplicitName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_EXPLICIT_MODE);
        defines.setValue(this._defineSkyboxName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_SKYBOX_MODE);
        defines.setValue(this._defineCubicName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_CUBIC_MODE);
        defines.setValue(this._defineSphericalName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_SPHERICAL_MODE);
        defines.setValue(this._definePlanarName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_PLANAR_MODE);
        defines.setValue(this._defineProjectionName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_PROJECTION_MODE);
        defines.setValue(this._defineEquirectangularName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_EQUIRECTANGULAR_MODE);
        defines.setValue(this._defineEquirectangularFixedName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_FIXED_EQUIRECTANGULAR_MODE);
        defines.setValue(this._defineMirroredEquirectangularFixedName, this.texture.coordinatesMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE);
    };
    ReflectionTextureBlock.prototype.isReady = function () {
        if (this.texture && !this.texture.isReadyOrNotBlocking()) {
            return false;
        }
        return true;
    };
    ReflectionTextureBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (!mesh || !this.texture) {
            return;
        }
        effect.setMatrix(this._reflectionMatrixName, this.texture.getReflectionTextureMatrix());
        if (this.texture.isCube) {
            effect.setTexture(this._cubeSamplerName, this.texture);
        }
        else {
            effect.setTexture(this._2DSamplerName, this.texture);
        }
    };
    ReflectionTextureBlock.prototype._injectVertexCode = function (state) {
        var worldPosVaryingName = "v_" + this.worldPosition.associatedVariableName;
        if (state._emitVaryingFromString(worldPosVaryingName, "vec4")) {
            state.compilationString += worldPosVaryingName + " = " + this.worldPosition.associatedVariableName + ";\r\n";
        }
        var worldNormalVaryingName = "v_" + this.worldNormal.associatedVariableName;
        if (state._emitVaryingFromString(worldNormalVaryingName, "vec4")) {
            state.compilationString += worldNormalVaryingName + " = " + this.worldNormal.associatedVariableName + ";\r\n";
        }
        this._positionUVWName = state._getFreeVariableName("positionUVW");
        this._directionWName = state._getFreeVariableName("directionW");
        if (state._emitVaryingFromString(this._positionUVWName, "vec3", this._defineSkyboxName)) {
            state.compilationString += "#ifdef " + this._defineSkyboxName + "\r\n";
            state.compilationString += this._positionUVWName + " = " + this.position.associatedVariableName + ";\r\n";
            state.compilationString += "#endif\r\n";
        }
        if (state._emitVaryingFromString(this._directionWName, "vec3", "defined(" + this._defineEquirectangularFixedName + ") || defined(" + this._defineMirroredEquirectangularFixedName + ")")) {
            state.compilationString += "#if defined(" + this._defineEquirectangularFixedName + ") || defined(" + this._defineMirroredEquirectangularFixedName + ")\r\n";
            state.compilationString += this._directionWName + " = normalize(vec3(" + this.world.associatedVariableName + " * vec4(" + this.position.associatedVariableName + ", 0.0)));\r\n";
            state.compilationString += "#endif\r\n";
        }
    };
    ReflectionTextureBlock.prototype._writeOutput = function (state, output, swizzle) {
        state.compilationString += this._declareOutput(output, state) + " = " + this._reflectionColorName + "." + swizzle + ";\r\n";
    };
    ReflectionTextureBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        if (state.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) {
            this._define3DName = state._getFreeDefineName("REFLECTIONMAP_3D");
            this._defineCubicName = state._getFreeDefineName("REFLECTIONMAP_CUBIC");
            this._defineSphericalName = state._getFreeDefineName("REFLECTIONMAP_SPHERICAL");
            this._definePlanarName = state._getFreeDefineName("REFLECTIONMAP_PLANAR");
            this._defineProjectionName = state._getFreeDefineName("REFLECTIONMAP_PROJECTION");
            this._defineExplicitName = state._getFreeDefineName("REFLECTIONMAP_EXPLICIT");
            this._defineEquirectangularName = state._getFreeDefineName("REFLECTIONMAP_EQUIRECTANGULAR");
            this._defineLocalCubicName = state._getFreeDefineName("USE_LOCAL_REFLECTIONMAP_CUBIC");
            this._defineMirroredEquirectangularFixedName = state._getFreeDefineName("REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED");
            this._defineEquirectangularFixedName = state._getFreeDefineName("REFLECTIONMAP_EQUIRECTANGULAR_FIXED");
            this._defineSkyboxName = state._getFreeDefineName("REFLECTIONMAP_SKYBOX");
            // Vertex
            this._injectVertexCode(state);
            return;
        }
        state.sharedData.blockingBlocks.push(this);
        state.sharedData.textureBlocks.push(this);
        // Samplers
        this._cubeSamplerName = state._getFreeVariableName(this.name + "CubeSampler");
        state.samplers.push(this._cubeSamplerName);
        this._2DSamplerName = state._getFreeVariableName(this.name + "2DSampler");
        state.samplers.push(this._2DSamplerName);
        state._samplerDeclaration += "#ifdef " + this._define3DName + "\r\n";
        state._samplerDeclaration += "uniform samplerCube " + this._cubeSamplerName + ";\r\n";
        state._samplerDeclaration += "#else\r\n";
        state._samplerDeclaration += "uniform sampler2D " + this._2DSamplerName + ";\r\n";
        state._samplerDeclaration += "#endif\r\n";
        // Fragment
        state.sharedData.blocksWithDefines.push(this);
        state.sharedData.bindableBlocks.push(this);
        var comments = "//" + this.name;
        state._emitFunction("ReciprocalPI", "#define RECIPROCAL_PI2 0.15915494", "");
        state._emitFunctionFromInclude("reflectionFunction", comments);
        this._reflectionColorName = state._getFreeVariableName("reflectionColor");
        this._reflectionCoordsName = state._getFreeVariableName("reflectionUVW");
        this._reflection2DCoordsName = state._getFreeVariableName("reflectionUV");
        this._reflectionMatrixName = state._getFreeVariableName("reflectionMatrix");
        state._emitUniformFromString(this._reflectionMatrixName, "mat4");
        // Code
        var worldPos = "v_" + this.worldPosition.associatedVariableName;
        var worldNormal = "v_" + this.worldNormal.associatedVariableName + ".xyz";
        var reflectionMatrix = this._reflectionMatrixName;
        var direction = "normalize(" + this._directionWName + ")";
        var positionUVW = "" + this._positionUVWName;
        var vEyePosition = "" + this.cameraPosition.associatedVariableName;
        var view = "" + this.view.associatedVariableName;
        state.compilationString += "vec3 " + this._reflectionColorName + ";\r\n";
        state.compilationString += "#ifdef " + this._define3DName + "\r\n";
        state.compilationString += "#ifdef " + this._defineMirroredEquirectangularFixedName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computeMirroredFixedEquirectangularCoords(" + worldPos + ", " + worldNormal + ", " + direction + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._defineEquirectangularFixedName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computeFixedEquirectangularCoords(" + worldPos + ", " + worldNormal + ", " + direction + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._defineEquirectangularName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computeEquirectangularCoords(" + worldPos + ", " + worldNormal + ", " + vEyePosition + ".xyz, " + reflectionMatrix + ");\r\n";
        state.compilationString += " #endif\r\n";
        state.compilationString += "#ifdef " + this._defineSphericalName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computeSphericalCoords(" + worldPos + ", " + worldNormal + ", " + view + ", " + reflectionMatrix + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._definePlanarName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computePlanarCoords(" + worldPos + ", " + worldNormal + ", " + vEyePosition + ".xyz, " + reflectionMatrix + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._defineCubicName + "\r\n";
        state.compilationString += "    #ifdef " + this._defineLocalCubicName + "\r\n";
        state.compilationString += "        vec3 " + this._reflectionCoordsName + " = computeCubicLocalCoords(" + worldPos + ", " + worldNormal + ", " + vEyePosition + ".xyz, " + reflectionMatrix + ", vReflectionSize, vReflectionPosition);\r\n";
        state.compilationString += "    #else\r\n";
        state.compilationString += "       vec3 " + this._reflectionCoordsName + " = computeCubicCoords(" + worldPos + ", " + worldNormal + ", " + vEyePosition + ".xyz, " + reflectionMatrix + ");\r\n";
        state.compilationString += "    #endif\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._defineProjectionName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computeProjectionCoords(" + worldPos + ", " + view + ", " + reflectionMatrix + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._defineSkyboxName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = computeSkyBoxCoords(" + positionUVW + ", " + reflectionMatrix + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef " + this._defineExplicitName + "\r\n";
        state.compilationString += "    vec3 " + this._reflectionCoordsName + " = vec3(0, 0, 0);\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += this._reflectionColorName + " = textureCube(" + this._cubeSamplerName + ", " + this._reflectionCoordsName + ").rgb;\r\n";
        state.compilationString += "#else\r\n";
        state.compilationString += "vec2 " + this._reflection2DCoordsName + " = " + this._reflectionCoordsName + ".xy;\r\n";
        state.compilationString += "#ifdef " + this._defineProjectionName + "\r\n";
        state.compilationString += this._reflection2DCoordsName + " /= " + this._reflectionCoordsName + ".z;\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += this._reflection2DCoordsName + ".y = 1.0 - " + this._reflection2DCoordsName + ".y;\r\n";
        state.compilationString += this._reflectionColorName + " = texture2D(" + this._2DSamplerName + ", " + this._reflection2DCoordsName + ").rgb;\r\n";
        state.compilationString += "#endif\r\n";
        for (var _i = 0, _a = this._outputs; _i < _a.length; _i++) {
            var output = _a[_i];
            if (output.hasEndpoints) {
                this._writeOutput(state, output, output.name);
            }
        }
        return this;
    };
    ReflectionTextureBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        if (this.texture) {
            serializationObject.texture = this.texture.serialize();
        }
        return serializationObject;
    };
    ReflectionTextureBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        if (serializationObject.texture) {
            this.texture = _Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].Parse(serializationObject.texture, scene, rootUrl);
        }
    };
    return ReflectionTextureBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ReflectionTextureBlock"] = ReflectionTextureBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Dual/textureBlock.ts":
/*!****************************************************!*\
  !*** ./Materials/Node/Blocks/Dual/textureBlock.ts ***!
  \****************************************************/
/*! exports provided: TextureBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return TextureBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Textures_texture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../Textures/texture */ "./Materials/Textures/texture.ts");







/**
 * Block used to read a texture from a sampler
 */
var TextureBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TextureBlock, _super);
    /**
     * Create a new TextureBlock
     * @param name defines the block name
     */
    function TextureBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment) || this;
        _this.registerInput("uv", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment);
        _this.registerOutput("rgba", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("rgb", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("r", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("g", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("b", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this.registerOutput("a", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment);
        _this._inputs[0].acceptedConnectionPointTypes.push(_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this._inputs[0].acceptedConnectionPointTypes.push(_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    TextureBlock.prototype.getClassName = function () {
        return "TextureBlock";
    };
    Object.defineProperty(TextureBlock.prototype, "uv", {
        /**
         * Gets the uv input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "rgba", {
        /**
         * Gets the rgba output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "rgb", {
        /**
         * Gets the rgb output component
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "r", {
        /**
         * Gets the r output component
         */
        get: function () {
            return this._outputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "g", {
        /**
         * Gets the g output component
         */
        get: function () {
            return this._outputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "b", {
        /**
         * Gets the b output component
         */
        get: function () {
            return this._outputs[4];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "a", {
        /**
         * Gets the a output component
         */
        get: function () {
            return this._outputs[5];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TextureBlock.prototype, "target", {
        get: function () {
            // TextureBlock has a special optimizations for uvs that come from the vertex shaders as they can be packed into a single varyings.
            // But we need to detect uvs coming from fragment then
            if (!this.uv.isConnected) {
                return _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment;
            }
            if (this.uv.sourceBlock.isInput) {
                return _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment;
            }
            var parent = this.uv.connectedPoint;
            while (parent) {
                if (parent.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) {
                    return _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment;
                }
                if (parent.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex) {
                    return _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment;
                }
                if (parent.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral || parent.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment) {
                    var parentBlock = parent.ownerBlock;
                    parent = null;
                    for (var _i = 0, _a = parentBlock.inputs; _i < _a.length; _i++) {
                        var input = _a[_i];
                        if (input.connectedPoint) {
                            parent = input.connectedPoint;
                            break;
                        }
                    }
                }
            }
            return _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].VertexAndFragment;
        },
        enumerable: true,
        configurable: true
    });
    TextureBlock.prototype.autoConfigure = function (material) {
        if (!this.uv.isConnected) {
            var uvInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "uv"; });
            if (!uvInput) {
                uvInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_4__["InputBlock"]("uv");
                uvInput.setAsAttribute();
            }
            uvInput.output.connectTo(this.uv);
        }
    };
    TextureBlock.prototype.initializeDefines = function (mesh, nodeMaterial, defines, useInstances) {
        if (useInstances === void 0) { useInstances = false; }
        if (!defines._areTexturesDirty) {
            return;
        }
        defines.setValue(this._mainUVDefineName, false);
    };
    TextureBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        if (!defines._areTexturesDirty) {
            return;
        }
        if (!this.texture || !this.texture.getTextureMatrix) {
            return;
        }
        if (!this.texture.getTextureMatrix().isIdentityAs3x2()) {
            defines.setValue(this._defineName, true);
        }
        else {
            defines.setValue(this._defineName, false);
            defines.setValue(this._mainUVDefineName, true);
        }
    };
    TextureBlock.prototype.isReady = function () {
        if (this.texture && !this.texture.isReadyOrNotBlocking()) {
            return false;
        }
        return true;
    };
    TextureBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (!mesh || !this.texture) {
            return;
        }
        if (this._isMixed) {
            effect.setFloat(this._textureInfoName, this.texture.level);
            effect.setMatrix(this._textureTransformName, this.texture.getTextureMatrix());
        }
        effect.setTexture(this._samplerName, this.texture);
    };
    Object.defineProperty(TextureBlock.prototype, "_isMixed", {
        get: function () {
            return this.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment;
        },
        enumerable: true,
        configurable: true
    });
    TextureBlock.prototype._injectVertexCode = function (state) {
        var uvInput = this.uv;
        // Inject code in vertex
        this._defineName = state._getFreeDefineName("UVTRANSFORM");
        this._mainUVDefineName = state._getFreeDefineName("vMain" + uvInput.associatedVariableName);
        if (uvInput.connectedPoint.ownerBlock.isInput) {
            var uvInputOwnerBlock = uvInput.connectedPoint.ownerBlock;
            if (!uvInputOwnerBlock.isAttribute) {
                state._emitUniformFromString(uvInput.associatedVariableName, "vec2");
            }
        }
        this._mainUVName = "vMain" + uvInput.associatedVariableName;
        this._transformedUVName = state._getFreeVariableName("transformedUV");
        this._textureTransformName = state._getFreeVariableName("textureTransform");
        this._textureInfoName = state._getFreeVariableName("textureInfoName");
        state._emitVaryingFromString(this._transformedUVName, "vec2", this._defineName);
        state._emitVaryingFromString(this._mainUVName, "vec2", this._mainUVDefineName);
        state._emitUniformFromString(this._textureTransformName, "mat4", this._defineName);
        state.compilationString += "#ifdef " + this._defineName + "\r\n";
        state.compilationString += this._transformedUVName + " = vec2(" + this._textureTransformName + " * vec4(" + uvInput.associatedVariableName + ".xy, 1.0, 0.0));\r\n";
        state.compilationString += "#else\r\n";
        state.compilationString += this._mainUVName + " = " + uvInput.associatedVariableName + ".xy;\r\n";
        state.compilationString += "#endif\r\n";
    };
    TextureBlock.prototype._writeOutput = function (state, output, swizzle) {
        var uvInput = this.uv;
        if (this.uv.ownerBlock.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) {
            state.compilationString += this._declareOutput(output, state) + " = texture2D(" + this._samplerName + ", " + uvInput.associatedVariableName + ")." + swizzle + ";\r\n";
            return;
        }
        var complement = " * " + this._textureInfoName;
        state.compilationString += "#ifdef " + this._defineName + "\r\n";
        state.compilationString += this._declareOutput(output, state) + " = texture2D(" + this._samplerName + ", " + this._transformedUVName + ")." + swizzle + complement + ";\r\n";
        state.compilationString += "#else\r\n";
        state.compilationString += this._declareOutput(output, state) + " = texture2D(" + this._samplerName + ", " + ("vMain" + uvInput.associatedVariableName) + ")." + swizzle + complement + ";\r\n";
        state.compilationString += "#endif\r\n";
    };
    TextureBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        if (state.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) {
            // Vertex
            this._injectVertexCode(state);
            return;
        }
        state.sharedData.blockingBlocks.push(this);
        state.sharedData.textureBlocks.push(this);
        this._samplerName = state._getFreeVariableName(this.name + "Sampler");
        state.samplers.push(this._samplerName);
        state._samplerDeclaration += "uniform sampler2D " + this._samplerName + ";\r\n";
        // Fragment
        state.sharedData.bindableBlocks.push(this);
        if (this._isMixed) {
            state.sharedData.blocksWithDefines.push(this);
            state._emitUniformFromString(this._textureInfoName, "float");
        }
        for (var _i = 0, _a = this._outputs; _i < _a.length; _i++) {
            var output = _a[_i];
            if (output.hasEndpoints) {
                this._writeOutput(state, output, output.name);
            }
        }
        return this;
    };
    TextureBlock.prototype._dumpPropertiesCode = function () {
        if (!this.texture) {
            return "";
        }
        var codeString = this._codeVariableName + ".texture = new BABYLON.Texture(\"" + this.texture.name + "\");\r\n";
        return codeString;
    };
    TextureBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        if (this.texture) {
            serializationObject.texture = this.texture.serialize();
        }
        return serializationObject;
    };
    TextureBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        if (serializationObject.texture) {
            this.texture = _Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].Parse(serializationObject.texture, scene, rootUrl);
        }
    };
    return TextureBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.TextureBlock"] = TextureBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Fragment/alphaTestBlock.ts":
/*!**********************************************************!*\
  !*** ./Materials/Node/Blocks/Fragment/alphaTestBlock.ts ***!
  \**********************************************************/
/*! exports provided: AlphaTestBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return AlphaTestBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to add an alpha test in the fragment shader
 */
var AlphaTestBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AlphaTestBlock, _super);
    /**
     * Create a new AlphaTestBlock
     * @param name defines the block name
     */
    function AlphaTestBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) || this;
        /**
         * Gets or sets the alpha value where alpha testing happens
         */
        _this.alphaCutOff = 0.4;
        _this.registerInput("color", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4, true);
        _this.registerInput("alpha", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    AlphaTestBlock.prototype.getClassName = function () {
        return "AlphaTestBlock";
    };
    Object.defineProperty(AlphaTestBlock.prototype, "color", {
        /**
         * Gets the color input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AlphaTestBlock.prototype, "alpha", {
        /**
         * Gets the alpha input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    AlphaTestBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        state.sharedData.hints.needAlphaTesting = true;
        if (this.color.connectedPoint) {
            state.compilationString += "if (" + this.color.associatedVariableName + ".a < " + this.alphaCutOff + ") discard;\r\n";
        }
        else {
            state.compilationString += "if (" + this.alpha.associatedVariableName + " < " + this.alphaCutOff + ") discard;\r\n";
        }
        return this;
    };
    AlphaTestBlock.prototype._dumpPropertiesCode = function () {
        var codeString = this._codeVariableName + ".alphaCutOff = " + this.alphaCutOff + ";\r\n";
        return codeString;
    };
    AlphaTestBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.alphaCutOff = this.alphaCutOff;
        return serializationObject;
    };
    AlphaTestBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        this.alphaCutOff = serializationObject.alphaCutOff;
    };
    return AlphaTestBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.AlphaTestBlock"] = AlphaTestBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts":
/*!***************************************************************!*\
  !*** ./Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts ***!
  \***************************************************************/
/*! exports provided: FragmentOutputBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return FragmentOutputBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to output the final color
 */
var FragmentOutputBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FragmentOutputBlock, _super);
    /**
     * Create a new FragmentOutputBlock
     * @param name defines the block name
     */
    function FragmentOutputBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment, true) || this;
        _this.registerInput("rgba", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4, true);
        _this.registerInput("rgb", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, true);
        _this.registerInput("a", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    FragmentOutputBlock.prototype.getClassName = function () {
        return "FragmentOutputBlock";
    };
    Object.defineProperty(FragmentOutputBlock.prototype, "rgba", {
        /**
         * Gets the rgba input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FragmentOutputBlock.prototype, "rgb", {
        /**
         * Gets the rgb input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FragmentOutputBlock.prototype, "a", {
        /**
         * Gets the a input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    FragmentOutputBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var rgba = this.rgba;
        var rgb = this.rgb;
        var a = this.a;
        state.sharedData.hints.needAlphaBlending = rgba.isConnected || a.isConnected;
        if (rgba.connectedPoint) {
            state.compilationString += "gl_FragColor = " + rgba.associatedVariableName + ";\r\n";
        }
        else if (rgb.connectedPoint) {
            if (a.connectedPoint) {
                state.compilationString += "gl_FragColor = vec4(" + rgb.associatedVariableName + ", " + a.associatedVariableName + ");\r\n";
            }
            else {
                state.compilationString += "gl_FragColor = vec4(" + rgb.associatedVariableName + ", 1.0);\r\n";
            }
        }
        else {
            state.sharedData.checks.notConnectedNonOptionalInputs.push(rgba);
        }
        return this;
    };
    return FragmentOutputBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.FragmentOutputBlock"] = FragmentOutputBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Fragment/imageProcessingBlock.ts":
/*!****************************************************************!*\
  !*** ./Materials/Node/Blocks/Fragment/imageProcessingBlock.ts ***!
  \****************************************************************/
/*! exports provided: ImageProcessingBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return ImageProcessingBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to add image processing support to fragment shader
 */
var ImageProcessingBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ImageProcessingBlock, _super);
    /**
     * Create a new ImageProcessingBlock
     * @param name defines the block name
     */
    function ImageProcessingBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) || this;
        _this.registerInput("color", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4);
        _this._inputs[0].acceptedConnectionPointTypes.push(_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ImageProcessingBlock.prototype.getClassName = function () {
        return "ImageProcessingBlock";
    };
    Object.defineProperty(ImageProcessingBlock.prototype, "color", {
        /**
         * Gets the color input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Initialize the block and prepare the context for build
     * @param state defines the state that will be used for the build
     */
    ImageProcessingBlock.prototype.initialize = function (state) {
        state._excludeVariableName("exposureLinear");
        state._excludeVariableName("contrast");
        state._excludeVariableName("vInverseScreenSize");
        state._excludeVariableName("vignetteSettings1");
        state._excludeVariableName("vignetteSettings2");
        state._excludeVariableName("vCameraColorCurveNegative");
        state._excludeVariableName("vCameraColorCurveNeutral");
        state._excludeVariableName("vCameraColorCurvePositive");
        state._excludeVariableName("txColorTransform");
        state._excludeVariableName("colorTransformSettings");
    };
    ImageProcessingBlock.prototype.isReady = function (mesh, nodeMaterial, defines) {
        if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {
            if (!nodeMaterial.imageProcessingConfiguration.isReady()) {
                return false;
            }
        }
        return true;
    };
    ImageProcessingBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        if (defines._areImageProcessingDirty && nodeMaterial.imageProcessingConfiguration) {
            nodeMaterial.imageProcessingConfiguration.prepareDefines(defines);
        }
    };
    ImageProcessingBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (!mesh) {
            return;
        }
        if (!nodeMaterial.imageProcessingConfiguration) {
            return;
        }
        nodeMaterial.imageProcessingConfiguration.bind(effect);
    };
    ImageProcessingBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        // Register for defines
        state.sharedData.blocksWithDefines.push(this);
        // Register for blocking
        state.sharedData.blockingBlocks.push(this);
        // Register for binding
        state.sharedData.bindableBlocks.push(this);
        // Uniforms
        state.uniforms.push("exposureLinear");
        state.uniforms.push("contrast");
        state.uniforms.push("vInverseScreenSize");
        state.uniforms.push("vignetteSettings1");
        state.uniforms.push("vignetteSettings2");
        state.uniforms.push("vCameraColorCurveNegative");
        state.uniforms.push("vCameraColorCurveNeutral");
        state.uniforms.push("vCameraColorCurvePositive");
        state.uniforms.push("txColorTransform");
        state.uniforms.push("colorTransformSettings");
        // Emit code
        var color = this.color;
        var output = this._outputs[0];
        var comments = "//" + this.name;
        state._emitFunctionFromInclude("helperFunctions", comments);
        state._emitFunctionFromInclude("imageProcessingDeclaration", comments);
        state._emitFunctionFromInclude("imageProcessingFunctions", comments);
        if (color.connectedPoint.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4) {
            state.compilationString += this._declareOutput(output, state) + " = " + color.associatedVariableName + ";\r\n";
        }
        else {
            state.compilationString += this._declareOutput(output, state) + " = vec4(" + color.associatedVariableName + ", 1.0);\r\n";
        }
        state.compilationString += "#ifdef IMAGEPROCESSINGPOSTPROCESS\r\n";
        state.compilationString += output.associatedVariableName + ".rgb = toLinearSpace(" + color.associatedVariableName + ".rgb);\r\n";
        state.compilationString += "#else\r\n";
        state.compilationString += "#ifdef IMAGEPROCESSING\r\n";
        state.compilationString += output.associatedVariableName + ".rgb = toLinearSpace(" + color.associatedVariableName + ".rgb);\r\n";
        state.compilationString += output.associatedVariableName + " = applyImageProcessing(" + output.associatedVariableName + ");\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#endif\r\n";
        return this;
    };
    return ImageProcessingBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ImageProcessingBlock"] = ImageProcessingBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Fragment/index.ts":
/*!*************************************************!*\
  !*** ./Materials/Node/Blocks/Fragment/index.ts ***!
  \*************************************************/
/*! exports provided: FragmentOutputBlock, AlphaTestBlock, ImageProcessingBlock, PerturbNormalBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _fragmentOutputBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./fragmentOutputBlock */ "./Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return _fragmentOutputBlock__WEBPACK_IMPORTED_MODULE_0__["FragmentOutputBlock"]; });

/* harmony import */ var _alphaTestBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./alphaTestBlock */ "./Materials/Node/Blocks/Fragment/alphaTestBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return _alphaTestBlock__WEBPACK_IMPORTED_MODULE_1__["AlphaTestBlock"]; });

/* harmony import */ var _imageProcessingBlock__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./imageProcessingBlock */ "./Materials/Node/Blocks/Fragment/imageProcessingBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return _imageProcessingBlock__WEBPACK_IMPORTED_MODULE_2__["ImageProcessingBlock"]; });

/* harmony import */ var _perturbNormalBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./perturbNormalBlock */ "./Materials/Node/Blocks/Fragment/perturbNormalBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return _perturbNormalBlock__WEBPACK_IMPORTED_MODULE_3__["PerturbNormalBlock"]; });







/***/ }),

/***/ "./Materials/Node/Blocks/Fragment/perturbNormalBlock.ts":
/*!**************************************************************!*\
  !*** ./Materials/Node/Blocks/Fragment/perturbNormalBlock.ts ***!
  \**************************************************************/
/*! exports provided: PerturbNormalBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return PerturbNormalBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");






/**
 * Block used to pertub normals based on a normal map
 */
var PerturbNormalBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PerturbNormalBlock, _super);
    /**
     * Create a new PerturbNormalBlock
     * @param name defines the block name
     */
    function PerturbNormalBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        // Vertex
        _this.registerInput("worldPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, false);
        _this.registerInput("worldNormal", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, false);
        _this.registerInput("uv", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2, false);
        _this.registerInput("normalMapColor", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, false);
        _this.registerInput("strength", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, false);
        // Fragment
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    PerturbNormalBlock.prototype.getClassName = function () {
        return "PerturbNormalBlock";
    };
    Object.defineProperty(PerturbNormalBlock.prototype, "worldPosition", {
        /**
         * Gets the world position input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerturbNormalBlock.prototype, "worldNormal", {
        /**
         * Gets the world normal input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerturbNormalBlock.prototype, "uv", {
        /**
         * Gets the uv input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerturbNormalBlock.prototype, "normalMapColor", {
        /**
        * Gets the normal map color input component
        */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerturbNormalBlock.prototype, "strength", {
        /**
        * Gets the strength input component
        */
        get: function () {
            return this._inputs[4];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerturbNormalBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    PerturbNormalBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        defines.setValue("BUMP", true);
    };
    PerturbNormalBlock.prototype.autoConfigure = function (material) {
        if (!this.uv.isConnected) {
            var uvInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "uv"; });
            if (!uvInput) {
                uvInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("uv");
                uvInput.setAsAttribute();
            }
            uvInput.output.connectTo(this.uv);
        }
        if (!this.strength.isConnected) {
            var strengthInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("strength");
            strengthInput.value = 1.0;
            strengthInput.output.connectTo(this.strength);
        }
    };
    PerturbNormalBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var comments = "//" + this.name;
        var uv = this.uv;
        var worldPosition = this.worldPosition;
        var worldNormal = this.worldNormal;
        state.sharedData.blocksWithDefines.push(this);
        state._emitExtension("bump", "#extension GL_OES_standard_derivatives : enable");
        state._emitFunctionFromInclude("bumpFragmentFunctions", comments, {
            replaceStrings: [
                { search: /vBumpInfos.y/g, replace: "1.0 / " + this.strength.associatedVariableName },
                { search: /vTangentSpaceParams/g, replace: "vec2(1.0, 1.0)" },
                { search: /vPositionW/g, replace: worldPosition.associatedVariableName + ".xyz" }
            ]
        });
        state.compilationString += this._declareOutput(this.output, state) + " = vec4(0.);\r\n";
        state.compilationString += state._emitCodeFromInclude("bumpFragment", comments, {
            replaceStrings: [
                { search: /perturbNormal\(TBN,vBumpUV\+uvOffset\)/g, replace: "perturbNormal(TBN, " + this.normalMapColor.associatedVariableName + ")" },
                { search: /vBumpInfos.y/g, replace: "1.0 / " + this.strength.associatedVariableName },
                { search: /vBumpUV/g, replace: uv.associatedVariableName },
                { search: /vPositionW/g, replace: worldPosition.associatedVariableName + ".xyz" },
                { search: /normalW=/g, replace: this.output.associatedVariableName + ".xyz = " },
                { search: /normalW/g, replace: worldNormal.associatedVariableName + ".xyz" }
            ]
        });
        return this;
    };
    return PerturbNormalBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.PerturbNormalBlock"] = PerturbNormalBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Input/animatedInputBlockTypes.ts":
/*!****************************************************************!*\
  !*** ./Materials/Node/Blocks/Input/animatedInputBlockTypes.ts ***!
  \****************************************************************/
/*! exports provided: AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return AnimatedInputBlockTypes; });
/**
 * Enum defining the type of animations supported by InputBlock
 */
var AnimatedInputBlockTypes;
(function (AnimatedInputBlockTypes) {
    /** No animation */
    AnimatedInputBlockTypes[AnimatedInputBlockTypes["None"] = 0] = "None";
    /** Time based animation. Will only work for floats */
    AnimatedInputBlockTypes[AnimatedInputBlockTypes["Time"] = 1] = "Time";
})(AnimatedInputBlockTypes || (AnimatedInputBlockTypes = {}));


/***/ }),

/***/ "./Materials/Node/Blocks/Input/index.ts":
/*!**********************************************!*\
  !*** ./Materials/Node/Blocks/Input/index.ts ***!
  \**********************************************/
/*! exports provided: InputBlock, AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _inputBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return _inputBlock__WEBPACK_IMPORTED_MODULE_0__["InputBlock"]; });

/* harmony import */ var _animatedInputBlockTypes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./animatedInputBlockTypes */ "./Materials/Node/Blocks/Input/animatedInputBlockTypes.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return _animatedInputBlockTypes__WEBPACK_IMPORTED_MODULE_1__["AnimatedInputBlockTypes"]; });





/***/ }),

/***/ "./Materials/Node/Blocks/Input/inputBlock.ts":
/*!***************************************************!*\
  !*** ./Materials/Node/Blocks/Input/inputBlock.ts ***!
  \***************************************************/
/*! exports provided: InputBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return InputBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../NodeMaterialBlockConnectionPointMode */ "./Materials/Node/NodeMaterialBlockConnectionPointMode.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Maths_math__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../../Maths/math */ "./Maths/math.ts");
/* harmony import */ var _animatedInputBlockTypes__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./animatedInputBlockTypes */ "./Materials/Node/Blocks/Input/animatedInputBlockTypes.ts");










/**
 * Block used to expose an input value
 */
var InputBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InputBlock, _super);
    /**
     * Creates a new InputBlock
     * @param name defines the block name
     * @param target defines the target of that block (Vertex by default)
     * @param type defines the type of the input (can be set to NodeMaterialBlockConnectionPointTypes.AutoDetect)
     */
    function InputBlock(name, target, type) {
        if (target === void 0) { target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_6__["NodeMaterialBlockTargets"].Vertex; }
        if (type === void 0) { type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect; }
        var _this = _super.call(this, name, target, false, true) || this;
        _this._mode = _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Undefined;
        _this._animationType = _animatedInputBlockTypes__WEBPACK_IMPORTED_MODULE_9__["AnimatedInputBlockTypes"].None;
        /** @hidden */
        _this._systemValue = null;
        /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
        _this.visibleInInspector = false;
        _this._type = type;
        _this.setDefaultValue();
        _this.registerOutput("output", type);
        return _this;
    }
    Object.defineProperty(InputBlock.prototype, "type", {
        /**
         * Gets or sets the connection point type (default is float)
         */
        get: function () {
            if (this._type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect) {
                if (this.isUniform && this.value != null) {
                    if (!isNaN(this.value)) {
                        this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float;
                        return this._type;
                    }
                    switch (this.value.getClassName()) {
                        case "Vector2":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2;
                            return this._type;
                        case "Vector3":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3;
                            return this._type;
                        case "Vector4":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4;
                            return this._type;
                        case "Color3":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3;
                            return this._type;
                        case "Color4":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4;
                            return this._type;
                    }
                }
                if (this.isAttribute) {
                    switch (this.name) {
                        case "position":
                        case "normal":
                        case "tangent":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3;
                            return this._type;
                        case "uv":
                        case "uv2":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2;
                            return this._type;
                        case "matricesIndices":
                        case "matricesWeights":
                        case "world0":
                        case "world1":
                        case "world2":
                        case "world3":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4;
                            return this._type;
                        case "color":
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4;
                            return this._type;
                    }
                }
                if (this.isSystemValue) {
                    switch (this._systemValue) {
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].World:
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldView:
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldViewProjection:
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].View:
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].ViewProjection:
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].Projection:
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix;
                            return this._type;
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].CameraPosition:
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3;
                            return this._type;
                        case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].FogColor:
                            this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3;
                            return this._type;
                    }
                }
            }
            return this._type;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Set the source of this connection point to a vertex attribute
     * @param attributeName defines the attribute name (position, uv, normal, etc...). If not specified it will take the connection point name
     * @returns the current connection point
     */
    InputBlock.prototype.setAsAttribute = function (attributeName) {
        if (attributeName) {
            this.name = attributeName;
        }
        this._mode = _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Attribute;
        return this;
    };
    /**
     * Set the source of this connection point to a system value
     * @param value define the system value to use (world, view, etc...) or null to switch to manual value
     * @returns the current connection point
     */
    InputBlock.prototype.setAsSystemValue = function (value) {
        this.systemValue = value;
        return this;
    };
    Object.defineProperty(InputBlock.prototype, "value", {
        /**
         * Gets or sets the value of that point.
         * Please note that this value will be ignored if valueCallback is defined
         */
        get: function () {
            return this._storedValue;
        },
        set: function (value) {
            this._storedValue = value;
            this._mode = _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "valueCallback", {
        /**
         * Gets or sets a callback used to get the value of that point.
         * Please note that setting this value will force the connection point to ignore the value property
         */
        get: function () {
            return this._valueCallback;
        },
        set: function (value) {
            this._valueCallback = value;
            this._mode = _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "associatedVariableName", {
        /**
         * Gets or sets the associated variable name in the shader
         */
        get: function () {
            return this._associatedVariableName;
        },
        set: function (value) {
            this._associatedVariableName = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "animationType", {
        /** Gets or sets the type of animation applied to the input */
        get: function () {
            return this._animationType;
        },
        set: function (value) {
            this._animationType = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "isUndefined", {
        /**
         * Gets a boolean indicating that this connection point not defined yet
         */
        get: function () {
            return this._mode === _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Undefined;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "isUniform", {
        /**
         * Gets or sets a boolean indicating that this connection point is coming from an uniform.
         * In this case the connection point name must be the name of the uniform to use.
         * Can only be set on inputs
         */
        get: function () {
            return this._mode === _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform;
        },
        set: function (value) {
            this._mode = value ? _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform : _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Undefined;
            this.associatedVariableName = "";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "isAttribute", {
        /**
         * Gets or sets a boolean indicating that this connection point is coming from an attribute.
         * In this case the connection point name must be the name of the attribute to use
         * Can only be set on inputs
         */
        get: function () {
            return this._mode === _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Attribute;
        },
        set: function (value) {
            this._mode = value ? _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Attribute : _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Undefined;
            this.associatedVariableName = "";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "isVarying", {
        /**
         * Gets or sets a boolean indicating that this connection point is generating a varying variable.
         * Can only be set on exit points
         */
        get: function () {
            return this._mode === _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Varying;
        },
        set: function (value) {
            this._mode = value ? _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Varying : _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Undefined;
            this.associatedVariableName = "";
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "isSystemValue", {
        /**
         * Gets a boolean indicating that the current connection point is a system value
         */
        get: function () {
            return this._systemValue != null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InputBlock.prototype, "systemValue", {
        /**
         * Gets or sets the current well known value or null if not defined as a system value
         */
        get: function () {
            return this._systemValue;
        },
        set: function (value) {
            this._mode = _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform;
            this.associatedVariableName = "";
            this._systemValue = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current class name
     * @returns the class name
     */
    InputBlock.prototype.getClassName = function () {
        return "InputBlock";
    };
    /**
     * Animate the input if animationType !== None
     * @param scene defines the rendering scene
     */
    InputBlock.prototype.animate = function (scene) {
        switch (this._animationType) {
            case _animatedInputBlockTypes__WEBPACK_IMPORTED_MODULE_9__["AnimatedInputBlockTypes"].Time: {
                if (this.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float) {
                    this.value += scene.getAnimationRatio() * 0.01;
                }
                break;
            }
        }
    };
    InputBlock.prototype._emitDefine = function (define) {
        if (define[0] === "!") {
            return "#ifndef " + define.substring(1) + "\r\n";
        }
        return "#ifdef " + define + "\r\n";
    };
    /**
     * Set the input block to its default value (based on its type)
     */
    InputBlock.prototype.setDefaultValue = function () {
        switch (this.type) {
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float:
                this.value = 0;
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                this.value = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"].Zero();
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                this.value = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4:
                this.value = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector4"].Zero();
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3:
                this.value = _Maths_math__WEBPACK_IMPORTED_MODULE_8__["Color3"].White();
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4:
                this.value = new _Maths_math__WEBPACK_IMPORTED_MODULE_8__["Color4"](1, 1, 1, 1);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix:
                this.value = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
                break;
        }
    };
    InputBlock.prototype._dumpPropertiesCode = function () {
        if (this.isAttribute) {
            return this._codeVariableName + ".setAsAttribute(\"" + this.name + "\");\r\n";
        }
        if (this.isSystemValue) {
            return this._codeVariableName + ".setAsSystemValue(BABYLON.NodeMaterialSystemValues." + _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"][this._systemValue] + ");\r\n";
        }
        if (this.isUniform) {
            var valueString = "";
            switch (this.type) {
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float:
                    valueString = this.value.toString();
                    break;
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                    valueString = "new BABYLON.Vector2(" + this.value.x + ", " + this.value.y + ")";
                    break;
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                    valueString = "new BABYLON.Vector3(" + this.value.x + ", " + this.value.y + ", " + this.value.z + ")";
                    break;
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4:
                    valueString = "new BABYLON.Vector4(" + this.value.x + ", " + this.value.y + ", " + this.value.z + ", " + this.value.w + ")";
                    break;
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3:
                    valueString = "new BABYLON.Color3(" + this.value.r + ", " + this.value.g + ", " + this.value.b + ")";
                    break;
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4:
                    valueString = "new BABYLON.Color4(" + this.value.r + ", " + this.value.g + ", " + this.value.b + ", " + this.value.a + ")";
                    break;
            }
            return this._codeVariableName + ".value = " + valueString + ";\r\n";
        }
        return "";
    };
    InputBlock.prototype._emit = function (state, define) {
        // Uniforms
        if (this.isUniform) {
            if (!this.associatedVariableName) {
                this.associatedVariableName = state._getFreeVariableName("u_" + this.name);
            }
            if (state.uniforms.indexOf(this.associatedVariableName) !== -1) {
                return;
            }
            state.uniforms.push(this.associatedVariableName);
            if (define) {
                state._uniformDeclaration += this._emitDefine(define);
            }
            state._uniformDeclaration += "uniform " + state._getGLType(this.type) + " " + this.associatedVariableName + ";\r\n";
            if (define) {
                state._uniformDeclaration += "#endif\r\n";
            }
            // well known
            var hints = state.sharedData.hints;
            if (this._systemValue !== null && this._systemValue !== undefined) {
                switch (this._systemValue) {
                    case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldView:
                        hints.needWorldViewMatrix = true;
                        break;
                    case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldViewProjection:
                        hints.needWorldViewProjectionMatrix = true;
                        break;
                }
            }
            else {
                if (this._animationType !== _animatedInputBlockTypes__WEBPACK_IMPORTED_MODULE_9__["AnimatedInputBlockTypes"].None) {
                    state.sharedData.animatedInputs.push(this);
                }
            }
            return;
        }
        // Attribute
        if (this.isAttribute) {
            this.associatedVariableName = this.name;
            if (this.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_6__["NodeMaterialBlockTargets"].Vertex && state._vertexState) { // Attribute for fragment need to be carried over by varyings
                this._emit(state._vertexState, define);
                return;
            }
            if (state.attributes.indexOf(this.associatedVariableName) !== -1) {
                return;
            }
            state.attributes.push(this.associatedVariableName);
            if (define) {
                state._attributeDeclaration += this._emitDefine(define);
            }
            state._attributeDeclaration += "attribute " + state._getGLType(this.type) + " " + this.associatedVariableName + ";\r\n";
            if (define) {
                state._attributeDeclaration += "#endif\r\n";
            }
        }
    };
    /** @hidden */
    InputBlock.prototype._transmitWorld = function (effect, world, worldView, worldViewProjection) {
        if (!this._systemValue) {
            return;
        }
        var variableName = this.associatedVariableName;
        switch (this._systemValue) {
            case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].World:
                effect.setMatrix(variableName, world);
                break;
            case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldView:
                effect.setMatrix(variableName, worldView);
                break;
            case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldViewProjection:
                effect.setMatrix(variableName, worldViewProjection);
                break;
        }
    };
    /** @hidden */
    InputBlock.prototype._transmit = function (effect, scene) {
        if (this.isAttribute) {
            return;
        }
        var variableName = this.associatedVariableName;
        if (this._systemValue) {
            switch (this._systemValue) {
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].World:
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldView:
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].WorldViewProjection:
                    return;
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].View:
                    effect.setMatrix(variableName, scene.getViewMatrix());
                    break;
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].Projection:
                    effect.setMatrix(variableName, scene.getProjectionMatrix());
                    break;
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].ViewProjection:
                    effect.setMatrix(variableName, scene.getTransformMatrix());
                    break;
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].CameraPosition:
                    effect.setVector3(variableName, scene.activeCamera.globalPosition);
                    break;
                case _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].FogColor:
                    effect.setColor3(variableName, scene.fogColor);
                    break;
            }
            return;
        }
        var value = this._valueCallback ? this._valueCallback() : this._storedValue;
        if (value === null) {
            return;
        }
        switch (this.type) {
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float:
                effect.setFloat(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Int:
                effect.setInt(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3:
                effect.setColor3(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4:
                effect.setDirectColor4(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                effect.setVector2(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                effect.setVector3(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4:
                effect.setVector4(variableName, value);
                break;
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix:
                effect.setMatrix(variableName, value);
                break;
        }
    };
    InputBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        if (this.isUniform || this.isSystemValue) {
            state.sharedData.inputBlocks.push(this);
        }
        this._emit(state);
    };
    InputBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.type = this.type;
        serializationObject.mode = this._mode;
        serializationObject.systemValue = this._systemValue;
        serializationObject.animationType = this._animationType;
        serializationObject.visibleInInspector = this.visibleInInspector;
        if (this._storedValue != null && this._mode === _NodeMaterialBlockConnectionPointMode__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointMode"].Uniform) {
            if (this._storedValue.asArray) {
                serializationObject.valueType = "BABYLON." + this._storedValue.getClassName();
                serializationObject.value = this._storedValue.asArray();
            }
            else {
                serializationObject.valueType = "number";
                serializationObject.value = this._storedValue;
            }
        }
        return serializationObject;
    };
    InputBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        this._type = serializationObject.type;
        this._mode = serializationObject.mode;
        this._systemValue = serializationObject.systemValue || serializationObject.wellKnownValue;
        this._animationType = serializationObject.animationType;
        this.visibleInInspector = serializationObject.visibleInInspector;
        if (!serializationObject.valueType) {
            return;
        }
        if (serializationObject.valueType === "number") {
            this._storedValue = serializationObject.value;
        }
        else {
            var valueType = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].GetClass(serializationObject.valueType);
            if (valueType) {
                this._storedValue = valueType.FromArray(serializationObject.value);
            }
        }
    };
    return InputBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.InputBlock"] = InputBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Vertex/bonesBlock.ts":
/*!****************************************************!*\
  !*** ./Materials/Node/Blocks/Vertex/bonesBlock.ts ***!
  \****************************************************/
/*! exports provided: BonesBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return BonesBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");








/**
 * Block used to add support for vertex skinning (bones)
 */
var BonesBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BonesBlock, _super);
    /**
     * Creates a new BonesBlock
     * @param name defines the block name
     */
    function BonesBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialBlockTargets"].Vertex) || this;
        _this.registerInput("matricesIndices", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("matricesWeights", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("matricesIndicesExtra", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, true);
        _this.registerInput("matricesWeightsExtra", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, true);
        _this.registerInput("world", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix);
        return _this;
    }
    /**
     * Initialize the block and prepare the context for build
     * @param state defines the state that will be used for the build
     */
    BonesBlock.prototype.initialize = function (state) {
        state._excludeVariableName("boneSampler");
        state._excludeVariableName("boneTextureWidth");
        state._excludeVariableName("mBones");
        state._excludeVariableName("BonesPerMesh");
    };
    /**
     * Gets the current class name
     * @returns the class name
     */
    BonesBlock.prototype.getClassName = function () {
        return "BonesBlock";
    };
    Object.defineProperty(BonesBlock.prototype, "matricesIndices", {
        /**
         * Gets the matrix indices input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BonesBlock.prototype, "matricesWeights", {
        /**
         * Gets the matrix weights input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BonesBlock.prototype, "matricesIndicesExtra", {
        /**
         * Gets the extra matrix indices input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BonesBlock.prototype, "matricesWeightsExtra", {
        /**
         * Gets the extra matrix weights input component
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BonesBlock.prototype, "world", {
        /**
         * Gets the world input component
         */
        get: function () {
            return this._inputs[4];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BonesBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    BonesBlock.prototype.autoConfigure = function (material) {
        if (!this.matricesIndices.isConnected) {
            var matricesIndicesInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "matricesIndices"; });
            if (!matricesIndicesInput) {
                matricesIndicesInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("matricesIndices");
                matricesIndicesInput.setAsAttribute("matricesIndices");
            }
            matricesIndicesInput.output.connectTo(this.matricesIndices);
        }
        if (!this.matricesWeights.isConnected) {
            var matricesWeightsInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "matricesWeights"; });
            if (!matricesWeightsInput) {
                matricesWeightsInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("matricesWeights");
                matricesWeightsInput.setAsAttribute("matricesWeights");
            }
            matricesWeightsInput.output.connectTo(this.matricesWeights);
        }
        if (!this.world.isConnected) {
            var worldInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialSystemValues"].World; });
            if (!worldInput) {
                worldInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("world");
                worldInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialSystemValues"].World);
            }
            worldInput.output.connectTo(this.world);
        }
    };
    BonesBlock.prototype.provideFallbacks = function (mesh, fallbacks) {
        if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
            fallbacks.addCPUSkinningFallback(0, mesh);
        }
    };
    BonesBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        _materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].BindBonesParameters(mesh, effect);
    };
    BonesBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        if (!defines._areAttributesDirty) {
            return;
        }
        _materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].PrepareDefinesForBones(mesh, defines);
    };
    BonesBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        // Register for compilation fallbacks
        state.sharedData.blocksWithFallbacks.push(this);
        // Register for binding
        state.sharedData.bindableBlocks.push(this);
        // Register for defines
        state.sharedData.blocksWithDefines.push(this);
        // Register internal uniforms and samplers
        state.uniforms.push("boneTextureWidth");
        state.uniforms.push("mBones");
        state.samplers.push("boneSampler");
        // Emit code
        var comments = "//" + this.name;
        state._emitFunctionFromInclude("bonesDeclaration", comments, {
            removeAttributes: true,
            removeUniforms: false,
            removeVaryings: true,
            removeIfDef: false
        });
        var influenceVariablename = state._getFreeVariableName("influence");
        state.compilationString += state._emitCodeFromInclude("bonesVertex", comments, {
            replaceStrings: [
                {
                    search: /finalWorld=finalWorld\*influence;/,
                    replace: ""
                },
                {
                    search: /influence/gm,
                    replace: influenceVariablename
                }
            ]
        });
        var output = this._outputs[0];
        var worldInput = this.world;
        state.compilationString += "#if NUM_BONE_INFLUENCERS>0\r\n";
        state.compilationString += this._declareOutput(output, state) + (" = " + worldInput.associatedVariableName + " * " + influenceVariablename + ";\r\n");
        state.compilationString += "#else\r\n";
        state.compilationString += this._declareOutput(output, state) + (" = " + worldInput.associatedVariableName + ";\r\n");
        state.compilationString += "#endif\r\n";
        return this;
    };
    return BonesBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.BonesBlock"] = BonesBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Vertex/index.ts":
/*!***********************************************!*\
  !*** ./Materials/Node/Blocks/Vertex/index.ts ***!
  \***********************************************/
/*! exports provided: VertexOutputBlock, BonesBlock, InstancesBlock, MorphTargetsBlock, LightInformationBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _vertexOutputBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vertexOutputBlock */ "./Materials/Node/Blocks/Vertex/vertexOutputBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return _vertexOutputBlock__WEBPACK_IMPORTED_MODULE_0__["VertexOutputBlock"]; });

/* harmony import */ var _bonesBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./bonesBlock */ "./Materials/Node/Blocks/Vertex/bonesBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return _bonesBlock__WEBPACK_IMPORTED_MODULE_1__["BonesBlock"]; });

/* harmony import */ var _instancesBlock__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./instancesBlock */ "./Materials/Node/Blocks/Vertex/instancesBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return _instancesBlock__WEBPACK_IMPORTED_MODULE_2__["InstancesBlock"]; });

/* harmony import */ var _morphTargetsBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./morphTargetsBlock */ "./Materials/Node/Blocks/Vertex/morphTargetsBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return _morphTargetsBlock__WEBPACK_IMPORTED_MODULE_3__["MorphTargetsBlock"]; });

/* harmony import */ var _lightInformationBlock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lightInformationBlock */ "./Materials/Node/Blocks/Vertex/lightInformationBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return _lightInformationBlock__WEBPACK_IMPORTED_MODULE_4__["LightInformationBlock"]; });








/***/ }),

/***/ "./Materials/Node/Blocks/Vertex/instancesBlock.ts":
/*!********************************************************!*\
  !*** ./Materials/Node/Blocks/Vertex/instancesBlock.ts ***!
  \********************************************************/
/*! exports provided: InstancesBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return InstancesBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");







/**
 * Block used to add support for instances
 * @see https://doc.babylonjs.com/how_to/how_to_use_instances
 */
var InstancesBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InstancesBlock, _super);
    /**
     * Creates a new InstancesBlock
     * @param name defines the block name
     */
    function InstancesBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Vertex) || this;
        _this.registerInput("world0", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("world1", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("world2", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("world3", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("world", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Matrix, true);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Matrix);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    InstancesBlock.prototype.getClassName = function () {
        return "InstancesBlock";
    };
    Object.defineProperty(InstancesBlock.prototype, "world0", {
        /**
         * Gets the first world row input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancesBlock.prototype, "world1", {
        /**
         * Gets the second world row input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancesBlock.prototype, "world2", {
        /**
         * Gets the third world row input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancesBlock.prototype, "world3", {
        /**
         * Gets the forth world row input component
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancesBlock.prototype, "world", {
        /**
         * Gets the world input component
         */
        get: function () {
            return this._inputs[4];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancesBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    InstancesBlock.prototype.autoConfigure = function (material) {
        if (!this.world0.connectedPoint) {
            var world0Input = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "world0"; });
            if (!world0Input) {
                world0Input = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("world0");
                world0Input.setAsAttribute("world0");
            }
            world0Input.output.connectTo(this.world0);
        }
        if (!this.world1.connectedPoint) {
            var world1Input = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "world1"; });
            if (!world1Input) {
                world1Input = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("world1");
                world1Input.setAsAttribute("world1");
            }
            world1Input.output.connectTo(this.world1);
        }
        if (!this.world2.connectedPoint) {
            var world2Input = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "world2"; });
            if (!world2Input) {
                world2Input = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("world2");
                world2Input.setAsAttribute("world2");
            }
            world2Input.output.connectTo(this.world2);
        }
        if (!this.world3.connectedPoint) {
            var world3Input = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "world3"; });
            if (!world3Input) {
                world3Input = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("world3");
                world3Input.setAsAttribute("world3");
            }
            world3Input.output.connectTo(this.world3);
        }
        if (!this.world.connectedPoint) {
            var worldInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "world"; });
            if (!worldInput) {
                worldInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("world");
                worldInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialSystemValues"].World);
            }
            worldInput.output.connectTo(this.world);
        }
        this.world.define = "!INSTANCES";
    };
    InstancesBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines, useInstances) {
        if (useInstances === void 0) { useInstances = false; }
        var changed = false;
        if (defines["INSTANCES"] !== useInstances) {
            defines.setValue("INSTANCES", useInstances);
            changed = true;
        }
        if (changed) {
            defines.markAsUnprocessed();
        }
    };
    InstancesBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        // Register for defines
        state.sharedData.blocksWithDefines.push(this);
        // Emit code
        var output = this._outputs[0];
        var world0 = this.world0;
        var world1 = this.world1;
        var world2 = this.world2;
        var world3 = this.world3;
        state.compilationString += "#ifdef INSTANCES\r\n";
        state.compilationString += this._declareOutput(output, state) + (" = mat4(" + world0.associatedVariableName + ", " + world1.associatedVariableName + ", " + world2.associatedVariableName + ", " + world3.associatedVariableName + ");\r\n");
        state.compilationString += "#else\r\n";
        state.compilationString += this._declareOutput(output, state) + (" = " + this.world.associatedVariableName + ";\r\n");
        state.compilationString += "#endif\r\n";
        return this;
    };
    return InstancesBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_6__["_TypeStore"].RegisteredTypes["BABYLON.InstancesBlock"] = InstancesBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Vertex/lightInformationBlock.ts":
/*!***************************************************************!*\
  !*** ./Materials/Node/Blocks/Vertex/lightInformationBlock.ts ***!
  \***************************************************************/
/*! exports provided: LightInformationBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return LightInformationBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Lights_pointLight__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../../Lights/pointLight */ "./Lights/pointLight.ts");






/**
 * Block used to get data information from a light
 */
var LightInformationBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LightInformationBlock, _super);
    /**
     * Creates a new LightInformationBlock
     * @param name defines the block name
     */
    function LightInformationBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex) || this;
        _this.registerInput("worldPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, false, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex);
        _this.registerOutput("direction", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("color", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    LightInformationBlock.prototype.getClassName = function () {
        return "LightInformationBlock";
    };
    Object.defineProperty(LightInformationBlock.prototype, "worldPosition", {
        /**
         * Gets the world position input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightInformationBlock.prototype, "direction", {
        /**
         * Gets the direction output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LightInformationBlock.prototype, "color", {
        /**
         * Gets the direction output component
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    LightInformationBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (!mesh) {
            return;
        }
        if (!this.light || !this.light.isEnabled) {
            effect.setFloat3(this._lightDataDefineName, 0, 0, 0);
            effect.setFloat3(this._lightColorDefineName, 0, 0, 0);
            return;
        }
        this.light.transferToNodeMaterialEffect(effect, this._lightDataDefineName);
        effect.setColor3(this._lightColorDefineName, this.light.diffuse);
    };
    LightInformationBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        state.sharedData.bindableBlocks.push(this);
        var direction = this.direction;
        var color = this.color;
        if (!this.light) {
            state.compilationString += this._declareOutput(direction, state) + " = vec3(0.);\r\n";
            state.compilationString += this._declareOutput(color, state) + " = vec3(0.);\r\n";
        }
        else {
            this._lightDataDefineName = state._getFreeDefineName("lightData");
            state._emitUniformFromString(this._lightDataDefineName, "vec3");
            this._lightColorDefineName = state._getFreeDefineName("lightColor");
            state._emitUniformFromString(this._lightColorDefineName, "vec3");
            if (this.light instanceof _Lights_pointLight__WEBPACK_IMPORTED_MODULE_5__["PointLight"]) {
                state.compilationString += this._declareOutput(direction, state) + (" = normalize(" + this._lightDataDefineName + " - " + this.worldPosition.associatedVariableName + ".xyz);\r\n");
            }
            else {
                state.compilationString += this._declareOutput(direction, state) + (" = " + this._lightDataDefineName + ";\r\n");
            }
            state.compilationString += this._declareOutput(color, state) + (" = " + this._lightColorDefineName + ";\r\n");
        }
        return this;
    };
    LightInformationBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        if (this.light) {
            serializationObject.lightId = this.light.id;
        }
        return serializationObject;
    };
    LightInformationBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        if (serializationObject.lightId) {
            this.light = scene.getLightByID(serializationObject.lightId);
        }
    };
    return LightInformationBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.LightInformationBlock"] = LightInformationBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Vertex/morphTargetsBlock.ts":
/*!***********************************************************!*\
  !*** ./Materials/Node/Blocks/Vertex/morphTargetsBlock.ts ***!
  \***********************************************************/
/*! exports provided: MorphTargetsBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return MorphTargetsBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");








/**
 * Block used to add morph targets support to vertex shader
 */
var MorphTargetsBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MorphTargetsBlock, _super);
    /**
     * Create a new MorphTargetsBlock
     * @param name defines the block name
     */
    function MorphTargetsBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex) || this;
        _this._repeatebleContentGenerated = 0;
        _this.registerInput("position", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerInput("normal", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerInput("tangent", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerInput("uv", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2);
        _this.registerOutput("positionOutput", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("normalOutput", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("tangentOutput", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("uvOutput", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    MorphTargetsBlock.prototype.getClassName = function () {
        return "MorphTargetsBlock";
    };
    Object.defineProperty(MorphTargetsBlock.prototype, "position", {
        /**
         * Gets the position input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "normal", {
        /**
         * Gets the normal input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "tangent", {
        /**
         * Gets the tangent input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "uv", {
        /**
         * Gets the tangent input component
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "positionOutput", {
        /**
         * Gets the position output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "normalOutput", {
        /**
         * Gets the normal output component
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "tangentOutput", {
        /**
         * Gets the tangent output component
         */
        get: function () {
            return this._outputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetsBlock.prototype, "uvOutput", {
        /**
         * Gets the tangent output component
         */
        get: function () {
            return this._outputs[3];
        },
        enumerable: true,
        configurable: true
    });
    MorphTargetsBlock.prototype.initialize = function (state) {
        state._excludeVariableName("morphTargetInfluences");
    };
    MorphTargetsBlock.prototype.autoConfigure = function (material) {
        if (!this.position.isConnected) {
            var positionInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "position"; });
            if (!positionInput) {
                positionInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("position");
                positionInput.setAsAttribute();
            }
            positionInput.output.connectTo(this.position);
        }
        if (!this.normal.isConnected) {
            var normalInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "normal"; });
            if (!normalInput) {
                normalInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("normal");
                normalInput.setAsAttribute("normal");
            }
            normalInput.output.connectTo(this.normal);
        }
        if (!this.tangent.isConnected) {
            var tangentInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "tangent"; });
            if (!tangentInput) {
                tangentInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("tangent");
                tangentInput.setAsAttribute("tangent");
            }
            tangentInput.output.connectTo(this.tangent);
        }
        if (!this.uv.isConnected) {
            var uvInput = material.getInputBlockByPredicate(function (b) { return b.isAttribute && b.name === "uv"; });
            if (!uvInput) {
                uvInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("uv");
                uvInput.setAsAttribute("uv");
            }
            uvInput.output.connectTo(this.uv);
        }
    };
    MorphTargetsBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines) {
        if (!defines._areAttributesDirty) {
            return;
        }
        _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForMorphTargets(mesh, defines);
    };
    MorphTargetsBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        if (mesh && this._repeatebleContentGenerated) {
            _materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindMorphTargetParameters(mesh, effect);
        }
    };
    MorphTargetsBlock.prototype.replaceRepeatableContent = function (vertexShaderState, fragmentShaderState, mesh, defines) {
        var position = this.position;
        var normal = this.normal;
        var tangent = this.tangent;
        var uv = this.uv;
        var positionOutput = this.positionOutput;
        var normalOutput = this.normalOutput;
        var tangentOutput = this.tangentOutput;
        var uvOutput = this.uvOutput;
        var state = vertexShaderState;
        var repeatCount = defines.NUM_MORPH_INFLUENCERS;
        this._repeatebleContentGenerated = repeatCount;
        var manager = mesh.morphTargetManager;
        var hasNormals = manager && manager.supportsNormals && defines["NORMAL"];
        var hasTangents = manager && manager.supportsTangents && defines["TANGENT"];
        var hasUVs = manager && manager.supportsUVs && defines["UV1"];
        var injectionCode = "";
        for (var index = 0; index < repeatCount; index++) {
            injectionCode += "#ifdef MORPHTARGETS\r\n";
            injectionCode += positionOutput.associatedVariableName + " += (position" + index + " - " + position.associatedVariableName + ") * morphTargetInfluences[" + index + "];\r\n";
            if (hasNormals) {
                injectionCode += "#ifdef MORPHTARGETS_NORMAL\r\n";
                injectionCode += normalOutput.associatedVariableName + " += (normal" + index + " - " + normal.associatedVariableName + ") * morphTargetInfluences[" + index + "];\r\n";
                injectionCode += "#endif\r\n";
            }
            if (hasTangents) {
                injectionCode += "#ifdef MORPHTARGETS_TANGENT\r\n";
                injectionCode += tangentOutput.associatedVariableName + ".xyz += (tangent" + index + " - " + tangent.associatedVariableName + ".xyz) * morphTargetInfluences[" + index + "];\r\n";
                injectionCode += "#endif\r\n";
            }
            if (hasUVs) {
                injectionCode += "#ifdef MORPHTARGETS_UV\r\n";
                injectionCode += uvOutput.associatedVariableName + ".xyz += (uv_" + index + " - " + uv.associatedVariableName + ".xyz) * morphTargetInfluences[" + index + "];\r\n";
                injectionCode += "#endif\r\n";
            }
            injectionCode += "#endif\r\n";
        }
        state.compilationString = state.compilationString.replace(this._repeatableContentAnchor, injectionCode);
        if (repeatCount > 0) {
            for (var index = 0; index < repeatCount; index++) {
                state.attributes.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind + index);
                if (hasNormals) {
                    state.attributes.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind + index);
                }
                if (hasTangents) {
                    state.attributes.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].TangentKind + index);
                }
            }
        }
    };
    MorphTargetsBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        // Register for defines
        state.sharedData.blocksWithDefines.push(this);
        // Register for binding
        state.sharedData.bindableBlocks.push(this);
        // Register for repeatable content generation
        state.sharedData.repeatableContentBlocks.push(this);
        // Emit code
        var position = this.position;
        var normal = this.normal;
        var tangent = this.tangent;
        var uv = this.uv;
        var positionOutput = this.positionOutput;
        var normalOutput = this.normalOutput;
        var tangentOutput = this.tangentOutput;
        var uvOutput = this.uvOutput;
        var comments = "//" + this.name;
        state.uniforms.push("morphTargetInfluences");
        state._emitFunctionFromInclude("morphTargetsVertexGlobalDeclaration", comments);
        state._emitFunctionFromInclude("morphTargetsVertexDeclaration", comments, {
            repeatKey: "maxSimultaneousMorphTargets"
        });
        state.compilationString += this._declareOutput(positionOutput, state) + " = " + position.associatedVariableName + ";\r\n";
        state.compilationString += "#ifdef NORMAL\r\n";
        state.compilationString += this._declareOutput(normalOutput, state) + " = " + normal.associatedVariableName + ";\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef TANGENT\r\n";
        state.compilationString += this._declareOutput(tangentOutput, state) + " = " + tangent.associatedVariableName + ";\r\n";
        state.compilationString += "#endif\r\n";
        state.compilationString += "#ifdef UV1\r\n";
        state.compilationString += this._declareOutput(uvOutput, state) + " = " + uv.associatedVariableName + ";\r\n";
        state.compilationString += "#endif\r\n";
        // Repeatable content
        this._repeatableContentAnchor = state._repeatableContentAnchor;
        state.compilationString += this._repeatableContentAnchor;
        return this;
    };
    return MorphTargetsBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.MorphTargetsBlock"] = MorphTargetsBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/Vertex/vertexOutputBlock.ts":
/*!***********************************************************!*\
  !*** ./Materials/Node/Blocks/Vertex/vertexOutputBlock.ts ***!
  \***********************************************************/
/*! exports provided: VertexOutputBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return VertexOutputBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to output the vertex position
 */
var VertexOutputBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VertexOutputBlock, _super);
    /**
     * Creates a new VertexOutputBlock
     * @param name defines the block name
     */
    function VertexOutputBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex, true) || this;
        _this.registerInput("vector", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    VertexOutputBlock.prototype.getClassName = function () {
        return "VertexOutputBlock";
    };
    Object.defineProperty(VertexOutputBlock.prototype, "vector", {
        /**
         * Gets the vector input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    VertexOutputBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var input = this.vector;
        state.compilationString += "gl_Position = " + input.associatedVariableName + ";\r\n";
        return this;
    };
    return VertexOutputBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.VertexOutputBlock"] = VertexOutputBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/addBlock.ts":
/*!*******************************************!*\
  !*** ./Materials/Node/Blocks/addBlock.ts ***!
  \*******************************************/
/*! exports provided: AddBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AddBlock", function() { return AddBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to add 2 vectors
 */
var AddBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AddBlock, _super);
    /**
     * Creates a new AddBlock
     * @param name defines the block name
     */
    function AddBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    AddBlock.prototype.getClassName = function () {
        return "AddBlock";
    };
    Object.defineProperty(AddBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AddBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AddBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    AddBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = " + this.left.associatedVariableName + " + " + this.right.associatedVariableName + ";\r\n");
        return this;
    };
    return AddBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.AddBlock"] = AddBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/clampBlock.ts":
/*!*********************************************!*\
  !*** ./Materials/Node/Blocks/clampBlock.ts ***!
  \*********************************************/
/*! exports provided: ClampBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClampBlock", function() { return ClampBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to clamp a float
 */
var ClampBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ClampBlock, _super);
    /**
     * Creates a new ClampBlock
     * @param name defines the block name
     */
    function ClampBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        /** Gets or sets the minimum range */
        _this.minimum = 0.0;
        /** Gets or sets the maximum range */
        _this.maximum = 1.0;
        _this.registerInput("value", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ClampBlock.prototype.getClassName = function () {
        return "ClampBlock";
    };
    Object.defineProperty(ClampBlock.prototype, "value", {
        /**
         * Gets the value input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ClampBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    ClampBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = clamp(" + this.value.associatedVariableName + ", " + this._writeFloat(this.minimum) + ", " + this._writeFloat(this.maximum) + ");\r\n");
        return this;
    };
    ClampBlock.prototype._dumpPropertiesCode = function () {
        var codeString = this._codeVariableName + ".minimum = " + this.minimum + ";\r\n";
        codeString += this._codeVariableName + ".maximum = " + this.maximum + ";\r\n";
        return codeString;
    };
    ClampBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.minimum = this.minimum;
        serializationObject.maximum = this.maximum;
        return serializationObject;
    };
    ClampBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        this.minimum = serializationObject.minimum;
        this.maximum = serializationObject.maximum;
    };
    return ClampBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ClampBlock"] = ClampBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/colorMergerBlock.ts":
/*!***************************************************!*\
  !*** ./Materials/Node/Blocks/colorMergerBlock.ts ***!
  \***************************************************/
/*! exports provided: ColorMergerBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorMergerBlock", function() { return ColorMergerBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to create a Color3/4 out of individual inputs (one for each component)
 */
var ColorMergerBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ColorMergerBlock, _super);
    /**
     * Create a new ColorMergerBlock
     * @param name defines the block name
     */
    function ColorMergerBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) || this;
        _this.registerInput("r", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        _this.registerInput("g", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        _this.registerInput("b", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        _this.registerInput("a", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        _this.registerOutput("rgba", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4);
        _this.registerOutput("rgb", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ColorMergerBlock.prototype.getClassName = function () {
        return "ColorMergerBlock";
    };
    Object.defineProperty(ColorMergerBlock.prototype, "r", {
        /**
         * Gets the r component (input)
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorMergerBlock.prototype, "g", {
        /**
         * Gets the g component (input)
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorMergerBlock.prototype, "b", {
        /**
         * Gets the b component (input)
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorMergerBlock.prototype, "a", {
        /**
         * Gets the a component (input)
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorMergerBlock.prototype, "rgba", {
        /**
         * Gets the rgba component (output)
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorMergerBlock.prototype, "rgb", {
        /**
         * Gets the rgb component (output)
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    ColorMergerBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var rInput = this.r;
        var gInput = this.g;
        var bInput = this.b;
        var aInput = this.a;
        var color4Output = this._outputs[0];
        var color3Output = this._outputs[1];
        if (color4Output.hasEndpoints) {
            state.compilationString += this._declareOutput(color4Output, state) + (" = vec4(" + (rInput.isConnected ? this._writeVariable(rInput) : "0.0") + ", " + (gInput.isConnected ? this._writeVariable(gInput) : "0.0") + ", " + (bInput.isConnected ? this._writeVariable(bInput) : "0.0") + ", " + (aInput.isConnected ? this._writeVariable(aInput) : "0.0") + ");\r\n");
        }
        else if (color3Output.hasEndpoints) {
            state.compilationString += this._declareOutput(color3Output, state) + (" = vec3(" + (rInput.isConnected ? this._writeVariable(rInput) : "0.0") + ", " + (gInput.isConnected ? this._writeVariable(gInput) : "0.0") + ", " + (bInput.isConnected ? this._writeVariable(bInput) : "0.0") + ");\r\n");
        }
        return this;
    };
    return ColorMergerBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ColorMergerBlock"] = ColorMergerBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/colorSplitterBlock.ts":
/*!*****************************************************!*\
  !*** ./Materials/Node/Blocks/colorSplitterBlock.ts ***!
  \*****************************************************/
/*! exports provided: ColorSplitterBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorSplitterBlock", function() { return ColorSplitterBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to expand a Color3/4 into 4 outputs (one for each component)
 */
var ColorSplitterBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ColorSplitterBlock, _super);
    /**
     * Create a new ColorSplitterBlock
     * @param name defines the block name
     */
    function ColorSplitterBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) || this;
        _this.registerInput("rgba", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color4, true);
        _this.registerInput("rgb ", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3, true);
        _this.registerOutput("rgb", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Color3);
        _this.registerOutput("r", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("g", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("b", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("a", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ColorSplitterBlock.prototype.getClassName = function () {
        return "ColorSplitterBlock";
    };
    Object.defineProperty(ColorSplitterBlock.prototype, "rgba", {
        /**
         * Gets the rgba component (input)
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorSplitterBlock.prototype, "rgbIn", {
        /**
         * Gets the rgb component (input)
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorSplitterBlock.prototype, "rgbOut", {
        /**
         * Gets the rgb component (output)
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorSplitterBlock.prototype, "r", {
        /**
         * Gets the r component (output)
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorSplitterBlock.prototype, "g", {
        /**
         * Gets the g component (output)
         */
        get: function () {
            return this._outputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorSplitterBlock.prototype, "b", {
        /**
         * Gets the b component (output)
         */
        get: function () {
            return this._outputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorSplitterBlock.prototype, "a", {
        /**
         * Gets the a component (output)
         */
        get: function () {
            return this._outputs[4];
        },
        enumerable: true,
        configurable: true
    });
    ColorSplitterBlock.prototype._inputRename = function (name) {
        if (name === "rgb ") {
            return "rgbIn";
        }
        return name;
    };
    ColorSplitterBlock.prototype._outputRename = function (name) {
        if (name === "rgb") {
            return "rgbOut";
        }
        return name;
    };
    ColorSplitterBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var input = this.rgba.isConnected ? this.rgba : this.rgbIn;
        if (!input.isConnected) {
            return;
        }
        var rgbOutput = this._outputs[0];
        var rOutput = this._outputs[1];
        var gOutput = this._outputs[2];
        var bOutput = this._outputs[3];
        var aOutput = this._outputs[4];
        if (rgbOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(rgbOutput, state) + (" = " + input.associatedVariableName + ".rgb;\r\n");
        }
        if (rOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(rOutput, state) + (" = " + input.associatedVariableName + ".r;\r\n");
        }
        if (gOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(gOutput, state) + (" = " + input.associatedVariableName + ".g;\r\n");
        }
        if (bOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(bOutput, state) + (" = " + input.associatedVariableName + ".b;\r\n");
        }
        if (aOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(aOutput, state) + (" = " + input.associatedVariableName + ".a;\r\n");
        }
        return this;
    };
    return ColorSplitterBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ColorSplitterBlock"] = ColorSplitterBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/crossBlock.ts":
/*!*********************************************!*\
  !*** ./Materials/Node/Blocks/crossBlock.ts ***!
  \*********************************************/
/*! exports provided: CrossBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CrossBlock", function() { return CrossBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to apply a cross product between 2 vectors
 */
var CrossBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CrossBlock, _super);
    /**
     * Creates a new CrossBlock
     * @param name defines the block name
     */
    function CrossBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    CrossBlock.prototype.getClassName = function () {
        return "CrossBlock";
    };
    Object.defineProperty(CrossBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CrossBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CrossBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    CrossBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = cross(" + this.left.associatedVariableName + ", " + this.right.associatedVariableName + ");\r\n");
        return this;
    };
    return CrossBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.CrossBlock"] = CrossBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/divideBlock.ts":
/*!**********************************************!*\
  !*** ./Materials/Node/Blocks/divideBlock.ts ***!
  \**********************************************/
/*! exports provided: DivideBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DivideBlock", function() { return DivideBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to divide 2 vectors
 */
var DivideBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DivideBlock, _super);
    /**
     * Creates a new DivideBlock
     * @param name defines the block name
     */
    function DivideBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    DivideBlock.prototype.getClassName = function () {
        return "DivideBlock";
    };
    Object.defineProperty(DivideBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DivideBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DivideBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    DivideBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = " + this.left.associatedVariableName + " / " + this.right.associatedVariableName + ";\r\n");
        return this;
    };
    return DivideBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.DivideBlock"] = DivideBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/dotBlock.ts":
/*!*******************************************!*\
  !*** ./Materials/Node/Blocks/dotBlock.ts ***!
  \*******************************************/
/*! exports provided: DotBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DotBlock", function() { return DotBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to apply a dot product between 2 vectors
 */
var DotBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DotBlock, _super);
    /**
     * Creates a new DotBlock
     * @param name defines the block name
     */
    function DotBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    DotBlock.prototype.getClassName = function () {
        return "DotBlock";
    };
    Object.defineProperty(DotBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DotBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DotBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    DotBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = dot(" + this.left.associatedVariableName + ", " + this.right.associatedVariableName + ");\r\n");
        return this;
    };
    return DotBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.DotBlock"] = DotBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/fresnelBlock.ts":
/*!***********************************************!*\
  !*** ./Materials/Node/Blocks/fresnelBlock.ts ***!
  \***********************************************/
/*! exports provided: FresnelBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FresnelBlock", function() { return FresnelBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");






/**
 * Block used to compute fresnel value
 */
var FresnelBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FresnelBlock, _super);
    /**
     * Create a new FresnelBlock
     * @param name defines the block name
     */
    function FresnelBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("worldNormal", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("viewDirection", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerInput("bias", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerInput("power", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("fresnel", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockConnectionPointTypes"].Float);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    FresnelBlock.prototype.getClassName = function () {
        return "FresnelBlock";
    };
    Object.defineProperty(FresnelBlock.prototype, "worldNormal", {
        /**
         * Gets the world normal input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FresnelBlock.prototype, "viewDirection", {
        /**
        * Gets the view direction input component
        */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FresnelBlock.prototype, "bias", {
        /**
        * Gets the bias input component
        */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FresnelBlock.prototype, "power", {
        /**
        * Gets the camera (or eye) position component
        */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(FresnelBlock.prototype, "fresnel", {
        /**
         * Gets the fresnel output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    FresnelBlock.prototype.autoConfigure = function (material) {
        if (!this.bias.isConnected) {
            var biasInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("bias");
            biasInput.value = 0;
            biasInput.output.connectTo(this.bias);
        }
        if (!this.power.isConnected) {
            var powerInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_5__["InputBlock"]("power");
            powerInput.value = 1;
            powerInput.output.connectTo(this.power);
        }
    };
    FresnelBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var comments = "//" + this.name;
        state._emitFunctionFromInclude("fresnelFunction", comments, { removeIfDef: true });
        state.compilationString += this._declareOutput(this.fresnel, state) + (" = computeFresnelTerm(" + this.viewDirection.associatedVariableName + ", " + this.worldNormal.associatedVariableName + ", " + this.bias.associatedVariableName + ", " + this.power.associatedVariableName + ");\r\n");
        return this;
    };
    return FresnelBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.FresnelBlock"] = FresnelBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/index.ts":
/*!****************************************!*\
  !*** ./Materials/Node/Blocks/index.ts ***!
  \****************************************/
/*! exports provided: MultiplyBlock, AddBlock, ScaleBlock, ClampBlock, CrossBlock, DotBlock, TransformBlock, RemapBlock, NormalizeBlock, TrigonometryBlockOperations, TrigonometryBlock, ColorMergerBlock, VectorMergerBlock, ColorSplitterBlock, VectorSplitterBlock, LerpBlock, DivideBlock, SubtractBlock, StepBlock, OppositeBlock, ViewDirectionBlock, FresnelBlock, MaxBlock, MinBlock, VertexOutputBlock, BonesBlock, InstancesBlock, MorphTargetsBlock, LightInformationBlock, FragmentOutputBlock, AlphaTestBlock, ImageProcessingBlock, PerturbNormalBlock, FogBlock, LightBlock, TextureBlock, ReflectionTextureBlock, InputBlock, AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Vertex_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Vertex/index */ "./Materials/Node/Blocks/Vertex/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return _Vertex_index__WEBPACK_IMPORTED_MODULE_0__["VertexOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return _Vertex_index__WEBPACK_IMPORTED_MODULE_0__["BonesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return _Vertex_index__WEBPACK_IMPORTED_MODULE_0__["InstancesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return _Vertex_index__WEBPACK_IMPORTED_MODULE_0__["MorphTargetsBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return _Vertex_index__WEBPACK_IMPORTED_MODULE_0__["LightInformationBlock"]; });

/* harmony import */ var _Fragment_index__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Fragment/index */ "./Materials/Node/Blocks/Fragment/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return _Fragment_index__WEBPACK_IMPORTED_MODULE_1__["FragmentOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return _Fragment_index__WEBPACK_IMPORTED_MODULE_1__["AlphaTestBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return _Fragment_index__WEBPACK_IMPORTED_MODULE_1__["ImageProcessingBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return _Fragment_index__WEBPACK_IMPORTED_MODULE_1__["PerturbNormalBlock"]; });

/* harmony import */ var _Dual_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Dual/index */ "./Materials/Node/Blocks/Dual/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return _Dual_index__WEBPACK_IMPORTED_MODULE_2__["FogBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return _Dual_index__WEBPACK_IMPORTED_MODULE_2__["LightBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return _Dual_index__WEBPACK_IMPORTED_MODULE_2__["TextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return _Dual_index__WEBPACK_IMPORTED_MODULE_2__["ReflectionTextureBlock"]; });

/* harmony import */ var _Input_index__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Input/index */ "./Materials/Node/Blocks/Input/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return _Input_index__WEBPACK_IMPORTED_MODULE_3__["InputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return _Input_index__WEBPACK_IMPORTED_MODULE_3__["AnimatedInputBlockTypes"]; });

/* harmony import */ var _multiplyBlock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./multiplyBlock */ "./Materials/Node/Blocks/multiplyBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlock", function() { return _multiplyBlock__WEBPACK_IMPORTED_MODULE_4__["MultiplyBlock"]; });

/* harmony import */ var _addBlock__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./addBlock */ "./Materials/Node/Blocks/addBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AddBlock", function() { return _addBlock__WEBPACK_IMPORTED_MODULE_5__["AddBlock"]; });

/* harmony import */ var _scaleBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./scaleBlock */ "./Materials/Node/Blocks/scaleBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleBlock", function() { return _scaleBlock__WEBPACK_IMPORTED_MODULE_6__["ScaleBlock"]; });

/* harmony import */ var _clampBlock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./clampBlock */ "./Materials/Node/Blocks/clampBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClampBlock", function() { return _clampBlock__WEBPACK_IMPORTED_MODULE_7__["ClampBlock"]; });

/* harmony import */ var _crossBlock__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./crossBlock */ "./Materials/Node/Blocks/crossBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CrossBlock", function() { return _crossBlock__WEBPACK_IMPORTED_MODULE_8__["CrossBlock"]; });

/* harmony import */ var _dotBlock__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./dotBlock */ "./Materials/Node/Blocks/dotBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DotBlock", function() { return _dotBlock__WEBPACK_IMPORTED_MODULE_9__["DotBlock"]; });

/* harmony import */ var _transformBlock__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./transformBlock */ "./Materials/Node/Blocks/transformBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformBlock", function() { return _transformBlock__WEBPACK_IMPORTED_MODULE_10__["TransformBlock"]; });

/* harmony import */ var _remapBlock__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./remapBlock */ "./Materials/Node/Blocks/remapBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RemapBlock", function() { return _remapBlock__WEBPACK_IMPORTED_MODULE_11__["RemapBlock"]; });

/* harmony import */ var _normalizeBlock__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./normalizeBlock */ "./Materials/Node/Blocks/normalizeBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NormalizeBlock", function() { return _normalizeBlock__WEBPACK_IMPORTED_MODULE_12__["NormalizeBlock"]; });

/* harmony import */ var _trigonometryBlock__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./trigonometryBlock */ "./Materials/Node/Blocks/trigonometryBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlockOperations", function() { return _trigonometryBlock__WEBPACK_IMPORTED_MODULE_13__["TrigonometryBlockOperations"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlock", function() { return _trigonometryBlock__WEBPACK_IMPORTED_MODULE_13__["TrigonometryBlock"]; });

/* harmony import */ var _colorMergerBlock__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./colorMergerBlock */ "./Materials/Node/Blocks/colorMergerBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorMergerBlock", function() { return _colorMergerBlock__WEBPACK_IMPORTED_MODULE_14__["ColorMergerBlock"]; });

/* harmony import */ var _vectorMergerBlock__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./vectorMergerBlock */ "./Materials/Node/Blocks/vectorMergerBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorMergerBlock", function() { return _vectorMergerBlock__WEBPACK_IMPORTED_MODULE_15__["VectorMergerBlock"]; });

/* harmony import */ var _colorSplitterBlock__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./colorSplitterBlock */ "./Materials/Node/Blocks/colorSplitterBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorSplitterBlock", function() { return _colorSplitterBlock__WEBPACK_IMPORTED_MODULE_16__["ColorSplitterBlock"]; });

/* harmony import */ var _vectorSplitterBlock__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./vectorSplitterBlock */ "./Materials/Node/Blocks/vectorSplitterBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorSplitterBlock", function() { return _vectorSplitterBlock__WEBPACK_IMPORTED_MODULE_17__["VectorSplitterBlock"]; });

/* harmony import */ var _lerpBlock__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./lerpBlock */ "./Materials/Node/Blocks/lerpBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LerpBlock", function() { return _lerpBlock__WEBPACK_IMPORTED_MODULE_18__["LerpBlock"]; });

/* harmony import */ var _divideBlock__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./divideBlock */ "./Materials/Node/Blocks/divideBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DivideBlock", function() { return _divideBlock__WEBPACK_IMPORTED_MODULE_19__["DivideBlock"]; });

/* harmony import */ var _subtractBlock__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./subtractBlock */ "./Materials/Node/Blocks/subtractBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubtractBlock", function() { return _subtractBlock__WEBPACK_IMPORTED_MODULE_20__["SubtractBlock"]; });

/* harmony import */ var _stepBlock__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./stepBlock */ "./Materials/Node/Blocks/stepBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StepBlock", function() { return _stepBlock__WEBPACK_IMPORTED_MODULE_21__["StepBlock"]; });

/* harmony import */ var _oppositeBlock__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./oppositeBlock */ "./Materials/Node/Blocks/oppositeBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OppositeBlock", function() { return _oppositeBlock__WEBPACK_IMPORTED_MODULE_22__["OppositeBlock"]; });

/* harmony import */ var _viewDirectionBlock__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./viewDirectionBlock */ "./Materials/Node/Blocks/viewDirectionBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViewDirectionBlock", function() { return _viewDirectionBlock__WEBPACK_IMPORTED_MODULE_23__["ViewDirectionBlock"]; });

/* harmony import */ var _fresnelBlock__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./fresnelBlock */ "./Materials/Node/Blocks/fresnelBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelBlock", function() { return _fresnelBlock__WEBPACK_IMPORTED_MODULE_24__["FresnelBlock"]; });

/* harmony import */ var _maxBlock__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./maxBlock */ "./Materials/Node/Blocks/maxBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaxBlock", function() { return _maxBlock__WEBPACK_IMPORTED_MODULE_25__["MaxBlock"]; });

/* harmony import */ var _minBlock__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./minBlock */ "./Materials/Node/Blocks/minBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MinBlock", function() { return _minBlock__WEBPACK_IMPORTED_MODULE_26__["MinBlock"]; });






























/***/ }),

/***/ "./Materials/Node/Blocks/lerpBlock.ts":
/*!********************************************!*\
  !*** ./Materials/Node/Blocks/lerpBlock.ts ***!
  \********************************************/
/*! exports provided: LerpBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LerpBlock", function() { return LerpBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to lerp 2 values
 */
var LerpBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LerpBlock, _super);
    /**
     * Creates a new LerpBlock
     * @param name defines the block name
     */
    function LerpBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("gradient", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    LerpBlock.prototype.getClassName = function () {
        return "LerpBlock";
    };
    Object.defineProperty(LerpBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LerpBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LerpBlock.prototype, "gradient", {
        /**
         * Gets the gradient operand input component
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LerpBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    LerpBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = mix(" + this.left.associatedVariableName + " , " + this.right.associatedVariableName + ", " + this.gradient.associatedVariableName + ");\r\n");
        return this;
    };
    return LerpBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.LerpBlock"] = LerpBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/maxBlock.ts":
/*!*******************************************!*\
  !*** ./Materials/Node/Blocks/maxBlock.ts ***!
  \*******************************************/
/*! exports provided: MaxBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MaxBlock", function() { return MaxBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to get the max of 2 values
 */
var MaxBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MaxBlock, _super);
    /**
     * Creates a new MaxBlock
     * @param name defines the block name
     */
    function MaxBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    MaxBlock.prototype.getClassName = function () {
        return "MaxBlock";
    };
    Object.defineProperty(MaxBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaxBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaxBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    MaxBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = max(" + this.left.associatedVariableName + ", " + this.right.associatedVariableName + ");\r\n");
        return this;
    };
    return MaxBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.MaxBlock"] = MaxBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/minBlock.ts":
/*!*******************************************!*\
  !*** ./Materials/Node/Blocks/minBlock.ts ***!
  \*******************************************/
/*! exports provided: MinBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MinBlock", function() { return MinBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to get the min of 2 values
 */
var MinBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MinBlock, _super);
    /**
     * Creates a new MinBlock
     * @param name defines the block name
     */
    function MinBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    MinBlock.prototype.getClassName = function () {
        return "MinBlock";
    };
    Object.defineProperty(MinBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MinBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MinBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    MinBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = min(" + this.left.associatedVariableName + ", " + this.right.associatedVariableName + ");\r\n");
        return this;
    };
    return MinBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.MinBlock"] = MinBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/multiplyBlock.ts":
/*!************************************************!*\
  !*** ./Materials/Node/Blocks/multiplyBlock.ts ***!
  \************************************************/
/*! exports provided: MultiplyBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlock", function() { return MultiplyBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to multiply 2 values
 */
var MultiplyBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MultiplyBlock, _super);
    /**
     * Creates a new MultiplyBlock
     * @param name defines the block name
     */
    function MultiplyBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    MultiplyBlock.prototype.getClassName = function () {
        return "MultiplyBlock";
    };
    Object.defineProperty(MultiplyBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiplyBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiplyBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    MultiplyBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = " + this.left.associatedVariableName + " * " + this.right.associatedVariableName + ";\r\n");
        return this;
    };
    return MultiplyBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.MultiplyBlock"] = MultiplyBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/normalizeBlock.ts":
/*!*************************************************!*\
  !*** ./Materials/Node/Blocks/normalizeBlock.ts ***!
  \*************************************************/
/*! exports provided: NormalizeBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NormalizeBlock", function() { return NormalizeBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to normalize a vector
 */
var NormalizeBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NormalizeBlock, _super);
    /**
     * Creates a new NormalizeBlock
     * @param name defines the block name
     */
    function NormalizeBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("input", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    NormalizeBlock.prototype.getClassName = function () {
        return "NormalizeBlock";
    };
    Object.defineProperty(NormalizeBlock.prototype, "input", {
        /**
         * Gets the input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NormalizeBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    NormalizeBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        var input = this._inputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = normalize(" + input.associatedVariableName + ");\r\n");
        return this;
    };
    return NormalizeBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.NormalizeBlock"] = NormalizeBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/oppositeBlock.ts":
/*!************************************************!*\
  !*** ./Materials/Node/Blocks/oppositeBlock.ts ***!
  \************************************************/
/*! exports provided: OppositeBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OppositeBlock", function() { return OppositeBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to get the opposite of a value
 */
var OppositeBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OppositeBlock, _super);
    /**
     * Creates a new OppositeBlock
     * @param name defines the block name
     */
    function OppositeBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("input", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    OppositeBlock.prototype.getClassName = function () {
        return "OppositeBlock";
    };
    Object.defineProperty(OppositeBlock.prototype, "input", {
        /**
         * Gets the input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(OppositeBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    OppositeBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = 1. - " + this.input.associatedVariableName + ";\r\n");
        return this;
    };
    return OppositeBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.OppositeBlock"] = OppositeBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/remapBlock.ts":
/*!*********************************************!*\
  !*** ./Materials/Node/Blocks/remapBlock.ts ***!
  \*********************************************/
/*! exports provided: RemapBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RemapBlock", function() { return RemapBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../Maths/math.vector */ "./Maths/math.vector.ts");






/**
 * Block used to remap a float from a range to a new one
 */
var RemapBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RemapBlock, _super);
    /**
     * Creates a new RemapBlock
     * @param name defines the block name
     */
    function RemapBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        /**
         * Gets or sets the source range
         */
        _this.sourceRange = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"](-1, 1);
        /**
         * Gets or sets the target range
         */
        _this.targetRange = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"](0, 1);
        _this.registerInput("input", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    RemapBlock.prototype.getClassName = function () {
        return "RemapBlock";
    };
    Object.defineProperty(RemapBlock.prototype, "input", {
        /**
         * Gets the input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RemapBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    RemapBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = " + this._writeFloat(this.targetRange.x) + " + (" + this._inputs[0].associatedVariableName + " - " + this._writeFloat(this.sourceRange.x) + ") * (" + this._writeFloat(this.targetRange.y) + " - " + this._writeFloat(this.targetRange.x) + ") / (" + this._writeFloat(this.sourceRange.y) + " - " + this._writeFloat(this.sourceRange.x) + ");\r\n");
        return this;
    };
    RemapBlock.prototype._dumpPropertiesCode = function () {
        var codeString = this._codeVariableName + ".sourceRange = new BABYLON.Vector2(" + this.sourceRange.x + ", " + this.sourceRange.y + ");\r\n";
        codeString += this._codeVariableName + ".targetRange = new BABYLON.Vector2(" + this.targetRange.x + ", " + this.targetRange.y + ");\r\n";
        return codeString;
    };
    RemapBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.sourceRange = this.sourceRange.asArray();
        serializationObject.targetRange = this.targetRange.asArray();
        return serializationObject;
    };
    RemapBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        this.sourceRange = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"].FromArray(serializationObject.sourceRange);
        this.targetRange = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"].FromArray(serializationObject.targetRange);
    };
    return RemapBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.RemapBlock"] = RemapBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/scaleBlock.ts":
/*!*********************************************!*\
  !*** ./Materials/Node/Blocks/scaleBlock.ts ***!
  \*********************************************/
/*! exports provided: ScaleBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScaleBlock", function() { return ScaleBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to scale a vector by a float
 */
var ScaleBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ScaleBlock, _super);
    /**
     * Creates a new ScaleBlock
     * @param name defines the block name
     */
    function ScaleBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("input", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("factor", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ScaleBlock.prototype.getClassName = function () {
        return "ScaleBlock";
    };
    Object.defineProperty(ScaleBlock.prototype, "input", {
        /**
         * Gets the input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ScaleBlock.prototype, "factor", {
        /**
         * Gets the factor input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ScaleBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    ScaleBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = " + this.input.associatedVariableName + " * " + this.factor.associatedVariableName + ";\r\n");
        return this;
    };
    return ScaleBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ScaleBlock"] = ScaleBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/stepBlock.ts":
/*!********************************************!*\
  !*** ./Materials/Node/Blocks/stepBlock.ts ***!
  \********************************************/
/*! exports provided: StepBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StepBlock", function() { return StepBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to step a value
 */
var StepBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StepBlock, _super);
    /**
     * Creates a new AddBlock
     * @param name defines the block name
     */
    function StepBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("value", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerInput("edge", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    StepBlock.prototype.getClassName = function () {
        return "StepBlock";
    };
    Object.defineProperty(StepBlock.prototype, "value", {
        /**
         * Gets the value operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StepBlock.prototype, "edge", {
        /**
         * Gets the edge operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StepBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    StepBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = step(" + this.edge.associatedVariableName + ", " + this.value.associatedVariableName + ");\r\n");
        return this;
    };
    return StepBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.StepBlock"] = StepBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/subtractBlock.ts":
/*!************************************************!*\
  !*** ./Materials/Node/Blocks/subtractBlock.ts ***!
  \************************************************/
/*! exports provided: SubtractBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubtractBlock", function() { return SubtractBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to subtract 2 vectors
 */
var SubtractBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubtractBlock, _super);
    /**
     * Creates a new SubtractBlock
     * @param name defines the block name
     */
    function SubtractBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("left", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("right", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput);
        _this._outputs[0]._typeConnectionSource = _this._inputs[0];
        _this._linkConnectionTypes(0, 1);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    SubtractBlock.prototype.getClassName = function () {
        return "SubtractBlock";
    };
    Object.defineProperty(SubtractBlock.prototype, "left", {
        /**
         * Gets the left operand input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SubtractBlock.prototype, "right", {
        /**
         * Gets the right operand input component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SubtractBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    SubtractBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = " + this.left.associatedVariableName + " - " + this.right.associatedVariableName + ";\r\n");
        return this;
    };
    return SubtractBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.SubtractBlock"] = SubtractBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/transformBlock.ts":
/*!*************************************************!*\
  !*** ./Materials/Node/Blocks/transformBlock.ts ***!
  \*************************************************/
/*! exports provided: TransformBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransformBlock", function() { return TransformBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to transform a vector (2, 3 or 4) with a matrix. It will generate a Vector4
 */
var TransformBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TransformBlock, _super);
    /**
     * Creates a new TransformBlock
     * @param name defines the block name
     */
    function TransformBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Vertex) || this;
        /**
         * Defines the value to use to complement W value to transform it to a Vector4
         */
        _this.complementW = 1;
        /**
         * Defines the value to use to complement z value to transform it to a Vector4
         */
        _this.complementZ = 0;
        _this.registerInput("vector", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].AutoDetect);
        _this.registerInput("transform", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Matrix);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    TransformBlock.prototype.getClassName = function () {
        return "TransformBlock";
    };
    Object.defineProperty(TransformBlock.prototype, "vector", {
        /**
         * Gets the vector input
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformBlock.prototype, "transform", {
        /**
         * Gets the matrix transform input
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    TransformBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        var vector = this.vector;
        var transform = this.transform;
        if (vector.connectedPoint) {
            switch (vector.connectedPoint.type) {
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                    state.compilationString += this._declareOutput(output, state) + (" = " + transform.associatedVariableName + " * vec4(" + vector.associatedVariableName + ", " + this._writeFloat(this.complementZ) + ", " + this._writeFloat(this.complementW) + ");\r\n");
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                    state.compilationString += this._declareOutput(output, state) + (" = " + transform.associatedVariableName + " * vec4(" + vector.associatedVariableName + ", " + this._writeFloat(this.complementW) + ");\r\n");
                    break;
                default:
                    state.compilationString += this._declareOutput(output, state) + (" = " + transform.associatedVariableName + " * " + vector.associatedVariableName + ";\r\n");
                    break;
            }
        }
        return this;
    };
    TransformBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.complementZ = this.complementZ;
        serializationObject.complementW = this.complementW;
        return serializationObject;
    };
    TransformBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        this.complementZ = serializationObject.complementZ !== undefined ? serializationObject.complementZ : 0.0;
        this.complementW = serializationObject.complementW !== undefined ? serializationObject.complementW : 1.0;
    };
    TransformBlock.prototype._dumpPropertiesCode = function () {
        var codeString = this._codeVariableName + ".complementZ = " + this.complementZ + ";\r\n";
        codeString += this._codeVariableName + ".complementW = " + this.complementW + ";\r\n";
        return codeString;
    };
    return TransformBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.TransformBlock"] = TransformBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/trigonometryBlock.ts":
/*!****************************************************!*\
  !*** ./Materials/Node/Blocks/trigonometryBlock.ts ***!
  \****************************************************/
/*! exports provided: TrigonometryBlockOperations, TrigonometryBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlockOperations", function() { return TrigonometryBlockOperations; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlock", function() { return TrigonometryBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Operations supported by the Trigonometry block
 */
var TrigonometryBlockOperations;
(function (TrigonometryBlockOperations) {
    /** Cos */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Cos"] = 0] = "Cos";
    /** Sin */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Sin"] = 1] = "Sin";
    /** Abs */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Abs"] = 2] = "Abs";
    /** Exp */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Exp"] = 3] = "Exp";
    /** Exp2 */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Exp2"] = 4] = "Exp2";
    /** Round */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Round"] = 5] = "Round";
    /** Floor */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Floor"] = 6] = "Floor";
    /** Ceiling */
    TrigonometryBlockOperations[TrigonometryBlockOperations["Ceiling"] = 7] = "Ceiling";
})(TrigonometryBlockOperations || (TrigonometryBlockOperations = {}));
/**
 * Block used to apply trigonometry operation to floats
 */
var TrigonometryBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TrigonometryBlock, _super);
    /**
     * Creates a new TrigonometryBlock
     * @param name defines the block name
     */
    function TrigonometryBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        /**
         * Gets or sets the operation applied by the block
         */
        _this.operation = TrigonometryBlockOperations.Cos;
        _this.registerInput("input", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    TrigonometryBlock.prototype.getClassName = function () {
        return "TrigonometryBlock";
    };
    Object.defineProperty(TrigonometryBlock.prototype, "input", {
        /**
         * Gets the input component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TrigonometryBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    TrigonometryBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        var operation = "";
        switch (this.operation) {
            case TrigonometryBlockOperations.Cos: {
                operation = "cos";
                break;
            }
            case TrigonometryBlockOperations.Sin: {
                operation = "sin";
                break;
            }
            case TrigonometryBlockOperations.Abs: {
                operation = "abs";
                break;
            }
            case TrigonometryBlockOperations.Exp: {
                operation = "exp";
                break;
            }
            case TrigonometryBlockOperations.Exp2: {
                operation = "exp2";
                break;
            }
            case TrigonometryBlockOperations.Round: {
                operation = "round";
                break;
            }
            case TrigonometryBlockOperations.Floor: {
                operation = "floor";
                break;
            }
            case TrigonometryBlockOperations.Ceiling: {
                operation = "ceil";
                break;
            }
        }
        state.compilationString += this._declareOutput(output, state) + (" = " + operation + "(" + this.input.associatedVariableName + ");\r\n");
        return this;
    };
    TrigonometryBlock.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.operation = this.operation;
        return serializationObject;
    };
    TrigonometryBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        _super.prototype._deserialize.call(this, serializationObject, scene, rootUrl);
        this.operation = serializationObject.operation;
    };
    return TrigonometryBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.TrigonometryBlock"] = TrigonometryBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/vectorMergerBlock.ts":
/*!****************************************************!*\
  !*** ./Materials/Node/Blocks/vectorMergerBlock.ts ***!
  \****************************************************/
/*! exports provided: VectorMergerBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VectorMergerBlock", function() { return VectorMergerBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to create a Vector2/3/4 out of individual inputs (one for each component)
 */
var VectorMergerBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VectorMergerBlock, _super);
    /**
     * Create a new VectorMergerBlock
     * @param name defines the block name
     */
    function VectorMergerBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) || this;
        _this.registerInput("x", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerInput("y", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerInput("z", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        _this.registerInput("w", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float, true);
        _this.registerOutput("xyzw", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerOutput("xyz", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("xy", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    VectorMergerBlock.prototype.getClassName = function () {
        return "VectorMergerBlock";
    };
    Object.defineProperty(VectorMergerBlock.prototype, "x", {
        /**
         * Gets the x component (input)
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorMergerBlock.prototype, "y", {
        /**
         * Gets the y component (input)
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorMergerBlock.prototype, "z", {
        /**
         * Gets the z component (input)
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorMergerBlock.prototype, "w", {
        /**
         * Gets the w component (input)
         */
        get: function () {
            return this._inputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorMergerBlock.prototype, "xyzw", {
        /**
         * Gets the xyzw component (output)
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorMergerBlock.prototype, "xyz", {
        /**
         * Gets the xyz component (output)
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorMergerBlock.prototype, "xy", {
        /**
         * Gets the xy component (output)
         */
        get: function () {
            return this._outputs[2];
        },
        enumerable: true,
        configurable: true
    });
    VectorMergerBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var xInput = this.x;
        var yInput = this.y;
        var zInput = this.z;
        var wInput = this.w;
        var v4Output = this._outputs[0];
        var v3Output = this._outputs[1];
        var v2Output = this._outputs[2];
        if (v4Output.hasEndpoints) {
            state.compilationString += this._declareOutput(v4Output, state) + (" = vec4(" + this._writeVariable(xInput) + ", " + this._writeVariable(yInput) + ", " + (zInput.isConnected ? this._writeVariable(zInput) : "0.0") + ", " + (zInput.isConnected ? this._writeVariable(wInput) : "0.0") + ");\r\n");
        }
        else if (v3Output.hasEndpoints) {
            state.compilationString += this._declareOutput(v3Output, state) + (" = vec3(" + this._writeVariable(xInput) + ", " + this._writeVariable(yInput) + ", " + (zInput.isConnected ? this._writeVariable(zInput) : "0.0") + ");\r\n");
        }
        else if (v2Output.hasEndpoints) {
            state.compilationString += this._declareOutput(v2Output, state) + (" = vec2(" + this._writeVariable(xInput) + ", " + this._writeVariable(yInput) + ");\r\n");
        }
        return this;
    };
    return VectorMergerBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.VectorMergerBlock"] = VectorMergerBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/vectorSplitterBlock.ts":
/*!******************************************************!*\
  !*** ./Materials/Node/Blocks/vectorSplitterBlock.ts ***!
  \******************************************************/
/*! exports provided: VectorSplitterBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VectorSplitterBlock", function() { return VectorSplitterBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Block used to expand a Vector3/4 into 4 outputs (one for each component)
 */
var VectorSplitterBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VectorSplitterBlock, _super);
    /**
     * Create a new VectorSplitterBlock
     * @param name defines the block name
     */
    function VectorSplitterBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Fragment) || this;
        _this.registerInput("xyzw", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4, true);
        _this.registerInput("xyz ", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3, true);
        _this.registerInput("xy ", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2, true);
        _this.registerOutput("xyz", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("xy", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector2);
        _this.registerOutput("x", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("y", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("z", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        _this.registerOutput("w", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Float);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    VectorSplitterBlock.prototype.getClassName = function () {
        return "VectorSplitterBlock";
    };
    Object.defineProperty(VectorSplitterBlock.prototype, "xyzw", {
        /**
         * Gets the xyzw component (input)
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "xyzIn", {
        /**
         * Gets the xyz component (input)
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "xyIn", {
        /**
         * Gets the xy component (input)
         */
        get: function () {
            return this._inputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "xyzOut", {
        /**
         * Gets the xyz component (output)
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "xyOut", {
        /**
         * Gets the xy component (output)
         */
        get: function () {
            return this._outputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "x", {
        /**
         * Gets the x component (output)
         */
        get: function () {
            return this._outputs[2];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "y", {
        /**
         * Gets the y component (output)
         */
        get: function () {
            return this._outputs[3];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "z", {
        /**
         * Gets the z component (output)
         */
        get: function () {
            return this._outputs[4];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(VectorSplitterBlock.prototype, "w", {
        /**
         * Gets the w component (output)
         */
        get: function () {
            return this._outputs[5];
        },
        enumerable: true,
        configurable: true
    });
    VectorSplitterBlock.prototype._inputRename = function (name) {
        switch (name) {
            case "xy ":
                return "xyIn";
            case "xyz ":
                return "xyzIn";
            default:
                return name;
        }
    };
    VectorSplitterBlock.prototype._outputRename = function (name) {
        switch (name) {
            case "xy":
                return "xyOut";
            case "xyz":
                return "xyzOut";
            default:
                return name;
        }
    };
    VectorSplitterBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var input = this.xyzw.isConnected ? this.xyzw : this.xyzIn.isConnected ? this.xyzIn : this.xyIn;
        var xyzOutput = this._outputs[0];
        var xyOutput = this._outputs[1];
        var xOutput = this._outputs[2];
        var yOutput = this._outputs[3];
        var zOutput = this._outputs[4];
        var wOutput = this._outputs[5];
        if (xyzOutput.hasEndpoints) {
            if (input === this.xyIn) {
                state.compilationString += this._declareOutput(xyzOutput, state) + (" = vec3(" + input.associatedVariableName + ", 0.0);\r\n");
            }
            else {
                state.compilationString += this._declareOutput(xyzOutput, state) + (" = " + input.associatedVariableName + ".xyz;\r\n");
            }
        }
        if (xyOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(xyOutput, state) + (" = " + input.associatedVariableName + ".xy;\r\n");
        }
        if (xOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(xOutput, state) + (" = " + input.associatedVariableName + ".x;\r\n");
        }
        if (yOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(yOutput, state) + (" = " + input.associatedVariableName + ".y;\r\n");
        }
        if (zOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(zOutput, state) + (" = " + input.associatedVariableName + ".z;\r\n");
        }
        if (wOutput.hasEndpoints) {
            state.compilationString += this._declareOutput(wOutput, state) + (" = " + input.associatedVariableName + ".w;\r\n");
        }
        return this;
    };
    return VectorSplitterBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.VectorSplitterBlock"] = VectorSplitterBlock;


/***/ }),

/***/ "./Materials/Node/Blocks/viewDirectionBlock.ts":
/*!*****************************************************!*\
  !*** ./Materials/Node/Blocks/viewDirectionBlock.ts ***!
  \*****************************************************/
/*! exports provided: ViewDirectionBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ViewDirectionBlock", function() { return ViewDirectionBlock; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony import */ var _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");







/**
 * Block used to get the view direction
 */
var ViewDirectionBlock = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ViewDirectionBlock, _super);
    /**
     * Creates a new ViewDirectionBlock
     * @param name defines the block name
     */
    function ViewDirectionBlock(name) {
        var _this = _super.call(this, name, _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlockTargets"].Neutral) || this;
        _this.registerInput("worldPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector4);
        _this.registerInput("cameraPosition", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        _this.registerOutput("output", _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockConnectionPointTypes"].Vector3);
        return _this;
    }
    /**
     * Gets the current class name
     * @returns the class name
     */
    ViewDirectionBlock.prototype.getClassName = function () {
        return "ViewDirectionBlock";
    };
    Object.defineProperty(ViewDirectionBlock.prototype, "worldPosition", {
        /**
         * Gets the world position component
         */
        get: function () {
            return this._inputs[0];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ViewDirectionBlock.prototype, "cameraPosition", {
        /**
         * Gets the camera position component
         */
        get: function () {
            return this._inputs[1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ViewDirectionBlock.prototype, "output", {
        /**
         * Gets the output component
         */
        get: function () {
            return this._outputs[0];
        },
        enumerable: true,
        configurable: true
    });
    ViewDirectionBlock.prototype.autoConfigure = function (material) {
        if (!this.cameraPosition.isConnected) {
            var cameraPositionInput = material.getInputBlockByPredicate(function (b) { return b.systemValue === _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialSystemValues"].CameraPosition; });
            if (!cameraPositionInput) {
                cameraPositionInput = new _Input_inputBlock__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]("cameraPosition");
                cameraPositionInput.setAsSystemValue(_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialSystemValues"].CameraPosition);
            }
            cameraPositionInput.output.connectTo(this.cameraPosition);
        }
    };
    ViewDirectionBlock.prototype._buildBlock = function (state) {
        _super.prototype._buildBlock.call(this, state);
        var output = this._outputs[0];
        state.compilationString += this._declareOutput(output, state) + (" = normalize(" + this.cameraPosition.associatedVariableName + " - " + this.worldPosition.associatedVariableName + ".xyz);\r\n");
        return this;
    };
    return ViewDirectionBlock;
}(_nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlock"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ViewDirectionBlock"] = ViewDirectionBlock;


/***/ }),

/***/ "./Materials/Node/NodeMaterialBlockConnectionPointMode.ts":
/*!****************************************************************!*\
  !*** ./Materials/Node/NodeMaterialBlockConnectionPointMode.ts ***!
  \****************************************************************/
/*! exports provided: NodeMaterialBlockConnectionPointMode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockConnectionPointMode", function() { return NodeMaterialBlockConnectionPointMode; });
/**
 * Enum defining the mode of a NodeMaterialBlockConnectionPoint
 */
var NodeMaterialBlockConnectionPointMode;
(function (NodeMaterialBlockConnectionPointMode) {
    /** Value is an uniform */
    NodeMaterialBlockConnectionPointMode[NodeMaterialBlockConnectionPointMode["Uniform"] = 0] = "Uniform";
    /** Value is a mesh attribute */
    NodeMaterialBlockConnectionPointMode[NodeMaterialBlockConnectionPointMode["Attribute"] = 1] = "Attribute";
    /** Value is a varying between vertex and fragment shaders */
    NodeMaterialBlockConnectionPointMode[NodeMaterialBlockConnectionPointMode["Varying"] = 2] = "Varying";
    /** Mode is undefined */
    NodeMaterialBlockConnectionPointMode[NodeMaterialBlockConnectionPointMode["Undefined"] = 3] = "Undefined";
})(NodeMaterialBlockConnectionPointMode || (NodeMaterialBlockConnectionPointMode = {}));


/***/ }),

/***/ "./Materials/Node/Optimizers/index.ts":
/*!********************************************!*\
  !*** ./Materials/Node/Optimizers/index.ts ***!
  \********************************************/
/*! exports provided: NodeMaterialOptimizer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _nodeMaterialOptimizer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./nodeMaterialOptimizer */ "./Materials/Node/Optimizers/nodeMaterialOptimizer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialOptimizer", function() { return _nodeMaterialOptimizer__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialOptimizer"]; });




/***/ }),

/***/ "./Materials/Node/Optimizers/nodeMaterialOptimizer.ts":
/*!************************************************************!*\
  !*** ./Materials/Node/Optimizers/nodeMaterialOptimizer.ts ***!
  \************************************************************/
/*! exports provided: NodeMaterialOptimizer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialOptimizer", function() { return NodeMaterialOptimizer; });
/**
 * Root class for all node material optimizers
 */
var NodeMaterialOptimizer = /** @class */ (function () {
    function NodeMaterialOptimizer() {
    }
    /**
     * Function used to optimize a NodeMaterial graph
     * @param vertexOutputNodes defines the list of output nodes for the vertex shader
     * @param fragmentOutputNodes defines the list of output nodes for the fragment shader
     */
    NodeMaterialOptimizer.prototype.optimize = function (vertexOutputNodes, fragmentOutputNodes) {
        // Do nothing by default
    };
    return NodeMaterialOptimizer;
}());



/***/ }),

/***/ "./Materials/Node/index.ts":
/*!*********************************!*\
  !*** ./Materials/Node/index.ts ***!
  \*********************************/
/*! exports provided: NodeMaterialBlockTargets, NodeMaterialBlockConnectionPointTypes, NodeMaterialConnectionPoint, NodeMaterialBlock, NodeMaterialDefines, NodeMaterial, NodeMaterialSystemValues, MultiplyBlock, AddBlock, ScaleBlock, ClampBlock, CrossBlock, DotBlock, TransformBlock, RemapBlock, NormalizeBlock, TrigonometryBlockOperations, TrigonometryBlock, ColorMergerBlock, VectorMergerBlock, ColorSplitterBlock, VectorSplitterBlock, LerpBlock, DivideBlock, SubtractBlock, StepBlock, OppositeBlock, ViewDirectionBlock, FresnelBlock, MaxBlock, MinBlock, NodeMaterialOptimizer, VertexOutputBlock, BonesBlock, InstancesBlock, MorphTargetsBlock, LightInformationBlock, FragmentOutputBlock, AlphaTestBlock, ImageProcessingBlock, PerturbNormalBlock, FogBlock, LightBlock, TextureBlock, ReflectionTextureBlock, InputBlock, AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockTargets", function() { return _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockTargets"]; });

/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockConnectionPointTypes", function() { return _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlockConnectionPointTypes"]; });

/* harmony import */ var _nodeMaterialBlockConnectionPoint__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./nodeMaterialBlockConnectionPoint */ "./Materials/Node/nodeMaterialBlockConnectionPoint.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialConnectionPoint", function() { return _nodeMaterialBlockConnectionPoint__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialConnectionPoint"]; });

/* harmony import */ var _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./nodeMaterialBlock */ "./Materials/Node/nodeMaterialBlock.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlock", function() { return _nodeMaterialBlock__WEBPACK_IMPORTED_MODULE_3__["NodeMaterialBlock"]; });

/* harmony import */ var _nodeMaterial__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./nodeMaterial */ "./Materials/Node/nodeMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialDefines", function() { return _nodeMaterial__WEBPACK_IMPORTED_MODULE_4__["NodeMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterial", function() { return _nodeMaterial__WEBPACK_IMPORTED_MODULE_4__["NodeMaterial"]; });

/* harmony import */ var _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./nodeMaterialSystemValues */ "./Materials/Node/nodeMaterialSystemValues.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialSystemValues", function() { return _nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialSystemValues"]; });

/* harmony import */ var _Blocks_index__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Blocks/index */ "./Materials/Node/Blocks/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["MultiplyBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AddBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["AddBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ScaleBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClampBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ClampBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CrossBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["CrossBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DotBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["DotBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["TransformBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RemapBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["RemapBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NormalizeBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["NormalizeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlockOperations", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["TrigonometryBlockOperations"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["TrigonometryBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorMergerBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ColorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorMergerBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["VectorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorSplitterBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ColorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorSplitterBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["VectorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LerpBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["LerpBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DivideBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["DivideBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubtractBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["SubtractBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StepBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["StepBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OppositeBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["OppositeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViewDirectionBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ViewDirectionBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["FresnelBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaxBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["MaxBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MinBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["MinBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["VertexOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["BonesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["InstancesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["MorphTargetsBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["LightInformationBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["FragmentOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["AlphaTestBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ImageProcessingBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["PerturbNormalBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["FogBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["LightBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["TextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["ReflectionTextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["InputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return _Blocks_index__WEBPACK_IMPORTED_MODULE_6__["AnimatedInputBlockTypes"]; });

/* harmony import */ var _Optimizers_index__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Optimizers/index */ "./Materials/Node/Optimizers/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialOptimizer", function() { return _Optimizers_index__WEBPACK_IMPORTED_MODULE_7__["NodeMaterialOptimizer"]; });











/***/ }),

/***/ "./Materials/Node/nodeMaterial.ts":
/*!****************************************!*\
  !*** ./Materials/Node/nodeMaterial.ts ***!
  \****************************************/
/*! exports provided: NodeMaterialDefines, NodeMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialDefines", function() { return NodeMaterialDefines; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterial", function() { return NodeMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _pushMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../pushMaterial */ "./Materials/pushMaterial.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _nodeMaterialBuildState__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./nodeMaterialBuildState */ "./Materials/Node/nodeMaterialBuildState.ts");
/* harmony import */ var _effect__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../effect */ "./Materials/effect.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _nodeMaterialBuildStateSharedData__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./nodeMaterialBuildStateSharedData */ "./Materials/Node/nodeMaterialBuildStateSharedData.ts");
/* harmony import */ var _Materials_materialDefines__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Materials/materialDefines */ "./Materials/materialDefines.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Blocks_transformBlock__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Blocks/transformBlock */ "./Materials/Node/Blocks/transformBlock.ts");
/* harmony import */ var _Blocks_Vertex_vertexOutputBlock__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Blocks/Vertex/vertexOutputBlock */ "./Materials/Node/Blocks/Vertex/vertexOutputBlock.ts");
/* harmony import */ var _Blocks_Fragment_fragmentOutputBlock__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Blocks/Fragment/fragmentOutputBlock */ "./Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts");
/* harmony import */ var _Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Blocks/Input/inputBlock */ "./Materials/Node/Blocks/Input/inputBlock.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_fileTools__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../../Misc/fileTools */ "./Misc/fileTools.ts");




















/** @hidden */
var NodeMaterialDefines = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NodeMaterialDefines, _super);
    function NodeMaterialDefines() {
        var _this = _super.call(this) || this;
        /** BONES */
        _this.NUM_BONE_INFLUENCERS = 0;
        _this.BonesPerMesh = 0;
        _this.BONETEXTURE = false;
        /** MORPH TARGETS */
        _this.MORPHTARGETS = false;
        _this.MORPHTARGETS_NORMAL = false;
        _this.MORPHTARGETS_TANGENT = false;
        _this.MORPHTARGETS_UV = false;
        _this.NUM_MORPH_INFLUENCERS = 0;
        /** IMAGE PROCESSING */
        _this.IMAGEPROCESSING = false;
        _this.VIGNETTE = false;
        _this.VIGNETTEBLENDMODEMULTIPLY = false;
        _this.VIGNETTEBLENDMODEOPAQUE = false;
        _this.TONEMAPPING = false;
        _this.TONEMAPPING_ACES = false;
        _this.CONTRAST = false;
        _this.EXPOSURE = false;
        _this.COLORCURVES = false;
        _this.COLORGRADING = false;
        _this.COLORGRADING3D = false;
        _this.SAMPLER3DGREENDEPTH = false;
        _this.SAMPLER3DBGRMAP = false;
        _this.IMAGEPROCESSINGPOSTPROCESS = false;
        _this.rebuild();
        return _this;
    }
    NodeMaterialDefines.prototype.setValue = function (name, value) {
        if (this[name] === undefined) {
            this._keys.push(name);
        }
        this[name] = value;
    };
    return NodeMaterialDefines;
}(_Materials_materialDefines__WEBPACK_IMPORTED_MODULE_10__["MaterialDefines"]));

/**
 * Class used to create a node based material built by assembling shader blocks
 */
var NodeMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NodeMaterial, _super);
    /**
     * Create a new node based material
     * @param name defines the material name
     * @param scene defines the hosting scene
     * @param options defines creation option
     */
    function NodeMaterial(name, scene, options) {
        if (options === void 0) { options = {}; }
        var _this = _super.call(this, name, scene || _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].LastCreatedScene) || this;
        _this._buildId = NodeMaterial._BuildIdGenerator++;
        _this._buildWasSuccessful = false;
        _this._cachedWorldViewMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        _this._cachedWorldViewProjectionMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        _this._optimizers = new Array();
        _this._animationFrame = -1;
        _this.BJSNODEMATERIALEDITOR = _this._getGlobalNodeMaterialEditor();
        /**
         * Gets or sets a boolean indicating that alpha value must be ignored (This will turn alpha blending off even if an alpha value is produced by the material)
         */
        _this.ignoreAlpha = false;
        /**
        * Defines the maximum number of lights that can be used in the material
        */
        _this.maxSimultaneousLights = 4;
        /**
         * Observable raised when the material is built
         */
        _this.onBuildObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_7__["Observable"]();
        /**
         * Gets or sets the root nodes of the material vertex shader
         */
        _this._vertexOutputNodes = new Array();
        /**
         * Gets or sets the root nodes of the material fragment (pixel) shader
         */
        _this._fragmentOutputNodes = new Array();
        /**
         * Gets an array of blocks that needs to be serialized even if they are not yet connected
         */
        _this.attachedBlocks = new Array();
        _this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ emitComments: false }, options);
        // Setup the default processing configuration to the scene.
        _this._attachImageProcessingConfiguration(null);
        return _this;
    }
    /** Get the inspector from bundle or global */
    NodeMaterial.prototype._getGlobalNodeMaterialEditor = function () {
        // UMD Global name detection from Webpack Bundle UMD Name.
        if (typeof NODEEDITOR !== 'undefined') {
            return NODEEDITOR;
        }
        // In case of module let's check the global emitted from the editor entry point.
        if (typeof BABYLON !== 'undefined' && typeof BABYLON.NodeEditor !== 'undefined') {
            return BABYLON;
        }
        return undefined;
    };
    Object.defineProperty(NodeMaterial.prototype, "options", {
        /** Gets or sets options to control the node material overall behavior */
        get: function () {
            return this._options;
        },
        set: function (options) {
            this._options = options;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterial.prototype, "imageProcessingConfiguration", {
        /**
         * Gets the image processing configuration used either in this material.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        /**
         * Sets the Default image processing configuration used either in the this material.
         *
         * If sets to null, the scene one is in use.
         */
        set: function (value) {
            this._attachImageProcessingConfiguration(value);
            // Ensure the effect will be rebuilt.
            this._markAllSubMeshesAsTexturesDirty();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current class name of the material e.g. "NodeMaterial"
     * @returns the class name
     */
    NodeMaterial.prototype.getClassName = function () {
        return "NodeMaterial";
    };
    /**
     * Attaches a new image processing configuration to the Standard Material.
     * @param configuration
     */
    NodeMaterial.prototype._attachImageProcessingConfiguration = function (configuration) {
        var _this = this;
        if (configuration === this._imageProcessingConfiguration) {
            return;
        }
        // Detaches observer.
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        // Pick the scene configuration if needed.
        if (!configuration) {
            this._imageProcessingConfiguration = this.getScene().imageProcessingConfiguration;
        }
        else {
            this._imageProcessingConfiguration = configuration;
        }
        // Attaches observer.
        if (this._imageProcessingConfiguration) {
            this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(function () {
                _this._markAllSubMeshesAsImageProcessingDirty();
            });
        }
    };
    /**
     * Get a block by its name
     * @param name defines the name of the block to retrieve
     * @returns the required block or null if not found
     */
    NodeMaterial.prototype.getBlockByName = function (name) {
        for (var _i = 0, _a = this.attachedBlocks; _i < _a.length; _i++) {
            var block = _a[_i];
            if (block.name === name) {
                return block;
            }
        }
        return null;
    };
    /**
     * Get a block by its name
     * @param predicate defines the predicate used to find the good candidate
     * @returns the required block or null if not found
     */
    NodeMaterial.prototype.getBlockByPredicate = function (predicate) {
        for (var _i = 0, _a = this.attachedBlocks; _i < _a.length; _i++) {
            var block = _a[_i];
            if (predicate(block)) {
                return block;
            }
        }
        return null;
    };
    /**
     * Get an input block by its name
     * @param predicate defines the predicate used to find the good candidate
     * @returns the required input block or null if not found
     */
    NodeMaterial.prototype.getInputBlockByPredicate = function (predicate) {
        for (var _i = 0, _a = this.attachedBlocks; _i < _a.length; _i++) {
            var block = _a[_i];
            if (block.isInput && predicate(block)) {
                return block;
            }
        }
        return null;
    };
    /**
     * Gets the list of input blocks attached to this material
     * @returns an array of InputBlocks
     */
    NodeMaterial.prototype.getInputBlocks = function () {
        var blocks = [];
        for (var _i = 0, _a = this.attachedBlocks; _i < _a.length; _i++) {
            var block = _a[_i];
            if (block.isInput) {
                blocks.push(block);
            }
        }
        return blocks;
    };
    /**
     * Adds a new optimizer to the list of optimizers
     * @param optimizer defines the optimizers to add
     * @returns the current material
     */
    NodeMaterial.prototype.registerOptimizer = function (optimizer) {
        var index = this._optimizers.indexOf(optimizer);
        if (index > -1) {
            return;
        }
        this._optimizers.push(optimizer);
        return this;
    };
    /**
     * Remove an optimizer from the list of optimizers
     * @param optimizer defines the optimizers to remove
     * @returns the current material
     */
    NodeMaterial.prototype.unregisterOptimizer = function (optimizer) {
        var index = this._optimizers.indexOf(optimizer);
        if (index === -1) {
            return;
        }
        this._optimizers.splice(index, 1);
        return this;
    };
    /**
     * Add a new block to the list of output nodes
     * @param node defines the node to add
     * @returns the current material
     */
    NodeMaterial.prototype.addOutputNode = function (node) {
        if (node.target === null) {
            throw "This node is not meant to be an output node. You may want to explicitly set its target value.";
        }
        if ((node.target & _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Vertex) !== 0) {
            this._addVertexOutputNode(node);
        }
        if ((node.target & _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Fragment) !== 0) {
            this._addFragmentOutputNode(node);
        }
        return this;
    };
    /**
     * Remove a block from the list of root nodes
     * @param node defines the node to remove
     * @returns the current material
     */
    NodeMaterial.prototype.removeOutputNode = function (node) {
        if (node.target === null) {
            return this;
        }
        if ((node.target & _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Vertex) !== 0) {
            this._removeVertexOutputNode(node);
        }
        if ((node.target & _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Fragment) !== 0) {
            this._removeFragmentOutputNode(node);
        }
        return this;
    };
    NodeMaterial.prototype._addVertexOutputNode = function (node) {
        if (this._vertexOutputNodes.indexOf(node) !== -1) {
            return;
        }
        node.target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Vertex;
        this._vertexOutputNodes.push(node);
        return this;
    };
    NodeMaterial.prototype._removeVertexOutputNode = function (node) {
        var index = this._vertexOutputNodes.indexOf(node);
        if (index === -1) {
            return;
        }
        this._vertexOutputNodes.splice(index, 1);
        return this;
    };
    NodeMaterial.prototype._addFragmentOutputNode = function (node) {
        if (this._fragmentOutputNodes.indexOf(node) !== -1) {
            return;
        }
        node.target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Fragment;
        this._fragmentOutputNodes.push(node);
        return this;
    };
    NodeMaterial.prototype._removeFragmentOutputNode = function (node) {
        var index = this._fragmentOutputNodes.indexOf(node);
        if (index === -1) {
            return;
        }
        this._fragmentOutputNodes.splice(index, 1);
        return this;
    };
    /**
     * Specifies if the material will require alpha blending
     * @returns a boolean specifying if alpha blending is needed
     */
    NodeMaterial.prototype.needAlphaBlending = function () {
        if (this.ignoreAlpha) {
            return false;
        }
        return (this.alpha < 1.0) || (this._sharedData && this._sharedData.hints.needAlphaBlending);
    };
    /**
     * Specifies if this material should be rendered in alpha test mode
     * @returns a boolean specifying if an alpha test is needed.
     */
    NodeMaterial.prototype.needAlphaTesting = function () {
        return this._sharedData && this._sharedData.hints.needAlphaTesting;
    };
    NodeMaterial.prototype._initializeBlock = function (node, state, nodesToProcessForOtherBuildState) {
        node.initialize(state);
        node.autoConfigure(this);
        node._preparationId = this._buildId;
        if (this.attachedBlocks.indexOf(node) === -1) {
            this.attachedBlocks.push(node);
        }
        for (var _i = 0, _a = node.inputs; _i < _a.length; _i++) {
            var input = _a[_i];
            if (!node.isInput) {
                input.associatedVariableName = "";
            }
            var connectedPoint = input.connectedPoint;
            if (connectedPoint) {
                var block = connectedPoint.ownerBlock;
                if (block !== node) {
                    if (block.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].VertexAndFragment) {
                        nodesToProcessForOtherBuildState.push(block);
                    }
                    else if (state.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Fragment
                        && block.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Vertex
                        && block._preparationId !== this._buildId) {
                        nodesToProcessForOtherBuildState.push(block);
                    }
                    this._initializeBlock(block, state, nodesToProcessForOtherBuildState);
                }
            }
        }
        for (var _b = 0, _c = node.outputs; _b < _c.length; _b++) {
            var output = _c[_b];
            output.associatedVariableName = "";
        }
    };
    NodeMaterial.prototype._resetDualBlocks = function (node, id) {
        if (node.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].VertexAndFragment) {
            node.buildId = id;
        }
        for (var _i = 0, _a = node.inputs; _i < _a.length; _i++) {
            var inputs = _a[_i];
            var connectedPoint = inputs.connectedPoint;
            if (connectedPoint) {
                var block = connectedPoint.ownerBlock;
                if (block !== node) {
                    this._resetDualBlocks(block, id);
                }
            }
        }
    };
    /**
     * Build the material and generates the inner effect
     * @param verbose defines if the build should log activity
     */
    NodeMaterial.prototype.build = function (verbose) {
        if (verbose === void 0) { verbose = false; }
        this._buildWasSuccessful = false;
        var engine = this.getScene().getEngine();
        if (this._vertexOutputNodes.length === 0) {
            throw "You must define at least one vertexOutputNode";
        }
        if (this._fragmentOutputNodes.length === 0) {
            throw "You must define at least one fragmentOutputNode";
        }
        // Compilation state
        this._vertexCompilationState = new _nodeMaterialBuildState__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBuildState"]();
        this._vertexCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;
        this._vertexCompilationState.target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Vertex;
        this._fragmentCompilationState = new _nodeMaterialBuildState__WEBPACK_IMPORTED_MODULE_5__["NodeMaterialBuildState"]();
        this._fragmentCompilationState.supportUniformBuffers = engine.supportsUniformBuffers;
        this._fragmentCompilationState.target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_8__["NodeMaterialBlockTargets"].Fragment;
        // Shared data
        this._sharedData = new _nodeMaterialBuildStateSharedData__WEBPACK_IMPORTED_MODULE_9__["NodeMaterialBuildStateSharedData"]();
        this._vertexCompilationState.sharedData = this._sharedData;
        this._fragmentCompilationState.sharedData = this._sharedData;
        this._sharedData.buildId = this._buildId;
        this._sharedData.emitComments = this._options.emitComments;
        this._sharedData.verbose = verbose;
        // Initialize blocks
        var vertexNodes = [];
        var fragmentNodes = [];
        for (var _i = 0, _a = this._vertexOutputNodes; _i < _a.length; _i++) {
            var vertexOutputNode = _a[_i];
            vertexNodes.push(vertexOutputNode);
            this._initializeBlock(vertexOutputNode, this._vertexCompilationState, fragmentNodes);
        }
        for (var _b = 0, _c = this._fragmentOutputNodes; _b < _c.length; _b++) {
            var fragmentOutputNode = _c[_b];
            fragmentNodes.push(fragmentOutputNode);
            this._initializeBlock(fragmentOutputNode, this._fragmentCompilationState, vertexNodes);
        }
        // Optimize
        this.optimize();
        // Vertex
        for (var _d = 0, vertexNodes_1 = vertexNodes; _d < vertexNodes_1.length; _d++) {
            var vertexOutputNode = vertexNodes_1[_d];
            vertexOutputNode.build(this._vertexCompilationState, vertexNodes);
        }
        // Fragment
        this._fragmentCompilationState.uniforms = this._vertexCompilationState.uniforms.slice(0);
        this._fragmentCompilationState._uniformDeclaration = this._vertexCompilationState._uniformDeclaration;
        this._fragmentCompilationState._vertexState = this._vertexCompilationState;
        for (var _e = 0, fragmentNodes_1 = fragmentNodes; _e < fragmentNodes_1.length; _e++) {
            var fragmentOutputNode = fragmentNodes_1[_e];
            this._resetDualBlocks(fragmentOutputNode, this._buildId - 1);
        }
        for (var _f = 0, fragmentNodes_2 = fragmentNodes; _f < fragmentNodes_2.length; _f++) {
            var fragmentOutputNode = fragmentNodes_2[_f];
            fragmentOutputNode.build(this._fragmentCompilationState, fragmentNodes);
        }
        // Finalize
        this._vertexCompilationState.finalize(this._vertexCompilationState);
        this._fragmentCompilationState.finalize(this._fragmentCompilationState);
        this._buildId = NodeMaterial._BuildIdGenerator++;
        // Errors
        this._sharedData.emitErrors();
        if (verbose) {
            console.log("Vertex shader:");
            console.log(this._vertexCompilationState.compilationString);
            console.log("Fragment shader:");
            console.log(this._fragmentCompilationState.compilationString);
        }
        this._buildWasSuccessful = true;
        this.onBuildObservable.notifyObservers(this);
        // Wipe defines
        var meshes = this.getScene().meshes;
        for (var _g = 0, meshes_1 = meshes; _g < meshes_1.length; _g++) {
            var mesh = meshes_1[_g];
            if (!mesh.subMeshes) {
                continue;
            }
            for (var _h = 0, _j = mesh.subMeshes; _h < _j.length; _h++) {
                var subMesh = _j[_h];
                if (subMesh.getMaterial() !== this) {
                    continue;
                }
                if (!subMesh._materialDefines) {
                    continue;
                }
                var defines = subMesh._materialDefines;
                defines.markAllAsDirty();
                defines.reset();
            }
        }
    };
    /**
     * Runs an otpimization phase to try to improve the shader code
     */
    NodeMaterial.prototype.optimize = function () {
        for (var _i = 0, _a = this._optimizers; _i < _a.length; _i++) {
            var optimizer = _a[_i];
            optimizer.optimize(this._vertexOutputNodes, this._fragmentOutputNodes);
        }
    };
    NodeMaterial.prototype._prepareDefinesForAttributes = function (mesh, defines) {
        if (!defines._areAttributesDirty) {
            return;
        }
        defines["NORMAL"] = mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_11__["VertexBuffer"].NormalKind);
        defines["TANGENT"] = mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_11__["VertexBuffer"].TangentKind);
        defines["UV1"] = mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_11__["VertexBuffer"].UVKind);
    };
    /**
      * Get if the submesh is ready to be used and all its information available.
      * Child classes can use it to update shaders
      * @param mesh defines the mesh to check
      * @param subMesh defines which submesh to check
      * @param useInstances specifies that instances should be used
      * @returns a boolean indicating that the submesh is ready or not
      */
    NodeMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        var _this = this;
        if (useInstances === void 0) { useInstances = false; }
        if (!this._buildWasSuccessful) {
            return false;
        }
        var scene = this.getScene();
        if (this._sharedData.animatedInputs) {
            var frameId = scene.getFrameId();
            if (this._animationFrame !== frameId) {
                for (var _i = 0, _a = this._sharedData.animatedInputs; _i < _a.length; _i++) {
                    var input = _a[_i];
                    input.animate(scene);
                }
                this._animationFrame = frameId;
            }
        }
        if (subMesh.effect && this.isFrozen) {
            if (this._wasPreviouslyReady) {
                return true;
            }
        }
        if (!subMesh._materialDefines) {
            subMesh._materialDefines = new NodeMaterialDefines();
        }
        var defines = subMesh._materialDefines;
        if (!this.checkReadyOnEveryCall && subMesh.effect) {
            if (defines._renderId === scene.getRenderId()) {
                return true;
            }
        }
        var engine = scene.getEngine();
        this._prepareDefinesForAttributes(mesh, defines);
        // Check if blocks are ready
        if (this._sharedData.blockingBlocks.some(function (b) { return !b.isReady(mesh, _this, defines, useInstances); })) {
            return false;
        }
        // Shared defines
        this._sharedData.blocksWithDefines.forEach(function (b) {
            b.initializeDefines(mesh, _this, defines, useInstances);
        });
        this._sharedData.blocksWithDefines.forEach(function (b) {
            b.prepareDefines(mesh, _this, defines, useInstances);
        });
        // Need to recompile?
        if (defines.isDirty) {
            defines.markAsProcessed();
            // Repeatable content generators
            this._vertexCompilationState.compilationString = this._vertexCompilationState._builtCompilationString;
            this._fragmentCompilationState.compilationString = this._fragmentCompilationState._builtCompilationString;
            this._sharedData.repeatableContentBlocks.forEach(function (b) {
                b.replaceRepeatableContent(_this._vertexCompilationState, _this._fragmentCompilationState, mesh, defines);
            });
            // Uniforms
            this._sharedData.dynamicUniformBlocks.forEach(function (b) {
                b.updateUniformsAndSamples(_this._vertexCompilationState, _this, defines);
            });
            var mergedUniforms_1 = this._vertexCompilationState.uniforms;
            this._fragmentCompilationState.uniforms.forEach(function (u) {
                var index = mergedUniforms_1.indexOf(u);
                if (index === -1) {
                    mergedUniforms_1.push(u);
                }
            });
            // Uniform buffers
            var mergedUniformBuffers_1 = this._vertexCompilationState.uniformBuffers;
            this._fragmentCompilationState.uniformBuffers.forEach(function (u) {
                var index = mergedUniformBuffers_1.indexOf(u);
                if (index === -1) {
                    mergedUniformBuffers_1.push(u);
                }
            });
            // Samplers
            var mergedSamplers_1 = this._vertexCompilationState.samplers;
            this._fragmentCompilationState.samplers.forEach(function (s) {
                var index = mergedSamplers_1.indexOf(s);
                if (index === -1) {
                    mergedSamplers_1.push(s);
                }
            });
            var fallbacks = new _effect__WEBPACK_IMPORTED_MODULE_6__["EffectFallbacks"]();
            this._sharedData.blocksWithFallbacks.forEach(function (b) {
                b.provideFallbacks(mesh, fallbacks);
            });
            var previousEffect = subMesh.effect;
            // Compilation
            var join = defines.toString();
            var effect = engine.createEffect({
                vertex: "nodeMaterial" + this._buildId,
                fragment: "nodeMaterial" + this._buildId,
                vertexSource: this._vertexCompilationState.compilationString,
                fragmentSource: this._fragmentCompilationState.compilationString
            }, {
                attributes: this._vertexCompilationState.attributes,
                uniformsNames: mergedUniforms_1,
                uniformBuffersNames: mergedUniformBuffers_1,
                samplers: mergedSamplers_1,
                defines: join,
                fallbacks: fallbacks,
                onCompiled: this.onCompiled,
                onError: this.onError,
                indexParameters: { maxSimultaneousLights: this.maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS }
            }, engine);
            if (effect) {
                // Use previous effect while new one is compiling
                if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {
                    effect = previousEffect;
                    defines.markAsUnprocessed();
                }
                else {
                    scene.resetCachedMaterial();
                    subMesh.setEffect(effect, defines);
                }
            }
        }
        if (!subMesh.effect || !subMesh.effect.isReady()) {
            return false;
        }
        defines._renderId = scene.getRenderId();
        this._wasPreviouslyReady = true;
        return true;
    };
    Object.defineProperty(NodeMaterial.prototype, "compiledShaders", {
        /**
         * Get a string representing the shaders built by the current node graph
         */
        get: function () {
            return "// Vertex shader\r\n" + this._vertexCompilationState.compilationString + "\r\n\r\n// Fragment shader\r\n" + this._fragmentCompilationState.compilationString;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Binds the world matrix to the material
     * @param world defines the world transformation matrix
     */
    NodeMaterial.prototype.bindOnlyWorldMatrix = function (world) {
        var scene = this.getScene();
        if (!this._activeEffect) {
            return;
        }
        var hints = this._sharedData.hints;
        if (hints.needWorldViewMatrix) {
            world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
        }
        if (hints.needWorldViewProjectionMatrix) {
            world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);
        }
        // Connection points
        for (var _i = 0, _a = this._sharedData.inputBlocks; _i < _a.length; _i++) {
            var inputBlock = _a[_i];
            inputBlock._transmitWorld(this._activeEffect, world, this._cachedWorldViewMatrix, this._cachedWorldViewProjectionMatrix);
        }
    };
    /**
     * Binds the submesh to this material by preparing the effect and shader to draw
     * @param world defines the world transformation matrix
     * @param mesh defines the mesh containing the submesh
     * @param subMesh defines the submesh to bind the material to
     */
    NodeMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
        var scene = this.getScene();
        var effect = subMesh.effect;
        if (!effect) {
            return;
        }
        this._activeEffect = effect;
        // Matrices
        this.bindOnlyWorldMatrix(world);
        var mustRebind = this._mustRebind(scene, effect, mesh.visibility);
        if (mustRebind) {
            var sharedData = this._sharedData;
            if (effect && scene.getCachedMaterial() !== this) {
                // Bindable blocks
                for (var _i = 0, _a = sharedData.bindableBlocks; _i < _a.length; _i++) {
                    var block = _a[_i];
                    block.bind(effect, this, mesh);
                }
                // Connection points
                for (var _b = 0, _c = sharedData.inputBlocks; _b < _c.length; _b++) {
                    var inputBlock = _c[_b];
                    inputBlock._transmit(effect, scene);
                }
            }
        }
        this._afterBind(mesh, this._activeEffect);
    };
    /**
     * Gets the active textures from the material
     * @returns an array of textures
     */
    NodeMaterial.prototype.getActiveTextures = function () {
        var activeTextures = _super.prototype.getActiveTextures.call(this);
        activeTextures.push.apply(activeTextures, this._sharedData.textureBlocks.filter(function (tb) { return tb.texture; }).map(function (tb) { return tb.texture; }));
        return activeTextures;
    };
    /**
     * Gets the list of texture blocks
     * @returns an array of texture blocks
     */
    NodeMaterial.prototype.getTextureBlocks = function () {
        if (!this._sharedData) {
            return [];
        }
        return this._sharedData.textureBlocks.filter(function (tb) { return tb.texture; });
    };
    /**
     * Specifies if the material uses a texture
     * @param texture defines the texture to check against the material
     * @returns a boolean specifying if the material uses the texture
     */
    NodeMaterial.prototype.hasTexture = function (texture) {
        if (_super.prototype.hasTexture.call(this, texture)) {
            return true;
        }
        if (!this._sharedData) {
            return false;
        }
        for (var _i = 0, _a = this._sharedData.textureBlocks; _i < _a.length; _i++) {
            var t = _a[_i];
            if (t.texture === texture) {
                return true;
            }
        }
        return false;
    };
    /**
     * Disposes the material
     * @param forceDisposeEffect specifies if effects should be forcefully disposed
     * @param forceDisposeTextures specifies if textures should be forcefully disposed
     * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh
     */
    NodeMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures, notBoundToMesh) {
        if (forceDisposeTextures) {
            for (var _i = 0, _a = this._sharedData.textureBlocks.filter(function (tb) { return tb.texture; }).map(function (tb) { return tb.texture; }); _i < _a.length; _i++) {
                var texture = _a[_i];
                texture.dispose();
            }
        }
        this.onBuildObservable.clear();
        _super.prototype.dispose.call(this, forceDisposeEffect, forceDisposeTextures, notBoundToMesh);
    };
    /** Creates the node editor window. */
    NodeMaterial.prototype._createNodeEditor = function () {
        this.BJSNODEMATERIALEDITOR = this.BJSNODEMATERIALEDITOR || this._getGlobalNodeMaterialEditor();
        this.BJSNODEMATERIALEDITOR.NodeEditor.Show({
            nodeMaterial: this
        });
    };
    /**
     * Launch the node material editor
     * @param config Define the configuration of the editor
     * @return a promise fulfilled when the node editor is visible
     */
    NodeMaterial.prototype.edit = function (config) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            if (typeof _this.BJSNODEMATERIALEDITOR == 'undefined') {
                var editorUrl = config && config.editorURL ? config.editorURL : NodeMaterial.EditorURL;
                // Load editor and add it to the DOM
                _Misc_tools__WEBPACK_IMPORTED_MODULE_12__["Tools"].LoadScript(editorUrl, function () {
                    _this._createNodeEditor();
                    resolve();
                });
            }
            else {
                // Otherwise creates the editor
                _this._createNodeEditor();
                resolve();
            }
        });
    };
    /**
     * Clear the current material
     */
    NodeMaterial.prototype.clear = function () {
        this._vertexOutputNodes = [];
        this._fragmentOutputNodes = [];
        this.attachedBlocks = [];
    };
    /**
     * Clear the current material and set it to a default state
     */
    NodeMaterial.prototype.setToDefault = function () {
        this.clear();
        var positionInput = new _Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_16__["InputBlock"]("position");
        positionInput.setAsAttribute("position");
        var worldInput = new _Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_16__["InputBlock"]("world");
        worldInput.setAsSystemValue(BABYLON.NodeMaterialSystemValues.World);
        var worldPos = new _Blocks_transformBlock__WEBPACK_IMPORTED_MODULE_13__["TransformBlock"]("worldPos");
        positionInput.connectTo(worldPos);
        worldInput.connectTo(worldPos);
        var viewProjectionInput = new _Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_16__["InputBlock"]("viewProjection");
        viewProjectionInput.setAsSystemValue(BABYLON.NodeMaterialSystemValues.ViewProjection);
        var worldPosdMultipliedByViewProjection = new _Blocks_transformBlock__WEBPACK_IMPORTED_MODULE_13__["TransformBlock"]("worldPos * viewProjectionTransform");
        worldPos.connectTo(worldPosdMultipliedByViewProjection);
        viewProjectionInput.connectTo(worldPosdMultipliedByViewProjection);
        var vertexOutput = new _Blocks_Vertex_vertexOutputBlock__WEBPACK_IMPORTED_MODULE_14__["VertexOutputBlock"]("vertexOutput");
        worldPosdMultipliedByViewProjection.connectTo(vertexOutput);
        // Pixel
        var pixelColor = new _Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_16__["InputBlock"]("color");
        pixelColor.value = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color4"](0.8, 0.8, 0.8, 1);
        var fragmentOutput = new _Blocks_Fragment_fragmentOutputBlock__WEBPACK_IMPORTED_MODULE_15__["FragmentOutputBlock"]("fragmentOutput");
        pixelColor.connectTo(fragmentOutput);
        // Add to nodes
        this.addOutputNode(vertexOutput);
        this.addOutputNode(fragmentOutput);
    };
    /**
     * Loads the current Node Material from a url pointing to a file save by the Node Material Editor
     * @param url defines the url to load from
     * @returns a promise that will fullfil when the material is fully loaded
     */
    NodeMaterial.prototype.loadAsync = function (url) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _Misc_fileTools__WEBPACK_IMPORTED_MODULE_19__["FileTools"].LoadFile(url, function (data) {
                var serializationObject = JSON.parse(data);
                _this.loadFromSerialization(serializationObject, "");
                resolve();
            }, undefined, undefined, false, function (request, exception) {
                reject(exception.message);
            });
        });
    };
    NodeMaterial.prototype._gatherBlocks = function (rootNode, list) {
        if (list.indexOf(rootNode) !== -1) {
            return;
        }
        list.push(rootNode);
        for (var _i = 0, _a = rootNode.inputs; _i < _a.length; _i++) {
            var input = _a[_i];
            var connectedPoint = input.connectedPoint;
            if (connectedPoint) {
                var block = connectedPoint.ownerBlock;
                if (block !== rootNode) {
                    this._gatherBlocks(block, list);
                }
            }
        }
    };
    /**
     * Generate a string containing the code declaration required to create an equivalent of this material
     * @returns a string
     */
    NodeMaterial.prototype.generateCode = function () {
        var alreadyDumped = [];
        var vertexBlocks = [];
        var uniqueNames = [];
        // Gets active blocks
        for (var _i = 0, _a = this._vertexOutputNodes; _i < _a.length; _i++) {
            var outputNode = _a[_i];
            this._gatherBlocks(outputNode, vertexBlocks);
        }
        var fragmentBlocks = [];
        for (var _b = 0, _c = this._fragmentOutputNodes; _b < _c.length; _b++) {
            var outputNode = _c[_b];
            this._gatherBlocks(outputNode, fragmentBlocks);
        }
        // Generate vertex shader
        var codeString = "var nodeMaterial = new BABYLON.NodeMaterial(`node material`);\r\n";
        for (var _d = 0, vertexBlocks_1 = vertexBlocks; _d < vertexBlocks_1.length; _d++) {
            var node = vertexBlocks_1[_d];
            if (node.isInput && alreadyDumped.indexOf(node) === -1) {
                codeString += node._dumpCode(uniqueNames, alreadyDumped);
            }
        }
        // Generate fragment shader
        for (var _e = 0, fragmentBlocks_1 = fragmentBlocks; _e < fragmentBlocks_1.length; _e++) {
            var node = fragmentBlocks_1[_e];
            if (node.isInput && alreadyDumped.indexOf(node) === -1) {
                codeString += node._dumpCode(uniqueNames, alreadyDumped);
            }
        }
        for (var _f = 0, _g = this._vertexOutputNodes; _f < _g.length; _f++) {
            var node = _g[_f];
            codeString += "nodeMaterial.addOutputNode(" + node._codeVariableName + ");\r\n";
        }
        for (var _h = 0, _j = this._fragmentOutputNodes; _h < _j.length; _h++) {
            var node = _j[_h];
            codeString += "nodeMaterial.addOutputNode(" + node._codeVariableName + ");\r\n";
        }
        codeString += "nodeMaterial.build();\r\n";
        return codeString;
    };
    /**
     * Serializes this material in a JSON representation
     * @returns the serialized material object
     */
    NodeMaterial.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_18__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.NodeMaterial";
        serializationObject.outputNodes = [];
        var blocks = [];
        // Outputs
        for (var _i = 0, _a = this._vertexOutputNodes; _i < _a.length; _i++) {
            var outputNode = _a[_i];
            this._gatherBlocks(outputNode, blocks);
            serializationObject.outputNodes.push(outputNode.uniqueId);
        }
        for (var _b = 0, _c = this._fragmentOutputNodes; _b < _c.length; _b++) {
            var outputNode = _c[_b];
            this._gatherBlocks(outputNode, blocks);
            if (serializationObject.outputNodes.indexOf(outputNode.uniqueId) === -1) {
                serializationObject.outputNodes.push(outputNode.uniqueId);
            }
        }
        // Blocks
        serializationObject.blocks = [];
        for (var _d = 0, blocks_1 = blocks; _d < blocks_1.length; _d++) {
            var block = blocks_1[_d];
            serializationObject.blocks.push(block.serialize());
        }
        for (var _e = 0, _f = this.attachedBlocks; _e < _f.length; _e++) {
            var block = _f[_e];
            if (blocks.indexOf(block) !== -1) {
                continue;
            }
            serializationObject.blocks.push(block.serialize());
        }
        return serializationObject;
    };
    NodeMaterial.prototype._restoreConnections = function (block, source, map) {
        for (var _i = 0, _a = block.outputs; _i < _a.length; _i++) {
            var outputPoint = _a[_i];
            for (var _b = 0, _c = source.blocks; _b < _c.length; _b++) {
                var candidate = _c[_b];
                var target = map[candidate.id];
                for (var _d = 0, _e = candidate.inputs; _d < _e.length; _d++) {
                    var input = _e[_d];
                    if (map[input.targetBlockId] === block && input.targetConnectionName === outputPoint.name) {
                        var inputPoint = target.getInputByName(input.inputName);
                        if (!inputPoint || inputPoint.isConnected) {
                            continue;
                        }
                        outputPoint.connectTo(inputPoint, true);
                        this._restoreConnections(target, source, map);
                        continue;
                    }
                }
            }
        }
    };
    /**
     * Clear the current graph and load a new one from a serialization object
     * @param source defines the JSON representation of the material
     * @param rootUrl defines the root URL to use to load textures and relative dependencies
     */
    NodeMaterial.prototype.loadFromSerialization = function (source, rootUrl) {
        if (rootUrl === void 0) { rootUrl = ""; }
        this.clear();
        var map = {};
        // Create blocks
        for (var _i = 0, _a = source.blocks; _i < _a.length; _i++) {
            var parsedBlock = _a[_i];
            var blockType = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_17__["_TypeStore"].GetClass(parsedBlock.customType);
            if (blockType) {
                var block = new blockType();
                block._deserialize(parsedBlock, this.getScene(), rootUrl);
                map[parsedBlock.id] = block;
                this.attachedBlocks.push(block);
            }
        }
        // Connections
        // Starts with input blocks only
        for (var blockIndex = 0; blockIndex < source.blocks.length; blockIndex++) {
            var parsedBlock_1 = source.blocks[blockIndex];
            var block = map[parsedBlock_1.id];
            if (!block.isInput) {
                continue;
            }
            this._restoreConnections(block, source, map);
        }
        // Outputs
        for (var _b = 0, _c = source.outputNodes; _b < _c.length; _b++) {
            var outputNodeId = _c[_b];
            this.addOutputNode(map[outputNodeId]);
        }
        // Store map for external uses
        source.map = {};
        for (var key in map) {
            source.map[key] = map[key].uniqueId;
        }
    };
    /**
     * Creates a node material from parsed material data
     * @param source defines the JSON representation of the material
     * @param scene defines the hosting scene
     * @param rootUrl defines the root URL to use to load textures and relative dependencies
     * @returns a new node material
     */
    NodeMaterial.Parse = function (source, scene, rootUrl) {
        if (rootUrl === void 0) { rootUrl = ""; }
        var nodeMaterial = _Misc_decorators__WEBPACK_IMPORTED_MODULE_18__["SerializationHelper"].Parse(function () { return new NodeMaterial(source.name, scene); }, source, scene, rootUrl);
        nodeMaterial.loadFromSerialization(source, rootUrl);
        return nodeMaterial;
    };
    /**
     * Creates a new node material set to default basic configuration
     * @param name defines the name of the material
     * @param scene defines the hosting scene
     * @returns a new NodeMaterial
     */
    NodeMaterial.CreateDefault = function (name, scene) {
        var newMaterial = new NodeMaterial(name, scene);
        newMaterial.setToDefault();
        newMaterial.build();
        return newMaterial;
    };
    NodeMaterial._BuildIdGenerator = 0;
    /** Define the URl to load node editor script */
    NodeMaterial.EditorURL = "https://unpkg.com/babylonjs-node-editor@" + _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].Version + "/babylon.nodeEditor.js";
    return NodeMaterial;
}(_pushMaterial__WEBPACK_IMPORTED_MODULE_1__["PushMaterial"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_17__["_TypeStore"].RegisteredTypes["BABYLON.NodeMaterial"] = NodeMaterial;


/***/ }),

/***/ "./Materials/Node/nodeMaterialBlock.ts":
/*!*********************************************!*\
  !*** ./Materials/Node/nodeMaterialBlock.ts ***!
  \*********************************************/
/*! exports provided: NodeMaterialBlock */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlock", function() { return NodeMaterialBlock; });
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockConnectionPoint__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./nodeMaterialBlockConnectionPoint */ "./Materials/Node/nodeMaterialBlockConnectionPoint.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _Misc_uniqueIdGenerator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/uniqueIdGenerator */ "./Misc/uniqueIdGenerator.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * Defines a block that can be used inside a node based material
 */
var NodeMaterialBlock = /** @class */ (function () {
    /**
     * Creates a new NodeMaterialBlock
     * @param name defines the block name
     * @param target defines the target of that block (Vertex by default)
     * @param isFinalMerger defines a boolean indicating that this block is an end block (e.g. it is generating a system value). Default is false
     * @param isInput defines a boolean indicating that this block is an input (e.g. it sends data to the shader). Default is false
     */
    function NodeMaterialBlock(name, target, isFinalMerger, isInput) {
        if (target === void 0) { target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Vertex; }
        if (isFinalMerger === void 0) { isFinalMerger = false; }
        if (isInput === void 0) { isInput = false; }
        this._isFinalMerger = false;
        this._isInput = false;
        /** @hidden */
        this._codeVariableName = "";
        /** @hidden */
        this._inputs = new Array();
        /** @hidden */
        this._outputs = new Array();
        this.name = name;
        this._target = target;
        this._isFinalMerger = isFinalMerger;
        this._isInput = isInput;
        this.uniqueId = _Misc_uniqueIdGenerator__WEBPACK_IMPORTED_MODULE_3__["UniqueIdGenerator"].UniqueId;
    }
    Object.defineProperty(NodeMaterialBlock.prototype, "isFinalMerger", {
        /**
         * Gets a boolean indicating that this block is an end block (e.g. it is generating a system value)
         */
        get: function () {
            return this._isFinalMerger;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialBlock.prototype, "isInput", {
        /**
         * Gets a boolean indicating that this block is an input (e.g. it sends data to the shader)
         */
        get: function () {
            return this._isInput;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialBlock.prototype, "buildId", {
        /**
         * Gets or sets the build Id
         */
        get: function () {
            return this._buildId;
        },
        set: function (value) {
            this._buildId = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialBlock.prototype, "target", {
        /**
         * Gets or sets the target of the block
         */
        get: function () {
            return this._target;
        },
        set: function (value) {
            if ((this._target & value) !== 0) {
                return;
            }
            this._target = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialBlock.prototype, "inputs", {
        /**
         * Gets the list of input points
         */
        get: function () {
            return this._inputs;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialBlock.prototype, "outputs", {
        /** Gets the list of output points */
        get: function () {
            return this._outputs;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Find an input by its name
     * @param name defines the name of the input to look for
     * @returns the input or null if not found
     */
    NodeMaterialBlock.prototype.getInputByName = function (name) {
        var filter = this._inputs.filter(function (e) { return e.name === name; });
        if (filter.length) {
            return filter[0];
        }
        return null;
    };
    /**
     * Find an output by its name
     * @param name defines the name of the outputto look for
     * @returns the output or null if not found
     */
    NodeMaterialBlock.prototype.getOutputByName = function (name) {
        var filter = this._outputs.filter(function (e) { return e.name === name; });
        if (filter.length) {
            return filter[0];
        }
        return null;
    };
    /**
     * Initialize the block and prepare the context for build
     * @param state defines the state that will be used for the build
     */
    NodeMaterialBlock.prototype.initialize = function (state) {
        // Do nothing
    };
    /**
     * Bind data to effect. Will only be called for blocks with isBindable === true
     * @param effect defines the effect to bind data to
     * @param nodeMaterial defines the hosting NodeMaterial
     * @param mesh defines the mesh that will be rendered
     */
    NodeMaterialBlock.prototype.bind = function (effect, nodeMaterial, mesh) {
        // Do nothing
    };
    NodeMaterialBlock.prototype._declareOutput = function (output, state) {
        return state._getGLType(output.type) + " " + output.associatedVariableName;
    };
    NodeMaterialBlock.prototype._writeVariable = function (currentPoint) {
        var connectionPoint = currentPoint.connectedPoint;
        if (connectionPoint) {
            return "" + currentPoint.associatedVariableName;
        }
        return "0.";
    };
    NodeMaterialBlock.prototype._writeFloat = function (value) {
        var stringVersion = value.toString();
        if (stringVersion.indexOf(".") === -1) {
            stringVersion += ".0";
        }
        return "" + stringVersion;
    };
    /**
     * Gets the current class name e.g. "NodeMaterialBlock"
     * @returns the class name
     */
    NodeMaterialBlock.prototype.getClassName = function () {
        return "NodeMaterialBlock";
    };
    /**
     * Register a new input. Must be called inside a block constructor
     * @param name defines the connection point name
     * @param type defines the connection point type
     * @param isOptional defines a boolean indicating that this input can be omitted
     * @param target defines the target to use to limit the connection point (will be VertexAndFragment by default)
     * @returns the current block
     */
    NodeMaterialBlock.prototype.registerInput = function (name, type, isOptional, target) {
        if (isOptional === void 0) { isOptional = false; }
        var point = new _nodeMaterialBlockConnectionPoint__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialConnectionPoint"](name, this);
        point.type = type;
        point.isOptional = isOptional;
        if (target) {
            point.target = target;
        }
        this._inputs.push(point);
        return this;
    };
    /**
     * Register a new output. Must be called inside a block constructor
     * @param name defines the connection point name
     * @param type defines the connection point type
     * @param target defines the target to use to limit the connection point (will be VertexAndFragment by default)
     * @returns the current block
     */
    NodeMaterialBlock.prototype.registerOutput = function (name, type, target) {
        var point = new _nodeMaterialBlockConnectionPoint__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialConnectionPoint"](name, this);
        point.type = type;
        if (target) {
            point.target = target;
        }
        this._outputs.push(point);
        return this;
    };
    /**
     * Will return the first available input e.g. the first one which is not an uniform or an attribute
     * @param forOutput defines an optional connection point to check compatibility with
     * @returns the first available input or null
     */
    NodeMaterialBlock.prototype.getFirstAvailableInput = function (forOutput) {
        if (forOutput === void 0) { forOutput = null; }
        for (var _i = 0, _a = this._inputs; _i < _a.length; _i++) {
            var input = _a[_i];
            if (!input.connectedPoint) {
                if (!forOutput || (forOutput.type === input.type) || (input.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].AutoDetect)) {
                    return input;
                }
            }
        }
        return null;
    };
    /**
     * Will return the first available output e.g. the first one which is not yet connected and not a varying
     * @param forBlock defines an optional block to check compatibility with
     * @returns the first available input or null
     */
    NodeMaterialBlock.prototype.getFirstAvailableOutput = function (forBlock) {
        if (forBlock === void 0) { forBlock = null; }
        for (var _i = 0, _a = this._outputs; _i < _a.length; _i++) {
            var output = _a[_i];
            if (!forBlock || !forBlock.target || forBlock.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Neutral || (forBlock.target & output.target) !== 0) {
                return output;
            }
        }
        return null;
    };
    /**
     * Gets the sibling of the given output
     * @param current defines the current output
     * @returns the next output in the list or null
     */
    NodeMaterialBlock.prototype.getSiblingOutput = function (current) {
        var index = this._outputs.indexOf(current);
        if (index === -1 || index >= this._outputs.length) {
            return null;
        }
        return this._outputs[index + 1];
    };
    /**
     * Connect current block with another block
     * @param other defines the block to connect with
     * @param options define the various options to help pick the right connections
     * @returns the current block
     */
    NodeMaterialBlock.prototype.connectTo = function (other, options) {
        if (this._outputs.length === 0) {
            return;
        }
        var output = options && options.output ? this.getOutputByName(options.output) : this.getFirstAvailableOutput(other);
        var notFound = true;
        while (notFound) {
            var input = options && options.input ? other.getInputByName(options.input) : other.getFirstAvailableInput(output);
            if (output && input && output.canConnectTo(input)) {
                output.connectTo(input);
                notFound = false;
            }
            else if (!output) {
                throw "Unable to find a compatible match";
            }
            else {
                output = this.getSiblingOutput(output);
            }
        }
        return this;
    };
    NodeMaterialBlock.prototype._buildBlock = function (state) {
        // Empty. Must be defined by child nodes
    };
    /**
     * Add uniforms, samplers and uniform buffers at compilation time
     * @param state defines the state to update
     * @param nodeMaterial defines the node material requesting the update
     * @param defines defines the material defines to update
     */
    NodeMaterialBlock.prototype.updateUniformsAndSamples = function (state, nodeMaterial, defines) {
        // Do nothing
    };
    /**
     * Add potential fallbacks if shader compilation fails
     * @param mesh defines the mesh to be rendered
     * @param fallbacks defines the current prioritized list of fallbacks
     */
    NodeMaterialBlock.prototype.provideFallbacks = function (mesh, fallbacks) {
        // Do nothing
    };
    /**
     * Update defines for shader compilation
     * @param mesh defines the mesh to be rendered
     * @param nodeMaterial defines the node material requesting the update
     * @param defines defines the material defines to update
     * @param useInstances specifies that instances should be used
     */
    NodeMaterialBlock.prototype.prepareDefines = function (mesh, nodeMaterial, defines, useInstances) {
        if (useInstances === void 0) { useInstances = false; }
        // Do nothing
    };
    /**
     * Initialize defines for shader compilation
     * @param mesh defines the mesh to be rendered
     * @param nodeMaterial defines the node material requesting the update
     * @param defines defines the material defines to be prepared
     * @param useInstances specifies that instances should be used
     */
    NodeMaterialBlock.prototype.initializeDefines = function (mesh, nodeMaterial, defines, useInstances) {
        if (useInstances === void 0) { useInstances = false; }
        // Do nothing
    };
    /**
     * Lets the block try to connect some inputs automatically
     * @param material defines the hosting NodeMaterial
     */
    NodeMaterialBlock.prototype.autoConfigure = function (material) {
        // Do nothing
    };
    /**
     * Function called when a block is declared as repeatable content generator
     * @param vertexShaderState defines the current compilation state for the vertex shader
     * @param fragmentShaderState defines the current compilation state for the fragment shader
     * @param mesh defines the mesh to be rendered
     * @param defines defines the material defines to update
     */
    NodeMaterialBlock.prototype.replaceRepeatableContent = function (vertexShaderState, fragmentShaderState, mesh, defines) {
        // Do nothing
    };
    /**
     * Checks if the block is ready
     * @param mesh defines the mesh to be rendered
     * @param nodeMaterial defines the node material requesting the update
     * @param defines defines the material defines to update
     * @param useInstances specifies that instances should be used
     * @returns true if the block is ready
     */
    NodeMaterialBlock.prototype.isReady = function (mesh, nodeMaterial, defines, useInstances) {
        if (useInstances === void 0) { useInstances = false; }
        return true;
    };
    NodeMaterialBlock.prototype._linkConnectionTypes = function (inputIndex0, inputIndex1) {
        this._inputs[inputIndex0]._linkedConnectionSource = this._inputs[inputIndex1];
        this._inputs[inputIndex1]._linkedConnectionSource = this._inputs[inputIndex0];
    };
    NodeMaterialBlock.prototype._processBuild = function (block, state, input, activeBlocks) {
        block.build(state, activeBlocks);
        var localBlockIsFragment = (state._vertexState != null);
        var otherBlockWasGeneratedInVertexShader = block._buildTarget === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Vertex && block.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].VertexAndFragment;
        if (localBlockIsFragment && (((block.target & input.target) === 0) ||
            (this.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].VertexAndFragment && otherBlockWasGeneratedInVertexShader))) { // context switch! We need a varying
            if ((!block.isInput && state.target !== block._buildTarget) // block was already emitted by vertex shader
                || (block.isInput && block.isAttribute) // block is an attribute
            ) {
                var connectedPoint = input.connectedPoint;
                if (state._vertexState._emitVaryingFromString("v_" + connectedPoint.associatedVariableName, state._getGLType(connectedPoint.type))) {
                    state._vertexState.compilationString += "v_" + connectedPoint.associatedVariableName + " = " + connectedPoint.associatedVariableName + ";\r\n";
                }
                input.associatedVariableName = "v_" + connectedPoint.associatedVariableName;
                input._enforceAssociatedVariableName = true;
            }
        }
    };
    /**
     * Compile the current node and generate the shader code
     * @param state defines the current compilation state (uniforms, samplers, current string)
     * @param activeBlocks defines the list of active blocks (i.e. blocks to compile)
     * @returns true if already built
     */
    NodeMaterialBlock.prototype.build = function (state, activeBlocks) {
        if (this._buildId === state.sharedData.buildId) {
            return true;
        }
        // Check if "parent" blocks are compiled
        for (var _i = 0, _a = this._inputs; _i < _a.length; _i++) {
            var input = _a[_i];
            if (!input.connectedPoint) {
                if (!input.isOptional) { // Emit a warning
                    state.sharedData.checks.notConnectedNonOptionalInputs.push(input);
                }
                continue;
            }
            if (this.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Neutral) {
                if ((input.target & this.target) === 0) {
                    continue;
                }
                if ((input.target & state.target) === 0) {
                    continue;
                }
            }
            var block = input.connectedPoint.ownerBlock;
            if (block && block !== this) {
                this._processBuild(block, state, input, activeBlocks);
            }
        }
        if (this._buildId === state.sharedData.buildId) {
            return true; // Need to check again as inputs can be connected multiple time to this endpoint
        }
        // Logs
        if (state.sharedData.verbose) {
            console.log((state.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Vertex ? "Vertex shader" : "Fragment shader") + ": Building " + this.name + " [" + this.getClassName() + "]");
        }
        if (!this.isInput) {
            /** Prepare outputs */
            for (var _b = 0, _c = this._outputs; _b < _c.length; _b++) {
                var output = _c[_b];
                if (this.target !== _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Neutral) {
                    if ((output.target & this.target) === 0) {
                        continue;
                    }
                    if ((output.target & state.target) === 0) {
                        continue;
                    }
                }
                if (!output.associatedVariableName) {
                    output.associatedVariableName = state._getFreeVariableName(output.name);
                }
            }
        }
        // Checks final outputs
        if (this.isFinalMerger) {
            switch (state.target) {
                case _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Vertex:
                    state.sharedData.checks.emitVertex = true;
                    break;
                case _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_2__["NodeMaterialBlockTargets"].Fragment:
                    state.sharedData.checks.emitFragment = true;
                    break;
            }
        }
        if (!this.isInput && state.sharedData.emitComments) {
            state.compilationString += "\r\n//" + this.name + "\r\n";
        }
        this._buildBlock(state);
        this._buildId = state.sharedData.buildId;
        this._buildTarget = state.target;
        // Compile connected blocks
        for (var _d = 0, _e = this._outputs; _d < _e.length; _d++) {
            var output = _e[_d];
            if ((output.target & state.target) === 0) {
                continue;
            }
            for (var _f = 0, _g = output.endpoints; _f < _g.length; _f++) {
                var endpoint = _g[_f];
                var block = endpoint.ownerBlock;
                if (block && (block.target & state.target) !== 0 && activeBlocks.indexOf(block) !== -1) {
                    this._processBuild(block, state, endpoint, activeBlocks);
                }
            }
        }
        return false;
    };
    NodeMaterialBlock.prototype._inputRename = function (name) {
        return name;
    };
    NodeMaterialBlock.prototype._outputRename = function (name) {
        return name;
    };
    NodeMaterialBlock.prototype._dumpPropertiesCode = function () {
        return "";
    };
    /** @hidden */
    NodeMaterialBlock.prototype._dumpCode = function (uniqueNames, alreadyDumped) {
        alreadyDumped.push(this);
        var codeString;
        // Get unique name
        var nameAsVariableName = this.name.replace(/[^A-Za-z_]+/g, "");
        this._codeVariableName = nameAsVariableName;
        if (uniqueNames.indexOf(this._codeVariableName) !== -1) {
            var index = 0;
            do {
                index++;
                this._codeVariableName = nameAsVariableName + index;
            } while (uniqueNames.indexOf(this._codeVariableName) !== -1);
        }
        uniqueNames.push(this._codeVariableName);
        // Declaration
        codeString = "\r\nvar " + this._codeVariableName + " = new BABYLON." + this.getClassName() + "(\"" + this.name + "\");\r\n";
        // Properties
        codeString += this._dumpPropertiesCode();
        // Inputs
        for (var _i = 0, _a = this.inputs; _i < _a.length; _i++) {
            var input = _a[_i];
            if (!input.isConnected) {
                continue;
            }
            var connectedOutput = input.connectedPoint;
            var connectedBlock = connectedOutput.ownerBlock;
            if (alreadyDumped.indexOf(connectedBlock) === -1) {
                codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);
            }
            codeString += connectedBlock._codeVariableName + "." + connectedBlock._outputRename(connectedOutput.name) + ".connectTo(" + this._codeVariableName + "." + this._inputRename(input.name) + ");\r\n";
        }
        // Outputs
        for (var _b = 0, _c = this.outputs; _b < _c.length; _b++) {
            var output = _c[_b];
            if (!output.hasEndpoints) {
                continue;
            }
            for (var _d = 0, _e = output.endpoints; _d < _e.length; _d++) {
                var endpoint = _e[_d];
                var connectedBlock = endpoint.ownerBlock;
                if (connectedBlock && alreadyDumped.indexOf(connectedBlock) === -1) {
                    codeString += connectedBlock._dumpCode(uniqueNames, alreadyDumped);
                }
            }
        }
        return codeString;
    };
    /**
     * Clone the current block to a new identical block
     * @param scene defines the hosting scene
     * @param rootUrl defines the root URL to use to load textures and relative dependencies
     * @returns a copy of the current block
     */
    NodeMaterialBlock.prototype.clone = function (scene, rootUrl) {
        if (rootUrl === void 0) { rootUrl = ""; }
        var serializationObject = this.serialize();
        var blockType = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].GetClass(serializationObject.customType);
        if (blockType) {
            var block = new blockType();
            block._deserialize(serializationObject, scene, rootUrl);
            return block;
        }
        return null;
    };
    /**
     * Serializes this block in a JSON representation
     * @returns the serialized block object
     */
    NodeMaterialBlock.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.customType = "BABYLON." + this.getClassName();
        serializationObject.id = this.uniqueId;
        serializationObject.name = this.name;
        serializationObject.inputs = [];
        for (var _i = 0, _a = this.inputs; _i < _a.length; _i++) {
            var input = _a[_i];
            serializationObject.inputs.push(input.serialize());
        }
        return serializationObject;
    };
    /** @hidden */
    NodeMaterialBlock.prototype._deserialize = function (serializationObject, scene, rootUrl) {
        this.name = serializationObject.name;
    };
    return NodeMaterialBlock;
}());



/***/ }),

/***/ "./Materials/Node/nodeMaterialBlockConnectionPoint.ts":
/*!************************************************************!*\
  !*** ./Materials/Node/nodeMaterialBlockConnectionPoint.ts ***!
  \************************************************************/
/*! exports provided: NodeMaterialConnectionPoint */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialConnectionPoint", function() { return NodeMaterialConnectionPoint; });
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");


/**
 * Defines a connection point for a block
 */
var NodeMaterialConnectionPoint = /** @class */ (function () {
    /**
     * Creates a new connection point
     * @param name defines the connection point name
     * @param ownerBlock defines the block hosting this connection point
     */
    function NodeMaterialConnectionPoint(name, ownerBlock) {
        /** @hidden */
        this._connectedPoint = null;
        this._endpoints = new Array();
        /** @hidden */
        this._typeConnectionSource = null;
        /** @hidden */
        this._linkedConnectionSource = null;
        this._type = _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Float;
        /** @hidden */
        this._enforceAssociatedVariableName = false;
        /**
         * Gets or sets the additional types supported byt this connection point
         */
        this.acceptedConnectionPointTypes = new Array();
        /** Gets or sets the target of that connection point */
        this.target = _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlockTargets"].VertexAndFragment;
        this._ownerBlock = ownerBlock;
        this.name = name;
    }
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "associatedVariableName", {
        /**
         * Gets or sets the associated variable name in the shader
         */
        get: function () {
            if (this._ownerBlock.isInput) {
                return this._ownerBlock.associatedVariableName;
            }
            if ((!this._enforceAssociatedVariableName || !this._associatedVariableName) && this._connectedPoint) {
                return this._connectedPoint.associatedVariableName;
            }
            return this._associatedVariableName;
        },
        set: function (value) {
            this._associatedVariableName = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "type", {
        /**
         * Gets or sets the connection point type (default is float)
         */
        get: function () {
            if (this._type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].AutoDetect) {
                if (this._ownerBlock.isInput) {
                    return this._ownerBlock.type;
                }
                if (this._connectedPoint) {
                    return this._connectedPoint.type;
                }
                if (this._linkedConnectionSource && this._linkedConnectionSource.isConnected) {
                    return this._linkedConnectionSource.type;
                }
            }
            if (this._type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].BasedOnInput && this._typeConnectionSource) {
                return this._typeConnectionSource.type;
            }
            return this._type;
        },
        set: function (value) {
            this._type = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "isConnected", {
        /**
         * Gets a boolean indicating that the current point is connected
         */
        get: function () {
            return this.connectedPoint !== null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "isConnectedToInputBlock", {
        /**
         * Gets a boolean indicating that the current point is connected to an input block
         */
        get: function () {
            return this.connectedPoint !== null && this.connectedPoint.ownerBlock.isInput;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "connectInputBlock", {
        /**
         * Gets a the connected input block (if any)
         */
        get: function () {
            if (!this.isConnectedToInputBlock) {
                return null;
            }
            return this.connectedPoint.ownerBlock;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "connectedPoint", {
        /** Get the other side of the connection (if any) */
        get: function () {
            return this._connectedPoint;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "ownerBlock", {
        /** Get the block that owns this connection point */
        get: function () {
            return this._ownerBlock;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "sourceBlock", {
        /** Get the block connected on the other side of this connection (if any) */
        get: function () {
            if (!this._connectedPoint) {
                return null;
            }
            return this._connectedPoint.ownerBlock;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "connectedBlocks", {
        /** Get the block connected on the endpoints of this connection (if any) */
        get: function () {
            if (this._endpoints.length === 0) {
                return [];
            }
            return this._endpoints.map(function (e) { return e.ownerBlock; });
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "endpoints", {
        /** Gets the list of connected endpoints */
        get: function () {
            return this._endpoints;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(NodeMaterialConnectionPoint.prototype, "hasEndpoints", {
        /** Gets a boolean indicating if that output point is connected to at least one input */
        get: function () {
            return this._endpoints && this._endpoints.length > 0;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current class name e.g. "NodeMaterialConnectionPoint"
     * @returns the class name
     */
    NodeMaterialConnectionPoint.prototype.getClassName = function () {
        return "NodeMaterialConnectionPoint";
    };
    /**
     * Gets an boolean indicating if the current point can be connected to another point
     * @param connectionPoint defines the other connection point
     * @returns true if the connection is possible
     */
    NodeMaterialConnectionPoint.prototype.canConnectTo = function (connectionPoint) {
        if (this.type !== connectionPoint.type && connectionPoint.type !== _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].AutoDetect) {
            // Equivalents
            switch (this.type) {
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector3: {
                    if (connectionPoint.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Color3) {
                        return true;
                    }
                }
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector4: {
                    if (connectionPoint.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Color4) {
                        return true;
                    }
                }
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Color3: {
                    if (connectionPoint.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector3) {
                        return true;
                    }
                }
                case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Color4: {
                    if (connectionPoint.type === _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector4) {
                        return true;
                    }
                }
            }
            // Accepted types
            return (connectionPoint.acceptedConnectionPointTypes && connectionPoint.acceptedConnectionPointTypes.indexOf(this.type) !== -1);
        }
        return true;
    };
    /**
     * Connect this point to another connection point
     * @param connectionPoint defines the other connection point
     * @param ignoreConstraints defines if the system will ignore connection type constraints (default is false)
     * @returns the current connection point
     */
    NodeMaterialConnectionPoint.prototype.connectTo = function (connectionPoint, ignoreConstraints) {
        if (ignoreConstraints === void 0) { ignoreConstraints = false; }
        if (!ignoreConstraints && !this.canConnectTo(connectionPoint)) {
            throw "Cannot connect two different connection types.";
        }
        this._endpoints.push(connectionPoint);
        connectionPoint._connectedPoint = this;
        this._enforceAssociatedVariableName = false;
        return this;
    };
    /**
     * Disconnect this point from one of his endpoint
     * @param endpoint defines the other connection point
     * @returns the current connection point
     */
    NodeMaterialConnectionPoint.prototype.disconnectFrom = function (endpoint) {
        var index = this._endpoints.indexOf(endpoint);
        if (index === -1) {
            return this;
        }
        this._endpoints.splice(index, 1);
        endpoint._connectedPoint = null;
        this._enforceAssociatedVariableName = false;
        endpoint._enforceAssociatedVariableName = false;
        return this;
    };
    /**
     * Serializes this point in a JSON representation
     * @returns the serialized point object
     */
    NodeMaterialConnectionPoint.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.name = this.name;
        if (this.connectedPoint) {
            serializationObject.inputName = this.name;
            serializationObject.targetBlockId = this.connectedPoint.ownerBlock.uniqueId;
            serializationObject.targetConnectionName = this.connectedPoint.name;
        }
        return serializationObject;
    };
    return NodeMaterialConnectionPoint;
}());



/***/ }),

/***/ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts":
/*!*****************************************************************!*\
  !*** ./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts ***!
  \*****************************************************************/
/*! exports provided: NodeMaterialBlockConnectionPointTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockConnectionPointTypes", function() { return NodeMaterialBlockConnectionPointTypes; });
/**
 * Defines the kind of connection point for node based material
 */
var NodeMaterialBlockConnectionPointTypes;
(function (NodeMaterialBlockConnectionPointTypes) {
    /** Float */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Float"] = 1] = "Float";
    /** Int */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Int"] = 2] = "Int";
    /** Vector2 */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Vector2"] = 4] = "Vector2";
    /** Vector3 */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Vector3"] = 8] = "Vector3";
    /** Vector4 */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Vector4"] = 16] = "Vector4";
    /** Color3 */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Color3"] = 32] = "Color3";
    /** Color4 */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Color4"] = 64] = "Color4";
    /** Matrix */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["Matrix"] = 128] = "Matrix";
    /** Detect type based on connection */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["AutoDetect"] = 1024] = "AutoDetect";
    /** Output type that will be defined by input type */
    NodeMaterialBlockConnectionPointTypes[NodeMaterialBlockConnectionPointTypes["BasedOnInput"] = 2048] = "BasedOnInput";
})(NodeMaterialBlockConnectionPointTypes || (NodeMaterialBlockConnectionPointTypes = {}));


/***/ }),

/***/ "./Materials/Node/nodeMaterialBlockTargets.ts":
/*!****************************************************!*\
  !*** ./Materials/Node/nodeMaterialBlockTargets.ts ***!
  \****************************************************/
/*! exports provided: NodeMaterialBlockTargets */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockTargets", function() { return NodeMaterialBlockTargets; });
/**
 * Enum used to define the target of a block
 */
var NodeMaterialBlockTargets;
(function (NodeMaterialBlockTargets) {
    /** Vertex shader */
    NodeMaterialBlockTargets[NodeMaterialBlockTargets["Vertex"] = 1] = "Vertex";
    /** Fragment shader */
    NodeMaterialBlockTargets[NodeMaterialBlockTargets["Fragment"] = 2] = "Fragment";
    /** Neutral */
    NodeMaterialBlockTargets[NodeMaterialBlockTargets["Neutral"] = 4] = "Neutral";
    /** Vertex and Fragment */
    NodeMaterialBlockTargets[NodeMaterialBlockTargets["VertexAndFragment"] = 3] = "VertexAndFragment";
})(NodeMaterialBlockTargets || (NodeMaterialBlockTargets = {}));


/***/ }),

/***/ "./Materials/Node/nodeMaterialBuildState.ts":
/*!**************************************************!*\
  !*** ./Materials/Node/nodeMaterialBuildState.ts ***!
  \**************************************************/
/*! exports provided: NodeMaterialBuildState */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBuildState", function() { return NodeMaterialBuildState; });
/* harmony import */ var _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./nodeMaterialBlockConnectionPointTypes */ "./Materials/Node/nodeMaterialBlockConnectionPointTypes.ts");
/* harmony import */ var _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./nodeMaterialBlockTargets */ "./Materials/Node/nodeMaterialBlockTargets.ts");
/* harmony import */ var _effect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../effect */ "./Materials/effect.ts");
/* harmony import */ var _Misc_stringTools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/stringTools */ "./Misc/stringTools.ts");




/**
 * Class used to store node based material build state
 */
var NodeMaterialBuildState = /** @class */ (function () {
    function NodeMaterialBuildState() {
        /** Gets or sets a boolean indicating if the current state can emit uniform buffers */
        this.supportUniformBuffers = false;
        /**
         * Gets the list of emitted attributes
         */
        this.attributes = new Array();
        /**
         * Gets the list of emitted uniforms
         */
        this.uniforms = new Array();
        /**
         * Gets the list of emitted uniform buffers
         */
        this.uniformBuffers = new Array();
        /**
         * Gets the list of emitted samplers
         */
        this.samplers = new Array();
        /**
         * Gets the list of emitted functions
         */
        this.functions = {};
        /**
         * Gets the list of emitted extensions
         */
        this.extensions = {};
        /**
         * Gets the list of emitted counters
         */
        this.counters = {};
        /** @hidden */
        this._attributeDeclaration = "";
        /** @hidden */
        this._uniformDeclaration = "";
        /** @hidden */
        this._samplerDeclaration = "";
        /** @hidden */
        this._varyingTransfer = "";
        this._repeatableContentAnchorIndex = 0;
        /** @hidden */
        this._builtCompilationString = "";
        /**
         * Gets the emitted compilation strings
         */
        this.compilationString = "";
    }
    /**
     * Finalize the compilation strings
     * @param state defines the current compilation state
     */
    NodeMaterialBuildState.prototype.finalize = function (state) {
        var emitComments = state.sharedData.emitComments;
        var isFragmentMode = (this.target === _nodeMaterialBlockTargets__WEBPACK_IMPORTED_MODULE_1__["NodeMaterialBlockTargets"].Fragment);
        this.compilationString = "\r\n" + (emitComments ? "//Entry point\r\n" : "") + "void main(void) {\r\n" + this.compilationString;
        var functionCode = "";
        for (var functionName in this.functions) {
            functionCode += this.functions[functionName] + "\r\n";
        }
        this.compilationString = "\r\n" + functionCode + "\r\n" + this.compilationString;
        if (!isFragmentMode && this._varyingTransfer) {
            this.compilationString = this.compilationString + "\r\n" + this._varyingTransfer;
        }
        this.compilationString = this.compilationString + "\r\n}";
        if (this.sharedData.varyingDeclaration) {
            this.compilationString = "\r\n" + (emitComments ? "//Varyings\r\n" : "") + this.sharedData.varyingDeclaration + "\r\n" + this.compilationString;
        }
        if (this._samplerDeclaration) {
            this.compilationString = "\r\n" + (emitComments ? "//Samplers\r\n" : "") + this._samplerDeclaration + "\r\n" + this.compilationString;
        }
        if (this._uniformDeclaration) {
            this.compilationString = "\r\n" + (emitComments ? "//Uniforms\r\n" : "") + this._uniformDeclaration + "\r\n" + this.compilationString;
        }
        if (this._attributeDeclaration && !isFragmentMode) {
            this.compilationString = "\r\n" + (emitComments ? "//Attributes\r\n" : "") + this._attributeDeclaration + "\r\n" + this.compilationString;
        }
        for (var extensionName in this.extensions) {
            var extension = this.extensions[extensionName];
            this.compilationString = extension + "\r\n" + this.compilationString;
        }
        this._builtCompilationString = this.compilationString;
    };
    Object.defineProperty(NodeMaterialBuildState.prototype, "_repeatableContentAnchor", {
        /** @hidden */
        get: function () {
            return "###___ANCHOR" + this._repeatableContentAnchorIndex++ + "___###";
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    NodeMaterialBuildState.prototype._getFreeVariableName = function (prefix) {
        prefix = prefix.replace(/[^a-zA-Z_]+/g, "");
        if (this.sharedData.variableNames[prefix] === undefined) {
            this.sharedData.variableNames[prefix] = 0;
            // Check reserved words
            if (prefix === "output" || prefix === "texture") {
                return prefix + this.sharedData.variableNames[prefix];
            }
            return prefix;
        }
        else {
            this.sharedData.variableNames[prefix]++;
        }
        return prefix + this.sharedData.variableNames[prefix];
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._getFreeDefineName = function (prefix) {
        if (this.sharedData.defineNames[prefix] === undefined) {
            this.sharedData.defineNames[prefix] = 0;
        }
        else {
            this.sharedData.defineNames[prefix]++;
        }
        return prefix + this.sharedData.defineNames[prefix];
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._excludeVariableName = function (name) {
        this.sharedData.variableNames[name] = 0;
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._getGLType = function (type) {
        switch (type) {
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Float:
                return "float";
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Int:
                return "int";
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector2:
                return "vec2";
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Color3:
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector3:
                return "vec3";
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Color4:
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Vector4:
                return "vec4";
            case _nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__["NodeMaterialBlockConnectionPointTypes"].Matrix:
                return "mat4";
        }
        return "";
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._emitExtension = function (name, extension) {
        if (this.extensions[name]) {
            return;
        }
        this.extensions[name] = extension;
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._emitFunction = function (name, code, comments) {
        if (this.functions[name]) {
            return;
        }
        if (this.sharedData.emitComments) {
            code = comments + "\r\n" + code;
        }
        this.functions[name] = code;
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._emitCodeFromInclude = function (includeName, comments, options) {
        if (options && options.repeatKey) {
            return "#include<" + includeName + ">[0.." + options.repeatKey + "]\r\n";
        }
        var code = _effect__WEBPACK_IMPORTED_MODULE_2__["Effect"].IncludesShadersStore[includeName] + "\r\n";
        if (this.sharedData.emitComments) {
            code = comments + "\r\n" + code;
        }
        if (!options) {
            return code;
        }
        if (options.replaceStrings) {
            for (var index = 0; index < options.replaceStrings.length; index++) {
                var replaceString = options.replaceStrings[index];
                code = code.replace(replaceString.search, replaceString.replace);
            }
        }
        return code;
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._emitFunctionFromInclude = function (includeName, comments, options, storeKey) {
        if (storeKey === void 0) { storeKey = ""; }
        var key = includeName + storeKey;
        if (this.functions[key]) {
            return;
        }
        if (!options || (!options.removeAttributes && !options.removeUniforms && !options.removeVaryings && !options.removeIfDef && !options.replaceStrings)) {
            if (options && options.repeatKey) {
                this.functions[key] = "#include<" + includeName + ">[0.." + options.repeatKey + "]\r\n";
            }
            else {
                this.functions[key] = "#include<" + includeName + ">\r\n";
            }
            if (this.sharedData.emitComments) {
                this.functions[key] = comments + "\r\n" + this.functions[key];
            }
            return;
        }
        this.functions[key] = _effect__WEBPACK_IMPORTED_MODULE_2__["Effect"].IncludesShadersStore[includeName];
        if (this.sharedData.emitComments) {
            this.functions[key] = comments + "\r\n" + this.functions[key];
        }
        if (options.removeIfDef) {
            this.functions[key] = this.functions[key].replace(/^\s*?#ifdef.+$/gm, "");
            this.functions[key] = this.functions[key].replace(/^\s*?#endif.*$/gm, "");
            this.functions[key] = this.functions[key].replace(/^\s*?#else.*$/gm, "");
            this.functions[key] = this.functions[key].replace(/^\s*?#elif.*$/gm, "");
        }
        if (options.removeAttributes) {
            this.functions[key] = this.functions[key].replace(/^\s*?attribute.+$/gm, "");
        }
        if (options.removeUniforms) {
            this.functions[key] = this.functions[key].replace(/^\s*?uniform.+$/gm, "");
        }
        if (options.removeVaryings) {
            this.functions[key] = this.functions[key].replace(/^\s*?varying.+$/gm, "");
        }
        if (options.replaceStrings) {
            for (var index = 0; index < options.replaceStrings.length; index++) {
                var replaceString = options.replaceStrings[index];
                this.functions[key] = this.functions[key].replace(replaceString.search, replaceString.replace);
            }
        }
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._registerTempVariable = function (name) {
        if (this.sharedData.temps.indexOf(name) !== -1) {
            return false;
        }
        this.sharedData.temps.push(name);
        return true;
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._emitVaryingFromString = function (name, type, define, notDefine) {
        if (define === void 0) { define = ""; }
        if (notDefine === void 0) { notDefine = false; }
        if (this.sharedData.varyings.indexOf(name) !== -1) {
            return false;
        }
        this.sharedData.varyings.push(name);
        if (define) {
            if (_Misc_stringTools__WEBPACK_IMPORTED_MODULE_3__["StringTools"].StartsWith(define, "defined(")) {
                this.sharedData.varyingDeclaration += "#if " + define + "\r\n";
            }
            else {
                this.sharedData.varyingDeclaration += (notDefine ? "#ifndef" : "#ifdef") + " " + define + "\r\n";
            }
        }
        this.sharedData.varyingDeclaration += "varying " + type + " " + name + ";\r\n";
        if (define) {
            this.sharedData.varyingDeclaration += "#endif\r\n";
        }
        return true;
    };
    /** @hidden */
    NodeMaterialBuildState.prototype._emitUniformFromString = function (name, type, define, notDefine) {
        if (define === void 0) { define = ""; }
        if (notDefine === void 0) { notDefine = false; }
        if (this.uniforms.indexOf(name) !== -1) {
            return;
        }
        this.uniforms.push(name);
        if (define) {
            this._uniformDeclaration += (notDefine ? "#ifndef" : "#ifdef") + " " + define + "\r\n";
        }
        this._uniformDeclaration += "uniform " + type + " " + name + ";\r\n";
        if (define) {
            this._uniformDeclaration += "#endif\r\n";
        }
    };
    return NodeMaterialBuildState;
}());



/***/ }),

/***/ "./Materials/Node/nodeMaterialBuildStateSharedData.ts":
/*!************************************************************!*\
  !*** ./Materials/Node/nodeMaterialBuildStateSharedData.ts ***!
  \************************************************************/
/*! exports provided: NodeMaterialBuildStateSharedData */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBuildStateSharedData", function() { return NodeMaterialBuildStateSharedData; });
/**
 * Class used to store shared data between 2 NodeMaterialBuildState
 */
var NodeMaterialBuildStateSharedData = /** @class */ (function () {
    /** Creates a new shared data */
    function NodeMaterialBuildStateSharedData() {
        /**
        * Gets the list of emitted varyings
        */
        this.temps = new Array();
        /**
         * Gets the list of emitted varyings
         */
        this.varyings = new Array();
        /**
         * Gets the varying declaration string
         */
        this.varyingDeclaration = "";
        /**
         * Input blocks
         */
        this.inputBlocks = new Array();
        /**
         * Input blocks
         */
        this.textureBlocks = new Array();
        /**
         * Bindable blocks (Blocks that need to set data to the effect)
         */
        this.bindableBlocks = new Array();
        /**
         * List of blocks that can provide a compilation fallback
         */
        this.blocksWithFallbacks = new Array();
        /**
         * List of blocks that can provide a define update
         */
        this.blocksWithDefines = new Array();
        /**
        * List of blocks that can provide a repeatable content
        */
        this.repeatableContentBlocks = new Array();
        /**
        * List of blocks that can provide a dynamic list of uniforms
        */
        this.dynamicUniformBlocks = new Array();
        /**
         * List of blocks that can block the isReady function for the material
         */
        this.blockingBlocks = new Array();
        /**
         * Gets the list of animated inputs
         */
        this.animatedInputs = new Array();
        /** List of emitted variables */
        this.variableNames = {};
        /** List of emitted defines */
        this.defineNames = {};
        /**
         * Gets the compilation hints emitted at compilation time
         */
        this.hints = {
            needWorldViewMatrix: false,
            needWorldViewProjectionMatrix: false,
            needAlphaBlending: false,
            needAlphaTesting: false
        };
        /**
         * List of compilation checks
         */
        this.checks = {
            emitVertex: false,
            emitFragment: false,
            notConnectedNonOptionalInputs: new Array()
        };
        // Exclude usual attributes from free variable names
        this.variableNames["position"] = 0;
        this.variableNames["normal"] = 0;
        this.variableNames["tangent"] = 0;
        this.variableNames["uv"] = 0;
        this.variableNames["uv2"] = 0;
        this.variableNames["uv3"] = 0;
        this.variableNames["uv4"] = 0;
        this.variableNames["uv4"] = 0;
        this.variableNames["uv5"] = 0;
        this.variableNames["uv6"] = 0;
        this.variableNames["color"] = 0;
        this.variableNames["matricesIndices"] = 0;
        this.variableNames["matricesWeights"] = 0;
        this.variableNames["matricesIndicesExtra"] = 0;
        this.variableNames["matricesWeightsExtra"] = 0;
        this.variableNames["diffuseBase"] = 0;
        this.variableNames["specularBase"] = 0;
        this.variableNames["worldPos"] = 0;
        // Exclude known varyings
        this.variableNames["vTBN"] = 0;
        // Exclude defines
        this.defineNames["MAINUV0"] = 0;
        this.defineNames["MAINUV1"] = 0;
        this.defineNames["MAINUV2"] = 0;
        this.defineNames["MAINUV3"] = 0;
        this.defineNames["MAINUV4"] = 0;
        this.defineNames["MAINUV5"] = 0;
        this.defineNames["MAINUV6"] = 0;
        this.defineNames["MAINUV7"] = 0;
    }
    /**
     * Emits console errors and exceptions if there is a failing check
     */
    NodeMaterialBuildStateSharedData.prototype.emitErrors = function () {
        var errorMessage = "";
        if (!this.checks.emitVertex) {
            errorMessage += "NodeMaterial does not have a vertex output. You need to at least add a block that generates a glPosition value.\r\n";
        }
        if (!this.checks.emitFragment) {
            errorMessage += "NodeMaterial does not have a fragment output. You need to at least add a block that generates a glFragColor value.\r\n";
        }
        for (var _i = 0, _a = this.checks.notConnectedNonOptionalInputs; _i < _a.length; _i++) {
            var notConnectedInput = _a[_i];
            errorMessage += "input " + notConnectedInput.name + " from block " + notConnectedInput.ownerBlock.name + "[" + notConnectedInput.ownerBlock.getClassName() + "] is not connected and is not optional.\r\n";
        }
        if (errorMessage) {
            throw "Build of NodeMaterial failed:\r\n" + errorMessage;
        }
    };
    return NodeMaterialBuildStateSharedData;
}());



/***/ }),

/***/ "./Materials/Node/nodeMaterialSystemValues.ts":
/*!****************************************************!*\
  !*** ./Materials/Node/nodeMaterialSystemValues.ts ***!
  \****************************************************/
/*! exports provided: NodeMaterialSystemValues */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialSystemValues", function() { return NodeMaterialSystemValues; });
/**
 * Enum used to define system values e.g. values automatically provided by the system
 */
var NodeMaterialSystemValues;
(function (NodeMaterialSystemValues) {
    /** World */
    NodeMaterialSystemValues[NodeMaterialSystemValues["World"] = 1] = "World";
    /** View */
    NodeMaterialSystemValues[NodeMaterialSystemValues["View"] = 2] = "View";
    /** Projection */
    NodeMaterialSystemValues[NodeMaterialSystemValues["Projection"] = 3] = "Projection";
    /** ViewProjection */
    NodeMaterialSystemValues[NodeMaterialSystemValues["ViewProjection"] = 4] = "ViewProjection";
    /** WorldView */
    NodeMaterialSystemValues[NodeMaterialSystemValues["WorldView"] = 5] = "WorldView";
    /** WorldViewProjection */
    NodeMaterialSystemValues[NodeMaterialSystemValues["WorldViewProjection"] = 6] = "WorldViewProjection";
    /** CameraPosition */
    NodeMaterialSystemValues[NodeMaterialSystemValues["CameraPosition"] = 7] = "CameraPosition";
    /** Fog Color */
    NodeMaterialSystemValues[NodeMaterialSystemValues["FogColor"] = 8] = "FogColor";
})(NodeMaterialSystemValues || (NodeMaterialSystemValues = {}));


/***/ }),

/***/ "./Materials/PBR/index.ts":
/*!********************************!*\
  !*** ./Materials/PBR/index.ts ***!
  \********************************/
/*! exports provided: PBRMaterialDefines, PBRBaseMaterial, PBRBaseSimpleMaterial, PBRMaterial, PBRMetallicRoughnessMaterial, PBRSpecularGlossinessMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pbrBaseMaterial */ "./Materials/PBR/pbrBaseMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterialDefines", function() { return _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_0__["PBRMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseMaterial", function() { return _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_0__["PBRBaseMaterial"]; });

/* harmony import */ var _pbrBaseSimpleMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pbrBaseSimpleMaterial */ "./Materials/PBR/pbrBaseSimpleMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseSimpleMaterial", function() { return _pbrBaseSimpleMaterial__WEBPACK_IMPORTED_MODULE_1__["PBRBaseSimpleMaterial"]; });

/* harmony import */ var _pbrMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./pbrMaterial */ "./Materials/PBR/pbrMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterial", function() { return _pbrMaterial__WEBPACK_IMPORTED_MODULE_2__["PBRMaterial"]; });

/* harmony import */ var _pbrMetallicRoughnessMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pbrMetallicRoughnessMaterial */ "./Materials/PBR/pbrMetallicRoughnessMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMetallicRoughnessMaterial", function() { return _pbrMetallicRoughnessMaterial__WEBPACK_IMPORTED_MODULE_3__["PBRMetallicRoughnessMaterial"]; });

/* harmony import */ var _pbrSpecularGlossinessMaterial__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./pbrSpecularGlossinessMaterial */ "./Materials/PBR/pbrSpecularGlossinessMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRSpecularGlossinessMaterial", function() { return _pbrSpecularGlossinessMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRSpecularGlossinessMaterial"]; });








/***/ }),

/***/ "./Materials/PBR/pbrAnisotropicConfiguration.ts":
/*!******************************************************!*\
  !*** ./Materials/PBR/pbrAnisotropicConfiguration.ts ***!
  \******************************************************/
/*! exports provided: PBRAnisotropicConfiguration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRAnisotropicConfiguration", function() { return PBRAnisotropicConfiguration; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");






/**
 * Define the code related to the anisotropic parameters of the pbr material.
 */
var PBRAnisotropicConfiguration = /** @class */ (function () {
    /**
     * Instantiate a new istance of anisotropy configuration.
     * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
     */
    function PBRAnisotropicConfiguration(markAllSubMeshesAsTexturesDirty) {
        this._isEnabled = false;
        /**
         * Defines if the anisotropy is enabled in the material.
         */
        this.isEnabled = false;
        /**
         * Defines the anisotropy strength (between 0 and 1) it defaults to 1.
         */
        this.intensity = 1;
        /**
         * Defines if the effect is along the tangents, bitangents or in between.
         * By default, the effect is "strectching" the highlights along the tangents.
         */
        this.direction = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](1, 0);
        this._texture = null;
        /**
         * Stores the anisotropy values in a texture.
         * rg is direction (like normal from -1 to 1)
         * b is a intensity
         */
        this.texture = null;
        this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
    }
    /** @hidden */
    PBRAnisotropicConfiguration.prototype._markAllSubMeshesAsTexturesDirty = function () {
        this._internalMarkAllSubMeshesAsTexturesDirty();
    };
    /**
     * Specifies that the submesh is ready to be used.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene the material belongs to.
     * @returns - boolean indicating that the submesh is ready or not.
     */
    PBRAnisotropicConfiguration.prototype.isReadyForSubMesh = function (defines, scene) {
        if (defines._areTexturesDirty) {
            if (scene.texturesEnabled) {
                if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_4__["MaterialFlags"].AnisotropicTextureEnabled) {
                    if (!this._texture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
            }
        }
        return true;
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param defines the list of "defines" to update.
     * @param mesh the mesh we are preparing the defines for.
     * @param scene defines the scene the material belongs to.
     */
    PBRAnisotropicConfiguration.prototype.prepareDefines = function (defines, mesh, scene) {
        if (this._isEnabled) {
            defines.ANISOTROPIC = this._isEnabled;
            if (this._isEnabled && !mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].TangentKind)) {
                defines._needUVs = true;
                defines.MAINUV1 = true;
            }
            if (defines._areTexturesDirty) {
                if (scene.texturesEnabled) {
                    if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_4__["MaterialFlags"].AnisotropicTextureEnabled) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].PrepareDefinesForMergedUV(this._texture, defines, "ANISOTROPIC_TEXTURE");
                    }
                    else {
                        defines.ANISOTROPIC_TEXTURE = false;
                    }
                }
            }
        }
        else {
            defines.ANISOTROPIC = false;
            defines.ANISOTROPIC_TEXTURE = false;
        }
    };
    /**
     * Binds the material data.
     * @param uniformBuffer defines the Uniform buffer to fill in.
     * @param scene defines the scene the material belongs to.
     * @param isFrozen defines wether the material is frozen or not.
     */
    PBRAnisotropicConfiguration.prototype.bindForSubMesh = function (uniformBuffer, scene, isFrozen) {
        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
            if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_4__["MaterialFlags"].AnisotropicTextureEnabled) {
                uniformBuffer.updateFloat2("vAnisotropyInfos", this._texture.coordinatesIndex, this._texture.level);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].BindTextureMatrix(this._texture, uniformBuffer, "anisotropy");
            }
            // Anisotropy
            uniformBuffer.updateFloat3("vAnisotropy", this.direction.x, this.direction.y, this.intensity);
        }
        // Textures
        if (scene.texturesEnabled) {
            if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_4__["MaterialFlags"].AnisotropicTextureEnabled) {
                uniformBuffer.setTexture("anisotropySampler", this._texture);
            }
        }
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param texture - Base texture to use.
     * @returns - Boolean specifying if a texture is used in the material.
     */
    PBRAnisotropicConfiguration.prototype.hasTexture = function (texture) {
        if (this._texture === texture) {
            return true;
        }
        return false;
    };
    /**
     * Returns an array of the actively used textures.
     * @param activeTextures Array of BaseTextures
     */
    PBRAnisotropicConfiguration.prototype.getActiveTextures = function (activeTextures) {
        if (this._texture) {
            activeTextures.push(this._texture);
        }
    };
    /**
     * Returns the animatable textures.
     * @param animatables Array of animatable textures.
     */
    PBRAnisotropicConfiguration.prototype.getAnimatables = function (animatables) {
        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
            animatables.push(this._texture);
        }
    };
    /**
     * Disposes the resources of the material.
     * @param forceDisposeTextures - Forces the disposal of all textures.
     */
    PBRAnisotropicConfiguration.prototype.dispose = function (forceDisposeTextures) {
        if (forceDisposeTextures) {
            if (this._texture) {
                this._texture.dispose();
            }
        }
    };
    /**
    * Get the current class name of the texture useful for serialization or dynamic coding.
    * @returns "PBRAnisotropicConfiguration"
    */
    PBRAnisotropicConfiguration.prototype.getClassName = function () {
        return "PBRAnisotropicConfiguration";
    };
    /**
     * Add fallbacks to the effect fallbacks list.
     * @param defines defines the Base texture to use.
     * @param fallbacks defines the current fallback list.
     * @param currentRank defines the current fallback rank.
     * @returns the new fallback rank.
     */
    PBRAnisotropicConfiguration.AddFallbacks = function (defines, fallbacks, currentRank) {
        if (defines.ANISOTROPIC) {
            fallbacks.addFallback(currentRank++, "ANISOTROPIC");
        }
        return currentRank;
    };
    /**
     * Add the required uniforms to the current list.
     * @param uniforms defines the current uniform list.
     */
    PBRAnisotropicConfiguration.AddUniforms = function (uniforms) {
        uniforms.push("vAnisotropy", "vAnisotropyInfos", "anisotropyMatrix");
    };
    /**
     * Add the required uniforms to the current buffer.
     * @param uniformBuffer defines the current uniform buffer.
     */
    PBRAnisotropicConfiguration.PrepareUniformBuffer = function (uniformBuffer) {
        uniformBuffer.addUniform("vAnisotropy", 3);
        uniformBuffer.addUniform("vAnisotropyInfos", 2);
        uniformBuffer.addUniform("anisotropyMatrix", 16);
    };
    /**
     * Add the required samplers to the current list.
     * @param samplers defines the current sampler list.
     */
    PBRAnisotropicConfiguration.AddSamplers = function (samplers) {
        samplers.push("anisotropySampler");
    };
    /**
     * Makes a duplicate of the current configuration into another one.
     * @param anisotropicConfiguration define the config where to copy the info
     */
    PBRAnisotropicConfiguration.prototype.copyTo = function (anisotropicConfiguration) {
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return anisotropicConfiguration; }, this);
    };
    /**
     * Serializes this anisotropy configuration.
     * @returns - An object with the serialized config.
     */
    PBRAnisotropicConfiguration.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses a anisotropy Configuration from a serialized object.
     * @param source - Serialized object.
     * @param scene Defines the scene we are parsing for
     * @param rootUrl Defines the rootUrl to load from
     */
    PBRAnisotropicConfiguration.prototype.parse = function (source, scene, rootUrl) {
        var _this = this;
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return _this; }, source, scene, rootUrl);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRAnisotropicConfiguration.prototype, "isEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRAnisotropicConfiguration.prototype, "intensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector2"])()
    ], PBRAnisotropicConfiguration.prototype, "direction", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRAnisotropicConfiguration.prototype, "texture", void 0);
    return PBRAnisotropicConfiguration;
}());



/***/ }),

/***/ "./Materials/PBR/pbrBRDFConfiguration.ts":
/*!***********************************************!*\
  !*** ./Materials/PBR/pbrBRDFConfiguration.ts ***!
  \***********************************************/
/*! exports provided: PBRBRDFConfiguration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRBRDFConfiguration", function() { return PBRBRDFConfiguration; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");


/**
 * Define the code related to the BRDF parameters of the pbr material.
 */
var PBRBRDFConfiguration = /** @class */ (function () {
    /**
     * Instantiate a new istance of clear coat configuration.
     * @param markAllSubMeshesAsMiscDirty Callback to flag the material to dirty
     */
    function PBRBRDFConfiguration(markAllSubMeshesAsMiscDirty) {
        this._useEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION;
        /**
         * Defines if the material uses energy conservation.
         */
        this.useEnergyConservation = PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION;
        this._useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED;
        /**
         * LEGACY Mode set to false
         * Defines if the material uses height smith correlated visibility term.
         * If you intent to not use our default BRDF, you need to load a separate BRDF Texture for the PBR
         * You can either load https://assets.babylonjs.com/environments/uncorrelatedBRDF.png
         * or https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds to have more precision
         * Not relying on height correlated will also disable energy conservation.
         */
        this.useSmithVisibilityHeightCorrelated = PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED;
        this._useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS;
        /**
         * LEGACY Mode set to false
         * Defines if the material uses spherical harmonics vs spherical polynomials for the
         * diffuse part of the IBL.
         * The harmonics despite a tiny bigger cost has been proven to provide closer results
         * to the ground truth.
         */
        this.useSphericalHarmonics = PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS;
        this._internalMarkAllSubMeshesAsMiscDirty = markAllSubMeshesAsMiscDirty;
    }
    /** @hidden */
    PBRBRDFConfiguration.prototype._markAllSubMeshesAsMiscDirty = function () {
        this._internalMarkAllSubMeshesAsMiscDirty();
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param defines the list of "defines" to update.
     */
    PBRBRDFConfiguration.prototype.prepareDefines = function (defines) {
        defines.BRDF_V_HEIGHT_CORRELATED = this._useSmithVisibilityHeightCorrelated;
        defines.MS_BRDF_ENERGY_CONSERVATION = this._useEnergyConservation && this._useSmithVisibilityHeightCorrelated;
        defines.SPHERICAL_HARMONICS = this._useSphericalHarmonics;
    };
    /**
    * Get the current class name of the texture useful for serialization or dynamic coding.
    * @returns "PBRClearCoatConfiguration"
    */
    PBRBRDFConfiguration.prototype.getClassName = function () {
        return "PBRBRDFConfiguration";
    };
    /**
     * Makes a duplicate of the current configuration into another one.
     * @param brdfConfiguration define the config where to copy the info
     */
    PBRBRDFConfiguration.prototype.copyTo = function (brdfConfiguration) {
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return brdfConfiguration; }, this);
    };
    /**
     * Serializes this BRDF configuration.
     * @returns - An object with the serialized config.
     */
    PBRBRDFConfiguration.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses a anisotropy Configuration from a serialized object.
     * @param source - Serialized object.
     * @param scene Defines the scene we are parsing for
     * @param rootUrl Defines the rootUrl to load from
     */
    PBRBRDFConfiguration.prototype.parse = function (source, scene, rootUrl) {
        var _this = this;
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return _this; }, source, scene, rootUrl);
    };
    /**
     * Default value used for the energy conservation.
     * This should only be changed to adapt to the type of texture in scene.environmentBRDFTexture.
     */
    PBRBRDFConfiguration.DEFAULT_USE_ENERGY_CONSERVATION = true;
    /**
     * Default value used for the Smith Visibility Height Correlated mode.
     * This should only be changed to adapt to the type of texture in scene.environmentBRDFTexture.
     */
    PBRBRDFConfiguration.DEFAULT_USE_SMITH_VISIBILITY_HEIGHT_CORRELATED = true;
    /**
     * Default value used for the IBL diffuse part.
     * This can help switching back to the polynomials mode globally which is a tiny bit
     * less GPU intensive at the drawback of a lower quality.
     */
    PBRBRDFConfiguration.DEFAULT_USE_SPHERICAL_HARMONICS = true;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsMiscDirty")
    ], PBRBRDFConfiguration.prototype, "useEnergyConservation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsMiscDirty")
    ], PBRBRDFConfiguration.prototype, "useSmithVisibilityHeightCorrelated", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsMiscDirty")
    ], PBRBRDFConfiguration.prototype, "useSphericalHarmonics", void 0);
    return PBRBRDFConfiguration;
}());



/***/ }),

/***/ "./Materials/PBR/pbrBaseMaterial.ts":
/*!******************************************!*\
  !*** ./Materials/PBR/pbrBaseMaterial.ts ***!
  \******************************************/
/*! exports provided: PBRMaterialDefines, PBRBaseMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRMaterialDefines", function() { return PBRMaterialDefines; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRBaseMaterial", function() { return PBRBaseMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Misc_brdfTextureTools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/brdfTextureTools */ "./Misc/brdfTextureTools.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _pbrClearCoatConfiguration__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./pbrClearCoatConfiguration */ "./Materials/PBR/pbrClearCoatConfiguration.ts");
/* harmony import */ var _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./pbrAnisotropicConfiguration */ "./Materials/PBR/pbrAnisotropicConfiguration.ts");
/* harmony import */ var _pbrBRDFConfiguration__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./pbrBRDFConfiguration */ "./Materials/PBR/pbrBRDFConfiguration.ts");
/* harmony import */ var _pbrSheenConfiguration__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./pbrSheenConfiguration */ "./Materials/PBR/pbrSheenConfiguration.ts");
/* harmony import */ var _pbrSubSurfaceConfiguration__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./pbrSubSurfaceConfiguration */ "./Materials/PBR/pbrSubSurfaceConfiguration.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_materialDefines__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../Materials/materialDefines */ "./Materials/materialDefines.ts");
/* harmony import */ var _Materials_pushMaterial__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../Materials/pushMaterial */ "./Materials/pushMaterial.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _materialFlags__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_pbr_fragment__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../../Shaders/pbr.fragment */ "./Shaders/pbr.fragment.ts");
/* harmony import */ var _Shaders_pbr_vertex__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../../Shaders/pbr.vertex */ "./Shaders/pbr.vertex.ts");
























/**
 * Manages the defines for the PBR Material.
 * @hidden
 */
var PBRMaterialDefines = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PBRMaterialDefines, _super);
    /**
     * Initializes the PBR Material defines.
     */
    function PBRMaterialDefines() {
        var _this = _super.call(this) || this;
        _this.PBR = true;
        _this.MAINUV1 = false;
        _this.MAINUV2 = false;
        _this.UV1 = false;
        _this.UV2 = false;
        _this.ALBEDO = false;
        _this.ALBEDODIRECTUV = 0;
        _this.VERTEXCOLOR = false;
        _this.AMBIENT = false;
        _this.AMBIENTDIRECTUV = 0;
        _this.AMBIENTINGRAYSCALE = false;
        _this.OPACITY = false;
        _this.VERTEXALPHA = false;
        _this.OPACITYDIRECTUV = 0;
        _this.OPACITYRGB = false;
        _this.ALPHATEST = false;
        _this.DEPTHPREPASS = false;
        _this.ALPHABLEND = false;
        _this.ALPHAFROMALBEDO = false;
        _this.ALPHATESTVALUE = "0.5";
        _this.SPECULAROVERALPHA = false;
        _this.RADIANCEOVERALPHA = false;
        _this.ALPHAFRESNEL = false;
        _this.LINEARALPHAFRESNEL = false;
        _this.PREMULTIPLYALPHA = false;
        _this.EMISSIVE = false;
        _this.EMISSIVEDIRECTUV = 0;
        _this.REFLECTIVITY = false;
        _this.REFLECTIVITYDIRECTUV = 0;
        _this.SPECULARTERM = false;
        _this.MICROSURFACEFROMREFLECTIVITYMAP = false;
        _this.MICROSURFACEAUTOMATIC = false;
        _this.LODBASEDMICROSFURACE = false;
        _this.MICROSURFACEMAP = false;
        _this.MICROSURFACEMAPDIRECTUV = 0;
        _this.METALLICWORKFLOW = false;
        _this.ROUGHNESSSTOREINMETALMAPALPHA = false;
        _this.ROUGHNESSSTOREINMETALMAPGREEN = false;
        _this.METALLNESSSTOREINMETALMAPBLUE = false;
        _this.AOSTOREINMETALMAPRED = false;
        _this.ENVIRONMENTBRDF = false;
        _this.ENVIRONMENTBRDF_RGBD = false;
        _this.NORMAL = false;
        _this.TANGENT = false;
        _this.BUMP = false;
        _this.BUMPDIRECTUV = 0;
        _this.OBJECTSPACE_NORMALMAP = false;
        _this.PARALLAX = false;
        _this.PARALLAXOCCLUSION = false;
        _this.NORMALXYSCALE = true;
        _this.LIGHTMAP = false;
        _this.LIGHTMAPDIRECTUV = 0;
        _this.USELIGHTMAPASSHADOWMAP = false;
        _this.GAMMALIGHTMAP = false;
        _this.RGBDLIGHTMAP = false;
        _this.REFLECTION = false;
        _this.REFLECTIONMAP_3D = false;
        _this.REFLECTIONMAP_SPHERICAL = false;
        _this.REFLECTIONMAP_PLANAR = false;
        _this.REFLECTIONMAP_CUBIC = false;
        _this.USE_LOCAL_REFLECTIONMAP_CUBIC = false;
        _this.REFLECTIONMAP_PROJECTION = false;
        _this.REFLECTIONMAP_SKYBOX = false;
        _this.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
        _this.REFLECTIONMAP_EXPLICIT = false;
        _this.REFLECTIONMAP_EQUIRECTANGULAR = false;
        _this.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
        _this.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
        _this.INVERTCUBICMAP = false;
        _this.USESPHERICALFROMREFLECTIONMAP = false;
        _this.USEIRRADIANCEMAP = false;
        _this.SPHERICAL_HARMONICS = false;
        _this.USESPHERICALINVERTEX = false;
        _this.REFLECTIONMAP_OPPOSITEZ = false;
        _this.LODINREFLECTIONALPHA = false;
        _this.GAMMAREFLECTION = false;
        _this.RGBDREFLECTION = false;
        _this.LINEARSPECULARREFLECTION = false;
        _this.RADIANCEOCCLUSION = false;
        _this.HORIZONOCCLUSION = false;
        _this.INSTANCES = false;
        _this.NUM_BONE_INFLUENCERS = 0;
        _this.BonesPerMesh = 0;
        _this.BONETEXTURE = false;
        _this.NONUNIFORMSCALING = false;
        _this.MORPHTARGETS = false;
        _this.MORPHTARGETS_NORMAL = false;
        _this.MORPHTARGETS_TANGENT = false;
        _this.MORPHTARGETS_UV = false;
        _this.NUM_MORPH_INFLUENCERS = 0;
        _this.IMAGEPROCESSING = false;
        _this.VIGNETTE = false;
        _this.VIGNETTEBLENDMODEMULTIPLY = false;
        _this.VIGNETTEBLENDMODEOPAQUE = false;
        _this.TONEMAPPING = false;
        _this.TONEMAPPING_ACES = false;
        _this.CONTRAST = false;
        _this.COLORCURVES = false;
        _this.COLORGRADING = false;
        _this.COLORGRADING3D = false;
        _this.SAMPLER3DGREENDEPTH = false;
        _this.SAMPLER3DBGRMAP = false;
        _this.IMAGEPROCESSINGPOSTPROCESS = false;
        _this.EXPOSURE = false;
        _this.MULTIVIEW = false;
        _this.USEPHYSICALLIGHTFALLOFF = false;
        _this.USEGLTFLIGHTFALLOFF = false;
        _this.TWOSIDEDLIGHTING = false;
        _this.SHADOWFLOAT = false;
        _this.CLIPPLANE = false;
        _this.CLIPPLANE2 = false;
        _this.CLIPPLANE3 = false;
        _this.CLIPPLANE4 = false;
        _this.POINTSIZE = false;
        _this.FOG = false;
        _this.LOGARITHMICDEPTH = false;
        _this.FORCENORMALFORWARD = false;
        _this.SPECULARAA = false;
        _this.CLEARCOAT = false;
        _this.CLEARCOAT_DEFAULTIOR = false;
        _this.CLEARCOAT_TEXTURE = false;
        _this.CLEARCOAT_TEXTUREDIRECTUV = 0;
        _this.CLEARCOAT_BUMP = false;
        _this.CLEARCOAT_BUMPDIRECTUV = 0;
        _this.CLEARCOAT_TINT = false;
        _this.CLEARCOAT_TINT_TEXTURE = false;
        _this.CLEARCOAT_TINT_TEXTUREDIRECTUV = 0;
        _this.ANISOTROPIC = false;
        _this.ANISOTROPIC_TEXTURE = false;
        _this.ANISOTROPIC_TEXTUREDIRECTUV = 0;
        _this.BRDF_V_HEIGHT_CORRELATED = false;
        _this.MS_BRDF_ENERGY_CONSERVATION = false;
        _this.SHEEN = false;
        _this.SHEEN_TEXTURE = false;
        _this.SHEEN_TEXTUREDIRECTUV = 0;
        _this.SHEEN_LINKWITHALBEDO = false;
        _this.SUBSURFACE = false;
        _this.SS_REFRACTION = false;
        _this.SS_TRANSLUCENCY = false;
        _this.SS_SCATERRING = false;
        _this.SS_THICKNESSANDMASK_TEXTURE = false;
        _this.SS_THICKNESSANDMASK_TEXTUREDIRECTUV = 0;
        _this.SS_REFRACTIONMAP_3D = false;
        _this.SS_REFRACTIONMAP_OPPOSITEZ = false;
        _this.SS_LODINREFRACTIONALPHA = false;
        _this.SS_GAMMAREFRACTION = false;
        _this.SS_RGBDREFRACTION = false;
        _this.SS_LINEARSPECULARREFRACTION = false;
        _this.SS_LINKREFRACTIONTOTRANSPARENCY = false;
        _this.SS_MASK_FROM_THICKNESS_TEXTURE = false;
        _this.UNLIT = false;
        _this.DEBUGMODE = 0;
        _this.rebuild();
        return _this;
    }
    /**
     * Resets the PBR Material defines.
     */
    PBRMaterialDefines.prototype.reset = function () {
        _super.prototype.reset.call(this);
        this.ALPHATESTVALUE = "0.5";
        this.PBR = true;
    };
    return PBRMaterialDefines;
}(_Materials_materialDefines__WEBPACK_IMPORTED_MODULE_16__["MaterialDefines"]));

/**
 * The Physically based material base class of BJS.
 *
 * This offers the main features of a standard PBR material.
 * For more information, please refer to the documentation :
 * https://doc.babylonjs.com/how_to/physically_based_rendering
 */
var PBRBaseMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PBRBaseMaterial, _super);
    /**
     * Instantiates a new PBRMaterial instance.
     *
     * @param name The material name
     * @param scene The scene the material will be use in.
     */
    function PBRBaseMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        /**
         * Intensity of the direct lights e.g. the four lights available in your scene.
         * This impacts both the direct diffuse and specular highlights.
         */
        _this._directIntensity = 1.0;
        /**
         * Intensity of the emissive part of the material.
         * This helps controlling the emissive effect without modifying the emissive color.
         */
        _this._emissiveIntensity = 1.0;
        /**
         * Intensity of the environment e.g. how much the environment will light the object
         * either through harmonics for rough material or through the refelction for shiny ones.
         */
        _this._environmentIntensity = 1.0;
        /**
         * This is a special control allowing the reduction of the specular highlights coming from the
         * four lights of the scene. Those highlights may not be needed in full environment lighting.
         */
        _this._specularIntensity = 1.0;
        /**
         * This stores the direct, emissive, environment, and specular light intensities into a Vector4.
         */
        _this._lightingInfos = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_6__["Vector4"](_this._directIntensity, _this._emissiveIntensity, _this._environmentIntensity, _this._specularIntensity);
        /**
         * Debug Control allowing disabling the bump map on this material.
         */
        _this._disableBumpMap = false;
        /**
         * AKA Diffuse Texture in standard nomenclature.
         */
        _this._albedoTexture = null;
        /**
         * AKA Occlusion Texture in other nomenclature.
         */
        _this._ambientTexture = null;
        /**
         * AKA Occlusion Texture Intensity in other nomenclature.
         */
        _this._ambientTextureStrength = 1.0;
        /**
         * Defines how much the AO map is occluding the analytical lights (point spot...).
         * 1 means it completely occludes it
         * 0 mean it has no impact
         */
        _this._ambientTextureImpactOnAnalyticalLights = PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS;
        /**
         * Stores the alpha values in a texture.
         */
        _this._opacityTexture = null;
        /**
         * Stores the reflection values in a texture.
         */
        _this._reflectionTexture = null;
        /**
         * Stores the emissive values in a texture.
         */
        _this._emissiveTexture = null;
        /**
         * AKA Specular texture in other nomenclature.
         */
        _this._reflectivityTexture = null;
        /**
         * Used to switch from specular/glossiness to metallic/roughness workflow.
         */
        _this._metallicTexture = null;
        /**
         * Specifies the metallic scalar of the metallic/roughness workflow.
         * Can also be used to scale the metalness values of the metallic texture.
         */
        _this._metallic = null;
        /**
         * Specifies the roughness scalar of the metallic/roughness workflow.
         * Can also be used to scale the roughness values of the metallic texture.
         */
        _this._roughness = null;
        /**
         * Used to enable roughness/glossiness fetch from a separate channel depending on the current mode.
         * Gray Scale represents roughness in metallic mode and glossiness in specular mode.
         */
        _this._microSurfaceTexture = null;
        /**
         * Stores surface normal data used to displace a mesh in a texture.
         */
        _this._bumpTexture = null;
        /**
         * Stores the pre-calculated light information of a mesh in a texture.
         */
        _this._lightmapTexture = null;
        /**
         * The color of a material in ambient lighting.
         */
        _this._ambientColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"](0, 0, 0);
        /**
         * AKA Diffuse Color in other nomenclature.
         */
        _this._albedoColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"](1, 1, 1);
        /**
         * AKA Specular Color in other nomenclature.
         */
        _this._reflectivityColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"](1, 1, 1);
        /**
         * The color applied when light is reflected from a material.
         */
        _this._reflectionColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"](1, 1, 1);
        /**
         * The color applied when light is emitted from a material.
         */
        _this._emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"](0, 0, 0);
        /**
         * AKA Glossiness in other nomenclature.
         */
        _this._microSurface = 0.9;
        /**
         * Specifies that the material will use the light map as a show map.
         */
        _this._useLightmapAsShadowmap = false;
        /**
         * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal
         * makes the reflect vector face the model (under horizon).
         */
        _this._useHorizonOcclusion = true;
        /**
         * This parameters will enable/disable radiance occlusion by preventing the radiance to lit
         * too much the area relying on ambient texture to define their ambient occlusion.
         */
        _this._useRadianceOcclusion = true;
        /**
         * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.
         */
        _this._useAlphaFromAlbedoTexture = false;
        /**
         * Specifies that the material will keeps the specular highlights over a transparent surface (only the most limunous ones).
         * A car glass is a good exemple of that. When sun reflects on it you can not see what is behind.
         */
        _this._useSpecularOverAlpha = true;
        /**
         * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.
         */
        _this._useMicroSurfaceFromReflectivityMapAlpha = false;
        /**
         * Specifies if the metallic texture contains the roughness information in its alpha channel.
         */
        _this._useRoughnessFromMetallicTextureAlpha = true;
        /**
         * Specifies if the metallic texture contains the roughness information in its green channel.
         */
        _this._useRoughnessFromMetallicTextureGreen = false;
        /**
         * Specifies if the metallic texture contains the metallness information in its blue channel.
         */
        _this._useMetallnessFromMetallicTextureBlue = false;
        /**
         * Specifies if the metallic texture contains the ambient occlusion information in its red channel.
         */
        _this._useAmbientOcclusionFromMetallicTextureRed = false;
        /**
         * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.
         */
        _this._useAmbientInGrayScale = false;
        /**
         * In case the reflectivity map does not contain the microsurface information in its alpha channel,
         * The material will try to infer what glossiness each pixel should be.
         */
        _this._useAutoMicroSurfaceFromReflectivityMap = false;
        /**
         * Defines the  falloff type used in this material.
         * It by default is Physical.
         */
        _this._lightFalloff = PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL;
        /**
         * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most limunous ones).
         * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind.
         */
        _this._useRadianceOverAlpha = true;
        /**
         * Allows using an object space normal map (instead of tangent space).
         */
        _this._useObjectSpaceNormalMap = false;
        /**
         * Allows using the bump map in parallax mode.
         */
        _this._useParallax = false;
        /**
         * Allows using the bump map in parallax occlusion mode.
         */
        _this._useParallaxOcclusion = false;
        /**
         * Controls the scale bias of the parallax mode.
         */
        _this._parallaxScaleBias = 0.05;
        /**
         * If sets to true, disables all the lights affecting the material.
         */
        _this._disableLighting = false;
        /**
         * Number of Simultaneous lights allowed on the material.
         */
        _this._maxSimultaneousLights = 4;
        /**
         * If sets to true, x component of normal map value will be inverted (x = 1.0 - x).
         */
        _this._invertNormalMapX = false;
        /**
         * If sets to true, y component of normal map value will be inverted (y = 1.0 - y).
         */
        _this._invertNormalMapY = false;
        /**
         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
         */
        _this._twoSidedLighting = false;
        /**
         * Defines the alpha limits in alpha test mode.
         */
        _this._alphaCutOff = 0.4;
        /**
         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
         */
        _this._forceAlphaTest = false;
        /**
         * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
         * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)
         */
        _this._useAlphaFresnel = false;
        /**
         * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
         * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)
         */
        _this._useLinearAlphaFresnel = false;
        /**
         * The transparency mode of the material.
         */
        _this._transparencyMode = null;
        /**
         * Specifies the environment BRDF texture used to comput the scale and offset roughness values
         * from cos thetav and roughness:
         * http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
         */
        _this._environmentBRDFTexture = null;
        /**
         * Force the shader to compute irradiance in the fragment shader in order to take bump in account.
         */
        _this._forceIrradianceInFragment = false;
        /**
         * Force normal to face away from face.
         */
        _this._forceNormalForward = false;
        /**
         * Enables specular anti aliasing in the PBR shader.
         * It will both interacts on the Geometry for analytical and IBL lighting.
         * It also prefilter the roughness map based on the bump values.
         */
        _this._enableSpecularAntiAliasing = false;
        /**
         * Keep track of the image processing observer to allow dispose and replace.
         */
        _this._imageProcessingObserver = null;
        /**
         * Stores the available render targets.
         */
        _this._renderTargets = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_3__["SmartArray"](16);
        /**
         * Sets the global ambient color for the material used in lighting calculations.
         */
        _this._globalAmbientColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"](0, 0, 0);
        /**
         * Enables the use of logarithmic depth buffers, which is good for wide depth buffers.
         */
        _this._useLogarithmicDepth = false;
        /**
         * If set to true, no lighting calculations will be applied.
         */
        _this._unlit = false;
        _this._debugMode = 0;
        /**
         * @hidden
         * This is reserved for the inspector.
         * Defines the material debug mode.
         * It helps seeing only some components of the material while troubleshooting.
         */
        _this.debugMode = 0;
        /**
         * @hidden
         * This is reserved for the inspector.
         * Specify from where on screen the debug mode should start.
         * The value goes from -1 (full screen) to 1 (not visible)
         * It helps with side by side comparison against the final render
         * This defaults to -1
         */
        _this.debugLimit = -1;
        /**
         * @hidden
         * This is reserved for the inspector.
         * As the default viewing range might not be enough (if the ambient is really small for instance)
         * You can use the factor to better multiply the final value.
         */
        _this.debugFactor = 1;
        /**
         * Defines the clear coat layer parameters for the material.
         */
        _this.clearCoat = new _pbrClearCoatConfiguration__WEBPACK_IMPORTED_MODULE_8__["PBRClearCoatConfiguration"](_this._markAllSubMeshesAsTexturesDirty.bind(_this));
        /**
         * Defines the anisotropic parameters for the material.
         */
        _this.anisotropy = new _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__["PBRAnisotropicConfiguration"](_this._markAllSubMeshesAsTexturesDirty.bind(_this));
        /**
         * Defines the BRDF parameters for the material.
         */
        _this.brdf = new _pbrBRDFConfiguration__WEBPACK_IMPORTED_MODULE_10__["PBRBRDFConfiguration"](_this._markAllSubMeshesAsMiscDirty.bind(_this));
        /**
         * Defines the Sheen parameters for the material.
         */
        _this.sheen = new _pbrSheenConfiguration__WEBPACK_IMPORTED_MODULE_11__["PBRSheenConfiguration"](_this._markAllSubMeshesAsTexturesDirty.bind(_this));
        /**
         * Defines the SubSurface parameters for the material.
         */
        _this.subSurface = new _pbrSubSurfaceConfiguration__WEBPACK_IMPORTED_MODULE_12__["PBRSubSurfaceConfiguration"](_this._markAllSubMeshesAsTexturesDirty.bind(_this));
        _this._rebuildInParallel = false;
        // Setup the default processing configuration to the scene.
        _this._attachImageProcessingConfiguration(null);
        _this.getRenderTargetTextures = function () {
            _this._renderTargets.reset();
            if (_materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled && _this._reflectionTexture && _this._reflectionTexture.isRenderTarget) {
                _this._renderTargets.push(_this._reflectionTexture);
            }
            _this.subSurface.fillRenderTargetTextures(_this._renderTargets);
            return _this._renderTargets;
        };
        _this._environmentBRDFTexture = _Misc_brdfTextureTools__WEBPACK_IMPORTED_MODULE_4__["BRDFTextureTools"].GetEnvironmentBRDFTexture(scene);
        return _this;
    }
    /**
     * Attaches a new image processing configuration to the PBR Material.
     * @param configuration
     */
    PBRBaseMaterial.prototype._attachImageProcessingConfiguration = function (configuration) {
        var _this = this;
        if (configuration === this._imageProcessingConfiguration) {
            return;
        }
        // Detaches observer.
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        // Pick the scene configuration if needed.
        if (!configuration) {
            this._imageProcessingConfiguration = this.getScene().imageProcessingConfiguration;
        }
        else {
            this._imageProcessingConfiguration = configuration;
        }
        // Attaches observer.
        if (this._imageProcessingConfiguration) {
            this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(function () {
                _this._markAllSubMeshesAsImageProcessingDirty();
            });
        }
    };
    Object.defineProperty(PBRBaseMaterial.prototype, "hasRenderTargetTextures", {
        /**
         * Gets a boolean indicating that current material needs to register RTT
         */
        get: function () {
            if (_materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                return true;
            }
            return this.subSurface.hasRenderTargetTextures();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the name of the material class.
     */
    PBRBaseMaterial.prototype.getClassName = function () {
        return "PBRBaseMaterial";
    };
    Object.defineProperty(PBRBaseMaterial.prototype, "useLogarithmicDepth", {
        /**
         * Enabled the use of logarithmic depth buffers, which is good for wide depth buffers.
         */
        get: function () {
            return this._useLogarithmicDepth;
        },
        /**
         * Enabled the use of logarithmic depth buffers, which is good for wide depth buffers.
         */
        set: function (value) {
            this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRBaseMaterial.prototype, "transparencyMode", {
        /**
         * Gets the current transparency mode.
         */
        get: function () {
            return this._transparencyMode;
        },
        /**
         * Sets the transparency mode of the material.
         *
         * | Value | Type                                | Description |
         * | ----- | ----------------------------------- | ----------- |
         * | 0     | OPAQUE                              |             |
         * | 1     | ALPHATEST                           |             |
         * | 2     | ALPHABLEND                          |             |
         * | 3     | ALPHATESTANDBLEND                   |             |
         *
         */
        set: function (value) {
            if (this._transparencyMode === value) {
                return;
            }
            this._transparencyMode = value;
            this._forceAlphaTest = (value === PBRBaseMaterial.PBRMATERIAL_ALPHATESTANDBLEND);
            this._markAllSubMeshesAsTexturesAndMiscDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRBaseMaterial.prototype, "_disableAlphaBlending", {
        /**
         * Returns true if alpha blending should be disabled.
         */
        get: function () {
            return (this.subSurface.disableAlphaBlending ||
                this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_OPAQUE ||
                this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Specifies whether or not this material should be rendered in alpha blend mode.
     */
    PBRBaseMaterial.prototype.needAlphaBlending = function () {
        if (this._disableAlphaBlending) {
            return false;
        }
        return (this.alpha < 1.0) || (this._opacityTexture != null) || this._shouldUseAlphaFromAlbedoTexture();
    };
    /**
     * Specifies if the mesh will require alpha blending.
     * @param mesh - BJS mesh.
     */
    PBRBaseMaterial.prototype.needAlphaBlendingForMesh = function (mesh) {
        if (this._disableAlphaBlending && mesh.visibility >= 1.0) {
            return false;
        }
        return _super.prototype.needAlphaBlendingForMesh.call(this, mesh);
    };
    /**
     * Specifies whether or not this material should be rendered in alpha test mode.
     */
    PBRBaseMaterial.prototype.needAlphaTesting = function () {
        if (this._forceAlphaTest) {
            return true;
        }
        if (this.subSurface.disableAlphaBlending) {
            return false;
        }
        return this._albedoTexture != null && this._albedoTexture.hasAlpha && (this._transparencyMode == null || this._transparencyMode === PBRBaseMaterial.PBRMATERIAL_ALPHATEST);
    };
    /**
     * Specifies whether or not the alpha value of the albedo texture should be used for alpha blending.
     */
    PBRBaseMaterial.prototype._shouldUseAlphaFromAlbedoTexture = function () {
        return this._albedoTexture != null && this._albedoTexture.hasAlpha && this._useAlphaFromAlbedoTexture && this._transparencyMode !== PBRBaseMaterial.PBRMATERIAL_OPAQUE;
    };
    /**
     * Gets the texture used for the alpha test.
     */
    PBRBaseMaterial.prototype.getAlphaTestTexture = function () {
        return this._albedoTexture;
    };
    /**
     * Specifies that the submesh is ready to be used.
     * @param mesh - BJS mesh.
     * @param subMesh - A submesh of the BJS mesh.  Used to check if it is ready.
     * @param useInstances - Specifies that instances should be used.
     * @returns - boolean indicating that the submesh is ready or not.
     */
    PBRBaseMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        if (subMesh.effect && this.isFrozen) {
            if (this._wasPreviouslyReady) {
                return true;
            }
        }
        if (!subMesh._materialDefines) {
            subMesh._materialDefines = new PBRMaterialDefines();
        }
        var defines = subMesh._materialDefines;
        if (!this.checkReadyOnEveryCall && subMesh.effect) {
            if (defines._renderId === this.getScene().getRenderId()) {
                return true;
            }
        }
        var scene = this.getScene();
        var engine = scene.getEngine();
        if (defines._areTexturesDirty) {
            if (scene.texturesEnabled) {
                if (this._albedoTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].DiffuseTextureEnabled) {
                    if (!this._albedoTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                if (this._ambientTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].AmbientTextureEnabled) {
                    if (!this._ambientTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                if (this._opacityTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].OpacityTextureEnabled) {
                    if (!this._opacityTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                var reflectionTexture = this._getReflectionTexture();
                if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled) {
                    if (!reflectionTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    if (reflectionTexture.irradianceTexture && !reflectionTexture.irradianceTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                if (this._lightmapTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].LightmapTextureEnabled) {
                    if (!this._lightmapTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                if (this._emissiveTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].EmissiveTextureEnabled) {
                    if (!this._emissiveTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                if (_materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].SpecularTextureEnabled) {
                    if (this._metallicTexture) {
                        if (!this._metallicTexture.isReadyOrNotBlocking()) {
                            return false;
                        }
                    }
                    else if (this._reflectivityTexture) {
                        if (!this._reflectivityTexture.isReadyOrNotBlocking()) {
                            return false;
                        }
                    }
                    if (this._microSurfaceTexture) {
                        if (!this._microSurfaceTexture.isReadyOrNotBlocking()) {
                            return false;
                        }
                    }
                }
                if (engine.getCaps().standardDerivatives && this._bumpTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].BumpTextureEnabled && !this._disableBumpMap) {
                    // Bump texture cannot be not blocking.
                    if (!this._bumpTexture.isReady()) {
                        return false;
                    }
                }
                if (this._environmentBRDFTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled) {
                    // This is blocking.
                    if (!this._environmentBRDFTexture.isReady()) {
                        return false;
                    }
                }
            }
        }
        if (!this.subSurface.isReadyForSubMesh(defines, scene) ||
            !this.clearCoat.isReadyForSubMesh(defines, scene, engine, this._disableBumpMap) ||
            !this.sheen.isReadyForSubMesh(defines, scene) ||
            !this.anisotropy.isReadyForSubMesh(defines, scene)) {
            return false;
        }
        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
            if (!this._imageProcessingConfiguration.isReady()) {
                return false;
            }
        }
        if (!engine.getCaps().standardDerivatives && !mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].NormalKind)) {
            mesh.createNormals(true);
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("PBRMaterial: Normals have been created for the mesh: " + mesh.name);
        }
        var previousEffect = subMesh.effect;
        var lightDisposed = defines._areLightsDisposed;
        var effect = this._prepareEffect(mesh, defines, this.onCompiled, this.onError, useInstances);
        if (effect) {
            // Use previous effect while new one is compiling
            if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {
                effect = previousEffect;
                this._rebuildInParallel = true;
                defines.markAsUnprocessed();
                if (lightDisposed) {
                    // re register in case it takes more than one frame.
                    defines._areLightsDisposed = true;
                    return false;
                }
            }
            else {
                this._rebuildInParallel = false;
                scene.resetCachedMaterial();
                subMesh.setEffect(effect, defines);
                this.buildUniformLayout();
            }
        }
        if (!subMesh.effect || !subMesh.effect.isReady()) {
            return false;
        }
        defines._renderId = scene.getRenderId();
        this._wasPreviouslyReady = true;
        return true;
    };
    /**
     * Specifies if the material uses metallic roughness workflow.
     * @returns boolean specifiying if the material uses metallic roughness workflow.
    */
    PBRBaseMaterial.prototype.isMetallicWorkflow = function () {
        if (this._metallic != null || this._roughness != null || this._metallicTexture) {
            return true;
        }
        return false;
    };
    PBRBaseMaterial.prototype._prepareEffect = function (mesh, defines, onCompiled, onError, useInstances, useClipPlane) {
        if (onCompiled === void 0) { onCompiled = null; }
        if (onError === void 0) { onError = null; }
        if (useInstances === void 0) { useInstances = null; }
        if (useClipPlane === void 0) { useClipPlane = null; }
        this._prepareDefines(mesh, defines, useInstances, useClipPlane);
        if (!defines.isDirty) {
            return null;
        }
        defines.markAsProcessed();
        var scene = this.getScene();
        var engine = scene.getEngine();
        // Fallbacks
        var fallbacks = new _Materials_effect__WEBPACK_IMPORTED_MODULE_15__["EffectFallbacks"]();
        var fallbackRank = 0;
        if (defines.USESPHERICALINVERTEX) {
            fallbacks.addFallback(fallbackRank++, "USESPHERICALINVERTEX");
        }
        if (defines.FOG) {
            fallbacks.addFallback(fallbackRank, "FOG");
        }
        if (defines.SPECULARAA) {
            fallbacks.addFallback(fallbackRank, "SPECULARAA");
        }
        if (defines.POINTSIZE) {
            fallbacks.addFallback(fallbackRank, "POINTSIZE");
        }
        if (defines.LOGARITHMICDEPTH) {
            fallbacks.addFallback(fallbackRank, "LOGARITHMICDEPTH");
        }
        if (defines.PARALLAX) {
            fallbacks.addFallback(fallbackRank, "PARALLAX");
        }
        if (defines.PARALLAXOCCLUSION) {
            fallbacks.addFallback(fallbackRank++, "PARALLAXOCCLUSION");
        }
        fallbackRank = _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__["PBRAnisotropicConfiguration"].AddFallbacks(defines, fallbacks, fallbackRank);
        fallbackRank = _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__["PBRAnisotropicConfiguration"].AddFallbacks(defines, fallbacks, fallbackRank);
        fallbackRank = _pbrSubSurfaceConfiguration__WEBPACK_IMPORTED_MODULE_12__["PBRSubSurfaceConfiguration"].AddFallbacks(defines, fallbacks, fallbackRank);
        fallbackRank = _pbrSheenConfiguration__WEBPACK_IMPORTED_MODULE_11__["PBRSheenConfiguration"].AddFallbacks(defines, fallbacks, fallbackRank);
        if (defines.ENVIRONMENTBRDF) {
            fallbacks.addFallback(fallbackRank++, "ENVIRONMENTBRDF");
        }
        if (defines.TANGENT) {
            fallbacks.addFallback(fallbackRank++, "TANGENT");
        }
        if (defines.BUMP) {
            fallbacks.addFallback(fallbackRank++, "BUMP");
        }
        fallbackRank = _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights, fallbackRank++);
        if (defines.SPECULARTERM) {
            fallbacks.addFallback(fallbackRank++, "SPECULARTERM");
        }
        if (defines.USESPHERICALFROMREFLECTIONMAP) {
            fallbacks.addFallback(fallbackRank++, "USESPHERICALFROMREFLECTIONMAP");
        }
        if (defines.USEIRRADIANCEMAP) {
            fallbacks.addFallback(fallbackRank++, "USEIRRADIANCEMAP");
        }
        if (defines.LIGHTMAP) {
            fallbacks.addFallback(fallbackRank++, "LIGHTMAP");
        }
        if (defines.NORMAL) {
            fallbacks.addFallback(fallbackRank++, "NORMAL");
        }
        if (defines.AMBIENT) {
            fallbacks.addFallback(fallbackRank++, "AMBIENT");
        }
        if (defines.EMISSIVE) {
            fallbacks.addFallback(fallbackRank++, "EMISSIVE");
        }
        if (defines.VERTEXCOLOR) {
            fallbacks.addFallback(fallbackRank++, "VERTEXCOLOR");
        }
        if (defines.MORPHTARGETS) {
            fallbacks.addFallback(fallbackRank++, "MORPHTARGETS");
        }
        if (defines.MULTIVIEW) {
            fallbacks.addFallback(0, "MULTIVIEW");
        }
        //Attributes
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].PositionKind];
        if (defines.NORMAL) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].NormalKind);
        }
        if (defines.TANGENT) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].TangentKind);
        }
        if (defines.UV1) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UVKind);
        }
        if (defines.UV2) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].UV2Kind);
        }
        if (defines.VERTEXCOLOR) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].ColorKind);
        }
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareAttributesForInstances(attribs, defines);
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareAttributesForMorphTargets(attribs, mesh, defines);
        var shaderName = "pbr";
        var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vAlbedoColor", "vReflectivityColor", "vEmissiveColor", "visibility", "vReflectionColor",
            "vFogInfos", "vFogColor", "pointSize",
            "vAlbedoInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vReflectionPosition", "vReflectionSize", "vEmissiveInfos", "vReflectivityInfos",
            "vMicroSurfaceSamplerInfos", "vBumpInfos", "vLightmapInfos",
            "mBones",
            "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "albedoMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "reflectivityMatrix", "normalMatrix", "microSurfaceSamplerMatrix", "bumpMatrix", "lightmapMatrix",
            "vLightingIntensity",
            "logarithmicDepthConstant",
            "vSphericalX", "vSphericalY", "vSphericalZ",
            "vSphericalXX_ZZ", "vSphericalYY_ZZ", "vSphericalZZ",
            "vSphericalXY", "vSphericalYZ", "vSphericalZX",
            "vSphericalL00",
            "vSphericalL1_1", "vSphericalL10", "vSphericalL11",
            "vSphericalL2_2", "vSphericalL2_1", "vSphericalL20", "vSphericalL21", "vSphericalL22",
            "vReflectionMicrosurfaceInfos",
            "vTangentSpaceParams", "boneTextureWidth",
            "vDebugMode"
        ];
        var samplers = ["albedoSampler", "reflectivitySampler", "ambientSampler", "emissiveSampler",
            "bumpSampler", "lightmapSampler", "opacitySampler",
            "reflectionSampler", "reflectionSamplerLow", "reflectionSamplerHigh", "irradianceSampler",
            "microSurfaceSampler", "environmentBrdfSampler", "boneSampler"];
        var uniformBuffers = ["Material", "Scene", "Mesh"];
        _pbrSubSurfaceConfiguration__WEBPACK_IMPORTED_MODULE_12__["PBRSubSurfaceConfiguration"].AddUniforms(uniforms);
        _pbrSubSurfaceConfiguration__WEBPACK_IMPORTED_MODULE_12__["PBRSubSurfaceConfiguration"].AddSamplers(samplers);
        _pbrClearCoatConfiguration__WEBPACK_IMPORTED_MODULE_8__["PBRClearCoatConfiguration"].AddUniforms(uniforms);
        _pbrClearCoatConfiguration__WEBPACK_IMPORTED_MODULE_8__["PBRClearCoatConfiguration"].AddSamplers(samplers);
        _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__["PBRAnisotropicConfiguration"].AddUniforms(uniforms);
        _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__["PBRAnisotropicConfiguration"].AddSamplers(samplers);
        _pbrSheenConfiguration__WEBPACK_IMPORTED_MODULE_11__["PBRSheenConfiguration"].AddUniforms(uniforms);
        _pbrSheenConfiguration__WEBPACK_IMPORTED_MODULE_11__["PBRSheenConfiguration"].AddSamplers(samplers);
        if (_Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_14__["ImageProcessingConfiguration"]) {
            _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_14__["ImageProcessingConfiguration"].PrepareUniforms(uniforms, defines);
            _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_14__["ImageProcessingConfiguration"].PrepareSamplers(samplers, defines);
        }
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareUniformsAndSamplersList({
            uniformsNames: uniforms,
            uniformBuffersNames: uniformBuffers,
            samplers: samplers,
            defines: defines,
            maxSimultaneousLights: this._maxSimultaneousLights
        });
        if (this.customShaderNameResolve) {
            shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines);
        }
        var join = defines.toString();
        return engine.createEffect(shaderName, {
            attributes: attribs,
            uniformsNames: uniforms,
            uniformBuffersNames: uniformBuffers,
            samplers: samplers,
            defines: join,
            fallbacks: fallbacks,
            onCompiled: onCompiled,
            onError: onError,
            indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS }
        }, engine);
    };
    PBRBaseMaterial.prototype._prepareDefines = function (mesh, defines, useInstances, useClipPlane) {
        if (useInstances === void 0) { useInstances = null; }
        if (useClipPlane === void 0) { useClipPlane = null; }
        var scene = this.getScene();
        var engine = scene.getEngine();
        // Lights
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
        defines._needNormals = true;
        // Multiview
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMultiview(scene, defines);
        // Textures
        defines.METALLICWORKFLOW = this.isMetallicWorkflow();
        if (defines._areTexturesDirty) {
            defines._needUVs = false;
            if (scene.texturesEnabled) {
                if (scene.getEngine().getCaps().textureLOD) {
                    defines.LODBASEDMICROSFURACE = true;
                }
                if (this._albedoTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].DiffuseTextureEnabled) {
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._albedoTexture, defines, "ALBEDO");
                }
                else {
                    defines.ALBEDO = false;
                }
                if (this._ambientTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].AmbientTextureEnabled) {
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._ambientTexture, defines, "AMBIENT");
                    defines.AMBIENTINGRAYSCALE = this._useAmbientInGrayScale;
                }
                else {
                    defines.AMBIENT = false;
                }
                if (this._opacityTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].OpacityTextureEnabled) {
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._opacityTexture, defines, "OPACITY");
                    defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;
                }
                else {
                    defines.OPACITY = false;
                }
                var reflectionTexture = this._getReflectionTexture();
                if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled) {
                    defines.REFLECTION = true;
                    defines.GAMMAREFLECTION = reflectionTexture.gammaSpace;
                    defines.RGBDREFLECTION = reflectionTexture.isRGBD;
                    defines.REFLECTIONMAP_OPPOSITEZ = this.getScene().useRightHandedSystem ? !reflectionTexture.invertZ : reflectionTexture.invertZ;
                    defines.LODINREFLECTIONALPHA = reflectionTexture.lodLevelInAlpha;
                    defines.LINEARSPECULARREFLECTION = reflectionTexture.linearSpecularLOD;
                    if (reflectionTexture.coordinatesMode === _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].INVCUBIC_MODE) {
                        defines.INVERTCUBICMAP = true;
                    }
                    defines.REFLECTIONMAP_3D = reflectionTexture.isCube;
                    defines.REFLECTIONMAP_CUBIC = false;
                    defines.REFLECTIONMAP_EXPLICIT = false;
                    defines.REFLECTIONMAP_PLANAR = false;
                    defines.REFLECTIONMAP_PROJECTION = false;
                    defines.REFLECTIONMAP_SKYBOX = false;
                    defines.REFLECTIONMAP_SPHERICAL = false;
                    defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
                    defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
                    defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
                    defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
                    switch (reflectionTexture.coordinatesMode) {
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].EXPLICIT_MODE:
                            defines.REFLECTIONMAP_EXPLICIT = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].PLANAR_MODE:
                            defines.REFLECTIONMAP_PLANAR = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].PROJECTION_MODE:
                            defines.REFLECTIONMAP_PROJECTION = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].SKYBOX_MODE:
                            defines.REFLECTIONMAP_SKYBOX = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].SPHERICAL_MODE:
                            defines.REFLECTIONMAP_SPHERICAL = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].EQUIRECTANGULAR_MODE:
                            defines.REFLECTIONMAP_EQUIRECTANGULAR = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].FIXED_EQUIRECTANGULAR_MODE:
                            defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
                            defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = true;
                            break;
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].CUBIC_MODE:
                        case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].INVCUBIC_MODE:
                        default:
                            defines.REFLECTIONMAP_CUBIC = true;
                            defines.USE_LOCAL_REFLECTIONMAP_CUBIC = reflectionTexture.boundingBoxSize ? true : false;
                            break;
                    }
                    if (reflectionTexture.coordinatesMode !== _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_19__["Texture"].SKYBOX_MODE) {
                        if (reflectionTexture.irradianceTexture) {
                            defines.USEIRRADIANCEMAP = true;
                            defines.USESPHERICALFROMREFLECTIONMAP = false;
                        }
                        else if (reflectionTexture.sphericalPolynomial) {
                            defines.USESPHERICALFROMREFLECTIONMAP = true;
                            defines.USEIRRADIANCEMAP = false;
                            if (this._forceIrradianceInFragment || scene.getEngine().getCaps().maxVaryingVectors <= 8) {
                                defines.USESPHERICALINVERTEX = false;
                            }
                            else {
                                defines.USESPHERICALINVERTEX = true;
                            }
                        }
                    }
                    else {
                        defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = !reflectionTexture.getReflectionTextureMatrix().isIdentity();
                    }
                }
                else {
                    defines.REFLECTION = false;
                    defines.REFLECTIONMAP_3D = false;
                    defines.REFLECTIONMAP_SPHERICAL = false;
                    defines.REFLECTIONMAP_PLANAR = false;
                    defines.REFLECTIONMAP_CUBIC = false;
                    defines.USE_LOCAL_REFLECTIONMAP_CUBIC = false;
                    defines.REFLECTIONMAP_PROJECTION = false;
                    defines.REFLECTIONMAP_SKYBOX = false;
                    defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
                    defines.REFLECTIONMAP_EXPLICIT = false;
                    defines.REFLECTIONMAP_EQUIRECTANGULAR = false;
                    defines.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
                    defines.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
                    defines.INVERTCUBICMAP = false;
                    defines.USESPHERICALFROMREFLECTIONMAP = false;
                    defines.USEIRRADIANCEMAP = false;
                    defines.USESPHERICALINVERTEX = false;
                    defines.REFLECTIONMAP_OPPOSITEZ = false;
                    defines.LODINREFLECTIONALPHA = false;
                    defines.GAMMAREFLECTION = false;
                    defines.RGBDREFLECTION = false;
                    defines.LINEARSPECULARREFLECTION = false;
                }
                if (this._lightmapTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].LightmapTextureEnabled) {
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._lightmapTexture, defines, "LIGHTMAP");
                    defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;
                    defines.GAMMALIGHTMAP = this._lightmapTexture.gammaSpace;
                    defines.RGBDLIGHTMAP = this._lightmapTexture.isRGBD;
                }
                else {
                    defines.LIGHTMAP = false;
                }
                if (this._emissiveTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].EmissiveTextureEnabled) {
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._emissiveTexture, defines, "EMISSIVE");
                }
                else {
                    defines.EMISSIVE = false;
                }
                if (_materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].SpecularTextureEnabled) {
                    if (this._metallicTexture) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._metallicTexture, defines, "REFLECTIVITY");
                        defines.ROUGHNESSSTOREINMETALMAPALPHA = this._useRoughnessFromMetallicTextureAlpha;
                        defines.ROUGHNESSSTOREINMETALMAPGREEN = !this._useRoughnessFromMetallicTextureAlpha && this._useRoughnessFromMetallicTextureGreen;
                        defines.METALLNESSSTOREINMETALMAPBLUE = this._useMetallnessFromMetallicTextureBlue;
                        defines.AOSTOREINMETALMAPRED = this._useAmbientOcclusionFromMetallicTextureRed;
                    }
                    else if (this._reflectivityTexture) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._reflectivityTexture, defines, "REFLECTIVITY");
                        defines.MICROSURFACEFROMREFLECTIVITYMAP = this._useMicroSurfaceFromReflectivityMapAlpha;
                        defines.MICROSURFACEAUTOMATIC = this._useAutoMicroSurfaceFromReflectivityMap;
                    }
                    else {
                        defines.REFLECTIVITY = false;
                    }
                    if (this._microSurfaceTexture) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._microSurfaceTexture, defines, "MICROSURFACEMAP");
                    }
                    else {
                        defines.MICROSURFACEMAP = false;
                    }
                }
                else {
                    defines.REFLECTIVITY = false;
                    defines.MICROSURFACEMAP = false;
                }
                if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].BumpTextureEnabled && !this._disableBumpMap) {
                    _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMergedUV(this._bumpTexture, defines, "BUMP");
                    if (this._useParallax && this._albedoTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].DiffuseTextureEnabled) {
                        defines.PARALLAX = true;
                        defines.PARALLAXOCCLUSION = !!this._useParallaxOcclusion;
                    }
                    else {
                        defines.PARALLAX = false;
                    }
                    defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;
                }
                else {
                    defines.BUMP = false;
                }
                if (this._environmentBRDFTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled) {
                    defines.ENVIRONMENTBRDF = true;
                    defines.ENVIRONMENTBRDF_RGBD = this._environmentBRDFTexture.isRGBD;
                }
                else {
                    defines.ENVIRONMENTBRDF = false;
                    defines.ENVIRONMENTBRDF_RGBD = false;
                }
                if (this._shouldUseAlphaFromAlbedoTexture()) {
                    defines.ALPHAFROMALBEDO = true;
                }
                else {
                    defines.ALPHAFROMALBEDO = false;
                }
            }
            defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
            if (this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_STANDARD) {
                defines.USEPHYSICALLIGHTFALLOFF = false;
                defines.USEGLTFLIGHTFALLOFF = false;
            }
            else if (this._lightFalloff === PBRBaseMaterial.LIGHTFALLOFF_GLTF) {
                defines.USEPHYSICALLIGHTFALLOFF = false;
                defines.USEGLTFLIGHTFALLOFF = true;
            }
            else {
                defines.USEPHYSICALLIGHTFALLOFF = true;
                defines.USEGLTFLIGHTFALLOFF = false;
            }
            defines.RADIANCEOVERALPHA = this._useRadianceOverAlpha;
            if (!this.backFaceCulling && this._twoSidedLighting) {
                defines.TWOSIDEDLIGHTING = true;
            }
            else {
                defines.TWOSIDEDLIGHTING = false;
            }
            defines.SPECULARAA = scene.getEngine().getCaps().standardDerivatives && this._enableSpecularAntiAliasing;
        }
        if (defines._areTexturesDirty || defines._areMiscDirty) {
            defines.ALPHATESTVALUE = "" + this._alphaCutOff + (this._alphaCutOff % 1 === 0 ? "." : "");
            defines.PREMULTIPLYALPHA = (this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_21__["Constants"].ALPHA_PREMULTIPLIED || this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_21__["Constants"].ALPHA_PREMULTIPLIED_PORTERDUFF);
            defines.ALPHABLEND = this.needAlphaBlendingForMesh(mesh);
            defines.ALPHAFRESNEL = this._useAlphaFresnel || this._useLinearAlphaFresnel;
            defines.LINEARALPHAFRESNEL = this._useLinearAlphaFresnel;
        }
        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
            this._imageProcessingConfiguration.prepareDefines(defines);
        }
        defines.FORCENORMALFORWARD = this._forceNormalForward;
        defines.RADIANCEOCCLUSION = this._useRadianceOcclusion;
        defines.HORIZONOCCLUSION = this._useHorizonOcclusion;
        // Misc.
        if (defines._areMiscDirty) {
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest, defines);
            defines.UNLIT = this._unlit || ((this.pointsCloud || this.wireframe) && !mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_7__["VertexBuffer"].NormalKind));
            defines.DEBUGMODE = this._debugMode;
        }
        // External config
        this.subSurface.prepareDefines(defines, scene);
        this.clearCoat.prepareDefines(defines, scene);
        this.anisotropy.prepareDefines(defines, mesh, scene);
        this.brdf.prepareDefines(defines);
        this.sheen.prepareDefines(defines, scene);
        // Values that need to be evaluated on every frame
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, useClipPlane);
        // Attribs
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].PrepareDefinesForAttributes(mesh, defines, true, true, true, this._transparencyMode !== PBRBaseMaterial.PBRMATERIAL_OPAQUE);
    };
    /**
     * Force shader compilation
     */
    PBRBaseMaterial.prototype.forceCompilation = function (mesh, onCompiled, options) {
        var _this = this;
        var localOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ clipPlane: false }, options);
        var defines = new PBRMaterialDefines();
        var effect = this._prepareEffect(mesh, defines, undefined, undefined, undefined, localOptions.clipPlane);
        if (effect.isReady()) {
            if (onCompiled) {
                onCompiled(this);
            }
        }
        else {
            effect.onCompileObservable.add(function () {
                if (onCompiled) {
                    onCompiled(_this);
                }
            });
        }
    };
    /**
     * Initializes the uniform buffer layout for the shader.
     */
    PBRBaseMaterial.prototype.buildUniformLayout = function () {
        // Order is important !
        var ubo = this._uniformBuffer;
        ubo.addUniform("vAlbedoInfos", 2);
        ubo.addUniform("vAmbientInfos", 4);
        ubo.addUniform("vOpacityInfos", 2);
        ubo.addUniform("vEmissiveInfos", 2);
        ubo.addUniform("vLightmapInfos", 2);
        ubo.addUniform("vReflectivityInfos", 3);
        ubo.addUniform("vMicroSurfaceSamplerInfos", 2);
        ubo.addUniform("vReflectionInfos", 2);
        ubo.addUniform("vReflectionPosition", 3);
        ubo.addUniform("vReflectionSize", 3);
        ubo.addUniform("vBumpInfos", 3);
        ubo.addUniform("albedoMatrix", 16);
        ubo.addUniform("ambientMatrix", 16);
        ubo.addUniform("opacityMatrix", 16);
        ubo.addUniform("emissiveMatrix", 16);
        ubo.addUniform("lightmapMatrix", 16);
        ubo.addUniform("reflectivityMatrix", 16);
        ubo.addUniform("microSurfaceSamplerMatrix", 16);
        ubo.addUniform("bumpMatrix", 16);
        ubo.addUniform("vTangentSpaceParams", 2);
        ubo.addUniform("reflectionMatrix", 16);
        ubo.addUniform("vReflectionColor", 3);
        ubo.addUniform("vAlbedoColor", 4);
        ubo.addUniform("vLightingIntensity", 4);
        ubo.addUniform("vReflectionMicrosurfaceInfos", 4);
        ubo.addUniform("pointSize", 1);
        ubo.addUniform("vReflectivityColor", 4);
        ubo.addUniform("vEmissiveColor", 3);
        ubo.addUniform("vEyePosition", 4);
        ubo.addUniform("vAmbientColor", 3);
        ubo.addUniform("vDebugMode", 2);
        _pbrClearCoatConfiguration__WEBPACK_IMPORTED_MODULE_8__["PBRClearCoatConfiguration"].PrepareUniformBuffer(ubo);
        _pbrAnisotropicConfiguration__WEBPACK_IMPORTED_MODULE_9__["PBRAnisotropicConfiguration"].PrepareUniformBuffer(ubo);
        _pbrSheenConfiguration__WEBPACK_IMPORTED_MODULE_11__["PBRSheenConfiguration"].PrepareUniformBuffer(ubo);
        _pbrSubSurfaceConfiguration__WEBPACK_IMPORTED_MODULE_12__["PBRSubSurfaceConfiguration"].PrepareUniformBuffer(ubo);
        ubo.addUniform("vSphericalL00", 3);
        ubo.addUniform("vSphericalL1_1", 3);
        ubo.addUniform("vSphericalL10", 3);
        ubo.addUniform("vSphericalL11", 3);
        ubo.addUniform("vSphericalL2_2", 3);
        ubo.addUniform("vSphericalL2_1", 3);
        ubo.addUniform("vSphericalL20", 3);
        ubo.addUniform("vSphericalL21", 3);
        ubo.addUniform("vSphericalL22", 3);
        ubo.addUniform("vSphericalX", 3);
        ubo.addUniform("vSphericalY", 3);
        ubo.addUniform("vSphericalZ", 3);
        ubo.addUniform("vSphericalXX_ZZ", 3);
        ubo.addUniform("vSphericalYY_ZZ", 3);
        ubo.addUniform("vSphericalZZ", 3);
        ubo.addUniform("vSphericalXY", 3);
        ubo.addUniform("vSphericalYZ", 3);
        ubo.addUniform("vSphericalZX", 3);
        ubo.create();
    };
    /**
     * Unbinds the material from the mesh
     */
    PBRBaseMaterial.prototype.unbind = function () {
        if (this._activeEffect) {
            var needFlag = false;
            if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                this._activeEffect.setTexture("reflection2DSampler", null);
                needFlag = true;
            }
            if (this.subSurface.unbind(this._activeEffect)) {
                needFlag = true;
            }
            if (needFlag) {
                this._markAllSubMeshesAsTexturesDirty();
            }
        }
        _super.prototype.unbind.call(this);
    };
    /**
     * Binds the submesh data.
     * @param world - The world matrix.
     * @param mesh - The BJS mesh.
     * @param subMesh - A submesh of the BJS mesh.
     */
    PBRBaseMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
        var scene = this.getScene();
        var defines = subMesh._materialDefines;
        if (!defines) {
            return;
        }
        var effect = subMesh.effect;
        if (!effect) {
            return;
        }
        this._activeEffect = effect;
        // Matrices Mesh.
        mesh.getMeshUniformBuffer().bindToEffect(effect, "Mesh");
        mesh.transferToEffect(world);
        // Matrices
        if (!defines.INSTANCES) {
            this.bindOnlyWorldMatrix(world);
        }
        // Normal Matrix
        if (defines.OBJECTSPACE_NORMALMAP) {
            world.toNormalMatrix(this._normalMatrix);
            this.bindOnlyNormalMatrix(this._normalMatrix);
        }
        var mustRebind = this._mustRebind(scene, effect, mesh.visibility);
        // Bones
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindBonesParameters(mesh, this._activeEffect);
        var reflectionTexture = null;
        var ubo = this._uniformBuffer;
        if (mustRebind) {
            var engine = scene.getEngine();
            ubo.bindToEffect(effect, "Material");
            this.bindViewProjection(effect);
            reflectionTexture = this._getReflectionTexture();
            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync) {
                // Texture uniforms
                if (scene.texturesEnabled) {
                    if (this._albedoTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].DiffuseTextureEnabled) {
                        ubo.updateFloat2("vAlbedoInfos", this._albedoTexture.coordinatesIndex, this._albedoTexture.level);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._albedoTexture, ubo, "albedo");
                    }
                    if (this._ambientTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].AmbientTextureEnabled) {
                        ubo.updateFloat4("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level, this._ambientTextureStrength, this._ambientTextureImpactOnAnalyticalLights);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._ambientTexture, ubo, "ambient");
                    }
                    if (this._opacityTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].OpacityTextureEnabled) {
                        ubo.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._opacityTexture, ubo, "opacity");
                    }
                    if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled) {
                        ubo.updateMatrix("reflectionMatrix", reflectionTexture.getReflectionTextureMatrix());
                        ubo.updateFloat2("vReflectionInfos", reflectionTexture.level, 0);
                        if (reflectionTexture.boundingBoxSize) {
                            var cubeTexture = reflectionTexture;
                            ubo.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
                            ubo.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
                        }
                        if (!defines.USEIRRADIANCEMAP) {
                            var polynomials = reflectionTexture.sphericalPolynomial;
                            if (defines.USESPHERICALFROMREFLECTIONMAP && polynomials) {
                                if (defines.SPHERICAL_HARMONICS) {
                                    var preScaledHarmonics = polynomials.preScaledHarmonics;
                                    ubo.updateVector3("vSphericalL00", preScaledHarmonics.l00);
                                    ubo.updateVector3("vSphericalL1_1", preScaledHarmonics.l1_1);
                                    ubo.updateVector3("vSphericalL10", preScaledHarmonics.l10);
                                    ubo.updateVector3("vSphericalL11", preScaledHarmonics.l11);
                                    ubo.updateVector3("vSphericalL2_2", preScaledHarmonics.l2_2);
                                    ubo.updateVector3("vSphericalL2_1", preScaledHarmonics.l2_1);
                                    ubo.updateVector3("vSphericalL20", preScaledHarmonics.l20);
                                    ubo.updateVector3("vSphericalL21", preScaledHarmonics.l21);
                                    ubo.updateVector3("vSphericalL22", preScaledHarmonics.l22);
                                }
                                else {
                                    ubo.updateFloat3("vSphericalX", polynomials.x.x, polynomials.x.y, polynomials.x.z);
                                    ubo.updateFloat3("vSphericalY", polynomials.y.x, polynomials.y.y, polynomials.y.z);
                                    ubo.updateFloat3("vSphericalZ", polynomials.z.x, polynomials.z.y, polynomials.z.z);
                                    ubo.updateFloat3("vSphericalXX_ZZ", polynomials.xx.x - polynomials.zz.x, polynomials.xx.y - polynomials.zz.y, polynomials.xx.z - polynomials.zz.z);
                                    ubo.updateFloat3("vSphericalYY_ZZ", polynomials.yy.x - polynomials.zz.x, polynomials.yy.y - polynomials.zz.y, polynomials.yy.z - polynomials.zz.z);
                                    ubo.updateFloat3("vSphericalZZ", polynomials.zz.x, polynomials.zz.y, polynomials.zz.z);
                                    ubo.updateFloat3("vSphericalXY", polynomials.xy.x, polynomials.xy.y, polynomials.xy.z);
                                    ubo.updateFloat3("vSphericalYZ", polynomials.yz.x, polynomials.yz.y, polynomials.yz.z);
                                    ubo.updateFloat3("vSphericalZX", polynomials.zx.x, polynomials.zx.y, polynomials.zx.z);
                                }
                            }
                        }
                        ubo.updateFloat3("vReflectionMicrosurfaceInfos", reflectionTexture.getSize().width, reflectionTexture.lodGenerationScale, reflectionTexture.lodGenerationOffset);
                    }
                    if (this._emissiveTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].EmissiveTextureEnabled) {
                        ubo.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._emissiveTexture, ubo, "emissive");
                    }
                    if (this._lightmapTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].LightmapTextureEnabled) {
                        ubo.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._lightmapTexture, ubo, "lightmap");
                    }
                    if (_materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].SpecularTextureEnabled) {
                        if (this._metallicTexture) {
                            ubo.updateFloat3("vReflectivityInfos", this._metallicTexture.coordinatesIndex, this._metallicTexture.level, this._ambientTextureStrength);
                            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._metallicTexture, ubo, "reflectivity");
                        }
                        else if (this._reflectivityTexture) {
                            ubo.updateFloat3("vReflectivityInfos", this._reflectivityTexture.coordinatesIndex, this._reflectivityTexture.level, 1.0);
                            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._reflectivityTexture, ubo, "reflectivity");
                        }
                        if (this._microSurfaceTexture) {
                            ubo.updateFloat2("vMicroSurfaceSamplerInfos", this._microSurfaceTexture.coordinatesIndex, this._microSurfaceTexture.level);
                            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._microSurfaceTexture, ubo, "microSurfaceSampler");
                        }
                    }
                    if (this._bumpTexture && engine.getCaps().standardDerivatives && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].BumpTextureEnabled && !this._disableBumpMap) {
                        ubo.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level, this._parallaxScaleBias);
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindTextureMatrix(this._bumpTexture, ubo, "bump");
                        if (scene._mirroredCameraPosition) {
                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
                        }
                        else {
                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
                        }
                    }
                }
                // Point size
                if (this.pointsCloud) {
                    ubo.updateFloat("pointSize", this.pointSize);
                }
                // Colors
                if (defines.METALLICWORKFLOW) {
                    _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["TmpColors"].Color3[0].r = (this._metallic === undefined || this._metallic === null) ? 1 : this._metallic;
                    _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["TmpColors"].Color3[0].g = (this._roughness === undefined || this._roughness === null) ? 1 : this._roughness;
                    ubo.updateColor4("vReflectivityColor", _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["TmpColors"].Color3[0], 0);
                }
                else {
                    ubo.updateColor4("vReflectivityColor", this._reflectivityColor, this._microSurface);
                }
                ubo.updateColor3("vEmissiveColor", _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].EmissiveTextureEnabled ? this._emissiveColor : _Maths_math_color__WEBPACK_IMPORTED_MODULE_13__["Color3"].BlackReadOnly);
                ubo.updateColor3("vReflectionColor", this._reflectionColor);
                if (!defines.SS_REFRACTION && this.subSurface.linkRefractionWithTransparency) {
                    ubo.updateColor4("vAlbedoColor", this._albedoColor, 1);
                }
                else {
                    ubo.updateColor4("vAlbedoColor", this._albedoColor, this.alpha);
                }
                // Misc
                this._lightingInfos.x = this._directIntensity;
                this._lightingInfos.y = this._emissiveIntensity;
                this._lightingInfos.z = this._environmentIntensity * scene.environmentIntensity;
                this._lightingInfos.w = this._specularIntensity;
                ubo.updateVector4("vLightingIntensity", this._lightingInfos);
                // Colors
                scene.ambientColor.multiplyToRef(this._ambientColor, this._globalAmbientColor);
                var eyePosition = scene._forcedViewPosition ? scene._forcedViewPosition : (scene._mirroredCameraPosition ? scene._mirroredCameraPosition : scene.activeCamera.globalPosition);
                var invertNormal = (scene.useRightHandedSystem === (scene._mirroredCameraPosition != null));
                ubo.updateFloat4("vEyePosition", eyePosition.x, eyePosition.y, eyePosition.z, invertNormal ? -1 : 1);
                ubo.updateColor3("vAmbientColor", this._globalAmbientColor);
                ubo.updateFloat2("vDebugMode", this.debugLimit, this.debugFactor);
            }
            // Textures
            if (scene.texturesEnabled) {
                if (this._albedoTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].DiffuseTextureEnabled) {
                    ubo.setTexture("albedoSampler", this._albedoTexture);
                }
                if (this._ambientTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].AmbientTextureEnabled) {
                    ubo.setTexture("ambientSampler", this._ambientTexture);
                }
                if (this._opacityTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].OpacityTextureEnabled) {
                    ubo.setTexture("opacitySampler", this._opacityTexture);
                }
                if (reflectionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].ReflectionTextureEnabled) {
                    if (defines.LODBASEDMICROSFURACE) {
                        ubo.setTexture("reflectionSampler", reflectionTexture);
                    }
                    else {
                        ubo.setTexture("reflectionSampler", reflectionTexture._lodTextureMid || reflectionTexture);
                        ubo.setTexture("reflectionSamplerLow", reflectionTexture._lodTextureLow || reflectionTexture);
                        ubo.setTexture("reflectionSamplerHigh", reflectionTexture._lodTextureHigh || reflectionTexture);
                    }
                    if (defines.USEIRRADIANCEMAP) {
                        ubo.setTexture("irradianceSampler", reflectionTexture.irradianceTexture);
                    }
                }
                if (defines.ENVIRONMENTBRDF) {
                    ubo.setTexture("environmentBrdfSampler", this._environmentBRDFTexture);
                }
                if (this._emissiveTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].EmissiveTextureEnabled) {
                    ubo.setTexture("emissiveSampler", this._emissiveTexture);
                }
                if (this._lightmapTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].LightmapTextureEnabled) {
                    ubo.setTexture("lightmapSampler", this._lightmapTexture);
                }
                if (_materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].SpecularTextureEnabled) {
                    if (this._metallicTexture) {
                        ubo.setTexture("reflectivitySampler", this._metallicTexture);
                    }
                    else if (this._reflectivityTexture) {
                        ubo.setTexture("reflectivitySampler", this._reflectivityTexture);
                    }
                    if (this._microSurfaceTexture) {
                        ubo.setTexture("microSurfaceSampler", this._microSurfaceTexture);
                    }
                }
                if (this._bumpTexture && engine.getCaps().standardDerivatives && _materialFlags__WEBPACK_IMPORTED_MODULE_20__["MaterialFlags"].BumpTextureEnabled && !this._disableBumpMap) {
                    ubo.setTexture("bumpSampler", this._bumpTexture);
                }
            }
            this.subSurface.bindForSubMesh(ubo, scene, engine, this.isFrozen, defines.LODBASEDMICROSFURACE);
            this.clearCoat.bindForSubMesh(ubo, scene, engine, this._disableBumpMap, this.isFrozen, this._invertNormalMapX, this._invertNormalMapY);
            this.anisotropy.bindForSubMesh(ubo, scene, this.isFrozen);
            this.sheen.bindForSubMesh(ubo, scene, this.isFrozen);
            // Clip plane
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindClipPlane(this._activeEffect, scene);
        }
        if (mustRebind || !this.isFrozen) {
            // Lights
            if (scene.lightsEnabled && !this._disableLighting) {
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindLights(scene, mesh, this._activeEffect, defines, this._maxSimultaneousLights, this._lightFalloff !== PBRBaseMaterial.LIGHTFALLOFF_STANDARD, this._rebuildInParallel);
            }
            // View
            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== _scene__WEBPACK_IMPORTED_MODULE_5__["Scene"].FOGMODE_NONE || reflectionTexture) {
                this.bindView(effect);
            }
            // Fog
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindFogParameters(scene, mesh, this._activeEffect, true);
            // Morph targets
            if (defines.NUM_MORPH_INFLUENCERS) {
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindMorphTargetParameters(mesh, this._activeEffect);
            }
            // image processing
            this._imageProcessingConfiguration.bind(this._activeEffect);
            // Log. depth
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_18__["MaterialHelper"].BindLogDepth(defines, this._activeEffect, scene);
        }
        ubo.update();
        this._afterBind(mesh, this._activeEffect);
    };
    /**
     * Returns the animatable textures.
     * @returns - Array of animatable textures.
     */
    PBRBaseMaterial.prototype.getAnimatables = function () {
        var results = [];
        if (this._albedoTexture && this._albedoTexture.animations && this._albedoTexture.animations.length > 0) {
            results.push(this._albedoTexture);
        }
        if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {
            results.push(this._ambientTexture);
        }
        if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {
            results.push(this._opacityTexture);
        }
        if (this._reflectionTexture && this._reflectionTexture.animations && this._reflectionTexture.animations.length > 0) {
            results.push(this._reflectionTexture);
        }
        if (this._emissiveTexture && this._emissiveTexture.animations && this._emissiveTexture.animations.length > 0) {
            results.push(this._emissiveTexture);
        }
        if (this._metallicTexture && this._metallicTexture.animations && this._metallicTexture.animations.length > 0) {
            results.push(this._metallicTexture);
        }
        else if (this._reflectivityTexture && this._reflectivityTexture.animations && this._reflectivityTexture.animations.length > 0) {
            results.push(this._reflectivityTexture);
        }
        if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {
            results.push(this._bumpTexture);
        }
        if (this._lightmapTexture && this._lightmapTexture.animations && this._lightmapTexture.animations.length > 0) {
            results.push(this._lightmapTexture);
        }
        this.subSurface.getAnimatables(results);
        this.clearCoat.getAnimatables(results);
        this.sheen.getAnimatables(results);
        this.anisotropy.getAnimatables(results);
        return results;
    };
    /**
     * Returns the texture used for reflections.
     * @returns - Reflection texture if present.  Otherwise, returns the environment texture.
     */
    PBRBaseMaterial.prototype._getReflectionTexture = function () {
        if (this._reflectionTexture) {
            return this._reflectionTexture;
        }
        return this.getScene().environmentTexture;
    };
    /**
     * Returns an array of the actively used textures.
     * @returns - Array of BaseTextures
     */
    PBRBaseMaterial.prototype.getActiveTextures = function () {
        var activeTextures = _super.prototype.getActiveTextures.call(this);
        if (this._albedoTexture) {
            activeTextures.push(this._albedoTexture);
        }
        if (this._ambientTexture) {
            activeTextures.push(this._ambientTexture);
        }
        if (this._opacityTexture) {
            activeTextures.push(this._opacityTexture);
        }
        if (this._reflectionTexture) {
            activeTextures.push(this._reflectionTexture);
        }
        if (this._emissiveTexture) {
            activeTextures.push(this._emissiveTexture);
        }
        if (this._reflectivityTexture) {
            activeTextures.push(this._reflectivityTexture);
        }
        if (this._metallicTexture) {
            activeTextures.push(this._metallicTexture);
        }
        if (this._microSurfaceTexture) {
            activeTextures.push(this._microSurfaceTexture);
        }
        if (this._bumpTexture) {
            activeTextures.push(this._bumpTexture);
        }
        if (this._lightmapTexture) {
            activeTextures.push(this._lightmapTexture);
        }
        this.subSurface.getActiveTextures(activeTextures);
        this.clearCoat.getActiveTextures(activeTextures);
        this.sheen.getActiveTextures(activeTextures);
        this.anisotropy.getActiveTextures(activeTextures);
        return activeTextures;
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param texture - Base texture to use.
     * @returns - Boolean specifying if a texture is used in the material.
     */
    PBRBaseMaterial.prototype.hasTexture = function (texture) {
        if (_super.prototype.hasTexture.call(this, texture)) {
            return true;
        }
        if (this._albedoTexture === texture) {
            return true;
        }
        if (this._ambientTexture === texture) {
            return true;
        }
        if (this._opacityTexture === texture) {
            return true;
        }
        if (this._reflectionTexture === texture) {
            return true;
        }
        if (this._reflectivityTexture === texture) {
            return true;
        }
        if (this._metallicTexture === texture) {
            return true;
        }
        if (this._microSurfaceTexture === texture) {
            return true;
        }
        if (this._bumpTexture === texture) {
            return true;
        }
        if (this._lightmapTexture === texture) {
            return true;
        }
        return this.subSurface.hasTexture(texture) ||
            this.clearCoat.hasTexture(texture) ||
            this.sheen.hasTexture(texture) ||
            this.anisotropy.hasTexture(texture);
    };
    /**
     * Disposes the resources of the material.
     * @param forceDisposeEffect - Forces the disposal of effects.
     * @param forceDisposeTextures - Forces the disposal of all textures.
     */
    PBRBaseMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
        if (forceDisposeTextures) {
            if (this._albedoTexture) {
                this._albedoTexture.dispose();
            }
            if (this._ambientTexture) {
                this._ambientTexture.dispose();
            }
            if (this._opacityTexture) {
                this._opacityTexture.dispose();
            }
            if (this._reflectionTexture) {
                this._reflectionTexture.dispose();
            }
            if (this._environmentBRDFTexture && this.getScene().environmentBRDFTexture !== this._environmentBRDFTexture) {
                this._environmentBRDFTexture.dispose();
            }
            if (this._emissiveTexture) {
                this._emissiveTexture.dispose();
            }
            if (this._metallicTexture) {
                this._metallicTexture.dispose();
            }
            if (this._reflectivityTexture) {
                this._reflectivityTexture.dispose();
            }
            if (this._bumpTexture) {
                this._bumpTexture.dispose();
            }
            if (this._lightmapTexture) {
                this._lightmapTexture.dispose();
            }
        }
        this.subSurface.dispose(forceDisposeTextures);
        this.clearCoat.dispose(forceDisposeTextures);
        this.sheen.dispose(forceDisposeTextures);
        this.anisotropy.dispose(forceDisposeTextures);
        this._renderTargets.dispose();
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        _super.prototype.dispose.call(this, forceDisposeEffect, forceDisposeTextures);
    };
    /**
     * PBRMaterialTransparencyMode: No transparency mode, Alpha channel is not use.
     */
    PBRBaseMaterial.PBRMATERIAL_OPAQUE = 0;
    /**
     * PBRMaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
     */
    PBRBaseMaterial.PBRMATERIAL_ALPHATEST = 1;
    /**
     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
     */
    PBRBaseMaterial.PBRMATERIAL_ALPHABLEND = 2;
    /**
     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
     * They are also discarded below the alpha cutoff threshold to improve performances.
     */
    PBRBaseMaterial.PBRMATERIAL_ALPHATESTANDBLEND = 3;
    /**
     * Defines the default value of how much AO map is occluding the analytical lights
     * (point spot...).
     */
    PBRBaseMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS = 0;
    /**
     * PBRMaterialLightFalloff Physical: light is falling off following the inverse squared distance law.
     */
    PBRBaseMaterial.LIGHTFALLOFF_PHYSICAL = 0;
    /**
     * PBRMaterialLightFalloff gltf: light is falling off as described in the gltf moving to PBR document
     * to enhance interoperability with other engines.
     */
    PBRBaseMaterial.LIGHTFALLOFF_GLTF = 1;
    /**
     * PBRMaterialLightFalloff Standard: light is falling off like in the standard material
     * to enhance interoperability with other materials.
     */
    PBRBaseMaterial.LIGHTFALLOFF_STANDARD = 2;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsImageProcessingConfiguration"])()
    ], PBRBaseMaterial.prototype, "_imageProcessingConfiguration", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsMiscDirty")
    ], PBRBaseMaterial.prototype, "debugMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRBaseMaterial.prototype, "useLogarithmicDepth", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRBaseMaterial.prototype, "transparencyMode", null);
    return PBRBaseMaterial;
}(_Materials_pushMaterial__WEBPACK_IMPORTED_MODULE_17__["PushMaterial"]));



/***/ }),

/***/ "./Materials/PBR/pbrBaseSimpleMaterial.ts":
/*!************************************************!*\
  !*** ./Materials/PBR/pbrBaseSimpleMaterial.ts ***!
  \************************************************/
/*! exports provided: PBRBaseSimpleMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRBaseSimpleMaterial", function() { return PBRBaseSimpleMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./pbrBaseMaterial */ "./Materials/PBR/pbrBaseMaterial.ts");




/**
 * The Physically based simple base material of BJS.
 *
 * This enables better naming and convention enforcements on top of the pbrMaterial.
 * It is used as the base class for both the specGloss and metalRough conventions.
 */
var PBRBaseSimpleMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PBRBaseSimpleMaterial, _super);
    /**
     * Instantiates a new PBRMaterial instance.
     *
     * @param name The material name
     * @param scene The scene the material will be use in.
     */
    function PBRBaseSimpleMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        /**
         * Number of Simultaneous lights allowed on the material.
         */
        _this.maxSimultaneousLights = 4;
        /**
         * If sets to true, disables all the lights affecting the material.
         */
        _this.disableLighting = false;
        /**
         * If sets to true, x component of normal map value will invert (x = 1.0 - x).
         */
        _this.invertNormalMapX = false;
        /**
         * If sets to true, y component of normal map value will invert (y = 1.0 - y).
         */
        _this.invertNormalMapY = false;
        /**
         * Emissivie color used to self-illuminate the model.
         */
        _this.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"](0, 0, 0);
        /**
         * Occlusion Channel Strenght.
         */
        _this.occlusionStrength = 1.0;
        /**
         * If true, the light map contains occlusion information instead of lighting info.
         */
        _this.useLightmapAsShadowmap = false;
        _this._useAlphaFromAlbedoTexture = true;
        _this._useAmbientInGrayScale = true;
        return _this;
    }
    Object.defineProperty(PBRBaseSimpleMaterial.prototype, "doubleSided", {
        /**
         * Gets the current double sided mode.
         */
        get: function () {
            return this._twoSidedLighting;
        },
        /**
         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
         */
        set: function (value) {
            if (this._twoSidedLighting === value) {
                return;
            }
            this._twoSidedLighting = value;
            this.backFaceCulling = !value;
            this._markAllSubMeshesAsTexturesDirty();
        },
        enumerable: true,
        configurable: true
    });
    PBRBaseSimpleMaterial.prototype.getClassName = function () {
        return "PBRBaseSimpleMaterial";
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], PBRBaseSimpleMaterial.prototype, "maxSimultaneousLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], PBRBaseSimpleMaterial.prototype, "disableLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_reflectionTexture")
    ], PBRBaseSimpleMaterial.prototype, "environmentTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRBaseSimpleMaterial.prototype, "invertNormalMapX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRBaseSimpleMaterial.prototype, "invertNormalMapY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_bumpTexture")
    ], PBRBaseSimpleMaterial.prototype, "normalTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("emissive"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRBaseSimpleMaterial.prototype, "emissiveColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRBaseSimpleMaterial.prototype, "emissiveTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_ambientTextureStrength")
    ], PBRBaseSimpleMaterial.prototype, "occlusionStrength", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_ambientTexture")
    ], PBRBaseSimpleMaterial.prototype, "occlusionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_alphaCutOff")
    ], PBRBaseSimpleMaterial.prototype, "alphaCutOff", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRBaseSimpleMaterial.prototype, "doubleSided", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", null)
    ], PBRBaseSimpleMaterial.prototype, "lightmapTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRBaseSimpleMaterial.prototype, "useLightmapAsShadowmap", void 0);
    return PBRBaseSimpleMaterial;
}(_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_3__["PBRBaseMaterial"]));



/***/ }),

/***/ "./Materials/PBR/pbrClearCoatConfiguration.ts":
/*!****************************************************!*\
  !*** ./Materials/PBR/pbrClearCoatConfiguration.ts ***!
  \****************************************************/
/*! exports provided: PBRClearCoatConfiguration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRClearCoatConfiguration", function() { return PBRClearCoatConfiguration; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _materialFlags__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");





/**
 * Define the code related to the clear coat parameters of the pbr material.
 */
var PBRClearCoatConfiguration = /** @class */ (function () {
    /**
     * Instantiate a new istance of clear coat configuration.
     * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
     */
    function PBRClearCoatConfiguration(markAllSubMeshesAsTexturesDirty) {
        this._isEnabled = false;
        /**
         * Defines if the clear coat is enabled in the material.
         */
        this.isEnabled = false;
        /**
         * Defines the clear coat layer strength (between 0 and 1) it defaults to 1.
         */
        this.intensity = 1;
        /**
         * Defines the clear coat layer roughness.
         */
        this.roughness = 0;
        this._indexOfRefraction = PBRClearCoatConfiguration._DefaultIndexOfRefraction;
        /**
         * Defines the index of refraction of the clear coat.
         * This defaults to 1.5 corresponding to a 0.04 f0 or a 4% reflectance at normal incidence
         * The default fits with a polyurethane material.
         * Changing the default value is more performance intensive.
         */
        this.indexOfRefraction = PBRClearCoatConfiguration._DefaultIndexOfRefraction;
        this._texture = null;
        /**
         * Stores the clear coat values in a texture.
         */
        this.texture = null;
        this._bumpTexture = null;
        /**
         * Define the clear coat specific bump texture.
         */
        this.bumpTexture = null;
        this._isTintEnabled = false;
        /**
         * Defines if the clear coat tint is enabled in the material.
         */
        this.isTintEnabled = false;
        /**
         * Defines the clear coat tint of the material.
         * This is only use if tint is enabled
         */
        this.tintColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"].White();
        /**
         * Defines the distance at which the tint color should be found in the
         * clear coat media.
         * This is only use if tint is enabled
         */
        this.tintColorAtDistance = 1;
        /**
         * Defines the clear coat layer thickness.
         * This is only use if tint is enabled
         */
        this.tintThickness = 1;
        this._tintTexture = null;
        /**
         * Stores the clear tint values in a texture.
         * rgb is tint
         * a is a thickness factor
         */
        this.tintTexture = null;
        this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
    }
    /** @hidden */
    PBRClearCoatConfiguration.prototype._markAllSubMeshesAsTexturesDirty = function () {
        this._internalMarkAllSubMeshesAsTexturesDirty();
    };
    /**
     * Gets wehter the submesh is ready to be used or not.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene the material belongs to.
     * @param engine defines the engine the material belongs to.
     * @param disableBumpMap defines wether the material disables bump or not.
     * @returns - boolean indicating that the submesh is ready or not.
     */
    PBRClearCoatConfiguration.prototype.isReadyForSubMesh = function (defines, scene, engine, disableBumpMap) {
        if (defines._areTexturesDirty) {
            if (scene.texturesEnabled) {
                if (this._texture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTextureEnabled) {
                    if (!this._texture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                if (engine.getCaps().standardDerivatives && this._bumpTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatBumpTextureEnabled && !disableBumpMap) {
                    // Bump texture cannot be not blocking.
                    if (!this._bumpTexture.isReady()) {
                        return false;
                    }
                }
                if (this._isTintEnabled && this._tintTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTintTextureEnabled) {
                    if (!this._tintTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
            }
        }
        return true;
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene to the material belongs to.
     */
    PBRClearCoatConfiguration.prototype.prepareDefines = function (defines, scene) {
        if (this._isEnabled) {
            defines.CLEARCOAT = true;
            if (defines._areTexturesDirty) {
                if (scene.texturesEnabled) {
                    if (this._texture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTextureEnabled) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForMergedUV(this._texture, defines, "CLEARCOAT_TEXTURE");
                    }
                    else {
                        defines.CLEARCOAT_TEXTURE = false;
                    }
                    if (this._bumpTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatBumpTextureEnabled) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForMergedUV(this._bumpTexture, defines, "CLEARCOAT_BUMP");
                    }
                    else {
                        defines.CLEARCOAT_BUMP = false;
                    }
                    defines.CLEARCOAT_DEFAULTIOR = this._indexOfRefraction === PBRClearCoatConfiguration._DefaultIndexOfRefraction;
                    if (this._isTintEnabled) {
                        defines.CLEARCOAT_TINT = true;
                        if (this._tintTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTintTextureEnabled) {
                            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForMergedUV(this._tintTexture, defines, "CLEARCOAT_TINT_TEXTURE");
                        }
                        else {
                            defines.CLEARCOAT_TINT_TEXTURE = false;
                        }
                    }
                    else {
                        defines.CLEARCOAT_TINT = false;
                        defines.CLEARCOAT_TINT_TEXTURE = false;
                    }
                }
            }
        }
        else {
            defines.CLEARCOAT = false;
            defines.CLEARCOAT_TEXTURE = false;
            defines.CLEARCOAT_BUMP = false;
            defines.CLEARCOAT_TINT = false;
            defines.CLEARCOAT_TINT_TEXTURE = false;
        }
    };
    /**
     * Binds the material data.
     * @param uniformBuffer defines the Uniform buffer to fill in.
     * @param scene defines the scene the material belongs to.
     * @param engine defines the engine the material belongs to.
     * @param disableBumpMap defines wether the material disables bump or not.
     * @param isFrozen defines wether the material is frozen or not.
     * @param invertNormalMapX If sets to true, x component of normal map value will be inverted (x = 1.0 - x).
     * @param invertNormalMapY If sets to true, y component of normal map value will be inverted (y = 1.0 - y).
     */
    PBRClearCoatConfiguration.prototype.bindForSubMesh = function (uniformBuffer, scene, engine, disableBumpMap, isFrozen, invertNormalMapX, invertNormalMapY) {
        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
            if (this._texture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTextureEnabled) {
                uniformBuffer.updateFloat2("vClearCoatInfos", this._texture.coordinatesIndex, this._texture.level);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindTextureMatrix(this._texture, uniformBuffer, "clearCoat");
            }
            if (this._bumpTexture && engine.getCaps().standardDerivatives && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTextureEnabled && !disableBumpMap) {
                uniformBuffer.updateFloat2("vClearCoatBumpInfos", this._bumpTexture.coordinatesIndex, this._bumpTexture.level);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindTextureMatrix(this._bumpTexture, uniformBuffer, "clearCoatBump");
                if (scene._mirroredCameraPosition) {
                    uniformBuffer.updateFloat2("vClearCoatTangentSpaceParams", invertNormalMapX ? 1.0 : -1.0, invertNormalMapY ? 1.0 : -1.0);
                }
                else {
                    uniformBuffer.updateFloat2("vClearCoatTangentSpaceParams", invertNormalMapX ? -1.0 : 1.0, invertNormalMapY ? -1.0 : 1.0);
                }
            }
            if (this._tintTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTintTextureEnabled) {
                uniformBuffer.updateFloat2("vClearCoatTintInfos", this._tintTexture.coordinatesIndex, this._tintTexture.level);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindTextureMatrix(this._tintTexture, uniformBuffer, "clearCoatTint");
            }
            // Clear Coat General params
            uniformBuffer.updateFloat2("vClearCoatParams", this.intensity, this.roughness);
            // Clear Coat Refraction params
            var a = 1 - this._indexOfRefraction;
            var b = 1 + this._indexOfRefraction;
            var f0 = Math.pow((-a / b), 2); // Schlicks approx: (ior1 - ior2) / (ior1 + ior2) where ior2 for air is close to vacuum = 1.
            var eta = 1 / this._indexOfRefraction;
            uniformBuffer.updateFloat4("vClearCoatRefractionParams", f0, eta, a, b);
            if (this._isTintEnabled) {
                uniformBuffer.updateFloat4("vClearCoatTintParams", this.tintColor.r, this.tintColor.g, this.tintColor.b, Math.max(0.00001, this.tintThickness));
                uniformBuffer.updateFloat("clearCoatColorAtDistance", Math.max(0.00001, this.tintColorAtDistance));
            }
        }
        // Textures
        if (scene.texturesEnabled) {
            if (this._texture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTextureEnabled) {
                uniformBuffer.setTexture("clearCoatSampler", this._texture);
            }
            if (this._bumpTexture && engine.getCaps().standardDerivatives && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatBumpTextureEnabled && !disableBumpMap) {
                uniformBuffer.setTexture("clearCoatBumpSampler", this._bumpTexture);
            }
            if (this._isTintEnabled && this._tintTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ClearCoatTintTextureEnabled) {
                uniformBuffer.setTexture("clearCoatTintSampler", this._tintTexture);
            }
        }
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param texture - Base texture to use.
     * @returns - Boolean specifying if a texture is used in the material.
     */
    PBRClearCoatConfiguration.prototype.hasTexture = function (texture) {
        if (this._texture === texture) {
            return true;
        }
        if (this._bumpTexture === texture) {
            return true;
        }
        if (this._tintTexture === texture) {
            return true;
        }
        return false;
    };
    /**
     * Returns an array of the actively used textures.
     * @param activeTextures Array of BaseTextures
     */
    PBRClearCoatConfiguration.prototype.getActiveTextures = function (activeTextures) {
        if (this._texture) {
            activeTextures.push(this._texture);
        }
        if (this._bumpTexture) {
            activeTextures.push(this._bumpTexture);
        }
        if (this._tintTexture) {
            activeTextures.push(this._tintTexture);
        }
    };
    /**
     * Returns the animatable textures.
     * @param animatables Array of animatable textures.
     */
    PBRClearCoatConfiguration.prototype.getAnimatables = function (animatables) {
        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
            animatables.push(this._texture);
        }
        if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {
            animatables.push(this._bumpTexture);
        }
        if (this._tintTexture && this._tintTexture.animations && this._tintTexture.animations.length > 0) {
            animatables.push(this._tintTexture);
        }
    };
    /**
     * Disposes the resources of the material.
     * @param forceDisposeTextures - Forces the disposal of all textures.
     */
    PBRClearCoatConfiguration.prototype.dispose = function (forceDisposeTextures) {
        if (forceDisposeTextures) {
            if (this._texture) {
                this._texture.dispose();
            }
            if (this._bumpTexture) {
                this._bumpTexture.dispose();
            }
            if (this._tintTexture) {
                this._tintTexture.dispose();
            }
        }
    };
    /**
    * Get the current class name of the texture useful for serialization or dynamic coding.
    * @returns "PBRClearCoatConfiguration"
    */
    PBRClearCoatConfiguration.prototype.getClassName = function () {
        return "PBRClearCoatConfiguration";
    };
    /**
     * Add fallbacks to the effect fallbacks list.
     * @param defines defines the Base texture to use.
     * @param fallbacks defines the current fallback list.
     * @param currentRank defines the current fallback rank.
     * @returns the new fallback rank.
     */
    PBRClearCoatConfiguration.AddFallbacks = function (defines, fallbacks, currentRank) {
        if (defines.CLEARCOAT_BUMP) {
            fallbacks.addFallback(currentRank++, "CLEARCOAT_BUMP");
        }
        if (defines.CLEARCOAT_TINT) {
            fallbacks.addFallback(currentRank++, "CLEARCOAT_TINT");
        }
        if (defines.CLEARCOAT) {
            fallbacks.addFallback(currentRank++, "CLEARCOAT");
        }
        return currentRank;
    };
    /**
     * Add the required uniforms to the current list.
     * @param uniforms defines the current uniform list.
     */
    PBRClearCoatConfiguration.AddUniforms = function (uniforms) {
        uniforms.push("vClearCoatTangentSpaceParams", "vClearCoatParams", "vClearCoatRefractionParams", "vClearCoatTintParams", "clearCoatColorAtDistance", "clearCoatMatrix", "clearCoatBumpMatrix", "clearCoatTintMatrix", "vClearCoatInfos", "vClearCoatBumpInfos", "vClearCoatTintInfos");
    };
    /**
     * Add the required samplers to the current list.
     * @param samplers defines the current sampler list.
     */
    PBRClearCoatConfiguration.AddSamplers = function (samplers) {
        samplers.push("clearCoatSampler", "clearCoatBumpSampler", "clearCoatTintSampler");
    };
    /**
     * Add the required uniforms to the current buffer.
     * @param uniformBuffer defines the current uniform buffer.
     */
    PBRClearCoatConfiguration.PrepareUniformBuffer = function (uniformBuffer) {
        uniformBuffer.addUniform("vClearCoatParams", 2);
        uniformBuffer.addUniform("vClearCoatRefractionParams", 4);
        uniformBuffer.addUniform("vClearCoatInfos", 2);
        uniformBuffer.addUniform("clearCoatMatrix", 16);
        uniformBuffer.addUniform("vClearCoatBumpInfos", 2);
        uniformBuffer.addUniform("vClearCoatTangentSpaceParams", 2);
        uniformBuffer.addUniform("clearCoatBumpMatrix", 16);
        uniformBuffer.addUniform("vClearCoatTintParams", 4);
        uniformBuffer.addUniform("clearCoatColorAtDistance", 1);
        uniformBuffer.addUniform("vClearCoatTintInfos", 2);
        uniformBuffer.addUniform("clearCoatTintMatrix", 16);
    };
    /**
     * Makes a duplicate of the current configuration into another one.
     * @param clearCoatConfiguration define the config where to copy the info
     */
    PBRClearCoatConfiguration.prototype.copyTo = function (clearCoatConfiguration) {
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return clearCoatConfiguration; }, this);
    };
    /**
     * Serializes this clear coat configuration.
     * @returns - An object with the serialized config.
     */
    PBRClearCoatConfiguration.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses a anisotropy Configuration from a serialized object.
     * @param source - Serialized object.
     * @param scene Defines the scene we are parsing for
     * @param rootUrl Defines the rootUrl to load from
     */
    PBRClearCoatConfiguration.prototype.parse = function (source, scene, rootUrl) {
        var _this = this;
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return _this; }, source, scene, rootUrl);
    };
    /**
     * This defaults to 1.5 corresponding to a 0.04 f0 or a 4% reflectance at normal incidence
     * The default fits with a polyurethane material.
     */
    PBRClearCoatConfiguration._DefaultIndexOfRefraction = 1.5;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRClearCoatConfiguration.prototype, "isEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRClearCoatConfiguration.prototype, "intensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRClearCoatConfiguration.prototype, "roughness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRClearCoatConfiguration.prototype, "indexOfRefraction", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRClearCoatConfiguration.prototype, "texture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRClearCoatConfiguration.prototype, "bumpTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRClearCoatConfiguration.prototype, "isTintEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], PBRClearCoatConfiguration.prototype, "tintColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRClearCoatConfiguration.prototype, "tintColorAtDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRClearCoatConfiguration.prototype, "tintThickness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRClearCoatConfiguration.prototype, "tintTexture", void 0);
    return PBRClearCoatConfiguration;
}());



/***/ }),

/***/ "./Materials/PBR/pbrMaterial.ts":
/*!**************************************!*\
  !*** ./Materials/PBR/pbrMaterial.ts ***!
  \**************************************/
/*! exports provided: PBRMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRMaterial", function() { return PBRMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_brdfTextureTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/brdfTextureTools */ "./Misc/brdfTextureTools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./pbrBaseMaterial */ "./Materials/PBR/pbrBaseMaterial.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");






/**
 * The Physically based material of BJS.
 *
 * This offers the main features of a standard PBR material.
 * For more information, please refer to the documentation :
 * https://doc.babylonjs.com/how_to/physically_based_rendering
 */
var PBRMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PBRMaterial, _super);
    /**
     * Instantiates a new PBRMaterial instance.
     *
     * @param name The material name
     * @param scene The scene the material will be use in.
     */
    function PBRMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        /**
         * Intensity of the direct lights e.g. the four lights available in your scene.
         * This impacts both the direct diffuse and specular highlights.
         */
        _this.directIntensity = 1.0;
        /**
         * Intensity of the emissive part of the material.
         * This helps controlling the emissive effect without modifying the emissive color.
         */
        _this.emissiveIntensity = 1.0;
        /**
         * Intensity of the environment e.g. how much the environment will light the object
         * either through harmonics for rough material or through the refelction for shiny ones.
         */
        _this.environmentIntensity = 1.0;
        /**
         * This is a special control allowing the reduction of the specular highlights coming from the
         * four lights of the scene. Those highlights may not be needed in full environment lighting.
         */
        _this.specularIntensity = 1.0;
        /**
         * Debug Control allowing disabling the bump map on this material.
         */
        _this.disableBumpMap = false;
        /**
         * AKA Occlusion Texture Intensity in other nomenclature.
         */
        _this.ambientTextureStrength = 1.0;
        /**
         * Defines how much the AO map is occluding the analytical lights (point spot...).
         * 1 means it completely occludes it
         * 0 mean it has no impact
         */
        _this.ambientTextureImpactOnAnalyticalLights = PBRMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS;
        /**
         * The color of a material in ambient lighting.
         */
        _this.ambientColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0, 0, 0);
        /**
         * AKA Diffuse Color in other nomenclature.
         */
        _this.albedoColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](1, 1, 1);
        /**
         * AKA Specular Color in other nomenclature.
         */
        _this.reflectivityColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](1, 1, 1);
        /**
         * The color reflected from the material.
         */
        _this.reflectionColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](1.0, 1.0, 1.0);
        /**
         * The color emitted from the material.
         */
        _this.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](0, 0, 0);
        /**
         * AKA Glossiness in other nomenclature.
         */
        _this.microSurface = 1.0;
        /**
         * If true, the light map contains occlusion information instead of lighting info.
         */
        _this.useLightmapAsShadowmap = false;
        /**
         * Specifies that the alpha is coming form the albedo channel alpha channel for alpha blending.
         */
        _this.useAlphaFromAlbedoTexture = false;
        /**
         * Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
         */
        _this.forceAlphaTest = false;
        /**
         * Defines the alpha limits in alpha test mode.
         */
        _this.alphaCutOff = 0.4;
        /**
         * Specifies that the material will keep the specular highlights over a transparent surface (only the most limunous ones).
         * A car glass is a good exemple of that. When sun reflects on it you can not see what is behind.
         */
        _this.useSpecularOverAlpha = true;
        /**
         * Specifies if the reflectivity texture contains the glossiness information in its alpha channel.
         */
        _this.useMicroSurfaceFromReflectivityMapAlpha = false;
        /**
         * Specifies if the metallic texture contains the roughness information in its alpha channel.
         */
        _this.useRoughnessFromMetallicTextureAlpha = true;
        /**
         * Specifies if the metallic texture contains the roughness information in its green channel.
         */
        _this.useRoughnessFromMetallicTextureGreen = false;
        /**
         * Specifies if the metallic texture contains the metallness information in its blue channel.
         */
        _this.useMetallnessFromMetallicTextureBlue = false;
        /**
         * Specifies if the metallic texture contains the ambient occlusion information in its red channel.
         */
        _this.useAmbientOcclusionFromMetallicTextureRed = false;
        /**
         * Specifies if the ambient texture contains the ambient occlusion information in its red channel only.
         */
        _this.useAmbientInGrayScale = false;
        /**
         * In case the reflectivity map does not contain the microsurface information in its alpha channel,
         * The material will try to infer what glossiness each pixel should be.
         */
        _this.useAutoMicroSurfaceFromReflectivityMap = false;
        /**
         * Specifies that the material will keeps the reflection highlights over a transparent surface (only the most limunous ones).
         * A car glass is a good exemple of that. When the street lights reflects on it you can not see what is behind.
         */
        _this.useRadianceOverAlpha = true;
        /**
         * Allows using an object space normal map (instead of tangent space).
         */
        _this.useObjectSpaceNormalMap = false;
        /**
         * Allows using the bump map in parallax mode.
         */
        _this.useParallax = false;
        /**
         * Allows using the bump map in parallax occlusion mode.
         */
        _this.useParallaxOcclusion = false;
        /**
         * Controls the scale bias of the parallax mode.
         */
        _this.parallaxScaleBias = 0.05;
        /**
         * If sets to true, disables all the lights affecting the material.
         */
        _this.disableLighting = false;
        /**
         * Force the shader to compute irradiance in the fragment shader in order to take bump in account.
         */
        _this.forceIrradianceInFragment = false;
        /**
         * Number of Simultaneous lights allowed on the material.
         */
        _this.maxSimultaneousLights = 4;
        /**
         * If sets to true, x component of normal map value will invert (x = 1.0 - x).
         */
        _this.invertNormalMapX = false;
        /**
         * If sets to true, y component of normal map value will invert (y = 1.0 - y).
         */
        _this.invertNormalMapY = false;
        /**
         * If sets to true and backfaceCulling is false, normals will be flipped on the backside.
         */
        _this.twoSidedLighting = false;
        /**
         * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
         * And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)
         */
        _this.useAlphaFresnel = false;
        /**
         * A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
         * And/Or occlude the blended part. (alpha stays linear to compute the fresnel)
         */
        _this.useLinearAlphaFresnel = false;
        /**
         * Let user defines the brdf lookup texture used for IBL.
         * A default 8bit version is embedded but you could point at :
         * * Default texture: https://assets.babylonjs.com/environments/correlatedMSBRDF_RGBD.png
         * * Default 16bit pixel depth texture: https://assets.babylonjs.com/environments/correlatedMSBRDF.dds
         * * LEGACY Default None correlated https://assets.babylonjs.com/environments/uncorrelatedBRDF_RGBD.png
         * * LEGACY Default None correlated 16bit pixel depth https://assets.babylonjs.com/environments/uncorrelatedBRDF.dds
         */
        _this.environmentBRDFTexture = null;
        /**
         * Force normal to face away from face.
         */
        _this.forceNormalForward = false;
        /**
         * Enables specular anti aliasing in the PBR shader.
         * It will both interacts on the Geometry for analytical and IBL lighting.
         * It also prefilter the roughness map based on the bump values.
         */
        _this.enableSpecularAntiAliasing = false;
        /**
         * This parameters will enable/disable Horizon occlusion to prevent normal maps to look shiny when the normal
         * makes the reflect vector face the model (under horizon).
         */
        _this.useHorizonOcclusion = true;
        /**
         * This parameters will enable/disable radiance occlusion by preventing the radiance to lit
         * too much the area relying on ambient texture to define their ambient occlusion.
         */
        _this.useRadianceOcclusion = true;
        /**
         * If set to true, no lighting calculations will be applied.
         */
        _this.unlit = false;
        _this._environmentBRDFTexture = _Misc_brdfTextureTools__WEBPACK_IMPORTED_MODULE_2__["BRDFTextureTools"].GetEnvironmentBRDFTexture(scene);
        return _this;
    }
    Object.defineProperty(PBRMaterial.prototype, "refractionTexture", {
        /**
         * Stores the refracted light information in a texture.
         */
        get: function () {
            return this.subSurface.refractionTexture;
        },
        set: function (value) {
            this.subSurface.refractionTexture = value;
            if (value) {
                this.subSurface.isRefractionEnabled = true;
            }
            else if (!this.subSurface.linkRefractionWithTransparency) {
                this.subSurface.isRefractionEnabled = false;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "indexOfRefraction", {
        /**
         * source material index of refraction (IOR)' / 'destination material IOR.
         */
        get: function () {
            return 1 / this.subSurface.indexOfRefraction;
        },
        set: function (value) {
            this.subSurface.indexOfRefraction = 1 / value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "invertRefractionY", {
        /**
         * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
         */
        get: function () {
            return this.subSurface.invertRefractionY;
        },
        set: function (value) {
            this.subSurface.invertRefractionY = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "linkRefractionWithTransparency", {
        /**
         * This parameters will make the material used its opacity to control how much it is refracting aginst not.
         * Materials half opaque for instance using refraction could benefit from this control.
         */
        get: function () {
            return this.subSurface.linkRefractionWithTransparency;
        },
        set: function (value) {
            this.subSurface.linkRefractionWithTransparency = value;
            if (value) {
                this.subSurface.isRefractionEnabled = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "usePhysicalLightFalloff", {
        /**
         * BJS is using an harcoded light falloff based on a manually sets up range.
         * In PBR, one way to represents the fallof is to use the inverse squared root algorythm.
         * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.
         */
        get: function () {
            return this._lightFalloff === _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].LIGHTFALLOFF_PHYSICAL;
        },
        /**
         * BJS is using an harcoded light falloff based on a manually sets up range.
         * In PBR, one way to represents the fallof is to use the inverse squared root algorythm.
         * This parameter can help you switch back to the BJS mode in order to create scenes using both materials.
         */
        set: function (value) {
            if (value !== this.usePhysicalLightFalloff) {
                // Ensure the effect will be rebuilt.
                this._markAllSubMeshesAsTexturesDirty();
                if (value) {
                    this._lightFalloff = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].LIGHTFALLOFF_PHYSICAL;
                }
                else {
                    this._lightFalloff = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].LIGHTFALLOFF_STANDARD;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "useGLTFLightFalloff", {
        /**
         * In order to support the falloff compatibility with gltf, a special mode has been added
         * to reproduce the gltf light falloff.
         */
        get: function () {
            return this._lightFalloff === _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].LIGHTFALLOFF_GLTF;
        },
        /**
         * In order to support the falloff compatibility with gltf, a special mode has been added
         * to reproduce the gltf light falloff.
         */
        set: function (value) {
            if (value !== this.useGLTFLightFalloff) {
                // Ensure the effect will be rebuilt.
                this._markAllSubMeshesAsTexturesDirty();
                if (value) {
                    this._lightFalloff = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].LIGHTFALLOFF_GLTF;
                }
                else {
                    this._lightFalloff = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].LIGHTFALLOFF_STANDARD;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "imageProcessingConfiguration", {
        /**
         * Gets the image processing configuration used either in this material.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        /**
         * Sets the Default image processing configuration used either in the this material.
         *
         * If sets to null, the scene one is in use.
         */
        set: function (value) {
            this._attachImageProcessingConfiguration(value);
            // Ensure the effect will be rebuilt.
            this._markAllSubMeshesAsTexturesDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraColorCurvesEnabled", {
        /**
         * Gets wether the color curves effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorCurvesEnabled;
        },
        /**
         * Sets wether the color curves effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorCurvesEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraColorGradingEnabled", {
        /**
         * Gets wether the color grading effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorGradingEnabled;
        },
        /**
         * Gets wether the color grading effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorGradingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraToneMappingEnabled", {
        /**
         * Gets wether tonemapping is enabled or not.
         */
        get: function () {
            return this._imageProcessingConfiguration.toneMappingEnabled;
        },
        /**
         * Sets wether tonemapping is enabled or not
         */
        set: function (value) {
            this._imageProcessingConfiguration.toneMappingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraExposure", {
        /**
         * The camera exposure used on this material.
         * This property is here and not in the camera to allow controlling exposure without full screen post process.
         * This corresponds to a photographic exposure.
         */
        get: function () {
            return this._imageProcessingConfiguration.exposure;
        },
        /**
         * The camera exposure used on this material.
         * This property is here and not in the camera to allow controlling exposure without full screen post process.
         * This corresponds to a photographic exposure.
         */
        set: function (value) {
            this._imageProcessingConfiguration.exposure = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraContrast", {
        /**
         * Gets The camera contrast used on this material.
         */
        get: function () {
            return this._imageProcessingConfiguration.contrast;
        },
        /**
         * Sets The camera contrast used on this material.
         */
        set: function (value) {
            this._imageProcessingConfiguration.contrast = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraColorGradingTexture", {
        /**
         * Gets the Color Grading 2D Lookup Texture.
         */
        get: function () {
            return this._imageProcessingConfiguration.colorGradingTexture;
        },
        /**
         * Sets the Color Grading 2D Lookup Texture.
         */
        set: function (value) {
            this._imageProcessingConfiguration.colorGradingTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PBRMaterial.prototype, "cameraColorCurves", {
        /**
         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
         */
        get: function () {
            return this._imageProcessingConfiguration.colorCurves;
        },
        /**
         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
         */
        set: function (value) {
            this._imageProcessingConfiguration.colorCurves = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the name of this material class.
     */
    PBRMaterial.prototype.getClassName = function () {
        return "PBRMaterial";
    };
    /**
     * Makes a duplicate of the current material.
     * @param name - name to use for the new material.
     */
    PBRMaterial.prototype.clone = function (name) {
        var _this = this;
        var clone = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new PBRMaterial(name, _this.getScene()); }, this);
        clone.id = name;
        clone.name = name;
        this.clearCoat.copyTo(clone.clearCoat);
        this.anisotropy.copyTo(clone.anisotropy);
        this.brdf.copyTo(clone.brdf);
        this.sheen.copyTo(clone.sheen);
        return clone;
    };
    /**
     * Serializes this PBR Material.
     * @returns - An object with the serialized material.
     */
    PBRMaterial.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.PBRMaterial";
        serializationObject.clearCoat = this.clearCoat.serialize();
        serializationObject.anisotropy = this.anisotropy.serialize();
        serializationObject.brdf = this.brdf.serialize();
        serializationObject.sheen = this.sheen.serialize();
        serializationObject.subSurface = this.subSurface.serialize();
        return serializationObject;
    };
    // Statics
    /**
     * Parses a PBR Material from a serialized object.
     * @param source - Serialized object.
     * @param scene - BJS scene instance.
     * @param rootUrl - url for the scene object
     * @returns - PBRMaterial
     */
    PBRMaterial.Parse = function (source, scene, rootUrl) {
        var material = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new PBRMaterial(source.name, scene); }, source, scene, rootUrl);
        if (source.clearCoat) {
            material.clearCoat.parse(source.clearCoat, scene, rootUrl);
        }
        if (source.anisotropy) {
            material.anisotropy.parse(source.anisotropy, scene, rootUrl);
        }
        if (source.brdf) {
            material.brdf.parse(source.brdf, scene, rootUrl);
        }
        if (source.sheen) {
            material.sheen.parse(source.sheen, scene, rootUrl);
        }
        if (source.subSurface) {
            material.subSurface.parse(source.subSurface, scene, rootUrl);
        }
        return material;
    };
    /**
     * PBRMaterialTransparencyMode: No transparency mode, Alpha channel is not use.
     */
    PBRMaterial.PBRMATERIAL_OPAQUE = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].PBRMATERIAL_OPAQUE;
    /**
     * PBRMaterialTransparencyMode: Alpha Test mode, pixel are discarded below a certain threshold defined by the alpha cutoff value.
     */
    PBRMaterial.PBRMATERIAL_ALPHATEST = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].PBRMATERIAL_ALPHATEST;
    /**
     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
     */
    PBRMaterial.PBRMATERIAL_ALPHABLEND = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].PBRMATERIAL_ALPHABLEND;
    /**
     * PBRMaterialTransparencyMode: Pixels are blended (according to the alpha mode) with the already drawn pixels in the current frame buffer.
     * They are also discarded below the alpha cutoff threshold to improve performances.
     */
    PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].PBRMATERIAL_ALPHATESTANDBLEND;
    /**
     * Defines the default value of how much AO map is occluding the analytical lights
     * (point spot...).
     */
    PBRMaterial.DEFAULT_AO_ON_ANALYTICAL_LIGHTS = _pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"].DEFAULT_AO_ON_ANALYTICAL_LIGHTS;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "directIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "emissiveIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "environmentIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "specularIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "disableBumpMap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "albedoTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "ambientTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "ambientTextureStrength", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "ambientTextureImpactOnAnalyticalLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesAndMiscDirty")
    ], PBRMaterial.prototype, "opacityTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "reflectionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "emissiveTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "reflectivityTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "metallicTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "metallic", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "roughness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "microSurfaceTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "bumpTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", null)
    ], PBRMaterial.prototype, "lightmapTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("ambient"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "ambientColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("albedo"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "albedoColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("reflectivity"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "reflectivityColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("reflection"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "reflectionColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("emissive"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "emissiveColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "microSurface", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useLightmapAsShadowmap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesAndMiscDirty")
    ], PBRMaterial.prototype, "useAlphaFromAlbedoTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesAndMiscDirty")
    ], PBRMaterial.prototype, "forceAlphaTest", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesAndMiscDirty")
    ], PBRMaterial.prototype, "alphaCutOff", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useSpecularOverAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useMicroSurfaceFromReflectivityMapAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useRoughnessFromMetallicTextureAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useRoughnessFromMetallicTextureGreen", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useMetallnessFromMetallicTextureBlue", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useAmbientOcclusionFromMetallicTextureRed", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useAmbientInGrayScale", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useAutoMicroSurfaceFromReflectivityMap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRMaterial.prototype, "usePhysicalLightFalloff", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRMaterial.prototype, "useGLTFLightFalloff", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useRadianceOverAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useObjectSpaceNormalMap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useParallax", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useParallaxOcclusion", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "parallaxScaleBias", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], PBRMaterial.prototype, "disableLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "forceIrradianceInFragment", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], PBRMaterial.prototype, "maxSimultaneousLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "invertNormalMapX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "invertNormalMapY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "twoSidedLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useAlphaFresnel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useLinearAlphaFresnel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "environmentBRDFTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "forceNormalForward", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "enableSpecularAntiAliasing", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useHorizonOcclusion", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMaterial.prototype, "useRadianceOcclusion", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsMiscDirty")
    ], PBRMaterial.prototype, "unlit", void 0);
    return PBRMaterial;
}(_pbrBaseMaterial__WEBPACK_IMPORTED_MODULE_4__["PBRBaseMaterial"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTypes["BABYLON.PBRMaterial"] = PBRMaterial;


/***/ }),

/***/ "./Materials/PBR/pbrMetallicRoughnessMaterial.ts":
/*!*******************************************************!*\
  !*** ./Materials/PBR/pbrMetallicRoughnessMaterial.ts ***!
  \*******************************************************/
/*! exports provided: PBRMetallicRoughnessMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRMetallicRoughnessMaterial", function() { return PBRMetallicRoughnessMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _pbrBaseSimpleMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./pbrBaseSimpleMaterial */ "./Materials/PBR/pbrBaseSimpleMaterial.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");




/**
 * The PBR material of BJS following the metal roughness convention.
 *
 * This fits to the PBR convention in the GLTF definition:
 * https://github.com/KhronosGroup/glTF/tree/2.0/specification/2.0
 */
var PBRMetallicRoughnessMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PBRMetallicRoughnessMaterial, _super);
    /**
     * Instantiates a new PBRMetalRoughnessMaterial instance.
     *
     * @param name The material name
     * @param scene The scene the material will be use in.
     */
    function PBRMetallicRoughnessMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._useRoughnessFromMetallicTextureAlpha = false;
        _this._useRoughnessFromMetallicTextureGreen = true;
        _this._useMetallnessFromMetallicTextureBlue = true;
        _this.metallic = 1.0;
        _this.roughness = 1.0;
        return _this;
    }
    /**
     * Return the currrent class name of the material.
     */
    PBRMetallicRoughnessMaterial.prototype.getClassName = function () {
        return "PBRMetallicRoughnessMaterial";
    };
    /**
     * Makes a duplicate of the current material.
     * @param name - name to use for the new material.
     */
    PBRMetallicRoughnessMaterial.prototype.clone = function (name) {
        var _this = this;
        var clone = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new PBRMetallicRoughnessMaterial(name, _this.getScene()); }, this);
        clone.id = name;
        clone.name = name;
        this.clearCoat.copyTo(clone.clearCoat);
        this.anisotropy.copyTo(clone.anisotropy);
        this.brdf.copyTo(clone.brdf);
        this.sheen.copyTo(clone.sheen);
        return clone;
    };
    /**
     * Serialize the material to a parsable JSON object.
     */
    PBRMetallicRoughnessMaterial.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.PBRMetallicRoughnessMaterial";
        serializationObject.clearCoat = this.clearCoat.serialize();
        serializationObject.anisotropy = this.anisotropy.serialize();
        serializationObject.brdf = this.brdf.serialize();
        serializationObject.sheen = this.sheen.serialize();
        serializationObject.subSurface = this.subSurface.serialize();
        return serializationObject;
    };
    /**
     * Parses a JSON object correponding to the serialize function.
     */
    PBRMetallicRoughnessMaterial.Parse = function (source, scene, rootUrl) {
        var material = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new PBRMetallicRoughnessMaterial(source.name, scene); }, source, scene, rootUrl);
        if (source.clearCoat) {
            material.clearCoat.parse(source.clearCoat, scene, rootUrl);
        }
        if (source.anisotropy) {
            material.anisotropy.parse(source.anisotropy, scene, rootUrl);
        }
        if (source.brdf) {
            material.brdf.parse(source.brdf, scene, rootUrl);
        }
        if (source.sheen) {
            material.sheen.parse(source.sheen, scene, rootUrl);
        }
        if (source.subSurface) {
            material.subSurface.parse(source.subSurface, scene, rootUrl);
        }
        return material;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_albedoColor")
    ], PBRMetallicRoughnessMaterial.prototype, "baseColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_albedoTexture")
    ], PBRMetallicRoughnessMaterial.prototype, "baseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMetallicRoughnessMaterial.prototype, "metallic", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRMetallicRoughnessMaterial.prototype, "roughness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_metallicTexture")
    ], PBRMetallicRoughnessMaterial.prototype, "metallicRoughnessTexture", void 0);
    return PBRMetallicRoughnessMaterial;
}(_pbrBaseSimpleMaterial__WEBPACK_IMPORTED_MODULE_2__["PBRBaseSimpleMaterial"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.PBRMetallicRoughnessMaterial"] = PBRMetallicRoughnessMaterial;


/***/ }),

/***/ "./Materials/PBR/pbrSheenConfiguration.ts":
/*!************************************************!*\
  !*** ./Materials/PBR/pbrSheenConfiguration.ts ***!
  \************************************************/
/*! exports provided: PBRSheenConfiguration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRSheenConfiguration", function() { return PBRSheenConfiguration; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");





/**
 * Define the code related to the Sheen parameters of the pbr material.
 */
var PBRSheenConfiguration = /** @class */ (function () {
    /**
     * Instantiate a new istance of clear coat configuration.
     * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
     */
    function PBRSheenConfiguration(markAllSubMeshesAsTexturesDirty) {
        this._isEnabled = false;
        /**
         * Defines if the material uses sheen.
         */
        this.isEnabled = false;
        this._linkSheenWithAlbedo = false;
        /**
         * Defines if the sheen is linked to the sheen color.
         */
        this.linkSheenWithAlbedo = false;
        /**
         * Defines the sheen intensity.
         */
        this.intensity = 1;
        /**
         * Defines the sheen color.
         */
        this.color = _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"].White();
        this._texture = null;
        /**
         * Stores the sheen tint values in a texture.
         * rgb is tint
         * a is a intensity
         */
        this.texture = null;
        this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
    }
    /** @hidden */
    PBRSheenConfiguration.prototype._markAllSubMeshesAsTexturesDirty = function () {
        this._internalMarkAllSubMeshesAsTexturesDirty();
    };
    /**
     * Specifies that the submesh is ready to be used.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene the material belongs to.
     * @returns - boolean indicating that the submesh is ready or not.
     */
    PBRSheenConfiguration.prototype.isReadyForSubMesh = function (defines, scene) {
        if (defines._areTexturesDirty) {
            if (scene.texturesEnabled) {
                if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].SheenTextureEnabled) {
                    if (!this._texture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
            }
        }
        return true;
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene the material belongs to.
     */
    PBRSheenConfiguration.prototype.prepareDefines = function (defines, scene) {
        if (this._isEnabled) {
            defines.SHEEN = this._isEnabled;
            defines.SHEEN_LINKWITHALBEDO = this._linkSheenWithAlbedo;
            if (defines._areTexturesDirty) {
                if (scene.texturesEnabled) {
                    if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].SheenTextureEnabled) {
                        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForMergedUV(this._texture, defines, "SHEEN_TEXTURE");
                    }
                    else {
                        defines.SHEEN_TEXTURE = false;
                    }
                }
            }
        }
        else {
            defines.SHEEN = false;
            defines.SHEEN_TEXTURE = false;
            defines.SHEEN_LINKWITHALBEDO = false;
        }
    };
    /**
     * Binds the material data.
     * @param uniformBuffer defines the Uniform buffer to fill in.
     * @param scene defines the scene the material belongs to.
     * @param isFrozen defines wether the material is frozen or not.
     */
    PBRSheenConfiguration.prototype.bindForSubMesh = function (uniformBuffer, scene, isFrozen) {
        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
            if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].SheenTextureEnabled) {
                uniformBuffer.updateFloat2("vSheenInfos", this._texture.coordinatesIndex, this._texture.level);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindTextureMatrix(this._texture, uniformBuffer, "sheen");
            }
            // Sheen
            uniformBuffer.updateFloat4("vSheenColor", this.color.r, this.color.g, this.color.b, this.intensity);
        }
        // Textures
        if (scene.texturesEnabled) {
            if (this._texture && _Materials_materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].SheenTextureEnabled) {
                uniformBuffer.setTexture("sheenSampler", this._texture);
            }
        }
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param texture - Base texture to use.
     * @returns - Boolean specifying if a texture is used in the material.
     */
    PBRSheenConfiguration.prototype.hasTexture = function (texture) {
        if (this._texture === texture) {
            return true;
        }
        return false;
    };
    /**
     * Returns an array of the actively used textures.
     * @param activeTextures Array of BaseTextures
     */
    PBRSheenConfiguration.prototype.getActiveTextures = function (activeTextures) {
        if (this._texture) {
            activeTextures.push(this._texture);
        }
    };
    /**
     * Returns the animatable textures.
     * @param animatables Array of animatable textures.
     */
    PBRSheenConfiguration.prototype.getAnimatables = function (animatables) {
        if (this._texture && this._texture.animations && this._texture.animations.length > 0) {
            animatables.push(this._texture);
        }
    };
    /**
     * Disposes the resources of the material.
     * @param forceDisposeTextures - Forces the disposal of all textures.
     */
    PBRSheenConfiguration.prototype.dispose = function (forceDisposeTextures) {
        if (forceDisposeTextures) {
            if (this._texture) {
                this._texture.dispose();
            }
        }
    };
    /**
    * Get the current class name of the texture useful for serialization or dynamic coding.
    * @returns "PBRSheenConfiguration"
    */
    PBRSheenConfiguration.prototype.getClassName = function () {
        return "PBRSheenConfiguration";
    };
    /**
     * Add fallbacks to the effect fallbacks list.
     * @param defines defines the Base texture to use.
     * @param fallbacks defines the current fallback list.
     * @param currentRank defines the current fallback rank.
     * @returns the new fallback rank.
     */
    PBRSheenConfiguration.AddFallbacks = function (defines, fallbacks, currentRank) {
        if (defines.SHEEN) {
            fallbacks.addFallback(currentRank++, "SHEEN");
        }
        return currentRank;
    };
    /**
     * Add the required uniforms to the current list.
     * @param uniforms defines the current uniform list.
     */
    PBRSheenConfiguration.AddUniforms = function (uniforms) {
        uniforms.push("vSheenColor", "vSheenInfos", "sheenMatrix");
    };
    /**
     * Add the required uniforms to the current buffer.
     * @param uniformBuffer defines the current uniform buffer.
     */
    PBRSheenConfiguration.PrepareUniformBuffer = function (uniformBuffer) {
        uniformBuffer.addUniform("vSheenColor", 4);
        uniformBuffer.addUniform("vSheenInfos", 2);
        uniformBuffer.addUniform("sheenMatrix", 16);
    };
    /**
     * Add the required samplers to the current list.
     * @param samplers defines the current sampler list.
     */
    PBRSheenConfiguration.AddSamplers = function (samplers) {
        samplers.push("sheenSampler");
    };
    /**
     * Makes a duplicate of the current configuration into another one.
     * @param sheenConfiguration define the config where to copy the info
     */
    PBRSheenConfiguration.prototype.copyTo = function (sheenConfiguration) {
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return sheenConfiguration; }, this);
    };
    /**
     * Serializes this BRDF configuration.
     * @returns - An object with the serialized config.
     */
    PBRSheenConfiguration.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses a anisotropy Configuration from a serialized object.
     * @param source - Serialized object.
     * @param scene Defines the scene we are parsing for
     * @param rootUrl Defines the rootUrl to load from
     */
    PBRSheenConfiguration.prototype.parse = function (source, scene, rootUrl) {
        var _this = this;
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return _this; }, source, scene, rootUrl);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSheenConfiguration.prototype, "isEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSheenConfiguration.prototype, "linkSheenWithAlbedo", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSheenConfiguration.prototype, "intensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], PBRSheenConfiguration.prototype, "color", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSheenConfiguration.prototype, "texture", void 0);
    return PBRSheenConfiguration;
}());



/***/ }),

/***/ "./Materials/PBR/pbrSpecularGlossinessMaterial.ts":
/*!********************************************************!*\
  !*** ./Materials/PBR/pbrSpecularGlossinessMaterial.ts ***!
  \********************************************************/
/*! exports provided: PBRSpecularGlossinessMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRSpecularGlossinessMaterial", function() { return PBRSpecularGlossinessMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _pbrBaseSimpleMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./pbrBaseSimpleMaterial */ "./Materials/PBR/pbrBaseSimpleMaterial.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");




/**
 * The PBR material of BJS following the specular glossiness convention.
 *
 * This fits to the PBR convention in the GLTF definition:
 * https://github.com/KhronosGroup/glTF/tree/2.0/extensions/Khronos/KHR_materials_pbrSpecularGlossiness
 */
var PBRSpecularGlossinessMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PBRSpecularGlossinessMaterial, _super);
    /**
     * Instantiates a new PBRSpecularGlossinessMaterial instance.
     *
     * @param name The material name
     * @param scene The scene the material will be use in.
     */
    function PBRSpecularGlossinessMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._useMicroSurfaceFromReflectivityMapAlpha = true;
        return _this;
    }
    /**
     * Return the currrent class name of the material.
     */
    PBRSpecularGlossinessMaterial.prototype.getClassName = function () {
        return "PBRSpecularGlossinessMaterial";
    };
    /**
     * Makes a duplicate of the current material.
     * @param name - name to use for the new material.
     */
    PBRSpecularGlossinessMaterial.prototype.clone = function (name) {
        var _this = this;
        var clone = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new PBRSpecularGlossinessMaterial(name, _this.getScene()); }, this);
        clone.id = name;
        clone.name = name;
        this.clearCoat.copyTo(clone.clearCoat);
        this.anisotropy.copyTo(clone.anisotropy);
        this.brdf.copyTo(clone.brdf);
        this.sheen.copyTo(clone.sheen);
        return clone;
    };
    /**
     * Serialize the material to a parsable JSON object.
     */
    PBRSpecularGlossinessMaterial.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.PBRSpecularGlossinessMaterial";
        serializationObject.clearCoat = this.clearCoat.serialize();
        serializationObject.anisotropy = this.anisotropy.serialize();
        serializationObject.brdf = this.brdf.serialize();
        serializationObject.sheen = this.sheen.serialize();
        serializationObject.subSurface = this.subSurface.serialize();
        return serializationObject;
    };
    /**
     * Parses a JSON object correponding to the serialize function.
     */
    PBRSpecularGlossinessMaterial.Parse = function (source, scene, rootUrl) {
        var material = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new PBRSpecularGlossinessMaterial(source.name, scene); }, source, scene, rootUrl);
        if (source.clearCoat) {
            material.clearCoat.parse(source.clearCoat, scene, rootUrl);
        }
        if (source.anisotropy) {
            material.anisotropy.parse(source.anisotropy, scene, rootUrl);
        }
        if (source.brdf) {
            material.brdf.parse(source.brdf, scene, rootUrl);
        }
        if (source.sheen) {
            material.sheen.parse(source.sheen, scene, rootUrl);
        }
        if (source.subSurface) {
            material.subSurface.parse(source.subSurface, scene, rootUrl);
        }
        return material;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("diffuse"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_albedoColor")
    ], PBRSpecularGlossinessMaterial.prototype, "diffuseColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_albedoTexture")
    ], PBRSpecularGlossinessMaterial.prototype, "diffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("specular"),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_reflectivityColor")
    ], PBRSpecularGlossinessMaterial.prototype, "specularColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_microSurface")
    ], PBRSpecularGlossinessMaterial.prototype, "glossiness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty", "_reflectivityTexture")
    ], PBRSpecularGlossinessMaterial.prototype, "specularGlossinessTexture", void 0);
    return PBRSpecularGlossinessMaterial;
}(_pbrBaseSimpleMaterial__WEBPACK_IMPORTED_MODULE_2__["PBRBaseSimpleMaterial"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.PBRSpecularGlossinessMaterial"] = PBRSpecularGlossinessMaterial;


/***/ }),

/***/ "./Materials/PBR/pbrSubSurfaceConfiguration.ts":
/*!*****************************************************!*\
  !*** ./Materials/PBR/pbrSubSurfaceConfiguration.ts ***!
  \*****************************************************/
/*! exports provided: PBRSubSurfaceConfiguration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PBRSubSurfaceConfiguration", function() { return PBRSubSurfaceConfiguration; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _materialFlags__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/materialHelper */ "./Materials/materialHelper.ts");





/**
 * Define the code related to the sub surface parameters of the pbr material.
 */
var PBRSubSurfaceConfiguration = /** @class */ (function () {
    /**
     * Instantiate a new istance of sub surface configuration.
     * @param markAllSubMeshesAsTexturesDirty Callback to flag the material to dirty
     */
    function PBRSubSurfaceConfiguration(markAllSubMeshesAsTexturesDirty) {
        this._isRefractionEnabled = false;
        /**
         * Defines if the refraction is enabled in the material.
         */
        this.isRefractionEnabled = false;
        this._isTranslucencyEnabled = false;
        /**
         * Defines if the translucency is enabled in the material.
         */
        this.isTranslucencyEnabled = false;
        this._isScatteringEnabled = false;
        // /**
        //  * Defines if the sub surface scattering is enabled in the material.
        //  */
        // @serialize()
        // @expandToProperty("_markAllSubMeshesAsTexturesDirty")
        // public isScatteringEnabled = false;
        /**
         * Defines the refraction intensity of the material.
         * The refraction when enabled replaces the Diffuse part of the material.
         * The intensity helps transitionning between diffuse and refraction.
         */
        this.refractionIntensity = 1;
        /**
         * Defines the translucency intensity of the material.
         * When translucency has been enabled, this defines how much of the "translucency"
         * is addded to the diffuse part of the material.
         */
        this.translucencyIntensity = 1;
        /**
         * Defines the scattering intensity of the material.
         * When scattering has been enabled, this defines how much of the "scattered light"
         * is addded to the diffuse part of the material.
         */
        this.scatteringIntensity = 1;
        this._thicknessTexture = null;
        /**
         * Stores the average thickness of a mesh in a texture (The texture is holding the values linearly).
         * The red channel of the texture should contain the thickness remapped between 0 and 1.
         * 0 would mean minimumThickness
         * 1 would mean maximumThickness
         * The other channels might be use as a mask to vary the different effects intensity.
         */
        this.thicknessTexture = null;
        this._refractionTexture = null;
        /**
         * Defines the texture to use for refraction.
         */
        this.refractionTexture = null;
        this._indexOfRefraction = 1;
        /**
         * Defines the index of refraction used in the material.
         * https://en.wikipedia.org/wiki/List_of_refractive_indices
         */
        this.indexOfRefraction = 1;
        this._invertRefractionY = false;
        /**
         * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
         */
        this.invertRefractionY = false;
        this._linkRefractionWithTransparency = false;
        /**
         * This parameters will make the material used its opacity to control how much it is refracting aginst not.
         * Materials half opaque for instance using refraction could benefit from this control.
         */
        this.linkRefractionWithTransparency = false;
        /**
         * Defines the minimum thickness stored in the thickness map.
         * If no thickness map is defined, this value will be used to simulate thickness.
         */
        this.minimumThickness = 0;
        /**
         * Defines the maximum thickness stored in the thickness map.
         */
        this.maximumThickness = 1;
        /**
         * Defines the volume tint of the material.
         * This is used for both translucency and scattering.
         */
        this.tintColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"].White();
        /**
         * Defines the distance at which the tint color should be found in the media.
         * This is used for refraction only.
         */
        this.tintColorAtDistance = 1;
        /**
         * Defines how far each channel transmit through the media.
         * It is defined as a color to simplify it selection.
         */
        this.diffusionDistance = _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color3"].White();
        this._useMaskFromThicknessTexture = false;
        /**
         * Stores the intensity of the different subsurface effects in the thickness texture.
         * * the green channel is the translucency intensity.
         * * the blue channel is the scattering intensity.
         * * the alpha channel is the refraction intensity.
         */
        this.useMaskFromThicknessTexture = false;
        this._internalMarkAllSubMeshesAsTexturesDirty = markAllSubMeshesAsTexturesDirty;
    }
    /** @hidden */
    PBRSubSurfaceConfiguration.prototype._markAllSubMeshesAsTexturesDirty = function () {
        this._internalMarkAllSubMeshesAsTexturesDirty();
    };
    /**
     * Gets wehter the submesh is ready to be used or not.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene the material belongs to.
     * @returns - boolean indicating that the submesh is ready or not.
     */
    PBRSubSurfaceConfiguration.prototype.isReadyForSubMesh = function (defines, scene) {
        if (defines._areTexturesDirty) {
            if (scene.texturesEnabled) {
                if (this._thicknessTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ThicknessTextureEnabled) {
                    if (!this._thicknessTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
                var refractionTexture = this._getRefractionTexture(scene);
                if (refractionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].RefractionTextureEnabled) {
                    if (!refractionTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                }
            }
        }
        return true;
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param defines the list of "defines" to update.
     * @param scene defines the scene to the material belongs to.
     */
    PBRSubSurfaceConfiguration.prototype.prepareDefines = function (defines, scene) {
        if (defines._areTexturesDirty) {
            defines.SUBSURFACE = false;
            defines.SS_TRANSLUCENCY = this._isTranslucencyEnabled;
            defines.SS_SCATERRING = this._isScatteringEnabled;
            defines.SS_THICKNESSANDMASK_TEXTURE = false;
            defines.SS_MASK_FROM_THICKNESS_TEXTURE = false;
            defines.SS_REFRACTION = false;
            defines.SS_REFRACTIONMAP_3D = false;
            defines.SS_GAMMAREFRACTION = false;
            defines.SS_RGBDREFRACTION = false;
            defines.SS_LINEARSPECULARREFRACTION = false;
            defines.SS_REFRACTIONMAP_OPPOSITEZ = false;
            defines.SS_LODINREFRACTIONALPHA = false;
            defines.SS_LINKREFRACTIONTOTRANSPARENCY = false;
            if (this._isRefractionEnabled || this._isTranslucencyEnabled || this._isScatteringEnabled) {
                defines.SUBSURFACE = true;
                if (defines._areTexturesDirty) {
                    if (scene.texturesEnabled) {
                        if (this._thicknessTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ThicknessTextureEnabled) {
                            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].PrepareDefinesForMergedUV(this._thicknessTexture, defines, "SS_THICKNESSANDMASK_TEXTURE");
                        }
                    }
                }
                defines.SS_MASK_FROM_THICKNESS_TEXTURE = this._useMaskFromThicknessTexture;
            }
            if (this._isRefractionEnabled) {
                if (scene.texturesEnabled) {
                    var refractionTexture = this._getRefractionTexture(scene);
                    if (refractionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].RefractionTextureEnabled) {
                        defines.SS_REFRACTION = true;
                        defines.SS_REFRACTIONMAP_3D = refractionTexture.isCube;
                        defines.SS_GAMMAREFRACTION = refractionTexture.gammaSpace;
                        defines.SS_RGBDREFRACTION = refractionTexture.isRGBD;
                        defines.SS_LINEARSPECULARREFRACTION = refractionTexture.linearSpecularLOD;
                        defines.SS_REFRACTIONMAP_OPPOSITEZ = refractionTexture.invertZ;
                        defines.SS_LODINREFRACTIONALPHA = refractionTexture.lodLevelInAlpha;
                        defines.SS_LINKREFRACTIONTOTRANSPARENCY = this._linkRefractionWithTransparency;
                    }
                }
            }
        }
    };
    /**
     * Binds the material data.
     * @param uniformBuffer defines the Uniform buffer to fill in.
     * @param scene defines the scene the material belongs to.
     * @param engine defines the engine the material belongs to.
     * @param isFrozen defines wether the material is frozen or not.
     * @param lodBasedMicrosurface defines wether the material relies on lod based microsurface or not.
     */
    PBRSubSurfaceConfiguration.prototype.bindForSubMesh = function (uniformBuffer, scene, engine, isFrozen, lodBasedMicrosurface) {
        var refractionTexture = this._getRefractionTexture(scene);
        if (!uniformBuffer.useUbo || !isFrozen || !uniformBuffer.isSync) {
            if (this._thicknessTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ThicknessTextureEnabled) {
                uniformBuffer.updateFloat2("vThicknessInfos", this._thicknessTexture.coordinatesIndex, this._thicknessTexture.level);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_4__["MaterialHelper"].BindTextureMatrix(this._thicknessTexture, uniformBuffer, "thickness");
            }
            uniformBuffer.updateFloat2("vThicknessParam", this.minimumThickness, this.maximumThickness - this.minimumThickness);
            if (refractionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].RefractionTextureEnabled) {
                uniformBuffer.updateMatrix("refractionMatrix", refractionTexture.getReflectionTextureMatrix());
                var depth = 1.0;
                if (!refractionTexture.isCube) {
                    if (refractionTexture.depth) {
                        depth = refractionTexture.depth;
                    }
                }
                uniformBuffer.updateFloat4("vRefractionInfos", refractionTexture.level, 1 / this._indexOfRefraction, depth, this._invertRefractionY ? -1 : 1);
                uniformBuffer.updateFloat3("vRefractionMicrosurfaceInfos", refractionTexture.getSize().width, refractionTexture.lodGenerationScale, refractionTexture.lodGenerationOffset);
            }
            uniformBuffer.updateColor3("vDiffusionDistance", this.diffusionDistance);
            uniformBuffer.updateFloat4("vTintColor", this.tintColor.r, this.tintColor.g, this.tintColor.b, this.tintColorAtDistance);
            uniformBuffer.updateFloat3("vSubSurfaceIntensity", this.refractionIntensity, this.translucencyIntensity, this.scatteringIntensity);
        }
        // Textures
        if (scene.texturesEnabled) {
            if (this._thicknessTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].ThicknessTextureEnabled) {
                uniformBuffer.setTexture("thicknessSampler", this._thicknessTexture);
            }
            if (refractionTexture && _materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].RefractionTextureEnabled) {
                if (lodBasedMicrosurface) {
                    uniformBuffer.setTexture("refractionSampler", refractionTexture);
                }
                else {
                    uniformBuffer.setTexture("refractionSampler", refractionTexture._lodTextureMid || refractionTexture);
                    uniformBuffer.setTexture("refractionSamplerLow", refractionTexture._lodTextureLow || refractionTexture);
                    uniformBuffer.setTexture("refractionSamplerHigh", refractionTexture._lodTextureHigh || refractionTexture);
                }
            }
        }
    };
    /**
     * Unbinds the material from the mesh.
     * @param activeEffect defines the effect that should be unbound from.
     * @returns true if unbound, otherwise false
     */
    PBRSubSurfaceConfiguration.prototype.unbind = function (activeEffect) {
        if (this._refractionTexture && this._refractionTexture.isRenderTarget) {
            activeEffect.setTexture("refractionSampler", null);
            return true;
        }
        return false;
    };
    /**
     * Returns the texture used for refraction or null if none is used.
     * @param scene defines the scene the material belongs to.
     * @returns - Refraction texture if present.  If no refraction texture and refraction
     * is linked with transparency, returns environment texture.  Otherwise, returns null.
     */
    PBRSubSurfaceConfiguration.prototype._getRefractionTexture = function (scene) {
        if (this._refractionTexture) {
            return this._refractionTexture;
        }
        if (this._isRefractionEnabled) {
            return scene.environmentTexture;
        }
        return null;
    };
    Object.defineProperty(PBRSubSurfaceConfiguration.prototype, "disableAlphaBlending", {
        /**
         * Returns true if alpha blending should be disabled.
         */
        get: function () {
            return this.isRefractionEnabled && this._linkRefractionWithTransparency;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Fills the list of render target textures.
     * @param renderTargets the list of render targets to update
     */
    PBRSubSurfaceConfiguration.prototype.fillRenderTargetTextures = function (renderTargets) {
        if (_materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
            renderTargets.push(this._refractionTexture);
        }
    };
    /**
     * Checks to see if a texture is used in the material.
     * @param texture - Base texture to use.
     * @returns - Boolean specifying if a texture is used in the material.
     */
    PBRSubSurfaceConfiguration.prototype.hasTexture = function (texture) {
        if (this._thicknessTexture === texture) {
            return true;
        }
        if (this._refractionTexture === texture) {
            return true;
        }
        return false;
    };
    /**
     * Gets a boolean indicating that current material needs to register RTT
     * @returns true if this uses a render target otherwise false.
     */
    PBRSubSurfaceConfiguration.prototype.hasRenderTargetTextures = function () {
        if (_materialFlags__WEBPACK_IMPORTED_MODULE_3__["MaterialFlags"].RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
            return true;
        }
        return false;
    };
    /**
     * Returns an array of the actively used textures.
     * @param activeTextures Array of BaseTextures
     */
    PBRSubSurfaceConfiguration.prototype.getActiveTextures = function (activeTextures) {
        if (this._thicknessTexture) {
            activeTextures.push(this._thicknessTexture);
        }
        if (this._refractionTexture) {
            activeTextures.push(this._refractionTexture);
        }
    };
    /**
     * Returns the animatable textures.
     * @param animatables Array of animatable textures.
     */
    PBRSubSurfaceConfiguration.prototype.getAnimatables = function (animatables) {
        if (this._thicknessTexture && this._thicknessTexture.animations && this._thicknessTexture.animations.length > 0) {
            animatables.push(this._thicknessTexture);
        }
        if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) {
            animatables.push(this._refractionTexture);
        }
    };
    /**
     * Disposes the resources of the material.
     * @param forceDisposeTextures - Forces the disposal of all textures.
     */
    PBRSubSurfaceConfiguration.prototype.dispose = function (forceDisposeTextures) {
        if (forceDisposeTextures) {
            if (this._thicknessTexture) {
                this._thicknessTexture.dispose();
            }
            if (this._refractionTexture) {
                this._refractionTexture.dispose();
            }
        }
    };
    /**
    * Get the current class name of the texture useful for serialization or dynamic coding.
    * @returns "PBRSubSurfaceConfiguration"
    */
    PBRSubSurfaceConfiguration.prototype.getClassName = function () {
        return "PBRSubSurfaceConfiguration";
    };
    /**
     * Add fallbacks to the effect fallbacks list.
     * @param defines defines the Base texture to use.
     * @param fallbacks defines the current fallback list.
     * @param currentRank defines the current fallback rank.
     * @returns the new fallback rank.
     */
    PBRSubSurfaceConfiguration.AddFallbacks = function (defines, fallbacks, currentRank) {
        if (defines.SS_SCATERRING) {
            fallbacks.addFallback(currentRank++, "SS_SCATERRING");
        }
        if (defines.SS_TRANSLUCENCY) {
            fallbacks.addFallback(currentRank++, "SS_TRANSLUCENCY");
        }
        return currentRank;
    };
    /**
     * Add the required uniforms to the current list.
     * @param uniforms defines the current uniform list.
     */
    PBRSubSurfaceConfiguration.AddUniforms = function (uniforms) {
        uniforms.push("vDiffusionDistance", "vTintColor", "vSubSurfaceIntensity", "vRefractionMicrosurfaceInfos", "vRefractionInfos", "vThicknessInfos", "vThicknessParam", "refractionMatrix", "thicknessMatrix");
    };
    /**
     * Add the required samplers to the current list.
     * @param samplers defines the current sampler list.
     */
    PBRSubSurfaceConfiguration.AddSamplers = function (samplers) {
        samplers.push("thicknessSampler", "refractionSampler", "refractionSamplerLow", "refractionSamplerHigh");
    };
    /**
     * Add the required uniforms to the current buffer.
     * @param uniformBuffer defines the current uniform buffer.
     */
    PBRSubSurfaceConfiguration.PrepareUniformBuffer = function (uniformBuffer) {
        uniformBuffer.addUniform("vRefractionMicrosurfaceInfos", 3);
        uniformBuffer.addUniform("vRefractionInfos", 4);
        uniformBuffer.addUniform("refractionMatrix", 16);
        uniformBuffer.addUniform("vThicknessInfos", 2);
        uniformBuffer.addUniform("thicknessMatrix", 16);
        uniformBuffer.addUniform("vThicknessParam", 2);
        uniformBuffer.addUniform("vDiffusionDistance", 3);
        uniformBuffer.addUniform("vTintColor", 4);
        uniformBuffer.addUniform("vSubSurfaceIntensity", 3);
    };
    /**
     * Makes a duplicate of the current configuration into another one.
     * @param configuration define the config where to copy the info
     */
    PBRSubSurfaceConfiguration.prototype.copyTo = function (configuration) {
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return configuration; }, this);
    };
    /**
     * Serializes this Sub Surface configuration.
     * @returns - An object with the serialized config.
     */
    PBRSubSurfaceConfiguration.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses a anisotropy Configuration from a serialized object.
     * @param source - Serialized object.
     * @param scene Defines the scene we are parsing for
     * @param rootUrl Defines the rootUrl to load from
     */
    PBRSubSurfaceConfiguration.prototype.parse = function (source, scene, rootUrl) {
        var _this = this;
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return _this; }, source, scene, rootUrl);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "isRefractionEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "isTranslucencyEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSubSurfaceConfiguration.prototype, "refractionIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSubSurfaceConfiguration.prototype, "translucencyIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSubSurfaceConfiguration.prototype, "scatteringIntensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "thicknessTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "refractionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "indexOfRefraction", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "invertRefractionY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "linkRefractionWithTransparency", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSubSurfaceConfiguration.prototype, "minimumThickness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSubSurfaceConfiguration.prototype, "maximumThickness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], PBRSubSurfaceConfiguration.prototype, "tintColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], PBRSubSurfaceConfiguration.prototype, "tintColorAtDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
    ], PBRSubSurfaceConfiguration.prototype, "diffusionDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])(),
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], PBRSubSurfaceConfiguration.prototype, "useMaskFromThicknessTexture", void 0);
    return PBRSubSurfaceConfiguration;
}());



/***/ }),

/***/ "./Materials/Textures/Loaders/basisTextureLoader.ts":
/*!**********************************************************!*\
  !*** ./Materials/Textures/Loaders/basisTextureLoader.ts ***!
  \**********************************************************/
/*! exports provided: _BasisTextureLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_BasisTextureLoader", function() { return _BasisTextureLoader; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Misc_basis__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Misc/basis */ "./Misc/basis.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Misc/tools */ "./Misc/tools.ts");



/**
 * Loader for .basis file format
 */
var _BasisTextureLoader = /** @class */ (function () {
    function _BasisTextureLoader() {
        /**
         * Defines whether the loader supports cascade loading the different faces.
         */
        this.supportCascades = true;
    }
    /**
     * This returns if the loader support the current file information.
     * @param extension defines the file extension of the file being loaded
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @param fallback defines the fallback internal texture if any
     * @param isBase64 defines whether the texture is encoded as a base64
     * @param isBuffer defines whether the texture data are stored as a buffer
     * @returns true if the loader can load the specified file
     */
    _BasisTextureLoader.prototype.canLoad = function (extension, textureFormatInUse, fallback, isBase64, isBuffer) {
        return extension.indexOf(".basis") === 0;
    };
    /**
     * Transform the url before loading if required.
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the transformed texture
     */
    _BasisTextureLoader.prototype.transformUrl = function (rootUrl, textureFormatInUse) {
        return rootUrl;
    };
    /**
     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the fallback texture
     */
    _BasisTextureLoader.prototype.getFallbackTextureUrl = function (rootUrl, textureFormatInUse) {
        return null;
    };
    /**
     * Uploads the cube texture data to the WebGl Texture. It has already been bound.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param createPolynomials will be true if polynomials have been requested
     * @param onLoad defines the callback to trigger once the texture is ready
     * @param onError defines the callback to trigger in case of error
     */
    _BasisTextureLoader.prototype.loadCubeData = function (data, texture, createPolynomials, onLoad, onError) {
        if (Array.isArray(data)) {
            return;
        }
        var caps = texture.getEngine().getCaps();
        var transcodeConfig = {
            supportedCompressionFormats: {
                etc1: caps.etc1 ? true : false,
                s3tc: caps.s3tc ? true : false,
                pvrtc: caps.pvrtc ? true : false,
                etc2: caps.etc2 ? true : false
            }
        };
        _Misc_basis__WEBPACK_IMPORTED_MODULE_1__["BasisTools"].TranscodeAsync(data, transcodeConfig).then(function (result) {
            var hasMipmap = result.fileInfo.images[0].levels.length > 1 && texture.generateMipMaps;
            _Misc_basis__WEBPACK_IMPORTED_MODULE_1__["BasisTools"].LoadTextureFromTranscodeResult(texture, result);
            texture.getEngine()._setCubeMapTextureParams(hasMipmap);
            texture.isReady = true;
        }).catch(function (err) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].Warn("Failed to transcode Basis file, transcoding may not be supported on this device");
            texture.isReady = true;
        });
    };
    /**
     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param callback defines the method to call once ready to upload
     */
    _BasisTextureLoader.prototype.loadData = function (data, texture, callback) {
        var caps = texture.getEngine().getCaps();
        var transcodeConfig = {
            supportedCompressionFormats: {
                etc1: caps.etc1 ? true : false,
                s3tc: caps.s3tc ? true : false,
                pvrtc: caps.pvrtc ? true : false,
                etc2: caps.etc2 ? true : false
            }
        };
        _Misc_basis__WEBPACK_IMPORTED_MODULE_1__["BasisTools"].TranscodeAsync(data, transcodeConfig).then(function (result) {
            var rootImage = result.fileInfo.images[0].levels[0];
            var hasMipmap = result.fileInfo.images[0].levels.length > 1 && texture.generateMipMaps;
            callback(rootImage.width, rootImage.height, hasMipmap, result.format !== -1, function () {
                _Misc_basis__WEBPACK_IMPORTED_MODULE_1__["BasisTools"].LoadTextureFromTranscodeResult(texture, result);
            });
        }).catch(function (err) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].Warn("Failed to transcode Basis file, transcoding may not be supported on this device");
            callback(0, 0, false, false, function () {
            });
        });
    };
    return _BasisTextureLoader;
}());

// Register the loader.
_Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"]._TextureLoaders.push(new _BasisTextureLoader());


/***/ }),

/***/ "./Materials/Textures/Loaders/ddsTextureLoader.ts":
/*!********************************************************!*\
  !*** ./Materials/Textures/Loaders/ddsTextureLoader.ts ***!
  \********************************************************/
/*! exports provided: _DDSTextureLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_DDSTextureLoader", function() { return _DDSTextureLoader; });
/* harmony import */ var _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../Maths/sphericalPolynomial */ "./Maths/sphericalPolynomial.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Misc_dds__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Misc/dds */ "./Misc/dds.ts");



/**
 * Implementation of the DDS Texture Loader.
 * @hidden
 */
var _DDSTextureLoader = /** @class */ (function () {
    function _DDSTextureLoader() {
        /**
         * Defines wether the loader supports cascade loading the different faces.
         */
        this.supportCascades = true;
    }
    /**
     * This returns if the loader support the current file information.
     * @param extension defines the file extension of the file being loaded
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @param fallback defines the fallback internal texture if any
     * @param isBase64 defines whether the texture is encoded as a base64
     * @param isBuffer defines whether the texture data are stored as a buffer
     * @returns true if the loader can load the specified file
     */
    _DDSTextureLoader.prototype.canLoad = function (extension, textureFormatInUse, fallback, isBase64, isBuffer) {
        return extension.indexOf(".dds") === 0;
    };
    /**
     * Transform the url before loading if required.
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the transformed texture
     */
    _DDSTextureLoader.prototype.transformUrl = function (rootUrl, textureFormatInUse) {
        return rootUrl;
    };
    /**
     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the fallback texture
     */
    _DDSTextureLoader.prototype.getFallbackTextureUrl = function (rootUrl, textureFormatInUse) {
        return null;
    };
    /**
     * Uploads the cube texture data to the WebGl Texture. It has alreday been bound.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param createPolynomials will be true if polynomials have been requested
     * @param onLoad defines the callback to trigger once the texture is ready
     * @param onError defines the callback to trigger in case of error
     */
    _DDSTextureLoader.prototype.loadCubeData = function (imgs, texture, createPolynomials, onLoad, onError) {
        var engine = texture.getEngine();
        var info;
        var loadMipmap = false;
        if (Array.isArray(imgs)) {
            for (var index = 0; index < imgs.length; index++) {
                var data_1 = imgs[index];
                info = _Misc_dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"].GetDDSInfo(data_1);
                texture.width = info.width;
                texture.height = info.height;
                loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && texture.generateMipMaps;
                engine._unpackFlipY(info.isCompressed);
                _Misc_dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"].UploadDDSLevels(engine, texture, data_1, info, loadMipmap, 6, -1, index);
                if (!info.isFourCC && info.mipmapCount === 1) {
                    engine.generateMipMapsForCubemap(texture);
                }
            }
        }
        else {
            var data = imgs;
            info = _Misc_dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"].GetDDSInfo(data);
            texture.width = info.width;
            texture.height = info.height;
            if (createPolynomials) {
                info.sphericalPolynomial = new _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__["SphericalPolynomial"]();
            }
            loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && texture.generateMipMaps;
            engine._unpackFlipY(info.isCompressed);
            _Misc_dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"].UploadDDSLevels(engine, texture, data, info, loadMipmap, 6);
            if (!info.isFourCC && info.mipmapCount === 1) {
                engine.generateMipMapsForCubemap(texture);
            }
        }
        engine._setCubeMapTextureParams(loadMipmap);
        texture.isReady = true;
        if (onLoad) {
            onLoad({ isDDS: true, width: texture.width, info: info, data: imgs, texture: texture });
        }
    };
    /**
     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param callback defines the method to call once ready to upload
     */
    _DDSTextureLoader.prototype.loadData = function (data, texture, callback) {
        var info = _Misc_dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"].GetDDSInfo(data);
        var loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && texture.generateMipMaps && ((info.width >> (info.mipmapCount - 1)) === 1);
        callback(info.width, info.height, loadMipmap, info.isFourCC, function () {
            _Misc_dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"].UploadDDSLevels(texture.getEngine(), texture, data, info, loadMipmap, 1);
        });
    };
    return _DDSTextureLoader;
}());

// Register the loader.
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._TextureLoaders.push(new _DDSTextureLoader());


/***/ }),

/***/ "./Materials/Textures/Loaders/envTextureLoader.ts":
/*!********************************************************!*\
  !*** ./Materials/Textures/Loaders/envTextureLoader.ts ***!
  \********************************************************/
/*! exports provided: _ENVTextureLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_ENVTextureLoader", function() { return _ENVTextureLoader; });
/* harmony import */ var _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../Misc/environmentTextureTools */ "./Misc/environmentTextureTools.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Engines/engine */ "./Engines/engine.ts");


/**
 * Implementation of the ENV Texture Loader.
 * @hidden
 */
var _ENVTextureLoader = /** @class */ (function () {
    function _ENVTextureLoader() {
        /**
         * Defines wether the loader supports cascade loading the different faces.
         */
        this.supportCascades = false;
    }
    /**
     * This returns if the loader support the current file information.
     * @param extension defines the file extension of the file being loaded
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @param fallback defines the fallback internal texture if any
     * @param isBase64 defines whether the texture is encoded as a base64
     * @param isBuffer defines whether the texture data are stored as a buffer
     * @returns true if the loader can load the specified file
     */
    _ENVTextureLoader.prototype.canLoad = function (extension, textureFormatInUse, fallback, isBase64, isBuffer) {
        return extension.indexOf(".env") === 0;
    };
    /**
     * Transform the url before loading if required.
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the transformed texture
     */
    _ENVTextureLoader.prototype.transformUrl = function (rootUrl, textureFormatInUse) {
        return rootUrl;
    };
    /**
     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the fallback texture
     */
    _ENVTextureLoader.prototype.getFallbackTextureUrl = function (rootUrl, textureFormatInUse) {
        return null;
    };
    /**
     * Uploads the cube texture data to the WebGl Texture. It has alreday been bound.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param createPolynomials will be true if polynomials have been requested
     * @param onLoad defines the callback to trigger once the texture is ready
     * @param onError defines the callback to trigger in case of error
     */
    _ENVTextureLoader.prototype.loadCubeData = function (data, texture, createPolynomials, onLoad, onError) {
        if (Array.isArray(data)) {
            return;
        }
        data = data;
        var info = _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_0__["EnvironmentTextureTools"].GetEnvInfo(data);
        if (info) {
            texture.width = info.width;
            texture.height = info.width;
            _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_0__["EnvironmentTextureTools"].UploadEnvSpherical(texture, info);
            _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_0__["EnvironmentTextureTools"].UploadEnvLevelsAsync(texture, data, info).then(function () {
                texture.isReady = true;
                if (onLoad) {
                    onLoad();
                }
            });
        }
        else if (onError) {
            onError("Can not parse the environment file", null);
        }
    };
    /**
     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param callback defines the method to call once ready to upload
     */
    _ENVTextureLoader.prototype.loadData = function (data, texture, callback) {
        throw ".env not supported in 2d.";
    };
    return _ENVTextureLoader;
}());

// Register the loader.
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._TextureLoaders.push(new _ENVTextureLoader());


/***/ }),

/***/ "./Materials/Textures/Loaders/index.ts":
/*!*********************************************!*\
  !*** ./Materials/Textures/Loaders/index.ts ***!
  \*********************************************/
/*! exports provided: _DDSTextureLoader, _ENVTextureLoader, _KTXTextureLoader, _TGATextureLoader, _BasisTextureLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _ddsTextureLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./ddsTextureLoader */ "./Materials/Textures/Loaders/ddsTextureLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DDSTextureLoader", function() { return _ddsTextureLoader__WEBPACK_IMPORTED_MODULE_0__["_DDSTextureLoader"]; });

/* harmony import */ var _envTextureLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./envTextureLoader */ "./Materials/Textures/Loaders/envTextureLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_ENVTextureLoader", function() { return _envTextureLoader__WEBPACK_IMPORTED_MODULE_1__["_ENVTextureLoader"]; });

/* harmony import */ var _ktxTextureLoader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ktxTextureLoader */ "./Materials/Textures/Loaders/ktxTextureLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_KTXTextureLoader", function() { return _ktxTextureLoader__WEBPACK_IMPORTED_MODULE_2__["_KTXTextureLoader"]; });

/* harmony import */ var _tgaTextureLoader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./tgaTextureLoader */ "./Materials/Textures/Loaders/tgaTextureLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TGATextureLoader", function() { return _tgaTextureLoader__WEBPACK_IMPORTED_MODULE_3__["_TGATextureLoader"]; });

/* harmony import */ var _basisTextureLoader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./basisTextureLoader */ "./Materials/Textures/Loaders/basisTextureLoader.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BasisTextureLoader", function() { return _basisTextureLoader__WEBPACK_IMPORTED_MODULE_4__["_BasisTextureLoader"]; });








/***/ }),

/***/ "./Materials/Textures/Loaders/ktxTextureLoader.ts":
/*!********************************************************!*\
  !*** ./Materials/Textures/Loaders/ktxTextureLoader.ts ***!
  \********************************************************/
/*! exports provided: _KTXTextureLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_KTXTextureLoader", function() { return _KTXTextureLoader; });
/* harmony import */ var _Misc_khronosTextureContainer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../Misc/khronosTextureContainer */ "./Misc/khronosTextureContainer.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Engines/engine */ "./Engines/engine.ts");


/**
 * Implementation of the KTX Texture Loader.
 * @hidden
 */
var _KTXTextureLoader = /** @class */ (function () {
    function _KTXTextureLoader() {
        /**
         * Defines wether the loader supports cascade loading the different faces.
         */
        this.supportCascades = false;
    }
    /**
     * This returns if the loader support the current file information.
     * @param extension defines the file extension of the file being loaded
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @param fallback defines the fallback internal texture if any
     * @param isBase64 defines whether the texture is encoded as a base64
     * @param isBuffer defines whether the texture data are stored as a buffer
     * @returns true if the loader can load the specified file
     */
    _KTXTextureLoader.prototype.canLoad = function (extension, textureFormatInUse, fallback, isBase64, isBuffer) {
        if (textureFormatInUse && !isBase64 && !fallback && !isBuffer) {
            return true;
        }
        return false;
    };
    /**
     * Transform the url before loading if required.
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the transformed texture
     */
    _KTXTextureLoader.prototype.transformUrl = function (rootUrl, textureFormatInUse) {
        var lastDot = rootUrl.lastIndexOf('.');
        if (lastDot != -1 && rootUrl.substring(lastDot + 1) == "ktx") {
            // Already transformed
            return rootUrl;
        }
        return (lastDot > -1 ? rootUrl.substring(0, lastDot) : rootUrl) + textureFormatInUse;
    };
    /**
     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the fallback texture
     */
    _KTXTextureLoader.prototype.getFallbackTextureUrl = function (rootUrl, textureFormatInUse) {
        // remove the format appended to the rootUrl in the original createCubeTexture call.
        var exp = new RegExp("" + textureFormatInUse + "$");
        return rootUrl.replace(exp, "");
    };
    /**
     * Uploads the cube texture data to the WebGl Texture. It has alreday been bound.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param createPolynomials will be true if polynomials have been requested
     * @param onLoad defines the callback to trigger once the texture is ready
     * @param onError defines the callback to trigger in case of error
     */
    _KTXTextureLoader.prototype.loadCubeData = function (data, texture, createPolynomials, onLoad, onError) {
        if (Array.isArray(data)) {
            return;
        }
        // Need to invert vScale as invertY via UNPACK_FLIP_Y_WEBGL is not supported by compressed texture
        texture._invertVScale = !texture.invertY;
        var engine = texture.getEngine();
        var ktx = new _Misc_khronosTextureContainer__WEBPACK_IMPORTED_MODULE_0__["KhronosTextureContainer"](data, 6);
        var loadMipmap = ktx.numberOfMipmapLevels > 1 && texture.generateMipMaps;
        engine._unpackFlipY(true);
        ktx.uploadLevels(texture, texture.generateMipMaps);
        texture.width = ktx.pixelWidth;
        texture.height = ktx.pixelHeight;
        engine._setCubeMapTextureParams(loadMipmap);
        texture.isReady = true;
    };
    /**
     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param callback defines the method to call once ready to upload
     */
    _KTXTextureLoader.prototype.loadData = function (data, texture, callback) {
        // Need to invert vScale as invertY via UNPACK_FLIP_Y_WEBGL is not supported by compressed texture
        texture._invertVScale = !texture.invertY;
        var ktx = new _Misc_khronosTextureContainer__WEBPACK_IMPORTED_MODULE_0__["KhronosTextureContainer"](data, 1);
        callback(ktx.pixelWidth, ktx.pixelHeight, false, true, function () {
            ktx.uploadLevels(texture, texture.generateMipMaps);
        }, ktx.isInvalid);
    };
    return _KTXTextureLoader;
}());

// Register the loader.
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._TextureLoaders.unshift(new _KTXTextureLoader());


/***/ }),

/***/ "./Materials/Textures/Loaders/tgaTextureLoader.ts":
/*!********************************************************!*\
  !*** ./Materials/Textures/Loaders/tgaTextureLoader.ts ***!
  \********************************************************/
/*! exports provided: _TGATextureLoader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_TGATextureLoader", function() { return _TGATextureLoader; });
/* harmony import */ var _Misc_tga__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../Misc/tga */ "./Misc/tga.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Engines/engine */ "./Engines/engine.ts");


/**
 * Implementation of the TGA Texture Loader.
 * @hidden
 */
var _TGATextureLoader = /** @class */ (function () {
    function _TGATextureLoader() {
        /**
         * Defines wether the loader supports cascade loading the different faces.
         */
        this.supportCascades = false;
    }
    /**
     * This returns if the loader support the current file information.
     * @param extension defines the file extension of the file being loaded
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @param fallback defines the fallback internal texture if any
     * @param isBase64 defines whether the texture is encoded as a base64
     * @param isBuffer defines whether the texture data are stored as a buffer
     * @returns true if the loader can load the specified file
     */
    _TGATextureLoader.prototype.canLoad = function (extension, textureFormatInUse, fallback, isBase64, isBuffer) {
        return extension.indexOf(".tga") === 0;
    };
    /**
     * Transform the url before loading if required.
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the transformed texture
     */
    _TGATextureLoader.prototype.transformUrl = function (rootUrl, textureFormatInUse) {
        return rootUrl;
    };
    /**
     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
     * @param rootUrl the url of the texture
     * @param textureFormatInUse defines the current compressed format in use iun the engine
     * @returns the fallback texture
     */
    _TGATextureLoader.prototype.getFallbackTextureUrl = function (rootUrl, textureFormatInUse) {
        return null;
    };
    /**
     * Uploads the cube texture data to the WebGl Texture. It has alreday been bound.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param createPolynomials will be true if polynomials have been requested
     * @param onLoad defines the callback to trigger once the texture is ready
     * @param onError defines the callback to trigger in case of error
     */
    _TGATextureLoader.prototype.loadCubeData = function (data, texture, createPolynomials, onLoad, onError) {
        throw ".env not supported in Cube.";
    };
    /**
     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
     * @param data contains the texture data
     * @param texture defines the BabylonJS internal texture
     * @param callback defines the method to call once ready to upload
     */
    _TGATextureLoader.prototype.loadData = function (data, texture, callback) {
        var uintData = new Uint8Array(data);
        var header = _Misc_tga__WEBPACK_IMPORTED_MODULE_0__["TGATools"].GetTGAHeader(uintData);
        callback(header.width, header.height, texture.generateMipMaps, false, function () {
            _Misc_tga__WEBPACK_IMPORTED_MODULE_0__["TGATools"].UploadContent(texture, uintData);
        });
    };
    return _TGATextureLoader;
}());

// Register the loader.
_Engines_engine__WEBPACK_IMPORTED_MODULE_1__["Engine"]._TextureLoaders.push(new _TGATextureLoader());


/***/ }),

/***/ "./Materials/Textures/MultiviewRenderTarget.ts":
/*!*****************************************************!*\
  !*** ./Materials/Textures/MultiviewRenderTarget.ts ***!
  \*****************************************************/
/*! exports provided: MultiviewRenderTarget */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiviewRenderTarget", function() { return MultiviewRenderTarget; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");



/**
 * Renders to multiple views with a single draw call
 * @see https://www.khronos.org/registry/webgl/extensions/WEBGL_multiview/
 */
var MultiviewRenderTarget = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MultiviewRenderTarget, _super);
    /**
     * Creates a multiview render target
     * @param scene scene used with the render target
     * @param size the size of the render target (used for each view)
     */
    function MultiviewRenderTarget(scene, size) {
        if (size === void 0) { size = 512; }
        var _this = _super.call(this, "multiview rtt", size, scene, false, true, _Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_UNKNOWN, false, undefined, false, false, true, undefined, true) || this;
        var internalTexture = scene.getEngine().createMultiviewRenderTargetTexture(_this.getRenderWidth(), _this.getRenderHeight());
        internalTexture.isMultiview = true;
        _this._texture = internalTexture;
        return _this;
    }
    /**
     * @hidden
     * @param faceIndex the face index, if its a cube texture
     */
    MultiviewRenderTarget.prototype._bindFrameBuffer = function (faceIndex) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (!this._texture) {
            return;
        }
        this.getScene().getEngine().bindMultiviewFramebuffer(this._texture);
    };
    /**
     * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)
     * @returns the view count
     */
    MultiviewRenderTarget.prototype.getViewCount = function () {
        return 2;
    };
    return MultiviewRenderTarget;
}(_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_1__["RenderTargetTexture"]));



/***/ }),

/***/ "./Materials/Textures/Procedurals/customProceduralTexture.ts":
/*!*******************************************************************!*\
  !*** ./Materials/Textures/Procedurals/customProceduralTexture.ts ***!
  \*******************************************************************/
/*! exports provided: CustomProceduralTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomProceduralTexture", function() { return CustomProceduralTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _proceduralTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./proceduralTexture */ "./Materials/Textures/Procedurals/proceduralTexture.ts");
/* harmony import */ var _Misc_webRequest__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../Misc/webRequest */ "./Misc/webRequest.ts");







/**
 * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes called 'refMaps' or 'sampler' images.
 * Custom Procedural textures are the easiest way to create your own procedural in your application.
 * @see http://doc.babylonjs.com/how_to/how_to_use_procedural_textures#creating-custom-procedural-textures
 */
var CustomProceduralTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CustomProceduralTexture, _super);
    /**
     * Instantiates a new Custom Procedural Texture.
     * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes called 'refMaps' or 'sampler' images.
     * Custom Procedural textures are the easiest way to create your own procedural in your application.
     * @see http://doc.babylonjs.com/how_to/how_to_use_procedural_textures#creating-custom-procedural-textures
     * @param name Define the name of the texture
     * @param texturePath Define the folder path containing all the cutom texture related files (config, shaders...)
     * @param size Define the size of the texture to create
     * @param scene Define the scene the texture belongs to
     * @param fallbackTexture Define a fallback texture in case there were issues to create the custom texture
     * @param generateMipMaps Define if the texture should creates mip maps or not
     */
    function CustomProceduralTexture(name, texturePath, size, scene, fallbackTexture, generateMipMaps) {
        var _this = _super.call(this, name, size, null, scene, fallbackTexture, generateMipMaps) || this;
        _this._animate = true;
        _this._time = 0;
        _this._texturePath = texturePath;
        //Try to load json
        _this._loadJson(texturePath);
        _this.refreshRate = 1;
        return _this;
    }
    CustomProceduralTexture.prototype._loadJson = function (jsonUrl) {
        var _this = this;
        var noConfigFile = function () {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Log("No config file found in " + jsonUrl + " trying to use ShadersStore or DOM element");
            try {
                _this.setFragment(_this._texturePath);
            }
            catch (ex) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("No json or ShaderStore or DOM element found for CustomProceduralTexture");
            }
        };
        var configFileUrl = jsonUrl + "/config.json";
        var xhr = new _Misc_webRequest__WEBPACK_IMPORTED_MODULE_6__["WebRequest"]();
        xhr.open("GET", configFileUrl);
        xhr.addEventListener("load", function () {
            if (xhr.status === 200 || (xhr.responseText && xhr.responseText.length > 0)) {
                try {
                    _this._config = JSON.parse(xhr.response);
                    _this.updateShaderUniforms();
                    _this.updateTextures();
                    _this.setFragment(_this._texturePath + "/custom");
                    _this._animate = _this._config.animate;
                    _this.refreshRate = _this._config.refreshrate;
                }
                catch (ex) {
                    noConfigFile();
                }
            }
            else {
                noConfigFile();
            }
        }, false);
        xhr.addEventListener("error", function () {
            noConfigFile();
        }, false);
        try {
            xhr.send();
        }
        catch (ex) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("CustomProceduralTexture: Error on XHR send request.");
        }
    };
    /**
     * Is the texture ready to be used ? (rendered at least once)
     * @returns true if ready, otherwise, false.
     */
    CustomProceduralTexture.prototype.isReady = function () {
        if (!_super.prototype.isReady.call(this)) {
            return false;
        }
        for (var name in this._textures) {
            var texture = this._textures[name];
            if (!texture.isReady()) {
                return false;
            }
        }
        return true;
    };
    /**
     * Render the texture to its associated render target.
     * @param useCameraPostProcess Define if camera post process should be applied to the texture
     */
    CustomProceduralTexture.prototype.render = function (useCameraPostProcess) {
        var scene = this.getScene();
        if (this._animate && scene) {
            this._time += scene.getAnimationRatio() * 0.03;
            this.updateShaderUniforms();
        }
        _super.prototype.render.call(this, useCameraPostProcess);
    };
    /**
     * Update the list of dependant textures samplers in the shader.
     */
    CustomProceduralTexture.prototype.updateTextures = function () {
        for (var i = 0; i < this._config.sampler2Ds.length; i++) {
            this.setTexture(this._config.sampler2Ds[i].sample2Dname, new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"](this._texturePath + "/" + this._config.sampler2Ds[i].textureRelativeUrl, this.getScene()));
        }
    };
    /**
     * Update the uniform values of the procedural texture in the shader.
     */
    CustomProceduralTexture.prototype.updateShaderUniforms = function () {
        if (this._config) {
            for (var j = 0; j < this._config.uniforms.length; j++) {
                var uniform = this._config.uniforms[j];
                switch (uniform.type) {
                    case "float":
                        this.setFloat(uniform.name, uniform.value);
                        break;
                    case "color3":
                        this.setColor3(uniform.name, new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"](uniform.r, uniform.g, uniform.b));
                        break;
                    case "color4":
                        this.setColor4(uniform.name, new _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color4"](uniform.r, uniform.g, uniform.b, uniform.a));
                        break;
                    case "vector2":
                        this.setVector2(uniform.name, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](uniform.x, uniform.y));
                        break;
                    case "vector3":
                        this.setVector3(uniform.name, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](uniform.x, uniform.y, uniform.z));
                        break;
                }
            }
        }
        this.setFloat("time", this._time);
    };
    Object.defineProperty(CustomProceduralTexture.prototype, "animate", {
        /**
         * Define if the texture animates or not.
         */
        get: function () {
            return this._animate;
        },
        set: function (value) {
            this._animate = value;
        },
        enumerable: true,
        configurable: true
    });
    return CustomProceduralTexture;
}(_proceduralTexture__WEBPACK_IMPORTED_MODULE_5__["ProceduralTexture"]));



/***/ }),

/***/ "./Materials/Textures/Procedurals/index.ts":
/*!*************************************************!*\
  !*** ./Materials/Textures/Procedurals/index.ts ***!
  \*************************************************/
/*! exports provided: CustomProceduralTexture, NoiseProceduralTexture, ProceduralTexture, ProceduralTextureSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _customProceduralTexture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./customProceduralTexture */ "./Materials/Textures/Procedurals/customProceduralTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomProceduralTexture", function() { return _customProceduralTexture__WEBPACK_IMPORTED_MODULE_0__["CustomProceduralTexture"]; });

/* harmony import */ var _noiseProceduralTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./noiseProceduralTexture */ "./Materials/Textures/Procedurals/noiseProceduralTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NoiseProceduralTexture", function() { return _noiseProceduralTexture__WEBPACK_IMPORTED_MODULE_1__["NoiseProceduralTexture"]; });

/* harmony import */ var _proceduralTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./proceduralTexture */ "./Materials/Textures/Procedurals/proceduralTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTexture", function() { return _proceduralTexture__WEBPACK_IMPORTED_MODULE_2__["ProceduralTexture"]; });

/* harmony import */ var _proceduralTextureSceneComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./proceduralTextureSceneComponent */ "./Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTextureSceneComponent", function() { return _proceduralTextureSceneComponent__WEBPACK_IMPORTED_MODULE_3__["ProceduralTextureSceneComponent"]; });







/***/ }),

/***/ "./Materials/Textures/Procedurals/noiseProceduralTexture.ts":
/*!******************************************************************!*\
  !*** ./Materials/Textures/Procedurals/noiseProceduralTexture.ts ***!
  \******************************************************************/
/*! exports provided: NoiseProceduralTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NoiseProceduralTexture", function() { return NoiseProceduralTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _proceduralTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./proceduralTexture */ "./Materials/Textures/Procedurals/proceduralTexture.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Shaders_noise_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Shaders/noise.fragment */ "./Shaders/noise.fragment.ts");





/**
 * Class used to generate noise procedural textures
 */
var NoiseProceduralTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](NoiseProceduralTexture, _super);
    /**
     * Creates a new NoiseProceduralTexture
     * @param name defines the name fo the texture
     * @param size defines the size of the texture (default is 256)
     * @param scene defines the hosting scene
     * @param fallbackTexture defines the texture to use if the NoiseProceduralTexture can't be created
     * @param generateMipMaps defines if mipmaps must be generated (true by default)
     */
    function NoiseProceduralTexture(name, size, scene, fallbackTexture, generateMipMaps) {
        if (size === void 0) { size = 256; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_1__["EngineStore"].LastCreatedScene; }
        var _this = _super.call(this, name, size, "noise", scene, fallbackTexture, generateMipMaps) || this;
        _this._time = 0;
        /** Gets or sets a value between 0 and 1 indicating the overall brightness of the texture (default is 0.2) */
        _this.brightness = 0.2;
        /** Defines the number of octaves to process */
        _this.octaves = 3;
        /** Defines the level of persistence (0.8 by default) */
        _this.persistence = 0.8;
        /** Gets or sets animation speed factor (default is 1) */
        _this.animationSpeedFactor = 1;
        _this.autoClear = false;
        _this._updateShaderUniforms();
        return _this;
    }
    NoiseProceduralTexture.prototype._updateShaderUniforms = function () {
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        this._time += scene.getAnimationRatio() * this.animationSpeedFactor * 0.01;
        this.setFloat("brightness", this.brightness);
        this.setFloat("persistence", this.persistence);
        this.setFloat("timeScale", this._time);
    };
    NoiseProceduralTexture.prototype._getDefines = function () {
        return "#define OCTAVES " + (this.octaves | 0);
    };
    /** Generate the current state of the procedural texture */
    NoiseProceduralTexture.prototype.render = function (useCameraPostProcess) {
        this._updateShaderUniforms();
        _super.prototype.render.call(this, useCameraPostProcess);
    };
    /**
     * Serializes this noise procedural texture
     * @returns a serialized noise procedural texture object
     */
    NoiseProceduralTexture.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.customType = "BABYLON.NoiseProceduralTexture";
        serializationObject.brightness = this.brightness;
        serializationObject.octaves = this.octaves;
        serializationObject.persistence = this.persistence;
        serializationObject.animationSpeedFactor = this.animationSpeedFactor;
        serializationObject.size = this.getSize().width;
        serializationObject.generateMipMaps = this._generateMipMaps;
        return serializationObject;
    };
    /**
     * Creates a NoiseProceduralTexture from parsed noise procedural texture data
     * @param parsedTexture defines parsed texture data
     * @param scene defines the current scene
     * @param rootUrl defines the root URL containing noise procedural texture information
     * @returns a parsed NoiseProceduralTexture
     */
    NoiseProceduralTexture.Parse = function (parsedTexture, scene) {
        var texture = new NoiseProceduralTexture(parsedTexture.name, parsedTexture.size, scene, undefined, parsedTexture.generateMipMaps);
        texture.brightness = parsedTexture.brightness;
        texture.octaves = parsedTexture.octaves;
        texture.persistence = parsedTexture.persistence;
        texture.animationSpeedFactor = parsedTexture.animationSpeedFactor;
        return texture;
    };
    return NoiseProceduralTexture;
}(_proceduralTexture__WEBPACK_IMPORTED_MODULE_2__["ProceduralTexture"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.NoiseProceduralTexture"] = NoiseProceduralTexture;


/***/ }),

/***/ "./Materials/Textures/Procedurals/proceduralTexture.ts":
/*!*************************************************************!*\
  !*** ./Materials/Textures/Procedurals/proceduralTexture.ts ***!
  \*************************************************************/
/*! exports provided: ProceduralTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProceduralTexture", function() { return ProceduralTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _proceduralTextureSceneComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./proceduralTextureSceneComponent */ "./Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts");
/* harmony import */ var _Engines_Extensions_engine_renderTarget__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../Engines/Extensions/engine.renderTarget */ "./Engines/Extensions/engine.renderTarget.ts");
/* harmony import */ var _Shaders_procedural_vertex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../Shaders/procedural.vertex */ "./Shaders/procedural.vertex.ts");











/**
 * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes calmpler' images.
 * This is the base class of any Procedural texture and contains most of the shareable code.
 * @see http://doc.babylonjs.com/how_to/how_to_use_procedural_textures
 */
var ProceduralTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ProceduralTexture, _super);
    /**
     * Instantiates a new procedural texture.
     * Procedural texturing is a way to programmatically create a texture. There are 2 types of procedural textures: code-only, and code that references some classic 2D images, sometimes called 'refMaps' or 'sampler' images.
     * This is the base class of any Procedural texture and contains most of the shareable code.
     * @see http://doc.babylonjs.com/how_to/how_to_use_procedural_textures
     * @param name  Define the name of the texture
     * @param size Define the size of the texture to create
     * @param fragment Define the fragment shader to use to generate the texture or null if it is defined later
     * @param scene Define the scene the texture belongs to
     * @param fallbackTexture Define a fallback texture in case there were issues to create the custom texture
     * @param generateMipMaps Define if the texture should creates mip maps or not
     * @param isCube Define if the texture is a cube texture or not (this will render each faces of the cube)
     */
    function ProceduralTexture(name, size, fragment, scene, fallbackTexture, generateMipMaps, isCube) {
        if (fallbackTexture === void 0) { fallbackTexture = null; }
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (isCube === void 0) { isCube = false; }
        var _this = _super.call(this, null, scene, !generateMipMaps) || this;
        _this.isCube = isCube;
        /**
         * Define if the texture is enabled or not (disabled texture will not render)
         */
        _this.isEnabled = true;
        /**
         * Define if the texture must be cleared before rendering (default is true)
         */
        _this.autoClear = true;
        /**
         * Event raised when the texture is generated
         */
        _this.onGeneratedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /** @hidden */
        _this._textures = {};
        _this._currentRefreshId = -1;
        _this._refreshRate = 1;
        _this._vertexBuffers = {};
        _this._uniforms = new Array();
        _this._samplers = new Array();
        _this._floats = {};
        _this._ints = {};
        _this._floatsArrays = {};
        _this._colors3 = {};
        _this._colors4 = {};
        _this._vectors2 = {};
        _this._vectors3 = {};
        _this._matrices = {};
        _this._fallbackTextureUsed = false;
        _this._cachedDefines = "";
        _this._contentUpdateId = -1;
        scene = _this.getScene();
        var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_PROCEDURALTEXTURE);
        if (!component) {
            component = new _proceduralTextureSceneComponent__WEBPACK_IMPORTED_MODULE_8__["ProceduralTextureSceneComponent"](scene);
            scene._addComponent(component);
        }
        scene.proceduralTextures.push(_this);
        _this._engine = scene.getEngine();
        _this.name = name;
        _this.isRenderTarget = true;
        _this._size = size;
        _this._generateMipMaps = generateMipMaps;
        _this.setFragment(fragment);
        _this._fallbackTexture = fallbackTexture;
        if (isCube) {
            _this._texture = _this._engine.createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps, generateDepthBuffer: false, generateStencilBuffer: false });
            _this.setFloat("face", 0);
        }
        else {
            _this._texture = _this._engine.createRenderTargetTexture(size, { generateMipMaps: generateMipMaps, generateDepthBuffer: false, generateStencilBuffer: false });
        }
        // VBO
        var vertices = [];
        vertices.push(1, 1);
        vertices.push(-1, 1);
        vertices.push(-1, -1);
        vertices.push(1, -1);
        _this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"](_this._engine, vertices, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, false, false, 2);
        _this._createIndexBuffer();
        return _this;
    }
    /**
     * The effect that is created when initializing the post process.
     * @returns The created effect corresponding the the postprocess.
     */
    ProceduralTexture.prototype.getEffect = function () {
        return this._effect;
    };
    /**
     * Gets texture content (Use this function wisely as reading from a texture can be slow)
     * @returns an ArrayBufferView (Uint8Array or Float32Array)
     */
    ProceduralTexture.prototype.getContent = function () {
        if (this._contentData && this._currentRefreshId == this._contentUpdateId) {
            return this._contentData;
        }
        this._contentData = this.readPixels(0, 0, this._contentData);
        this._contentUpdateId = this._currentRefreshId;
        return this._contentData;
    };
    ProceduralTexture.prototype._createIndexBuffer = function () {
        var engine = this._engine;
        // Indices
        var indices = [];
        indices.push(0);
        indices.push(1);
        indices.push(2);
        indices.push(0);
        indices.push(2);
        indices.push(3);
        this._indexBuffer = engine.createIndexBuffer(indices);
    };
    /** @hidden */
    ProceduralTexture.prototype._rebuild = function () {
        var vb = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind];
        if (vb) {
            vb._rebuild();
        }
        this._createIndexBuffer();
        if (this.refreshRate === _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_7__["RenderTargetTexture"].REFRESHRATE_RENDER_ONCE) {
            this.refreshRate = _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_7__["RenderTargetTexture"].REFRESHRATE_RENDER_ONCE;
        }
    };
    /**
     * Resets the texture in order to recreate its associated resources.
     * This can be called in case of context loss
     */
    ProceduralTexture.prototype.reset = function () {
        if (this._effect === undefined) {
            return;
        }
        this._effect.dispose();
    };
    ProceduralTexture.prototype._getDefines = function () {
        return "";
    };
    /**
     * Is the texture ready to be used ? (rendered at least once)
     * @returns true if ready, otherwise, false.
     */
    ProceduralTexture.prototype.isReady = function () {
        var _this = this;
        var engine = this._engine;
        var shaders;
        if (!this._fragment) {
            return false;
        }
        if (this._fallbackTextureUsed) {
            return true;
        }
        var defines = this._getDefines();
        if (this._effect && defines === this._cachedDefines && this._effect.isReady()) {
            return true;
        }
        if (this._fragment.fragmentElement !== undefined) {
            shaders = { vertex: "procedural", fragmentElement: this._fragment.fragmentElement };
        }
        else {
            shaders = { vertex: "procedural", fragment: this._fragment };
        }
        this._cachedDefines = defines;
        this._effect = engine.createEffect(shaders, [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind], this._uniforms, this._samplers, defines, undefined, undefined, function () {
            _this.releaseInternalTexture();
            if (_this._fallbackTexture) {
                _this._texture = _this._fallbackTexture._texture;
                if (_this._texture) {
                    _this._texture.incrementReferences();
                }
            }
            _this._fallbackTextureUsed = true;
        });
        return this._effect.isReady();
    };
    /**
     * Resets the refresh counter of the texture and start bak from scratch.
     * Could be useful to regenerate the texture if it is setup to render only once.
     */
    ProceduralTexture.prototype.resetRefreshCounter = function () {
        this._currentRefreshId = -1;
    };
    /**
     * Set the fragment shader to use in order to render the texture.
     * @param fragment This can be set to a path (into the shader store) or to a json object containing a fragmentElement property.
     */
    ProceduralTexture.prototype.setFragment = function (fragment) {
        this._fragment = fragment;
    };
    Object.defineProperty(ProceduralTexture.prototype, "refreshRate", {
        /**
         * Define the refresh rate of the texture or the rendering frequency.
         * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
         */
        get: function () {
            return this._refreshRate;
        },
        set: function (value) {
            this._refreshRate = value;
            this.resetRefreshCounter();
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    ProceduralTexture.prototype._shouldRender = function () {
        if (!this.isEnabled || !this.isReady() || !this._texture) {
            if (this._texture) {
                this._texture.isReady = false;
            }
            return false;
        }
        if (this._fallbackTextureUsed) {
            return false;
        }
        if (this._currentRefreshId === -1) { // At least render once
            this._currentRefreshId = 1;
            return true;
        }
        if (this.refreshRate === this._currentRefreshId) {
            this._currentRefreshId = 1;
            return true;
        }
        this._currentRefreshId++;
        return false;
    };
    /**
     * Get the size the texture is rendering at.
     * @returns the size (texture is always squared)
     */
    ProceduralTexture.prototype.getRenderSize = function () {
        return this._size;
    };
    /**
     * Resize the texture to new value.
     * @param size Define the new size the texture should have
     * @param generateMipMaps Define whether the new texture should create mip maps
     */
    ProceduralTexture.prototype.resize = function (size, generateMipMaps) {
        if (this._fallbackTextureUsed) {
            return;
        }
        this.releaseInternalTexture();
        this._texture = this._engine.createRenderTargetTexture(size, generateMipMaps);
        // Update properties
        this._size = size;
        this._generateMipMaps = generateMipMaps;
    };
    ProceduralTexture.prototype._checkUniform = function (uniformName) {
        if (this._uniforms.indexOf(uniformName) === -1) {
            this._uniforms.push(uniformName);
        }
    };
    /**
     * Set a texture in the shader program used to render.
     * @param name Define the name of the uniform samplers as defined in the shader
     * @param texture Define the texture to bind to this sampler
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setTexture = function (name, texture) {
        if (this._samplers.indexOf(name) === -1) {
            this._samplers.push(name);
        }
        this._textures[name] = texture;
        return this;
    };
    /**
     * Set a float in the shader.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setFloat = function (name, value) {
        this._checkUniform(name);
        this._floats[name] = value;
        return this;
    };
    /**
     * Set a int in the shader.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setInt = function (name, value) {
        this._checkUniform(name);
        this._ints[name] = value;
        return this;
    };
    /**
     * Set an array of floats in the shader.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setFloats = function (name, value) {
        this._checkUniform(name);
        this._floatsArrays[name] = value;
        return this;
    };
    /**
     * Set a vec3 in the shader from a Color3.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setColor3 = function (name, value) {
        this._checkUniform(name);
        this._colors3[name] = value;
        return this;
    };
    /**
     * Set a vec4 in the shader from a Color4.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setColor4 = function (name, value) {
        this._checkUniform(name);
        this._colors4[name] = value;
        return this;
    };
    /**
     * Set a vec2 in the shader from a Vector2.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setVector2 = function (name, value) {
        this._checkUniform(name);
        this._vectors2[name] = value;
        return this;
    };
    /**
     * Set a vec3 in the shader from a Vector3.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setVector3 = function (name, value) {
        this._checkUniform(name);
        this._vectors3[name] = value;
        return this;
    };
    /**
     * Set a mat4 in the shader from a MAtrix.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the texture itself allowing "fluent" like uniform updates
     */
    ProceduralTexture.prototype.setMatrix = function (name, value) {
        this._checkUniform(name);
        this._matrices[name] = value;
        return this;
    };
    /**
     * Render the texture to its associated render target.
     * @param useCameraPostProcess Define if camera post process should be applied to the texture
     */
    ProceduralTexture.prototype.render = function (useCameraPostProcess) {
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        var engine = this._engine;
        // Render
        engine.enableEffect(this._effect);
        engine.setState(false);
        // Texture
        for (var name in this._textures) {
            this._effect.setTexture(name, this._textures[name]);
        }
        // Float
        for (name in this._ints) {
            this._effect.setInt(name, this._ints[name]);
        }
        // Float
        for (name in this._floats) {
            this._effect.setFloat(name, this._floats[name]);
        }
        // Floats
        for (name in this._floatsArrays) {
            this._effect.setArray(name, this._floatsArrays[name]);
        }
        // Color3
        for (name in this._colors3) {
            this._effect.setColor3(name, this._colors3[name]);
        }
        // Color4
        for (name in this._colors4) {
            var color = this._colors4[name];
            this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
        }
        // Vector2
        for (name in this._vectors2) {
            this._effect.setVector2(name, this._vectors2[name]);
        }
        // Vector3
        for (name in this._vectors3) {
            this._effect.setVector3(name, this._vectors3[name]);
        }
        // Matrix
        for (name in this._matrices) {
            this._effect.setMatrix(name, this._matrices[name]);
        }
        if (!this._texture) {
            return;
        }
        if (this.isCube) {
            for (var face = 0; face < 6; face++) {
                engine.bindFramebuffer(this._texture, face, undefined, undefined, true);
                // VBOs
                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._effect);
                this._effect.setFloat("face", face);
                // Clear
                if (this.autoClear) {
                    engine.clear(scene.clearColor, true, false, false);
                }
                // Draw order
                engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, 0, 6);
                // Mipmaps
                if (face === 5) {
                    engine.generateMipMapsForCubemap(this._texture);
                }
            }
        }
        else {
            engine.bindFramebuffer(this._texture, 0, undefined, undefined, true);
            // VBOs
            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._effect);
            // Clear
            if (this.autoClear) {
                engine.clear(scene.clearColor, true, false, false);
            }
            // Draw order
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, 0, 6);
        }
        // Unbind
        engine.unBindFramebuffer(this._texture, this.isCube);
        if (this.onGenerated) {
            this.onGenerated();
        }
        this.onGeneratedObservable.notifyObservers(this);
    };
    /**
     * Clone the texture.
     * @returns the cloned texture
     */
    ProceduralTexture.prototype.clone = function () {
        var textureSize = this.getSize();
        var newTexture = new ProceduralTexture(this.name, textureSize.width, this._fragment, this.getScene(), this._fallbackTexture, this._generateMipMaps);
        // Base texture
        newTexture.hasAlpha = this.hasAlpha;
        newTexture.level = this.level;
        // RenderTarget Texture
        newTexture.coordinatesMode = this.coordinatesMode;
        return newTexture;
    };
    /**
     * Dispose the texture and release its asoociated resources.
     */
    ProceduralTexture.prototype.dispose = function () {
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        var index = scene.proceduralTextures.indexOf(this);
        if (index >= 0) {
            scene.proceduralTextures.splice(index, 1);
        }
        var vertexBuffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind];
        if (vertexBuffer) {
            vertexBuffer.dispose();
            this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind] = null;
        }
        if (this._indexBuffer && this._engine._releaseBuffer(this._indexBuffer)) {
            this._indexBuffer = null;
        }
        _super.prototype.dispose.call(this);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ProceduralTexture.prototype, "isEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ProceduralTexture.prototype, "autoClear", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ProceduralTexture.prototype, "_generateMipMaps", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ProceduralTexture.prototype, "_size", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ProceduralTexture.prototype, "refreshRate", null);
    return ProceduralTexture;
}(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"]));



/***/ }),

/***/ "./Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts":
/*!***************************************************************************!*\
  !*** ./Materials/Textures/Procedurals/proceduralTextureSceneComponent.ts ***!
  \***************************************************************************/
/*! exports provided: ProceduralTextureSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProceduralTextureSceneComponent", function() { return ProceduralTextureSceneComponent; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../sceneComponent */ "./sceneComponent.ts");


/**
 * Defines the Procedural Texture scene component responsible to manage any Procedural Texture
 * in a given scene.
 */
var ProceduralTextureSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function ProceduralTextureSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_PROCEDURALTEXTURE;
        this.scene = scene;
        this.scene.proceduralTextures = new Array();
    }
    /**
     * Registers the component in a given scene
     */
    ProceduralTextureSceneComponent.prototype.register = function () {
        this.scene._beforeClearStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_BEFORECLEAR_PROCEDURALTEXTURE, this, this._beforeClear);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    ProceduralTextureSceneComponent.prototype.rebuild = function () {
        // Nothing to do here.
    };
    /**
     * Disposes the component and the associated ressources.
     */
    ProceduralTextureSceneComponent.prototype.dispose = function () {
        // Nothing to do here.
    };
    ProceduralTextureSceneComponent.prototype._beforeClear = function () {
        if (this.scene.proceduralTexturesEnabled) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].StartPerformanceCounter("Procedural textures", this.scene.proceduralTextures.length > 0);
            for (var proceduralIndex = 0; proceduralIndex < this.scene.proceduralTextures.length; proceduralIndex++) {
                var proceduralTexture = this.scene.proceduralTextures[proceduralIndex];
                if (proceduralTexture._shouldRender()) {
                    proceduralTexture.render();
                }
            }
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].EndPerformanceCounter("Procedural textures", this.scene.proceduralTextures.length > 0);
        }
    };
    return ProceduralTextureSceneComponent;
}());



/***/ }),

/***/ "./Materials/Textures/baseTexture.ts":
/*!*******************************************!*\
  !*** ./Materials/Textures/baseTexture.ts ***!
  \*******************************************/
/*! exports provided: BaseTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseTexture", function() { return BaseTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/HighDynamicRange/cubemapToSphericalPolynomial */ "./Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_guid__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Misc/guid */ "./Misc/guid.ts");
/* harmony import */ var _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Maths/math.size */ "./Maths/math.size.ts");









/**
 * Base class of all the textures in babylon.
 * It groups all the common properties the materials, post process, lights... might need
 * in order to make a correct use of the texture.
 */
var BaseTexture = /** @class */ (function () {
    /**
     * Instantiates a new BaseTexture.
     * Base class of all the textures in babylon.
     * It groups all the common properties the materials, post process, lights... might need
     * in order to make a correct use of the texture.
     * @param scene Define the scene the texture blongs to
     */
    function BaseTexture(scene) {
        /**
         * Gets or sets an object used to store user defined information.
         */
        this.metadata = null;
        /**
         * For internal use only. Please do not use.
         */
        this.reservedDataStore = null;
        this._hasAlpha = false;
        /**
         * Defines if the alpha value should be determined via the rgb values.
         * If true the luminance of the pixel might be used to find the corresponding alpha value.
         */
        this.getAlphaFromRGB = false;
        /**
         * Intensity or strength of the texture.
         * It is commonly used by materials to fine tune the intensity of the texture
         */
        this.level = 1;
        /**
         * Define the UV chanel to use starting from 0 and defaulting to 0.
         * This is part of the texture as textures usually maps to one uv set.
         */
        this.coordinatesIndex = 0;
        this._coordinatesMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_EXPLICIT_MODE;
        /**
        * | Value | Type               | Description |
        * | ----- | ------------------ | ----------- |
        * | 0     | CLAMP_ADDRESSMODE  |             |
        * | 1     | WRAP_ADDRESSMODE   |             |
        * | 2     | MIRROR_ADDRESSMODE |             |
        */
        this.wrapU = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_WRAP_ADDRESSMODE;
        /**
        * | Value | Type               | Description |
        * | ----- | ------------------ | ----------- |
        * | 0     | CLAMP_ADDRESSMODE  |             |
        * | 1     | WRAP_ADDRESSMODE   |             |
        * | 2     | MIRROR_ADDRESSMODE |             |
        */
        this.wrapV = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_WRAP_ADDRESSMODE;
        /**
        * | Value | Type               | Description |
        * | ----- | ------------------ | ----------- |
        * | 0     | CLAMP_ADDRESSMODE  |             |
        * | 1     | WRAP_ADDRESSMODE   |             |
        * | 2     | MIRROR_ADDRESSMODE |             |
        */
        this.wrapR = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_WRAP_ADDRESSMODE;
        /**
         * With compliant hardware and browser (supporting anisotropic filtering)
         * this defines the level of anisotropic filtering in the texture.
         * The higher the better but the slower. This defaults to 4 as it seems to be the best tradeoff.
         */
        this.anisotropicFilteringLevel = BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL;
        /**
         * Define if the texture contains data in gamma space (most of the png/jpg aside bump).
         * HDR texture are usually stored in linear space.
         * This only impacts the PBR and Background materials
         */
        this.gammaSpace = true;
        /**
         * Is Z inverted in the texture (useful in a cube texture).
         */
        this.invertZ = false;
        /**
         * @hidden
         */
        this.lodLevelInAlpha = false;
        /**
         * Define if the texture is a render target.
         */
        this.isRenderTarget = false;
        /**
         * Define the list of animation attached to the texture.
         */
        this.animations = new Array();
        /**
        * An event triggered when the texture is disposed.
        */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        this._onDisposeObserver = null;
        /**
         * Define the current state of the loading sequence when in delayed load mode.
         */
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].DELAYLOADSTATE_NONE;
        this._scene = null;
        /** @hidden */
        this._texture = null;
        this._uid = null;
        this._cachedSize = _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__["Size"].Zero();
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_5__["EngineStore"].LastCreatedScene;
        if (this._scene) {
            this.uniqueId = this._scene.getUniqueId();
            this._scene.addTexture(this);
        }
        this._uid = null;
    }
    Object.defineProperty(BaseTexture.prototype, "hasAlpha", {
        get: function () {
            return this._hasAlpha;
        },
        /**
         * Define if the texture is having a usable alpha value (can be use for transparency or glossiness for instance).
         */
        set: function (value) {
            if (this._hasAlpha === value) {
                return;
            }
            this._hasAlpha = value;
            if (this._scene) {
                this._scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].MATERIAL_TextureDirtyFlag | _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].MATERIAL_MiscDirtyFlag);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "coordinatesMode", {
        get: function () {
            return this._coordinatesMode;
        },
        /**
        * How a texture is mapped.
        *
        * | Value | Type                                | Description |
        * | ----- | ----------------------------------- | ----------- |
        * | 0     | EXPLICIT_MODE                       |             |
        * | 1     | SPHERICAL_MODE                      |             |
        * | 2     | PLANAR_MODE                         |             |
        * | 3     | CUBIC_MODE                          |             |
        * | 4     | PROJECTION_MODE                     |             |
        * | 5     | SKYBOX_MODE                         |             |
        * | 6     | INVCUBIC_MODE                       |             |
        * | 7     | EQUIRECTANGULAR_MODE                |             |
        * | 8     | FIXED_EQUIRECTANGULAR_MODE          |             |
        * | 9     | FIXED_EQUIRECTANGULAR_MIRRORED_MODE |             |
        */
        set: function (value) {
            if (this._coordinatesMode === value) {
                return;
            }
            this._coordinatesMode = value;
            if (this._scene) {
                this._scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].MATERIAL_TextureDirtyFlag);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "isCube", {
        /**
         * Define if the texture is a cube texture or if false a 2d texture.
         */
        get: function () {
            if (!this._texture) {
                return false;
            }
            return this._texture.isCube;
        },
        set: function (value) {
            if (!this._texture) {
                return;
            }
            this._texture.isCube = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "is3D", {
        /**
         * Define if the texture is a 3d texture (webgl 2) or if false a 2d texture.
         */
        get: function () {
            if (!this._texture) {
                return false;
            }
            return this._texture.is3D;
        },
        set: function (value) {
            if (!this._texture) {
                return;
            }
            this._texture.is3D = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "isRGBD", {
        /**
         * Gets or sets whether or not the texture contains RGBD data.
         */
        get: function () {
            return this._texture != null && this._texture._isRGBD;
        },
        set: function (value) {
            if (this._texture) {
                this._texture._isRGBD = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "noMipmap", {
        /**
         * Are mip maps generated for this texture or not.
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "lodGenerationOffset", {
        /**
         * With prefiltered texture, defined the offset used during the prefiltering steps.
         */
        get: function () {
            if (this._texture) {
                return this._texture._lodGenerationOffset;
            }
            return 0.0;
        },
        set: function (value) {
            if (this._texture) {
                this._texture._lodGenerationOffset = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "lodGenerationScale", {
        /**
         * With prefiltered texture, defined the scale used during the prefiltering steps.
         */
        get: function () {
            if (this._texture) {
                return this._texture._lodGenerationScale;
            }
            return 0.0;
        },
        set: function (value) {
            if (this._texture) {
                this._texture._lodGenerationScale = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "linearSpecularLOD", {
        /**
         * With prefiltered texture, defined if the specular generation is based on a linear ramp.
         * By default we are using a log2 of the linear roughness helping to keep a better resolution for
         * average roughness values.
         */
        get: function () {
            if (this._texture) {
                return this._texture._linearSpecularLOD;
            }
            return false;
        },
        set: function (value) {
            if (this._texture) {
                this._texture._linearSpecularLOD = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "irradianceTexture", {
        /**
         * In case a better definition than spherical harmonics is required for the diffuse part of the environment.
         * You can set the irradiance texture to rely on a texture instead of the spherical approach.
         * This texture need to have the same characteristics than its parent (Cube vs 2d, coordinates mode, Gamma/Linear, RGBD).
         */
        get: function () {
            if (this._texture) {
                return this._texture._irradianceTexture;
            }
            return null;
        },
        set: function (value) {
            if (this._texture) {
                this._texture._irradianceTexture = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "uid", {
        /**
         * Define the unique id of the texture in the scene.
         */
        get: function () {
            if (!this._uid) {
                this._uid = _Misc_guid__WEBPACK_IMPORTED_MODULE_7__["GUID"].RandomId();
            }
            return this._uid;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Return a string representation of the texture.
     * @returns the texture as a string
     */
    BaseTexture.prototype.toString = function () {
        return this.name;
    };
    /**
     * Get the class name of the texture.
     * @returns "BaseTexture"
     */
    BaseTexture.prototype.getClassName = function () {
        return "BaseTexture";
    };
    Object.defineProperty(BaseTexture.prototype, "onDispose", {
        /**
         * Callback triggered when the texture has been disposed.
         * Kept for back compatibility, you can use the onDisposeObservable instead.
         */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "isBlocking", {
        /**
         * Define if the texture is preventinga material to render or not.
         * If not and the texture is not ready, the engine will use a default black texture instead.
         */
        get: function () {
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the scene the texture belongs to.
     * @returns the scene or null if undefined
     */
    BaseTexture.prototype.getScene = function () {
        return this._scene;
    };
    /**
     * Get the texture transform matrix used to offset tile the texture for istance.
     * @returns the transformation matrix
     */
    BaseTexture.prototype.getTextureMatrix = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].IdentityReadOnly;
    };
    /**
     * Get the texture reflection matrix used to rotate/transform the reflection.
     * @returns the reflection matrix
     */
    BaseTexture.prototype.getReflectionTextureMatrix = function () {
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].IdentityReadOnly;
    };
    /**
     * Get the underlying lower level texture from Babylon.
     * @returns the insternal texture
     */
    BaseTexture.prototype.getInternalTexture = function () {
        return this._texture;
    };
    /**
     * Get if the texture is ready to be consumed (either it is ready or it is not blocking)
     * @returns true if ready or not blocking
     */
    BaseTexture.prototype.isReadyOrNotBlocking = function () {
        return !this.isBlocking || this.isReady();
    };
    /**
     * Get if the texture is ready to be used (downloaded, converted, mip mapped...).
     * @returns true if fully ready
     */
    BaseTexture.prototype.isReady = function () {
        if (this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].DELAYLOADSTATE_NOTLOADED) {
            this.delayLoad();
            return false;
        }
        if (this._texture) {
            return this._texture.isReady;
        }
        return false;
    };
    /**
     * Get the size of the texture.
     * @returns the texture size.
     */
    BaseTexture.prototype.getSize = function () {
        if (this._texture) {
            if (this._texture.width) {
                this._cachedSize.width = this._texture.width;
                this._cachedSize.height = this._texture.height;
                return this._cachedSize;
            }
            if (this._texture._size) {
                this._cachedSize.width = this._texture._size;
                this._cachedSize.height = this._texture._size;
                return this._cachedSize;
            }
        }
        return this._cachedSize;
    };
    /**
     * Get the base size of the texture.
     * It can be different from the size if the texture has been resized for POT for instance
     * @returns the base size
     */
    BaseTexture.prototype.getBaseSize = function () {
        if (!this.isReady() || !this._texture) {
            return _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__["Size"].Zero();
        }
        if (this._texture._size) {
            return new _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__["Size"](this._texture._size, this._texture._size);
        }
        return new _Maths_math_size__WEBPACK_IMPORTED_MODULE_8__["Size"](this._texture.baseWidth, this._texture.baseHeight);
    };
    /**
           * Update the sampling mode of the texture.
           * Default is Trilinear mode.
           *
           * | Value | Type               | Description |
           * | ----- | ------------------ | ----------- |
           * | 1     | NEAREST_SAMPLINGMODE or NEAREST_NEAREST_MIPLINEAR  | Nearest is: mag = nearest, min = nearest, mip = linear |
           * | 2     | BILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPNEAREST | Bilinear is: mag = linear, min = linear, mip = nearest |
           * | 3     | TRILINEAR_SAMPLINGMODE or LINEAR_LINEAR_MIPLINEAR | Trilinear is: mag = linear, min = linear, mip = linear |
           * | 4     | NEAREST_NEAREST_MIPNEAREST |             |
           * | 5    | NEAREST_LINEAR_MIPNEAREST |             |
           * | 6    | NEAREST_LINEAR_MIPLINEAR |             |
           * | 7    | NEAREST_LINEAR |             |
           * | 8    | NEAREST_NEAREST |             |
           * | 9   | LINEAR_NEAREST_MIPNEAREST |             |
           * | 10   | LINEAR_NEAREST_MIPLINEAR |             |
           * | 11   | LINEAR_LINEAR |             |
           * | 12   | LINEAR_NEAREST |             |
           *
           *    > _mag_: magnification filter (close to the viewer)
           *    > _min_: minification filter (far from the viewer)
           *    > _mip_: filter used between mip map levels
           *@param samplingMode Define the new sampling mode of the texture
           */
    BaseTexture.prototype.updateSamplingMode = function (samplingMode) {
        if (!this._texture) {
            return;
        }
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        scene.getEngine().updateTextureSamplingMode(samplingMode, this._texture);
    };
    /**
     * Scales the texture if is `canRescale()`
     * @param ratio the resize factor we want to use to rescale
     */
    BaseTexture.prototype.scale = function (ratio) {
    };
    Object.defineProperty(BaseTexture.prototype, "canRescale", {
        /**
         * Get if the texture can rescale.
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    BaseTexture.prototype._getFromCache = function (url, noMipmap, sampling, invertY) {
        if (!this._scene) {
            return null;
        }
        var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
        for (var index = 0; index < texturesCache.length; index++) {
            var texturesCacheEntry = texturesCache[index];
            if (invertY === undefined || invertY === texturesCacheEntry.invertY) {
                if (texturesCacheEntry.url === url && texturesCacheEntry.generateMipMaps === !noMipmap) {
                    if (!sampling || sampling === texturesCacheEntry.samplingMode) {
                        texturesCacheEntry.incrementReferences();
                        return texturesCacheEntry;
                    }
                }
            }
        }
        return null;
    };
    /** @hidden */
    BaseTexture.prototype._rebuild = function () {
    };
    /**
     * Triggers the load sequence in delayed load mode.
     */
    BaseTexture.prototype.delayLoad = function () {
    };
    /**
     * Clones the texture.
     * @returns the cloned texture
     */
    BaseTexture.prototype.clone = function () {
        return null;
    };
    Object.defineProperty(BaseTexture.prototype, "textureType", {
        /**
         * Get the texture underlying type (INT, FLOAT...)
         */
        get: function () {
            if (!this._texture) {
                return _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_INT;
            }
            return (this._texture.type !== undefined) ? this._texture.type : _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "textureFormat", {
        /**
         * Get the texture underlying format (RGB, RGBA...)
         */
        get: function () {
            if (!this._texture) {
                return _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA;
            }
            return (this._texture.format !== undefined) ? this._texture.format : _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Reads the pixels stored in the webgl texture and returns them as an ArrayBuffer.
     * This will returns an RGBA array buffer containing either in values (0-255) or
     * float values (0-1) depending of the underlying buffer type.
     * @param faceIndex defines the face of the texture to read (in case of cube texture)
     * @param level defines the LOD level of the texture to read (in case of Mip Maps)
     * @param buffer defines a user defined buffer to fill with data (can be null)
     * @returns The Array buffer containing the pixels data.
     */
    BaseTexture.prototype.readPixels = function (faceIndex, level, buffer) {
        if (faceIndex === void 0) { faceIndex = 0; }
        if (level === void 0) { level = 0; }
        if (buffer === void 0) { buffer = null; }
        if (!this._texture) {
            return null;
        }
        var size = this.getSize();
        var width = size.width;
        var height = size.height;
        var scene = this.getScene();
        if (!scene) {
            return null;
        }
        var engine = scene.getEngine();
        if (level != 0) {
            width = width / Math.pow(2, level);
            height = height / Math.pow(2, level);
            width = Math.round(width);
            height = Math.round(height);
        }
        if (this._texture.isCube) {
            return engine._readTexturePixels(this._texture, width, height, faceIndex, level, buffer);
        }
        return engine._readTexturePixels(this._texture, width, height, -1, level, buffer);
    };
    /**
     * Release and destroy the underlying lower level texture aka internalTexture.
     */
    BaseTexture.prototype.releaseInternalTexture = function () {
        if (this._texture) {
            this._texture.dispose();
            this._texture = null;
        }
    };
    Object.defineProperty(BaseTexture.prototype, "sphericalPolynomial", {
        /**
         * Get the polynomial representation of the texture data.
         * This is mainly use as a fast way to recover IBL Diffuse irradiance data.
         * @see https://learnopengl.com/PBR/IBL/Diffuse-irradiance
         */
        get: function () {
            if (!this._texture || !_Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_3__["CubeMapToSphericalPolynomialTools"] || !this.isReady()) {
                return null;
            }
            if (!this._texture._sphericalPolynomial) {
                this._texture._sphericalPolynomial =
                    _Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_3__["CubeMapToSphericalPolynomialTools"].ConvertCubeMapTextureToSphericalPolynomial(this);
            }
            return this._texture._sphericalPolynomial;
        },
        set: function (value) {
            if (this._texture) {
                this._texture._sphericalPolynomial = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "_lodTextureHigh", {
        /** @hidden */
        get: function () {
            if (this._texture) {
                return this._texture._lodTextureHigh;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "_lodTextureMid", {
        /** @hidden */
        get: function () {
            if (this._texture) {
                return this._texture._lodTextureMid;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseTexture.prototype, "_lodTextureLow", {
        /** @hidden */
        get: function () {
            if (this._texture) {
                return this._texture._lodTextureLow;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Dispose the texture and release its associated resources.
     */
    BaseTexture.prototype.dispose = function () {
        if (!this._scene) {
            return;
        }
        // Animations
        if (this._scene.stopAnimation) {
            this._scene.stopAnimation(this);
        }
        // Remove from scene
        this._scene._removePendingData(this);
        var index = this._scene.textures.indexOf(this);
        if (index >= 0) {
            this._scene.textures.splice(index, 1);
        }
        this._scene.onTextureRemovedObservable.notifyObservers(this);
        if (this._texture === undefined) {
            return;
        }
        // Release
        this.releaseInternalTexture();
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
    };
    /**
     * Serialize the texture into a JSON representation that can be parsed later on.
     * @returns the JSON representation of the texture
     */
    BaseTexture.prototype.serialize = function () {
        if (!this.name) {
            return null;
        }
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        // Animations
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].AppendSerializedAnimations(this, serializationObject);
        return serializationObject;
    };
    /**
     * Helper function to be called back once a list of texture contains only ready textures.
     * @param textures Define the list of textures to wait for
     * @param callback Define the callback triggered once the entire list will be ready
     */
    BaseTexture.WhenAllReady = function (textures, callback) {
        var numRemaining = textures.length;
        if (numRemaining === 0) {
            callback();
            return;
        }
        var _loop_1 = function () {
            texture = textures[i];
            if (texture.isReady()) {
                if (--numRemaining === 0) {
                    callback();
                }
            }
            else {
                onLoadObservable = texture.onLoadObservable;
                var onLoadCallback_1 = function () {
                    onLoadObservable.removeCallback(onLoadCallback_1);
                    if (--numRemaining === 0) {
                        callback();
                    }
                };
                onLoadObservable.add(onLoadCallback_1);
            }
        };
        var texture, onLoadObservable;
        for (var i = 0; i < textures.length; i++) {
            _loop_1();
        }
    };
    /**
     * Default anisotropic filtering level for the application.
     * It is set to 4 as a good tradeoff between perf and quality.
     */
    BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL = 4;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "uniqueId", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "name", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "metadata", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("hasAlpha")
    ], BaseTexture.prototype, "_hasAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "getAlphaFromRGB", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "level", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "coordinatesIndex", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("coordinatesMode")
    ], BaseTexture.prototype, "_coordinatesMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "wrapU", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "wrapV", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "wrapR", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "anisotropicFilteringLevel", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "isCube", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "is3D", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "gammaSpace", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "invertZ", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "lodLevelInAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "lodGenerationOffset", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "lodGenerationScale", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "linearSpecularLOD", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])()
    ], BaseTexture.prototype, "irradianceTexture", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], BaseTexture.prototype, "isRenderTarget", void 0);
    return BaseTexture;
}());



/***/ }),

/***/ "./Materials/Textures/colorGradingTexture.ts":
/*!***************************************************!*\
  !*** ./Materials/Textures/colorGradingTexture.ts ***!
  \***************************************************/
/*! exports provided: ColorGradingTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorGradingTexture", function() { return ColorGradingTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");





/**
 * This represents a color grading texture. This acts as a lookup table LUT, useful during post process
 * It can help converting any input color in a desired output one. This can then be used to create effects
 * from sepia, black and white to sixties or futuristic rendering...
 *
 * The only supported format is currently 3dl.
 * More information on LUT: https://en.wikipedia.org/wiki/3D_lookup_table
 */
var ColorGradingTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ColorGradingTexture, _super);
    /**
     * Instantiates a ColorGradingTexture from the following parameters.
     *
     * @param url The location of the color gradind data (currently only supporting 3dl)
     * @param scene The scene the texture will be used in
     */
    function ColorGradingTexture(url, scene) {
        var _this = _super.call(this, scene) || this;
        if (!url) {
            return _this;
        }
        _this._engine = scene.getEngine();
        _this._textureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        _this.name = url;
        _this.url = url;
        _this.hasAlpha = false;
        _this.isCube = false;
        _this.is3D = _this._engine.webGLVersion > 1;
        _this.wrapU = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_CLAMP_ADDRESSMODE;
        _this.wrapV = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_CLAMP_ADDRESSMODE;
        _this.wrapR = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_CLAMP_ADDRESSMODE;
        _this.anisotropicFilteringLevel = 1;
        _this._texture = _this._getFromCache(url, true);
        if (!_this._texture) {
            if (!scene.useDelayedTextureLoading) {
                _this.loadTexture();
            }
            else {
                _this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].DELAYLOADSTATE_NOTLOADED;
            }
        }
        return _this;
    }
    /**
     * Returns the texture matrix used in most of the material.
     * This is not used in color grading but keep for troubleshooting purpose (easily swap diffuse by colorgrading to look in).
     */
    ColorGradingTexture.prototype.getTextureMatrix = function () {
        return this._textureMatrix;
    };
    /**
     * Occurs when the file being loaded is a .3dl LUT file.
     */
    ColorGradingTexture.prototype.load3dlTexture = function () {
        var engine = this._engine;
        var texture;
        if (engine.webGLVersion === 1) {
            texture = engine.createRawTexture(null, 1, 1, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE);
        }
        else {
            texture = engine.createRawTexture3D(null, 1, 1, 1, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE);
        }
        this._texture = texture;
        var callback = function (text) {
            if (typeof text !== "string") {
                return;
            }
            var data = null;
            var tempData = null;
            var line;
            var lines = text.split('\n');
            var size = 0, pixelIndexW = 0, pixelIndexH = 0, pixelIndexSlice = 0;
            var maxColor = 0;
            for (var i = 0; i < lines.length; i++) {
                line = lines[i];
                if (!ColorGradingTexture._noneEmptyLineRegex.test(line)) {
                    continue;
                }
                if (line.indexOf('#') === 0) {
                    continue;
                }
                var words = line.split(" ");
                if (size === 0) {
                    // Number of space + one
                    size = words.length;
                    data = new Uint8Array(size * size * size * 4); // volume texture of side size and rgb 8
                    tempData = new Float32Array(size * size * size * 4);
                    continue;
                }
                if (size != 0) {
                    var r = Math.max(parseInt(words[0]), 0);
                    var g = Math.max(parseInt(words[1]), 0);
                    var b = Math.max(parseInt(words[2]), 0);
                    maxColor = Math.max(r, maxColor);
                    maxColor = Math.max(g, maxColor);
                    maxColor = Math.max(b, maxColor);
                    var pixelStorageIndex = (pixelIndexW + pixelIndexSlice * size + pixelIndexH * size * size) * 4;
                    if (tempData) {
                        tempData[pixelStorageIndex + 0] = r;
                        tempData[pixelStorageIndex + 1] = g;
                        tempData[pixelStorageIndex + 2] = b;
                    }
                    // Keep for reference in case of back compat problems.
                    // pixelIndexSlice++;
                    // if (pixelIndexSlice % size == 0) {
                    //     pixelIndexH++;
                    //     pixelIndexSlice = 0;
                    //     if (pixelIndexH % size == 0) {
                    //         pixelIndexW++;
                    //         pixelIndexH = 0;
                    //     }
                    // }
                    pixelIndexH++;
                    if (pixelIndexH % size == 0) {
                        pixelIndexSlice++;
                        pixelIndexH = 0;
                        if (pixelIndexSlice % size == 0) {
                            pixelIndexW++;
                            pixelIndexSlice = 0;
                        }
                    }
                }
            }
            if (tempData && data) {
                for (var i = 0; i < tempData.length; i++) {
                    if (i > 0 && (i + 1) % 4 === 0) {
                        data[i] = 255;
                    }
                    else {
                        var value = tempData[i];
                        data[i] = (value / maxColor * 255);
                    }
                }
            }
            if (texture.is3D) {
                texture.updateSize(size, size, size);
                engine.updateRawTexture3D(texture, data, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA, false);
            }
            else {
                texture.updateSize(size * size, size);
                engine.updateRawTexture(texture, data, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA, false);
            }
        };
        var scene = this.getScene();
        if (scene) {
            scene._loadFile(this.url, callback);
        }
        else {
            this._engine._loadFile(this.url, callback);
        }
        return this._texture;
    };
    /**
     * Starts the loading process of the texture.
     */
    ColorGradingTexture.prototype.loadTexture = function () {
        if (this.url && this.url.toLocaleLowerCase().indexOf(".3dl") == (this.url.length - 4)) {
            this.load3dlTexture();
        }
    };
    /**
     * Clones the color gradind texture.
     */
    ColorGradingTexture.prototype.clone = function () {
        var newTexture = new ColorGradingTexture(this.url, this.getScene());
        // Base texture
        newTexture.level = this.level;
        return newTexture;
    };
    /**
     * Called during delayed load for textures.
     */
    ColorGradingTexture.prototype.delayLoad = function () {
        if (this.delayLoadState !== _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].DELAYLOADSTATE_NOTLOADED) {
            return;
        }
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].DELAYLOADSTATE_LOADED;
        this._texture = this._getFromCache(this.url, true);
        if (!this._texture) {
            this.loadTexture();
        }
    };
    /**
     * Parses a color grading texture serialized by Babylon.
     * @param parsedTexture The texture information being parsedTexture
     * @param scene The scene to load the texture in
     * @param rootUrl The root url of the data assets to load
     * @return A color gradind texture
     */
    ColorGradingTexture.Parse = function (parsedTexture, scene) {
        var texture = null;
        if (parsedTexture.name && !parsedTexture.isRenderTarget) {
            texture = new ColorGradingTexture(parsedTexture.name, scene);
            texture.name = parsedTexture.name;
            texture.level = parsedTexture.level;
        }
        return texture;
    };
    /**
     * Serializes the LUT texture to json format.
     */
    ColorGradingTexture.prototype.serialize = function () {
        if (!this.name) {
            return null;
        }
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.level = this.level;
        serializationObject.customType = "BABYLON.ColorGradingTexture";
        return serializationObject;
    };
    /**
     * Empty line regex stored for GC.
     */
    ColorGradingTexture._noneEmptyLineRegex = /\S+/;
    return ColorGradingTexture;
}(_Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_2__["BaseTexture"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes["BABYLON.ColorGradingTexture"] = ColorGradingTexture;


/***/ }),

/***/ "./Materials/Textures/cubeTexture.ts":
/*!*******************************************!*\
  !*** ./Materials/Textures/cubeTexture.ts ***!
  \*******************************************/
/*! exports provided: CubeTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeTexture", function() { return CubeTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Engines_Extensions_engine_cubeTexture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Engines/Extensions/engine.cubeTexture */ "./Engines/Extensions/engine.cubeTexture.ts");









/**
 * Class for creating a cube texture
 */
var CubeTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CubeTexture, _super);
    /**
     * Creates a cube texture to use with reflection for instance. It can be based upon dds or six images as well
     * as prefiltered data.
     * @param rootUrl defines the url of the texture or the root name of the six images
     * @param scene defines the scene the texture is attached to
     * @param extensions defines the suffixes add to the picture name in case six images are in use like _px.jpg...
     * @param noMipmap defines if mipmaps should be created or not
     * @param files defines the six files to load for the different faces in that order: px, py, pz, nx, ny, nz
     * @param onLoad defines a callback triggered at the end of the file load if no errors occured
     * @param onError defines a callback triggered in case of error during load
     * @param format defines the internal format to use for the texture once loaded
     * @param prefiltered defines whether or not the texture is created from prefiltered data
     * @param forcedExtension defines the extensions to use (force a special type of file to load) in case it is different from the file name
     * @param createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary
     * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
     * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
     * @return the cube texture
     */
    function CubeTexture(rootUrl, scene, extensions, noMipmap, files, onLoad, onError, format, prefiltered, forcedExtension, createPolynomials, lodScale, lodOffset) {
        if (extensions === void 0) { extensions = null; }
        if (noMipmap === void 0) { noMipmap = false; }
        if (files === void 0) { files = null; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (format === void 0) { format = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA; }
        if (prefiltered === void 0) { prefiltered = false; }
        if (forcedExtension === void 0) { forcedExtension = null; }
        if (createPolynomials === void 0) { createPolynomials = false; }
        if (lodScale === void 0) { lodScale = 0.8; }
        if (lodOffset === void 0) { lodOffset = 0; }
        var _this = _super.call(this, scene) || this;
        /**
         * Gets or sets the center of the bounding box associated with the cube texture.
         * It must define where the camera used to render the texture was set
         * @see http://doc.babylonjs.com/how_to/reflect#using-local-cubemap-mode
         */
        _this.boundingBoxPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._rotationY = 0;
        /** @hidden */
        _this._prefiltered = false;
        _this.name = rootUrl;
        _this.url = rootUrl;
        _this._noMipmap = noMipmap;
        _this.hasAlpha = false;
        _this._format = format;
        _this.isCube = true;
        _this._textureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
        _this._createPolynomials = createPolynomials;
        _this.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].CUBIC_MODE;
        if (!rootUrl && !files) {
            return _this;
        }
        var lastDot = rootUrl.lastIndexOf(".");
        var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
        var isDDS = (extension === ".dds");
        var isEnv = (extension === ".env");
        if (isEnv) {
            _this.gammaSpace = false;
            _this._prefiltered = false;
        }
        else {
            _this._prefiltered = prefiltered;
            if (prefiltered) {
                _this.gammaSpace = false;
            }
        }
        _this._texture = _this._getFromCache(rootUrl, noMipmap);
        if (!files) {
            if (!isEnv && !isDDS && !extensions) {
                extensions = ["_px.jpg", "_py.jpg", "_pz.jpg", "_nx.jpg", "_ny.jpg", "_nz.jpg"];
            }
            files = [];
            if (extensions) {
                for (var index = 0; index < extensions.length; index++) {
                    files.push(rootUrl + extensions[index]);
                }
            }
        }
        _this._files = files;
        if (!_this._texture) {
            if (!scene.useDelayedTextureLoading) {
                if (prefiltered) {
                    _this._texture = scene.getEngine().createPrefilteredCubeTexture(rootUrl, scene, lodScale, lodOffset, onLoad, onError, format, forcedExtension, _this._createPolynomials);
                }
                else {
                    _this._texture = scene.getEngine().createCubeTexture(rootUrl, scene, files, noMipmap, onLoad, onError, _this._format, forcedExtension, false, lodScale, lodOffset);
                }
            }
            else {
                _this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].DELAYLOADSTATE_NOTLOADED;
            }
        }
        else if (onLoad) {
            if (_this._texture.isReady) {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].SetImmediate(function () { return onLoad(); });
            }
            else {
                _this._texture.onLoadedObservable.add(onLoad);
            }
        }
        return _this;
    }
    Object.defineProperty(CubeTexture.prototype, "boundingBoxSize", {
        /**
         * Returns the bounding box size
         * @see http://doc.babylonjs.com/how_to/reflect#using-local-cubemap-mode
         */
        get: function () {
            return this._boundingBoxSize;
        },
        /**
         * Gets or sets the size of the bounding box associated with the cube texture
         * When defined, the cubemap will switch to local mode
         * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity
         * @example https://www.babylonjs-playground.com/#RNASML
         */
        set: function (value) {
            if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {
                return;
            }
            this._boundingBoxSize = value;
            var scene = this.getScene();
            if (scene) {
                scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].MATERIAL_TextureDirtyFlag);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CubeTexture.prototype, "rotationY", {
        /**
         * Gets texture matrix rotation angle around Y axis radians.
         */
        get: function () {
            return this._rotationY;
        },
        /**
         * Sets texture matrix rotation angle around Y axis in radians.
         */
        set: function (value) {
            this._rotationY = value;
            this.setReflectionTextureMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationY(this._rotationY));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(CubeTexture.prototype, "noMipmap", {
        /**
         * Are mip maps generated for this texture or not.
         */
        get: function () {
            return this._noMipmap;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Creates a cube texture from an array of image urls
     * @param files defines an array of image urls
     * @param scene defines the hosting scene
     * @param noMipmap specifies if mip maps are not used
     * @returns a cube texture
     */
    CubeTexture.CreateFromImages = function (files, scene, noMipmap) {
        var rootUrlKey = "";
        files.forEach(function (url) { return rootUrlKey += url; });
        return new CubeTexture(rootUrlKey, scene, null, noMipmap, files);
    };
    /**
     * Creates and return a texture created from prefilterd data by tools like IBL Baker or Lys.
     * @param url defines the url of the prefiltered texture
     * @param scene defines the scene the texture is attached to
     * @param forcedExtension defines the extension of the file if different from the url
     * @param createPolynomials defines whether or not to create polynomial harmonics from the texture data if necessary
     * @return the prefiltered texture
     */
    CubeTexture.CreateFromPrefilteredData = function (url, scene, forcedExtension, createPolynomials) {
        if (forcedExtension === void 0) { forcedExtension = null; }
        if (createPolynomials === void 0) { createPolynomials = true; }
        return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
    };
    Object.defineProperty(CubeTexture.prototype, "isPrefiltered", {
        /**
         * Gets a boolean indicating if the cube texture contains prefiltered mips (used to simulate roughness with PBR)
         */
        get: function () {
            return this._prefiltered;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the current class name of the texture useful for serialization or dynamic coding.
     * @returns "CubeTexture"
     */
    CubeTexture.prototype.getClassName = function () {
        return "CubeTexture";
    };
    /**
     * Update the url (and optional buffer) of this texture if url was null during construction.
     * @param url the url of the texture
     * @param forcedExtension defines the extension to use
     * @param onLoad callback called when the texture is loaded  (defaults to null)
     */
    CubeTexture.prototype.updateURL = function (url, forcedExtension, onLoad) {
        if (this.url) {
            this.releaseInternalTexture();
            this.getScene().markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].MATERIAL_TextureDirtyFlag);
        }
        this.name = url;
        this.url = url;
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].DELAYLOADSTATE_NOTLOADED;
        this._prefiltered = false;
        if (onLoad) {
            this._delayedOnLoad = onLoad;
        }
        this.delayLoad(forcedExtension);
    };
    /**
     * Delays loading of the cube texture
     * @param forcedExtension defines the extension to use
     */
    CubeTexture.prototype.delayLoad = function (forcedExtension) {
        if (this.delayLoadState !== _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].DELAYLOADSTATE_NOTLOADED) {
            return;
        }
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].DELAYLOADSTATE_LOADED;
        this._texture = this._getFromCache(this.url, this._noMipmap);
        if (!this._texture) {
            if (this._prefiltered) {
                this._texture = scene.getEngine().createPrefilteredCubeTexture(this.url, scene, this.lodGenerationScale, this.lodGenerationOffset, this._delayedOnLoad, undefined, this._format, undefined, this._createPolynomials);
            }
            else {
                this._texture = scene.getEngine().createCubeTexture(this.url, scene, this._files, this._noMipmap, this._delayedOnLoad, null, this._format, forcedExtension);
            }
        }
    };
    /**
     * Returns the reflection texture matrix
     * @returns the reflection texture matrix
     */
    CubeTexture.prototype.getReflectionTextureMatrix = function () {
        return this._textureMatrix;
    };
    /**
     * Sets the reflection texture matrix
     * @param value Reflection texture matrix
     */
    CubeTexture.prototype.setReflectionTextureMatrix = function (value) {
        var _this = this;
        if (value.updateFlag === this._textureMatrix.updateFlag) {
            return;
        }
        if (value.isIdentity() !== this._textureMatrix.isIdentity()) {
            this.getScene().markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].MATERIAL_TextureDirtyFlag, function (mat) { return mat.getActiveTextures().indexOf(_this) !== -1; });
        }
        this._textureMatrix = value;
    };
    /**
     * Parses text to create a cube texture
     * @param parsedTexture define the serialized text to read from
     * @param scene defines the hosting scene
     * @param rootUrl defines the root url of the cube texture
     * @returns a cube texture
     */
    CubeTexture.Parse = function (parsedTexture, scene, rootUrl) {
        var texture = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () {
            var prefiltered = false;
            if (parsedTexture.prefiltered) {
                prefiltered = parsedTexture.prefiltered;
            }
            return new CubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.extensions, false, parsedTexture.files || null, null, null, undefined, prefiltered);
        }, parsedTexture, scene);
        // Local Cubemaps
        if (parsedTexture.boundingBoxPosition) {
            texture.boundingBoxPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].FromArray(parsedTexture.boundingBoxPosition);
        }
        if (parsedTexture.boundingBoxSize) {
            texture.boundingBoxSize = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].FromArray(parsedTexture.boundingBoxSize);
        }
        // Animations
        if (parsedTexture.animations) {
            for (var animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {
                var parsedAnimation = parsedTexture.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    texture.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
        }
        return texture;
    };
    /**
     * Makes a clone, or deep copy, of the cube texture
     * @returns a new cube texture
     */
    CubeTexture.prototype.clone = function () {
        var _this = this;
        var scene = this.getScene();
        var uniqueId = 0;
        var newCubeTexture = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () {
            if (!scene) {
                return _this;
            }
            var cubeTexture = new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
            uniqueId = cubeTexture.uniqueId;
            return cubeTexture;
        }, this);
        newCubeTexture.uniqueId = uniqueId;
        return newCubeTexture;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("rotationY")
    ], CubeTexture.prototype, "rotationY", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("files")
    ], CubeTexture.prototype, "_files", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsMatrix"])("textureMatrix")
    ], CubeTexture.prototype, "_textureMatrix", void 0);
    return CubeTexture;
}(_Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_4__["BaseTexture"]));

_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"]._CubeTextureParser = CubeTexture.Parse;
// Some exporters relies on Tools.Instantiate
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__["_TypeStore"].RegisteredTypes["BABYLON.CubeTexture"] = CubeTexture;


/***/ }),

/***/ "./Materials/Textures/dynamicTexture.ts":
/*!**********************************************!*\
  !*** ./Materials/Textures/dynamicTexture.ts ***!
  \**********************************************/
/*! exports provided: DynamicTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DynamicTexture", function() { return DynamicTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");




/**
 * A class extending Texture allowing drawing on a texture
 * @see http://doc.babylonjs.com/how_to/dynamictexture
 */
var DynamicTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DynamicTexture, _super);
    /**
     * Creates a DynamicTexture
     * @param name defines the name of the texture
     * @param options provides 3 alternatives for width and height of texture, a canvas, object with width and height properties, number for both width and height
     * @param scene defines the scene where you want the texture
     * @param generateMipMaps defines the use of MinMaps or not (default is false)
     * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
     * @param format defines the texture format to use (default is Engine.TEXTUREFORMAT_RGBA)
     */
    function DynamicTexture(name, options, scene, generateMipMaps, samplingMode, format) {
        if (scene === void 0) { scene = null; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (format === void 0) { format = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA; }
        var _this = _super.call(this, null, scene, !generateMipMaps, undefined, samplingMode, undefined, undefined, undefined, undefined, format) || this;
        _this.name = name;
        _this._engine = _this.getScene().getEngine();
        _this.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].CLAMP_ADDRESSMODE;
        _this.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].CLAMP_ADDRESSMODE;
        _this._generateMipMaps = generateMipMaps;
        if (options.getContext) {
            _this._canvas = options;
            _this._texture = _this._engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
        }
        else {
            _this._canvas = document.createElement("canvas");
            if (options.width || options.width === 0) {
                _this._texture = _this._engine.createDynamicTexture(options.width, options.height, generateMipMaps, samplingMode);
            }
            else {
                _this._texture = _this._engine.createDynamicTexture(options, options, generateMipMaps, samplingMode);
            }
        }
        var textureSize = _this.getSize();
        _this._canvas.width = textureSize.width;
        _this._canvas.height = textureSize.height;
        _this._context = _this._canvas.getContext("2d");
        return _this;
    }
    /**
     * Get the current class name of the texture useful for serialization or dynamic coding.
     * @returns "DynamicTexture"
     */
    DynamicTexture.prototype.getClassName = function () {
        return "DynamicTexture";
    };
    Object.defineProperty(DynamicTexture.prototype, "canRescale", {
        /**
         * Gets the current state of canRescale
         */
        get: function () {
            return true;
        },
        enumerable: true,
        configurable: true
    });
    DynamicTexture.prototype._recreate = function (textureSize) {
        this._canvas.width = textureSize.width;
        this._canvas.height = textureSize.height;
        this.releaseInternalTexture();
        this._texture = this._engine.createDynamicTexture(textureSize.width, textureSize.height, this._generateMipMaps, this.samplingMode);
    };
    /**
     * Scales the texture
     * @param ratio the scale factor to apply to both width and height
     */
    DynamicTexture.prototype.scale = function (ratio) {
        var textureSize = this.getSize();
        textureSize.width *= ratio;
        textureSize.height *= ratio;
        this._recreate(textureSize);
    };
    /**
     * Resizes the texture
     * @param width the new width
     * @param height the new height
     */
    DynamicTexture.prototype.scaleTo = function (width, height) {
        var textureSize = this.getSize();
        textureSize.width = width;
        textureSize.height = height;
        this._recreate(textureSize);
    };
    /**
     * Gets the context of the canvas used by the texture
     * @returns the canvas context of the dynamic texture
     */
    DynamicTexture.prototype.getContext = function () {
        return this._context;
    };
    /**
     * Clears the texture
     */
    DynamicTexture.prototype.clear = function () {
        var size = this.getSize();
        this._context.fillRect(0, 0, size.width, size.height);
    };
    /**
     * Updates the texture
     * @param invertY defines the direction for the Y axis (default is true - y increases downwards)
     * @param premulAlpha defines if alpha is stored as premultiplied (default is false)
     */
    DynamicTexture.prototype.update = function (invertY, premulAlpha) {
        if (premulAlpha === void 0) { premulAlpha = false; }
        this._engine.updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY, premulAlpha, this._format || undefined);
    };
    /**
     * Draws text onto the texture
     * @param text defines the text to be drawn
     * @param x defines the placement of the text from the left
     * @param y defines the placement of the text from the top when invertY is true and from the bottom when false
     * @param font defines the font to be used with font-style, font-size, font-name
     * @param color defines the color used for the text
     * @param clearColor defines the color for the canvas, use null to not overwrite canvas
     * @param invertY defines the direction for the Y axis (default is true - y increases downwards)
     * @param update defines whether texture is immediately update (default is true)
     */
    DynamicTexture.prototype.drawText = function (text, x, y, font, color, clearColor, invertY, update) {
        if (update === void 0) { update = true; }
        var size = this.getSize();
        if (clearColor) {
            this._context.fillStyle = clearColor;
            this._context.fillRect(0, 0, size.width, size.height);
        }
        this._context.font = font;
        if (x === null || x === undefined) {
            var textSize = this._context.measureText(text);
            x = (size.width - textSize.width) / 2;
        }
        if (y === null || y === undefined) {
            var fontSize = parseInt((font.replace(/\D/g, '')));
            y = (size.height / 2) + (fontSize / 3.65);
        }
        this._context.fillStyle = color;
        this._context.fillText(text, x, y);
        if (update) {
            this.update(invertY);
        }
    };
    /**
     * Clones the texture
     * @returns the clone of the texture.
     */
    DynamicTexture.prototype.clone = function () {
        var scene = this.getScene();
        if (!scene) {
            return this;
        }
        var textureSize = this.getSize();
        var newTexture = new DynamicTexture(this.name, textureSize, scene, this._generateMipMaps);
        // Base texture
        newTexture.hasAlpha = this.hasAlpha;
        newTexture.level = this.level;
        // Dynamic Texture
        newTexture.wrapU = this.wrapU;
        newTexture.wrapV = this.wrapV;
        return newTexture;
    };
    /**
     * Serializes the dynamic texture.  The scene should be ready before the dynamic texture is serialized
     * @returns a serialized dynamic texture object
     */
    DynamicTexture.prototype.serialize = function () {
        var scene = this.getScene();
        if (scene && !scene.isReady()) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("The scene must be ready before serializing the dynamic texture");
        }
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.base64String = this._canvas.toDataURL();
        serializationObject.invertY = this._invertY;
        serializationObject.samplingMode = this.samplingMode;
        return serializationObject;
    };
    /** @hidden */
    DynamicTexture.prototype._rebuild = function () {
        this.update();
    };
    return DynamicTexture;
}(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"]));



/***/ }),

/***/ "./Materials/Textures/equiRectangularCubeTexture.ts":
/*!**********************************************************!*\
  !*** ./Materials/Textures/equiRectangularCubeTexture.ts ***!
  \**********************************************************/
/*! exports provided: EquiRectangularCubeTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTexture", function() { return EquiRectangularCubeTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_HighDynamicRange_panoramaToCubemap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/HighDynamicRange/panoramaToCubemap */ "./Misc/HighDynamicRange/panoramaToCubemap.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _baseTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Engines_Extensions_engine_rawTexture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Engines/Extensions/engine.rawTexture */ "./Engines/Extensions/engine.rawTexture.ts");







/**
 * This represents a texture coming from an equirectangular image supported by the web browser canvas.
 */
var EquiRectangularCubeTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](EquiRectangularCubeTexture, _super);
    /**
     * Instantiates an EquiRectangularCubeTexture from the following parameters.
     * @param url The location of the image
     * @param scene The scene the texture will be used in
     * @param size The cubemap desired size (the more it increases the longer the generation will be)
     * @param noMipmap Forces to not generate the mipmap if true
     * @param gammaSpace Specifies if the texture will be used in gamma or linear space
     * (the PBR material requires those textures in linear space, but the standard material would require them in Gamma space)
     * @param onLoad — defines a callback called when texture is loaded
     * @param onError — defines a callback called if there is an error
     */
    function EquiRectangularCubeTexture(url, scene, size, noMipmap, gammaSpace, onLoad, onError) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (gammaSpace === void 0) { gammaSpace = true; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        var _this = _super.call(this, scene) || this;
        _this._onLoad = null;
        _this._onError = null;
        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
        _this.coordinatesMode = _texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CUBIC_MODE;
        if (!url) {
            throw new Error('Image url is not set');
        }
        _this.name = url;
        _this.url = url;
        _this._size = size;
        _this._noMipmap = noMipmap;
        _this.gammaSpace = gammaSpace;
        _this._onLoad = onLoad;
        _this._onError = onError;
        _this.hasAlpha = false;
        _this.isCube = true;
        _this._texture = _this._getFromCache(url, _this._noMipmap);
        if (!_this._texture) {
            if (!scene.useDelayedTextureLoading) {
                _this.loadImage(_this.loadTexture.bind(_this), _this._onError);
            }
            else {
                _this.delayLoadState = _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].DELAYLOADSTATE_NOTLOADED;
            }
        }
        else if (onLoad) {
            if (_this._texture.isReady) {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].SetImmediate(function () { return onLoad(); });
            }
            else {
                _this._texture.onLoadedObservable.add(onLoad);
            }
        }
        return _this;
    }
    /**
     * Load the image data, by putting the image on a canvas and extracting its buffer.
     */
    EquiRectangularCubeTexture.prototype.loadImage = function (loadTextureCallback, onError) {
        var _this = this;
        var canvas = document.createElement('canvas');
        var image = new Image();
        image.addEventListener('load', function () {
            _this._width = image.width;
            _this._height = image.height;
            canvas.width = _this._width;
            canvas.height = _this._height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(image, 0, 0);
            var imageData = ctx.getImageData(0, 0, image.width, image.height);
            _this._buffer = imageData.data.buffer;
            canvas.remove();
            loadTextureCallback();
        });
        image.addEventListener('error', function (error) {
            if (onError) {
                onError(_this.getClassName() + " could not be loaded", error);
            }
        });
        image.src = this.url;
    };
    /**
     * Convert the image buffer into a cubemap and create a CubeTexture.
     */
    EquiRectangularCubeTexture.prototype.loadTexture = function () {
        var _this = this;
        var scene = this.getScene();
        var callback = function () {
            var imageData = _this.getFloat32ArrayFromArrayBuffer(_this._buffer);
            // Extract the raw linear data.
            var data = _Misc_HighDynamicRange_panoramaToCubemap__WEBPACK_IMPORTED_MODULE_1__["PanoramaToCubeMapTools"].ConvertPanoramaToCubemap(imageData, _this._width, _this._height, _this._size);
            var results = [];
            // Push each faces.
            for (var i = 0; i < 6; i++) {
                var dataFace = data[EquiRectangularCubeTexture._FacesMapping[i]];
                results.push(dataFace);
            }
            return results;
        };
        if (!scene) {
            return;
        }
        this._texture = scene
            .getEngine()
            .createRawCubeTextureFromUrl(this.url, scene, this._size, _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].TEXTUREFORMAT_RGB, scene.getEngine().getCaps().textureFloat
            ? _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].TEXTURETYPE_FLOAT
            : _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].TEXTURETYPE_UNSIGNED_INTEGER, this._noMipmap, callback, null, this._onLoad, this._onError);
    };
    /**
     * Convert the ArrayBuffer into a Float32Array and drop the transparency channel.
     * @param buffer The ArrayBuffer that should be converted.
     * @returns The buffer as Float32Array.
     */
    EquiRectangularCubeTexture.prototype.getFloat32ArrayFromArrayBuffer = function (buffer) {
        var dataView = new DataView(buffer);
        var floatImageData = new Float32Array((buffer.byteLength * 3) / 4);
        var k = 0;
        for (var i = 0; i < buffer.byteLength; i++) {
            // We drop the transparency channel, because we do not need/want it
            if ((i + 1) % 4 !== 0) {
                floatImageData[k++] = dataView.getUint8(i) / 255;
            }
        }
        return floatImageData;
    };
    /**
     * Get the current class name of the texture useful for serialization or dynamic coding.
     * @returns "EquiRectangularCubeTexture"
     */
    EquiRectangularCubeTexture.prototype.getClassName = function () {
        return "EquiRectangularCubeTexture";
    };
    /**
     * Create a clone of the current EquiRectangularCubeTexture and return it.
     * @returns A clone of the current EquiRectangularCubeTexture.
     */
    EquiRectangularCubeTexture.prototype.clone = function () {
        var scene = this.getScene();
        if (!scene) {
            return this;
        }
        var newTexture = new EquiRectangularCubeTexture(this.url, scene, this._size, this._noMipmap, this.gammaSpace);
        // Base texture
        newTexture.level = this.level;
        newTexture.wrapU = this.wrapU;
        newTexture.wrapV = this.wrapV;
        newTexture.coordinatesIndex = this.coordinatesIndex;
        newTexture.coordinatesMode = this.coordinatesMode;
        return newTexture;
    };
    /** The six faces of the cube. */
    EquiRectangularCubeTexture._FacesMapping = ['right', 'left', 'up', 'down', 'front', 'back'];
    return EquiRectangularCubeTexture;
}(_baseTexture__WEBPACK_IMPORTED_MODULE_3__["BaseTexture"]));



/***/ }),

/***/ "./Materials/Textures/hdrCubeTexture.ts":
/*!**********************************************!*\
  !*** ./Materials/Textures/hdrCubeTexture.ts ***!
  \**********************************************/
/*! exports provided: HDRCubeTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTexture", function() { return HDRCubeTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_HighDynamicRange_hdr__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Misc/HighDynamicRange/hdr */ "./Misc/HighDynamicRange/hdr.ts");
/* harmony import */ var _Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Misc/HighDynamicRange/cubemapToSphericalPolynomial */ "./Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Engines_Extensions_engine_rawTexture__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Engines/Extensions/engine.rawTexture */ "./Engines/Extensions/engine.rawTexture.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../Maths/math.constants */ "./Maths/math.constants.ts");












/**
 * This represents a texture coming from an HDR input.
 *
 * The only supported format is currently panorama picture stored in RGBE format.
 * Example of such files can be found on HDRLib: http://hdrlib.com/
 */
var HDRCubeTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HDRCubeTexture, _super);
    /**
     * Instantiates an HDRTexture from the following parameters.
     *
     * @param url The location of the HDR raw data (Panorama stored in RGBE format)
     * @param scene The scene the texture will be used in
     * @param size The cubemap desired size (the more it increases the longer the generation will be)
     * @param noMipmap Forces to not generate the mipmap if true
     * @param generateHarmonics Specifies whether you want to extract the polynomial harmonics during the generation process
     * @param gammaSpace Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)
     * @param reserved Reserved flag for internal use.
     */
    function HDRCubeTexture(url, scene, size, noMipmap, generateHarmonics, gammaSpace, reserved, onLoad, onError) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (generateHarmonics === void 0) { generateHarmonics = true; }
        if (gammaSpace === void 0) { gammaSpace = false; }
        if (reserved === void 0) { reserved = false; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        var _this = _super.call(this, scene) || this;
        _this._generateHarmonics = true;
        _this._onLoad = null;
        _this._onError = null;
        /**
         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
         */
        _this.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CUBIC_MODE;
        _this._isBlocking = true;
        _this._rotationY = 0;
        /**
         * Gets or sets the center of the bounding box associated with the cube texture
         * It must define where the camera used to render the texture was set
         */
        _this.boundingBoxPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        if (!url) {
            return _this;
        }
        _this.name = url;
        _this.url = url;
        _this.hasAlpha = false;
        _this.isCube = true;
        _this._textureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        _this._onLoad = onLoad;
        _this._onError = onError;
        _this.gammaSpace = gammaSpace;
        _this._noMipmap = noMipmap;
        _this._size = size;
        _this._texture = _this._getFromCache(url, _this._noMipmap);
        if (!_this._texture) {
            if (!scene.useDelayedTextureLoading) {
                _this.loadTexture();
            }
            else {
                _this.delayLoadState = _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].DELAYLOADSTATE_NOTLOADED;
            }
        }
        else if (onLoad) {
            if (_this._texture.isReady) {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_9__["Tools"].SetImmediate(function () { return onLoad(); });
            }
            else {
                _this._texture.onLoadedObservable.add(onLoad);
            }
        }
        return _this;
    }
    Object.defineProperty(HDRCubeTexture.prototype, "isBlocking", {
        /**
         * Gets wether or not the texture is blocking during loading.
         */
        get: function () {
            return this._isBlocking;
        },
        /**
         * Sets wether or not the texture is blocking during loading.
         */
        set: function (value) {
            this._isBlocking = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HDRCubeTexture.prototype, "rotationY", {
        /**
         * Gets texture matrix rotation angle around Y axis radians.
         */
        get: function () {
            return this._rotationY;
        },
        /**
         * Sets texture matrix rotation angle around Y axis in radians.
         */
        set: function (value) {
            this._rotationY = value;
            this.setReflectionTextureMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].RotationY(this._rotationY));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(HDRCubeTexture.prototype, "boundingBoxSize", {
        get: function () {
            return this._boundingBoxSize;
        },
        /**
         * Gets or sets the size of the bounding box associated with the cube texture
         * When defined, the cubemap will switch to local mode
         * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity
         * @example https://www.babylonjs-playground.com/#RNASML
         */
        set: function (value) {
            if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {
                return;
            }
            this._boundingBoxSize = value;
            var scene = this.getScene();
            if (scene) {
                scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].MATERIAL_TextureDirtyFlag);
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the current class name of the texture useful for serialization or dynamic coding.
     * @returns "HDRCubeTexture"
     */
    HDRCubeTexture.prototype.getClassName = function () {
        return "HDRCubeTexture";
    };
    /**
     * Occurs when the file is raw .hdr file.
     */
    HDRCubeTexture.prototype.loadTexture = function () {
        var _this = this;
        var callback = function (buffer) {
            _this.lodGenerationOffset = 0.0;
            _this.lodGenerationScale = 0.8;
            var scene = _this.getScene();
            if (!scene) {
                return null;
            }
            // Extract the raw linear data.
            var data = _Misc_HighDynamicRange_hdr__WEBPACK_IMPORTED_MODULE_6__["HDRTools"].GetCubeMapTextureData(buffer, _this._size);
            // Generate harmonics if needed.
            if (_this._generateHarmonics) {
                var sphericalPolynomial = _Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_7__["CubeMapToSphericalPolynomialTools"].ConvertCubeMapToSphericalPolynomial(data);
                _this.sphericalPolynomial = sphericalPolynomial;
            }
            var results = [];
            var byteArray = null;
            // Push each faces.
            for (var j = 0; j < 6; j++) {
                // Create uintarray fallback.
                if (!scene.getEngine().getCaps().textureFloat) {
                    // 3 channels of 1 bytes per pixel in bytes.
                    var byteBuffer = new ArrayBuffer(_this._size * _this._size * 3);
                    byteArray = new Uint8Array(byteBuffer);
                }
                var dataFace = (data[HDRCubeTexture._facesMapping[j]]);
                // If special cases.
                if (_this.gammaSpace || byteArray) {
                    for (var i = 0; i < _this._size * _this._size; i++) {
                        // Put in gamma space if requested.
                        if (_this.gammaSpace) {
                            dataFace[(i * 3) + 0] = Math.pow(dataFace[(i * 3) + 0], _Maths_math_constants__WEBPACK_IMPORTED_MODULE_11__["ToGammaSpace"]);
                            dataFace[(i * 3) + 1] = Math.pow(dataFace[(i * 3) + 1], _Maths_math_constants__WEBPACK_IMPORTED_MODULE_11__["ToGammaSpace"]);
                            dataFace[(i * 3) + 2] = Math.pow(dataFace[(i * 3) + 2], _Maths_math_constants__WEBPACK_IMPORTED_MODULE_11__["ToGammaSpace"]);
                        }
                        // Convert to int texture for fallback.
                        if (byteArray) {
                            var r = Math.max(dataFace[(i * 3) + 0] * 255, 0);
                            var g = Math.max(dataFace[(i * 3) + 1] * 255, 0);
                            var b = Math.max(dataFace[(i * 3) + 2] * 255, 0);
                            // May use luminance instead if the result is not accurate.
                            var max = Math.max(Math.max(r, g), b);
                            if (max > 255) {
                                var scale = 255 / max;
                                r *= scale;
                                g *= scale;
                                b *= scale;
                            }
                            byteArray[(i * 3) + 0] = r;
                            byteArray[(i * 3) + 1] = g;
                            byteArray[(i * 3) + 2] = b;
                        }
                    }
                }
                if (byteArray) {
                    results.push(byteArray);
                }
                else {
                    results.push(dataFace);
                }
            }
            return results;
        };
        var scene = this.getScene();
        if (scene) {
            this._texture = scene.getEngine().createRawCubeTextureFromUrl(this.url, scene, this._size, _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].TEXTUREFORMAT_RGB, scene.getEngine().getCaps().textureFloat ? _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].TEXTURETYPE_FLOAT : _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].TEXTURETYPE_UNSIGNED_INT, this._noMipmap, callback, null, this._onLoad, this._onError);
        }
    };
    HDRCubeTexture.prototype.clone = function () {
        var scene = this.getScene();
        if (!scene) {
            return this;
        }
        var newTexture = new HDRCubeTexture(this.url, scene, this._size, this._noMipmap, this._generateHarmonics, this.gammaSpace);
        // Base texture
        newTexture.level = this.level;
        newTexture.wrapU = this.wrapU;
        newTexture.wrapV = this.wrapV;
        newTexture.coordinatesIndex = this.coordinatesIndex;
        newTexture.coordinatesMode = this.coordinatesMode;
        return newTexture;
    };
    // Methods
    HDRCubeTexture.prototype.delayLoad = function () {
        if (this.delayLoadState !== _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].DELAYLOADSTATE_NOTLOADED) {
            return;
        }
        this.delayLoadState = _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].DELAYLOADSTATE_LOADED;
        this._texture = this._getFromCache(this.url, this._noMipmap);
        if (!this._texture) {
            this.loadTexture();
        }
    };
    /**
     * Get the texture reflection matrix used to rotate/transform the reflection.
     * @returns the reflection matrix
     */
    HDRCubeTexture.prototype.getReflectionTextureMatrix = function () {
        return this._textureMatrix;
    };
    /**
     * Set the texture reflection matrix used to rotate/transform the reflection.
     * @param value Define the reflection matrix to set
     */
    HDRCubeTexture.prototype.setReflectionTextureMatrix = function (value) {
        var _this = this;
        this._textureMatrix = value;
        if (value.updateFlag === this._textureMatrix.updateFlag) {
            return;
        }
        if (value.isIdentity() !== this._textureMatrix.isIdentity()) {
            this.getScene().markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].MATERIAL_TextureDirtyFlag, function (mat) { return mat.getActiveTextures().indexOf(_this) !== -1; });
        }
    };
    /**
     * Parses a JSON representation of an HDR Texture in order to create the texture
     * @param parsedTexture Define the JSON representation
     * @param scene Define the scene the texture should be created in
     * @param rootUrl Define the root url in case we need to load relative dependencies
     * @returns the newly created texture after parsing
     */
    HDRCubeTexture.Parse = function (parsedTexture, scene, rootUrl) {
        var texture = null;
        if (parsedTexture.name && !parsedTexture.isRenderTarget) {
            texture = new HDRCubeTexture(rootUrl + parsedTexture.name, scene, parsedTexture.size, parsedTexture.noMipmap, parsedTexture.generateHarmonics, parsedTexture.useInGammaSpace);
            texture.name = parsedTexture.name;
            texture.hasAlpha = parsedTexture.hasAlpha;
            texture.level = parsedTexture.level;
            texture.coordinatesMode = parsedTexture.coordinatesMode;
            texture.isBlocking = parsedTexture.isBlocking;
        }
        if (texture) {
            if (parsedTexture.boundingBoxPosition) {
                texture.boundingBoxPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(parsedTexture.boundingBoxPosition);
            }
            if (parsedTexture.boundingBoxSize) {
                texture.boundingBoxSize = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(parsedTexture.boundingBoxSize);
            }
            if (parsedTexture.rotationY) {
                texture.rotationY = parsedTexture.rotationY;
            }
        }
        return texture;
    };
    HDRCubeTexture.prototype.serialize = function () {
        if (!this.name) {
            return null;
        }
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.hasAlpha = this.hasAlpha;
        serializationObject.isCube = true;
        serializationObject.level = this.level;
        serializationObject.size = this._size;
        serializationObject.coordinatesMode = this.coordinatesMode;
        serializationObject.useInGammaSpace = this.gammaSpace;
        serializationObject.generateHarmonics = this._generateHarmonics;
        serializationObject.customType = "BABYLON.HDRCubeTexture";
        serializationObject.noMipmap = this._noMipmap;
        serializationObject.isBlocking = this._isBlocking;
        serializationObject.rotationY = this._rotationY;
        return serializationObject;
    };
    HDRCubeTexture._facesMapping = [
        "right",
        "left",
        "up",
        "down",
        "front",
        "back"
    ];
    return HDRCubeTexture;
}(_Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_3__["BaseTexture"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_8__["_TypeStore"].RegisteredTypes["BABYLON.HDRCubeTexture"] = HDRCubeTexture;


/***/ }),

/***/ "./Materials/Textures/htmlElementTexture.ts":
/*!**************************************************!*\
  !*** ./Materials/Textures/htmlElementTexture.ts ***!
  \**************************************************/
/*! exports provided: HtmlElementTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HtmlElementTexture", function() { return HtmlElementTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");




/**
 * This represents the smallest workload to use an already existing element (Canvas or Video) as a texture.
 * To be as efficient as possible depending on your constraints nothing aside the first upload
 * is automatically managed.
 * It is a cheap VideoTexture or DynamicTexture if you prefer to keep full control of the elements
 * in your application.
 *
 * As the update is not automatic, you need to call them manually.
 */
var HtmlElementTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HtmlElementTexture, _super);
    /**
     * Instantiates a HtmlElementTexture from the following parameters.
     *
     * @param name Defines the name of the texture
     * @param element Defines the video or canvas the texture is filled with
     * @param options Defines the other none mandatory texture creation options
     */
    function HtmlElementTexture(name, element, options) {
        var _this = _super.call(this, options.scene) || this;
        if (!element || (!options.engine && !options.scene)) {
            return _this;
        }
        options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, HtmlElementTexture.DefaultOptions, options);
        _this._engine = options.engine || options.scene.getEngine();
        _this._generateMipMaps = options.generateMipMaps;
        _this._samplingMode = options.samplingMode;
        _this._textureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
        _this.name = name;
        _this.element = element;
        _this._isVideo = (element instanceof HTMLVideoElement);
        _this.anisotropicFilteringLevel = 1;
        _this._createInternalTexture();
        return _this;
    }
    HtmlElementTexture.prototype._createInternalTexture = function () {
        var width = 0;
        var height = 0;
        if (this._isVideo) {
            width = this.element.videoWidth;
            height = this.element.videoHeight;
        }
        else {
            width = this.element.width;
            height = this.element.height;
        }
        this._texture = this._engine.createDynamicTexture(width, height, this._generateMipMaps, this._samplingMode);
        this.update();
    };
    /**
     * Returns the texture matrix used in most of the material.
     */
    HtmlElementTexture.prototype.getTextureMatrix = function () {
        return this._textureMatrix;
    };
    /**
     * Updates the content of the texture.
     * @param invertY Defines wether the texture should be inverted on Y (false by default on video and true on canvas)
     */
    HtmlElementTexture.prototype.update = function (invertY) {
        if (invertY === void 0) { invertY = null; }
        if (this._texture == null) {
            return;
        }
        if (this._isVideo) {
            var videoElement = this.element;
            if (videoElement.readyState < videoElement.HAVE_CURRENT_DATA) {
                return;
            }
            this._engine.updateVideoTexture(this._texture, videoElement, invertY === null ? true : invertY);
        }
        else {
            var canvasElement = this.element;
            this._engine.updateDynamicTexture(this._texture, canvasElement, invertY === null ? true : invertY, false);
        }
    };
    HtmlElementTexture.DefaultOptions = {
        generateMipMaps: false,
        samplingMode: _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE,
        engine: null,
        scene: null
    };
    return HtmlElementTexture;
}(_Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_1__["BaseTexture"]));



/***/ }),

/***/ "./Materials/Textures/index.ts":
/*!*************************************!*\
  !*** ./Materials/Textures/index.ts ***!
  \*************************************/
/*! exports provided: BaseTexture, CubeTexture, DynamicTexture, EquiRectangularCubeTexture, HDRCubeTexture, InternalTexture, MirrorTexture, MultiRenderTarget, RawTexture, RenderTargetTexture, Texture, ColorGradingTexture, RawCubeTexture, RawTexture3D, RefractionTexture, VideoTexture, HtmlElementTexture, _DDSTextureLoader, _ENVTextureLoader, _KTXTextureLoader, _TGATextureLoader, _BasisTextureLoader, CustomProceduralTexture, NoiseProceduralTexture, ProceduralTexture, ProceduralTextureSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _baseTexture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseTexture", function() { return _baseTexture__WEBPACK_IMPORTED_MODULE_0__["BaseTexture"]; });

/* harmony import */ var _colorGradingTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colorGradingTexture */ "./Materials/Textures/colorGradingTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradingTexture", function() { return _colorGradingTexture__WEBPACK_IMPORTED_MODULE_1__["ColorGradingTexture"]; });

/* harmony import */ var _cubeTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cubeTexture */ "./Materials/Textures/cubeTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTexture", function() { return _cubeTexture__WEBPACK_IMPORTED_MODULE_2__["CubeTexture"]; });

/* harmony import */ var _dynamicTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./dynamicTexture */ "./Materials/Textures/dynamicTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DynamicTexture", function() { return _dynamicTexture__WEBPACK_IMPORTED_MODULE_3__["DynamicTexture"]; });

/* harmony import */ var _equiRectangularCubeTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./equiRectangularCubeTexture */ "./Materials/Textures/equiRectangularCubeTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTexture", function() { return _equiRectangularCubeTexture__WEBPACK_IMPORTED_MODULE_4__["EquiRectangularCubeTexture"]; });

/* harmony import */ var _hdrCubeTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./hdrCubeTexture */ "./Materials/Textures/hdrCubeTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTexture", function() { return _hdrCubeTexture__WEBPACK_IMPORTED_MODULE_5__["HDRCubeTexture"]; });

/* harmony import */ var _internalTexture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InternalTexture", function() { return _internalTexture__WEBPACK_IMPORTED_MODULE_6__["InternalTexture"]; });

/* harmony import */ var _Loaders_index__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Loaders/index */ "./Materials/Textures/Loaders/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DDSTextureLoader", function() { return _Loaders_index__WEBPACK_IMPORTED_MODULE_7__["_DDSTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_ENVTextureLoader", function() { return _Loaders_index__WEBPACK_IMPORTED_MODULE_7__["_ENVTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_KTXTextureLoader", function() { return _Loaders_index__WEBPACK_IMPORTED_MODULE_7__["_KTXTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TGATextureLoader", function() { return _Loaders_index__WEBPACK_IMPORTED_MODULE_7__["_TGATextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BasisTextureLoader", function() { return _Loaders_index__WEBPACK_IMPORTED_MODULE_7__["_BasisTextureLoader"]; });

/* harmony import */ var _mirrorTexture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./mirrorTexture */ "./Materials/Textures/mirrorTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MirrorTexture", function() { return _mirrorTexture__WEBPACK_IMPORTED_MODULE_8__["MirrorTexture"]; });

/* harmony import */ var _multiRenderTarget__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./multiRenderTarget */ "./Materials/Textures/multiRenderTarget.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiRenderTarget", function() { return _multiRenderTarget__WEBPACK_IMPORTED_MODULE_9__["MultiRenderTarget"]; });

/* harmony import */ var _Procedurals_index__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Procedurals/index */ "./Materials/Textures/Procedurals/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomProceduralTexture", function() { return _Procedurals_index__WEBPACK_IMPORTED_MODULE_10__["CustomProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NoiseProceduralTexture", function() { return _Procedurals_index__WEBPACK_IMPORTED_MODULE_10__["NoiseProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTexture", function() { return _Procedurals_index__WEBPACK_IMPORTED_MODULE_10__["ProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTextureSceneComponent", function() { return _Procedurals_index__WEBPACK_IMPORTED_MODULE_10__["ProceduralTextureSceneComponent"]; });

/* harmony import */ var _rawCubeTexture__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./rawCubeTexture */ "./Materials/Textures/rawCubeTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawCubeTexture", function() { return _rawCubeTexture__WEBPACK_IMPORTED_MODULE_11__["RawCubeTexture"]; });

/* harmony import */ var _rawTexture__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./rawTexture */ "./Materials/Textures/rawTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture", function() { return _rawTexture__WEBPACK_IMPORTED_MODULE_12__["RawTexture"]; });

/* harmony import */ var _rawTexture3D__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./rawTexture3D */ "./Materials/Textures/rawTexture3D.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture3D", function() { return _rawTexture3D__WEBPACK_IMPORTED_MODULE_13__["RawTexture3D"]; });

/* harmony import */ var _refractionTexture__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./refractionTexture */ "./Materials/Textures/refractionTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionTexture", function() { return _refractionTexture__WEBPACK_IMPORTED_MODULE_14__["RefractionTexture"]; });

/* harmony import */ var _renderTargetTexture__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetTexture", function() { return _renderTargetTexture__WEBPACK_IMPORTED_MODULE_15__["RenderTargetTexture"]; });

/* harmony import */ var _texture__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./texture */ "./Materials/Textures/texture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Texture", function() { return _texture__WEBPACK_IMPORTED_MODULE_16__["Texture"]; });

/* harmony import */ var _videoTexture__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./videoTexture */ "./Materials/Textures/videoTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoTexture", function() { return _videoTexture__WEBPACK_IMPORTED_MODULE_17__["VideoTexture"]; });

/* harmony import */ var _htmlElementTexture__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./htmlElementTexture */ "./Materials/Textures/htmlElementTexture.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HtmlElementTexture", function() { return _htmlElementTexture__WEBPACK_IMPORTED_MODULE_18__["HtmlElementTexture"]; });






















/***/ }),

/***/ "./Materials/Textures/internalTexture.ts":
/*!***********************************************!*\
  !*** ./Materials/Textures/internalTexture.ts ***!
  \***********************************************/
/*! exports provided: InternalTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InternalTexture", function() { return InternalTexture; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Materials/Textures/renderTargetCreationOptions */ "./Materials/Textures/renderTargetCreationOptions.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/devTools */ "./Misc/devTools.ts");




/**
 * Class used to store data associated with WebGL texture data for the engine
 * This class should not be used directly
 */
var InternalTexture = /** @class */ (function () {
    /**
     * Creates a new InternalTexture
     * @param engine defines the engine to use
     * @param dataSource defines the type of data that will be used
     * @param delayAllocation if the texture allocation should be delayed (default: false)
     */
    function InternalTexture(engine, dataSource, delayAllocation) {
        if (delayAllocation === void 0) { delayAllocation = false; }
        /**
         * Defines if the texture is ready
         */
        this.isReady = false;
        /**
         * Defines if the texture is a cube texture
         */
        this.isCube = false;
        /**
         * Defines if the texture contains 3D data
         */
        this.is3D = false;
        /**
         * Defines if the texture contains multiview data
         */
        this.isMultiview = false;
        /**
         * Gets the URL used to load this texture
         */
        this.url = "";
        /**
         * Gets the sampling mode of the texture
         */
        this.samplingMode = -1;
        /**
         * Gets a boolean indicating if the texture needs mipmaps generation
         */
        this.generateMipMaps = false;
        /**
         * Gets the number of samples used by the texture (WebGL2+ only)
         */
        this.samples = 0;
        /**
         * Gets the type of the texture (int, float...)
         */
        this.type = -1;
        /**
         * Gets the format of the texture (RGB, RGBA...)
         */
        this.format = -1;
        /**
         * Observable called when the texture is loaded
         */
        this.onLoadedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /**
         * Gets the width of the texture
         */
        this.width = 0;
        /**
         * Gets the height of the texture
         */
        this.height = 0;
        /**
         * Gets the depth of the texture
         */
        this.depth = 0;
        /**
         * Gets the initial width of the texture (It could be rescaled if the current system does not support non power of two textures)
         */
        this.baseWidth = 0;
        /**
         * Gets the initial height of the texture (It could be rescaled if the current system does not support non power of two textures)
         */
        this.baseHeight = 0;
        /**
         * Gets the initial depth of the texture (It could be rescaled if the current system does not support non power of two textures)
         */
        this.baseDepth = 0;
        /**
         * Gets a boolean indicating if the texture is inverted on Y axis
         */
        this.invertY = false;
        // Private
        /** @hidden */
        this._invertVScale = false;
        /** @hidden */
        this._associatedChannel = -1;
        /** @hidden */
        this._dataSource = InternalTexture.DATASOURCE_UNKNOWN;
        /** @hidden */
        this._buffer = null;
        /** @hidden */
        this._bufferView = null;
        /** @hidden */
        this._bufferViewArray = null;
        /** @hidden */
        this._bufferViewArrayArray = null;
        /** @hidden */
        this._size = 0;
        /** @hidden */
        this._extension = "";
        /** @hidden */
        this._files = null;
        /** @hidden */
        this._workingCanvas = null;
        /** @hidden */
        this._workingContext = null;
        /** @hidden */
        this._framebuffer = null;
        /** @hidden */
        this._depthStencilBuffer = null;
        /** @hidden */
        this._MSAAFramebuffer = null;
        /** @hidden */
        this._MSAARenderBuffer = null;
        /** @hidden */
        this._attachments = null;
        /** @hidden */
        this._cachedCoordinatesMode = null;
        /** @hidden */
        this._cachedWrapU = null;
        /** @hidden */
        this._cachedWrapV = null;
        /** @hidden */
        this._cachedWrapR = null;
        /** @hidden */
        this._cachedAnisotropicFilteringLevel = null;
        /** @hidden */
        this._isDisabled = false;
        /** @hidden */
        this._compression = null;
        /** @hidden */
        this._generateStencilBuffer = false;
        /** @hidden */
        this._generateDepthBuffer = false;
        /** @hidden */
        this._comparisonFunction = 0;
        /** @hidden */
        this._sphericalPolynomial = null;
        /** @hidden */
        this._lodGenerationScale = 0;
        /** @hidden */
        this._lodGenerationOffset = 0;
        // Multiview
        /** @hidden */
        this._colorTextureArray = null;
        /** @hidden */
        this._depthStencilTextureArray = null;
        // The following three fields helps sharing generated fixed LODs for texture filtering
        // In environment not supporting the textureLOD extension like EDGE. They are for internal use only.
        // They are at the level of the gl texture to benefit from the cache.
        /** @hidden */
        this._lodTextureHigh = null;
        /** @hidden */
        this._lodTextureMid = null;
        /** @hidden */
        this._lodTextureLow = null;
        /** @hidden */
        this._isRGBD = false;
        /** @hidden */
        this._linearSpecularLOD = false;
        /** @hidden */
        this._irradianceTexture = null;
        /** @hidden */
        this._webGLTexture = null;
        /** @hidden */
        this._webGPUTexture = null;
        /** @hidden */
        this._webGPUSampler = null;
        /** @hidden */
        this._webGPUTextureView = null;
        /** @hidden */
        this._references = 1;
        this._engine = engine;
        this._dataSource = dataSource;
        if (!delayAllocation) {
            this._webGLTexture = engine._createTexture();
        }
    }
    /**
     * Gets the Engine the texture belongs to.
     * @returns The babylon engine
     */
    InternalTexture.prototype.getEngine = function () {
        return this._engine;
    };
    Object.defineProperty(InternalTexture.prototype, "dataSource", {
        /**
         * Gets the data source type of the texture (can be one of the InternalTexture.DATASOURCE_XXXX)
         */
        get: function () {
            return this._dataSource;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Increments the number of references (ie. the number of Texture that point to it)
     */
    InternalTexture.prototype.incrementReferences = function () {
        this._references++;
    };
    /**
     * Change the size of the texture (not the size of the content)
     * @param width defines the new width
     * @param height defines the new height
     * @param depth defines the new depth (1 by default)
     */
    InternalTexture.prototype.updateSize = function (width, height, depth) {
        if (depth === void 0) { depth = 1; }
        this.width = width;
        this.height = height;
        this.depth = depth;
        this.baseWidth = width;
        this.baseHeight = height;
        this.baseDepth = depth;
        this._size = width * height * depth;
    };
    /** @hidden */
    InternalTexture.prototype._rebuild = function () {
        var _this = this;
        var proxy;
        this.isReady = false;
        this._cachedCoordinatesMode = null;
        this._cachedWrapU = null;
        this._cachedWrapV = null;
        this._cachedAnisotropicFilteringLevel = null;
        switch (this._dataSource) {
            case InternalTexture.DATASOURCE_TEMP:
                return;
            case InternalTexture.DATASOURCE_URL:
                proxy = this._engine.createTexture(this.url, !this.generateMipMaps, this.invertY, null, this.samplingMode, function () {
                    proxy._swapAndDie(_this);
                    _this.isReady = true;
                }, null, this._buffer, undefined, this.format);
                return;
            case InternalTexture.DATASOURCE_RAW:
                proxy = this._engine.createRawTexture(this._bufferView, this.baseWidth, this.baseHeight, this.format, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
                proxy._swapAndDie(this);
                this.isReady = true;
                return;
            case InternalTexture.DATASOURCE_RAW3D:
                proxy = this._engine.createRawTexture3D(this._bufferView, this.baseWidth, this.baseHeight, this.baseDepth, this.format, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
                proxy._swapAndDie(this);
                this.isReady = true;
                return;
            case InternalTexture.DATASOURCE_DYNAMIC:
                proxy = this._engine.createDynamicTexture(this.baseWidth, this.baseHeight, this.generateMipMaps, this.samplingMode);
                proxy._swapAndDie(this);
                this._engine.updateDynamicTexture(this, this._engine.getRenderingCanvas(), this.invertY, undefined, undefined, true);
                // The engine will make sure to update content so no need to flag it as isReady = true
                return;
            case InternalTexture.DATASOURCE_RENDERTARGET:
                var options = new _Materials_Textures_renderTargetCreationOptions__WEBPACK_IMPORTED_MODULE_1__["RenderTargetCreationOptions"]();
                options.generateDepthBuffer = this._generateDepthBuffer;
                options.generateMipMaps = this.generateMipMaps;
                options.generateStencilBuffer = this._generateStencilBuffer;
                options.samplingMode = this.samplingMode;
                options.type = this.type;
                if (this.isCube) {
                    proxy = this._engine.createRenderTargetCubeTexture(this.width, options);
                }
                else {
                    var size = {
                        width: this.width,
                        height: this.height
                    };
                    proxy = this._engine.createRenderTargetTexture(size, options);
                }
                proxy._swapAndDie(this);
                this.isReady = true;
                return;
            case InternalTexture.DATASOURCE_DEPTHTEXTURE:
                var depthTextureOptions = {
                    bilinearFiltering: this.samplingMode !== _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE,
                    comparisonFunction: this._comparisonFunction,
                    generateStencil: this._generateStencilBuffer,
                    isCube: this.isCube
                };
                proxy = this._engine.createDepthStencilTexture({ width: this.width, height: this.height }, depthTextureOptions);
                proxy._swapAndDie(this);
                this.isReady = true;
                return;
            case InternalTexture.DATASOURCE_CUBE:
                proxy = this._engine.createCubeTexture(this.url, null, this._files, !this.generateMipMaps, function () {
                    proxy._swapAndDie(_this);
                    _this.isReady = true;
                }, null, this.format, this._extension);
                return;
            case InternalTexture.DATASOURCE_CUBERAW:
                proxy = this._engine.createRawCubeTexture(this._bufferViewArray, this.width, this.format, this.type, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
                proxy._swapAndDie(this);
                this.isReady = true;
                return;
            case InternalTexture.DATASOURCE_CUBERAW_RGBD:
                proxy = this._engine.createRawCubeTexture(null, this.width, this.format, this.type, this.generateMipMaps, this.invertY, this.samplingMode, this._compression);
                InternalTexture._UpdateRGBDAsync(proxy, this._bufferViewArrayArray, this._sphericalPolynomial, this._lodGenerationScale, this._lodGenerationOffset).then(function () {
                    proxy._swapAndDie(_this);
                    _this.isReady = true;
                });
                return;
            case InternalTexture.DATASOURCE_CUBEPREFILTERED:
                proxy = this._engine.createPrefilteredCubeTexture(this.url, null, this._lodGenerationScale, this._lodGenerationOffset, function (proxy) {
                    if (proxy) {
                        proxy._swapAndDie(_this);
                    }
                    _this.isReady = true;
                }, null, this.format, this._extension);
                proxy._sphericalPolynomial = this._sphericalPolynomial;
                return;
        }
    };
    /** @hidden */
    InternalTexture.prototype._swapAndDie = function (target) {
        target._webGLTexture = this._webGLTexture;
        target._isRGBD = this._isRGBD;
        if (this._framebuffer) {
            target._framebuffer = this._framebuffer;
        }
        if (this._depthStencilBuffer) {
            target._depthStencilBuffer = this._depthStencilBuffer;
        }
        if (this._lodTextureHigh) {
            if (target._lodTextureHigh) {
                target._lodTextureHigh.dispose();
            }
            target._lodTextureHigh = this._lodTextureHigh;
        }
        if (this._lodTextureMid) {
            if (target._lodTextureMid) {
                target._lodTextureMid.dispose();
            }
            target._lodTextureMid = this._lodTextureMid;
        }
        if (this._lodTextureLow) {
            if (target._lodTextureLow) {
                target._lodTextureLow.dispose();
            }
            target._lodTextureLow = this._lodTextureLow;
        }
        if (this._irradianceTexture) {
            if (target._irradianceTexture) {
                target._irradianceTexture.dispose();
            }
            target._irradianceTexture = this._irradianceTexture;
        }
        var cache = this._engine.getLoadedTexturesCache();
        var index = cache.indexOf(this);
        if (index !== -1) {
            cache.splice(index, 1);
        }
        var index = cache.indexOf(target);
        if (index === -1) {
            cache.push(target);
        }
    };
    /**
     * Dispose the current allocated resources
     */
    InternalTexture.prototype.dispose = function () {
        if (!this._webGLTexture) {
            return;
        }
        this._references--;
        if (this._references === 0) {
            this._engine._releaseTexture(this);
            this._webGLTexture = null;
            this._webGPUTexture = null;
            this._webGPUSampler = null;
        }
    };
    /** @hidden */
    InternalTexture._UpdateRGBDAsync = function (internalTexture, data, sphericalPolynomial, lodScale, lodOffset) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_3__["_DevTools"].WarnImport("environmentTextureTools");
    };
    /**
     * The source of the texture data is unknown
     */
    InternalTexture.DATASOURCE_UNKNOWN = 0;
    /**
     * Texture data comes from an URL
     */
    InternalTexture.DATASOURCE_URL = 1;
    /**
     * Texture data is only used for temporary storage
     */
    InternalTexture.DATASOURCE_TEMP = 2;
    /**
     * Texture data comes from raw data (ArrayBuffer)
     */
    InternalTexture.DATASOURCE_RAW = 3;
    /**
     * Texture content is dynamic (video or dynamic texture)
     */
    InternalTexture.DATASOURCE_DYNAMIC = 4;
    /**
     * Texture content is generated by rendering to it
     */
    InternalTexture.DATASOURCE_RENDERTARGET = 5;
    /**
     * Texture content is part of a multi render target process
     */
    InternalTexture.DATASOURCE_MULTIRENDERTARGET = 6;
    /**
     * Texture data comes from a cube data file
     */
    InternalTexture.DATASOURCE_CUBE = 7;
    /**
     * Texture data comes from a raw cube data
     */
    InternalTexture.DATASOURCE_CUBERAW = 8;
    /**
     * Texture data come from a prefiltered cube data file
     */
    InternalTexture.DATASOURCE_CUBEPREFILTERED = 9;
    /**
     * Texture content is raw 3D data
     */
    InternalTexture.DATASOURCE_RAW3D = 10;
    /**
     * Texture content is a depth texture
     */
    InternalTexture.DATASOURCE_DEPTHTEXTURE = 11;
    /**
     * Texture data comes from a raw cube data encoded with RGBD
     */
    InternalTexture.DATASOURCE_CUBERAW_RGBD = 12;
    return InternalTexture;
}());



/***/ }),

/***/ "./Materials/Textures/mirrorTexture.ts":
/*!*********************************************!*\
  !*** ./Materials/Textures/mirrorTexture.ts ***!
  \*********************************************/
/*! exports provided: MirrorTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MirrorTexture", function() { return MirrorTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../PostProcesses/blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Maths_math_plane__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Maths/math.plane */ "./Maths/math.plane.ts");







/**
 * Mirror texture can be used to simulate the view from a mirror in a scene.
 * It will dynamically be rendered every frame to adapt to the camera point of view.
 * You can then easily use it as a reflectionTexture on a flat surface.
 * In case the surface is not a plane, please consider relying on reflection probes.
 * @see https://doc.babylonjs.com/how_to/reflect#mirrors
 */
var MirrorTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MirrorTexture, _super);
    /**
     * Instantiates a Mirror Texture.
     * Mirror texture can be used to simulate the view from a mirror in a scene.
     * It will dynamically be rendered every frame to adapt to the camera point of view.
     * You can then easily use it as a reflectionTexture on a flat surface.
     * In case the surface is not a plane, please consider relying on reflection probes.
     * @see https://doc.babylonjs.com/how_to/reflect#mirrors
     * @param name
     * @param size
     * @param scene
     * @param generateMipMaps
     * @param type
     * @param samplingMode
     * @param generateDepthBuffer
     */
    function MirrorTexture(name, size, scene, generateMipMaps, type, samplingMode, generateDepthBuffer) {
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE; }
        if (generateDepthBuffer === void 0) { generateDepthBuffer = true; }
        var _this = _super.call(this, name, size, scene, generateMipMaps, true, type, false, samplingMode, generateDepthBuffer) || this;
        _this.scene = scene;
        /**
         * Define the reflection plane we want to use. The mirrorPlane is usually set to the constructed reflector.
         * It is possible to directly set the mirrorPlane by directly using a Plane(a, b, c, d) where a, b and c give the plane normal vector (a, b, c) and d is a scalar displacement from the mirrorPlane to the origin. However in all but the very simplest of situations it is more straight forward to set it to the reflector as stated in the doc.
         * @see https://doc.babylonjs.com/how_to/reflect#mirrors
         */
        _this.mirrorPlane = new _Maths_math_plane__WEBPACK_IMPORTED_MODULE_6__["Plane"](0, 1, 0, 1);
        _this._transformMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Zero();
        _this._mirrorMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Zero();
        _this._adaptiveBlurKernel = 0;
        _this._blurKernelX = 0;
        _this._blurKernelY = 0;
        _this._blurRatio = 1.0;
        _this.ignoreCameraViewport = true;
        _this._updateGammaSpace();
        _this._imageProcessingConfigChangeObserver = scene.imageProcessingConfiguration.onUpdateParameters.add(function () {
            _this._updateGammaSpace;
        });
        _this.onBeforeRenderObservable.add(function () {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].ReflectionToRef(_this.mirrorPlane, _this._mirrorMatrix);
            _this._savedViewMatrix = scene.getViewMatrix();
            _this._mirrorMatrix.multiplyToRef(_this._savedViewMatrix, _this._transformMatrix);
            scene.setTransformMatrix(_this._transformMatrix, scene.getProjectionMatrix());
            scene.clipPlane = _this.mirrorPlane;
            scene.getEngine().cullBackFaces = false;
            scene._mirroredCameraPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinates(scene.activeCamera.globalPosition, _this._mirrorMatrix);
        });
        _this.onAfterRenderObservable.add(function () {
            scene.setTransformMatrix(_this._savedViewMatrix, scene.getProjectionMatrix());
            scene.getEngine().cullBackFaces = true;
            scene._mirroredCameraPosition = null;
            scene.clipPlane = null;
        });
        return _this;
    }
    Object.defineProperty(MirrorTexture.prototype, "blurRatio", {
        get: function () {
            return this._blurRatio;
        },
        /**
         * Define the blur ratio used to blur the reflection if needed.
         */
        set: function (value) {
            if (this._blurRatio === value) {
                return;
            }
            this._blurRatio = value;
            this._preparePostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MirrorTexture.prototype, "adaptiveBlurKernel", {
        /**
         * Define the adaptive blur kernel used to blur the reflection if needed.
         * This will autocompute the closest best match for the `blurKernel`
         */
        set: function (value) {
            this._adaptiveBlurKernel = value;
            this._autoComputeBlurKernel();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MirrorTexture.prototype, "blurKernel", {
        /**
         * Define the blur kernel used to blur the reflection if needed.
         * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.
         */
        set: function (value) {
            this.blurKernelX = value;
            this.blurKernelY = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MirrorTexture.prototype, "blurKernelX", {
        get: function () {
            return this._blurKernelX;
        },
        /**
         * Define the blur kernel on the X Axis used to blur the reflection if needed.
         * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.
         */
        set: function (value) {
            if (this._blurKernelX === value) {
                return;
            }
            this._blurKernelX = value;
            this._preparePostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MirrorTexture.prototype, "blurKernelY", {
        get: function () {
            return this._blurKernelY;
        },
        /**
         * Define the blur kernel on the Y Axis used to blur the reflection if needed.
         * Please consider using `adaptiveBlurKernel` as it could find the closest best value for you.
         */
        set: function (value) {
            if (this._blurKernelY === value) {
                return;
            }
            this._blurKernelY = value;
            this._preparePostProcesses();
        },
        enumerable: true,
        configurable: true
    });
    MirrorTexture.prototype._autoComputeBlurKernel = function () {
        var engine = this.getScene().getEngine();
        var dw = this.getRenderWidth() / engine.getRenderWidth();
        var dh = this.getRenderHeight() / engine.getRenderHeight();
        this.blurKernelX = this._adaptiveBlurKernel * dw;
        this.blurKernelY = this._adaptiveBlurKernel * dh;
    };
    MirrorTexture.prototype._onRatioRescale = function () {
        if (this._sizeRatio) {
            this.resize(this._initialSizeParameter);
            if (!this._adaptiveBlurKernel) {
                this._preparePostProcesses();
            }
        }
        if (this._adaptiveBlurKernel) {
            this._autoComputeBlurKernel();
        }
    };
    MirrorTexture.prototype._updateGammaSpace = function () {
        this.gammaSpace = !this.scene.imageProcessingConfiguration.isEnabled || !this.scene.imageProcessingConfiguration.applyByPostProcess;
    };
    MirrorTexture.prototype._preparePostProcesses = function () {
        this.clearPostProcesses(true);
        if (this._blurKernelX && this._blurKernelY) {
            var engine = this.getScene().getEngine();
            var textureType = engine.getCaps().textureFloatRender ? _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_FLOAT : _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_HALF_FLOAT;
            this._blurX = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_4__["BlurPostProcess"]("horizontal blur", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1.0, 0), this._blurKernelX, this._blurRatio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, textureType);
            this._blurX.autoClear = false;
            if (this._blurRatio === 1 && this.samples < 2 && this._texture) {
                this._blurX.inputTexture = this._texture;
            }
            else {
                this._blurX.alwaysForcePOT = true;
            }
            this._blurY = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_4__["BlurPostProcess"]("vertical blur", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0, 1.0), this._blurKernelY, this._blurRatio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, textureType);
            this._blurY.autoClear = false;
            this._blurY.alwaysForcePOT = this._blurRatio !== 1;
            this.addPostProcess(this._blurX);
            this.addPostProcess(this._blurY);
        }
        else {
            if (this._blurY) {
                this.removePostProcess(this._blurY);
                this._blurY.dispose();
                this._blurY = null;
            }
            if (this._blurX) {
                this.removePostProcess(this._blurX);
                this._blurX.dispose();
                this._blurX = null;
            }
        }
    };
    /**
     * Clone the mirror texture.
     * @returns the cloned texture
     */
    MirrorTexture.prototype.clone = function () {
        var scene = this.getScene();
        if (!scene) {
            return this;
        }
        var textureSize = this.getSize();
        var newTexture = new MirrorTexture(this.name, textureSize.width, scene, this._renderTargetOptions.generateMipMaps, this._renderTargetOptions.type, this._renderTargetOptions.samplingMode, this._renderTargetOptions.generateDepthBuffer);
        // Base texture
        newTexture.hasAlpha = this.hasAlpha;
        newTexture.level = this.level;
        // Mirror Texture
        newTexture.mirrorPlane = this.mirrorPlane.clone();
        if (this.renderList) {
            newTexture.renderList = this.renderList.slice(0);
        }
        return newTexture;
    };
    /**
     * Serialize the texture to a JSON representation you could use in Parse later on
     * @returns the serialized JSON representation
     */
    MirrorTexture.prototype.serialize = function () {
        if (!this.name) {
            return null;
        }
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.mirrorPlane = this.mirrorPlane.asArray();
        return serializationObject;
    };
    /**
     * Dispose the texture and release its associated resources.
     */
    MirrorTexture.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigChangeObserver);
    };
    return MirrorTexture;
}(_Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_3__["RenderTargetTexture"]));

_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"]._CreateMirror = function (name, renderTargetSize, scene, generateMipMaps) {
    return new MirrorTexture(name, renderTargetSize, scene, generateMipMaps);
};


/***/ }),

/***/ "./Materials/Textures/multiRenderTarget.ts":
/*!*************************************************!*\
  !*** ./Materials/Textures/multiRenderTarget.ts ***!
  \*************************************************/
/*! exports provided: MultiRenderTarget */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiRenderTarget", function() { return MultiRenderTarget; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_Extensions_engine_multiRender__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Engines/Extensions/engine.multiRender */ "./Engines/Extensions/engine.multiRender.ts");





/**
 * A multi render target, like a render target provides the ability to render to a texture.
 * Unlike the render target, it can render to several draw buffers in one draw.
 * This is specially interesting in deferred rendering or for any effects requiring more than
 * just one color from a single pass.
 */
var MultiRenderTarget = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MultiRenderTarget, _super);
    /**
     * Instantiate a new multi render target texture.
     * A multi render target, like a render target provides the ability to render to a texture.
     * Unlike the render target, it can render to several draw buffers in one draw.
     * This is specially interesting in deferred rendering or for any effects requiring more than
     * just one color from a single pass.
     * @param name Define the name of the texture
     * @param size Define the size of the buffers to render to
     * @param count Define the number of target we are rendering into
     * @param scene Define the scene the texture belongs to
     * @param options Define the options used to create the multi render target
     */
    function MultiRenderTarget(name, size, count, scene, options) {
        var _this = this;
        var generateMipMaps = options && options.generateMipMaps ? options.generateMipMaps : false;
        var generateDepthTexture = options && options.generateDepthTexture ? options.generateDepthTexture : false;
        var doNotChangeAspectRatio = !options || options.doNotChangeAspectRatio === undefined ? true : options.doNotChangeAspectRatio;
        _this = _super.call(this, name, size, scene, generateMipMaps, doNotChangeAspectRatio) || this;
        _this._engine = scene.getEngine();
        if (!_this.isSupported) {
            _this.dispose();
            return;
        }
        var types = [];
        var samplingModes = [];
        for (var i = 0; i < count; i++) {
            if (options && options.types && options.types[i] !== undefined) {
                types.push(options.types[i]);
            }
            else {
                types.push(options && options.defaultType ? options.defaultType : _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            }
            if (options && options.samplingModes && options.samplingModes[i] !== undefined) {
                samplingModes.push(options.samplingModes[i]);
            }
            else {
                samplingModes.push(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].BILINEAR_SAMPLINGMODE);
            }
        }
        var generateDepthBuffer = !options || options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
        var generateStencilBuffer = !options || options.generateStencilBuffer === undefined ? false : options.generateStencilBuffer;
        _this._size = size;
        _this._multiRenderTargetOptions = {
            samplingModes: samplingModes,
            generateMipMaps: generateMipMaps,
            generateDepthBuffer: generateDepthBuffer,
            generateStencilBuffer: generateStencilBuffer,
            generateDepthTexture: generateDepthTexture,
            types: types,
            textureCount: count
        };
        _this._createInternalTextures();
        _this._createTextures();
        return _this;
    }
    Object.defineProperty(MultiRenderTarget.prototype, "isSupported", {
        /**
         * Get if draw buffers are currently supported by the used hardware and browser.
         */
        get: function () {
            return this._engine.webGLVersion > 1 || this._engine.getCaps().drawBuffersExtension;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiRenderTarget.prototype, "textures", {
        /**
         * Get the list of textures generated by the multi render target.
         */
        get: function () {
            return this._textures;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiRenderTarget.prototype, "depthTexture", {
        /**
         * Get the depth texture generated by the multi render target if options.generateDepthTexture has been set
         */
        get: function () {
            return this._textures[this._textures.length - 1];
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiRenderTarget.prototype, "wrapU", {
        /**
         * Set the wrapping mode on U of all the textures we are rendering to.
         * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)
         */
        set: function (wrap) {
            if (this._textures) {
                for (var i = 0; i < this._textures.length; i++) {
                    this._textures[i].wrapU = wrap;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MultiRenderTarget.prototype, "wrapV", {
        /**
         * Set the wrapping mode on V of all the textures we are rendering to.
         * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)
         */
        set: function (wrap) {
            if (this._textures) {
                for (var i = 0; i < this._textures.length; i++) {
                    this._textures[i].wrapV = wrap;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    MultiRenderTarget.prototype._rebuild = function () {
        this.releaseInternalTextures();
        this._createInternalTextures();
        for (var i = 0; i < this._internalTextures.length; i++) {
            var texture = this._textures[i];
            texture._texture = this._internalTextures[i];
        }
        // Keeps references to frame buffer and stencil/depth buffer
        this._texture = this._internalTextures[0];
    };
    MultiRenderTarget.prototype._createInternalTextures = function () {
        this._internalTextures = this._engine.createMultipleRenderTarget(this._size, this._multiRenderTargetOptions);
    };
    MultiRenderTarget.prototype._createTextures = function () {
        this._textures = [];
        for (var i = 0; i < this._internalTextures.length; i++) {
            var texture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"](null, this.getScene());
            texture._texture = this._internalTextures[i];
            this._textures.push(texture);
        }
        // Keeps references to frame buffer and stencil/depth buffer
        this._texture = this._internalTextures[0];
    };
    Object.defineProperty(MultiRenderTarget.prototype, "samples", {
        /**
         * Define the number of samples used if MSAA is enabled.
         */
        get: function () {
            return this._samples;
        },
        set: function (value) {
            if (this._samples === value) {
                return;
            }
            this._samples = this._engine.updateMultipleRenderTargetTextureSampleCount(this._internalTextures, value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resize all the textures in the multi render target.
     * Be carrefull as it will recreate all the data in the new texture.
     * @param size Define the new size
     */
    MultiRenderTarget.prototype.resize = function (size) {
        this.releaseInternalTextures();
        this._internalTextures = this._engine.createMultipleRenderTarget(size, this._multiRenderTargetOptions);
        this._createInternalTextures();
    };
    MultiRenderTarget.prototype.unbindFrameBuffer = function (engine, faceIndex) {
        var _this = this;
        engine.unBindMultiColorAttachmentFramebuffer(this._internalTextures, this.isCube, function () {
            _this.onAfterRenderObservable.notifyObservers(faceIndex);
        });
    };
    /**
     * Dispose the render targets and their associated resources
     */
    MultiRenderTarget.prototype.dispose = function () {
        this.releaseInternalTextures();
        _super.prototype.dispose.call(this);
    };
    /**
     * Release all the underlying texture used as draw buffers.
     */
    MultiRenderTarget.prototype.releaseInternalTextures = function () {
        if (!this._internalTextures) {
            return;
        }
        for (var i = this._internalTextures.length - 1; i >= 0; i--) {
            if (this._internalTextures[i] !== undefined) {
                this._internalTextures[i].dispose();
                this._internalTextures.splice(i, 1);
            }
        }
    };
    return MultiRenderTarget;
}(_Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_2__["RenderTargetTexture"]));



/***/ }),

/***/ "./Materials/Textures/rawCubeTexture.ts":
/*!**********************************************!*\
  !*** ./Materials/Textures/rawCubeTexture.ts ***!
  \**********************************************/
/*! exports provided: RawCubeTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RawCubeTexture", function() { return RawCubeTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/environmentTextureTools */ "./Misc/environmentTextureTools.ts");
/* harmony import */ var _internalTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _cubeTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./cubeTexture */ "./Materials/Textures/cubeTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_Extensions_engine_rawTexture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Engines/Extensions/engine.rawTexture */ "./Engines/Extensions/engine.rawTexture.ts");







/**
 * Raw cube texture where the raw buffers are passed in
 */
var RawCubeTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RawCubeTexture, _super);
    /**
     * Creates a cube texture where the raw buffers are passed in.
     * @param scene defines the scene the texture is attached to
     * @param data defines the array of data to use to create each face
     * @param size defines the size of the textures
     * @param format defines the format of the data
     * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
     * @param generateMipMaps  defines if the engine should generate the mip levels
     * @param invertY defines if data must be stored with Y axis inverted
     * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
     * @param compression defines the compression used (null by default)
     */
    function RawCubeTexture(scene, data, size, format, type, generateMipMaps, invertY, samplingMode, compression) {
        if (format === void 0) { format = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTUREFORMAT_RGBA; }
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (generateMipMaps === void 0) { generateMipMaps = false; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (compression === void 0) { compression = null; }
        var _this = _super.call(this, "", scene) || this;
        _this._texture = scene.getEngine().createRawCubeTexture(data, size, format, type, generateMipMaps, invertY, samplingMode, compression);
        return _this;
    }
    /**
     * Updates the raw cube texture.
     * @param data defines the data to store
     * @param format defines the data format
     * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
     * @param invertY defines if data must be stored with Y axis inverted
     * @param compression defines the compression used (null by default)
     * @param level defines which level of the texture to update
     */
    RawCubeTexture.prototype.update = function (data, format, type, invertY, compression) {
        if (compression === void 0) { compression = null; }
        this._texture.getEngine().updateRawCubeTexture(this._texture, data, format, type, invertY, compression);
    };
    /**
     * Updates a raw cube texture with RGBD encoded data.
     * @param data defines the array of data [mipmap][face] to use to create each face
     * @param sphericalPolynomial defines the spherical polynomial for irradiance
     * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
     * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
     * @returns a promsie that resolves when the operation is complete
     */
    RawCubeTexture.prototype.updateRGBDAsync = function (data, sphericalPolynomial, lodScale, lodOffset) {
        if (sphericalPolynomial === void 0) { sphericalPolynomial = null; }
        if (lodScale === void 0) { lodScale = 0.8; }
        if (lodOffset === void 0) { lodOffset = 0; }
        return RawCubeTexture._UpdateRGBDAsync(this._texture, data, sphericalPolynomial, lodScale, lodOffset);
    };
    /**
     * Clones the raw cube texture.
     * @return a new cube texture
     */
    RawCubeTexture.prototype.clone = function () {
        var _this = this;
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () {
            var scene = _this.getScene();
            var internalTexture = _this._texture;
            var texture = new RawCubeTexture(scene, internalTexture._bufferViewArray, internalTexture.width, internalTexture.format, internalTexture.type, internalTexture.generateMipMaps, internalTexture.invertY, internalTexture.samplingMode, internalTexture._compression);
            if (internalTexture.dataSource === _internalTexture__WEBPACK_IMPORTED_MODULE_3__["InternalTexture"].DATASOURCE_CUBERAW_RGBD) {
                texture.updateRGBDAsync(internalTexture._bufferViewArrayArray, internalTexture._sphericalPolynomial, internalTexture._lodGenerationScale, internalTexture._lodGenerationOffset);
            }
            return texture;
        }, this);
    };
    /** @hidden */
    RawCubeTexture._UpdateRGBDAsync = function (internalTexture, data, sphericalPolynomial, lodScale, lodOffset) {
        internalTexture._dataSource = _internalTexture__WEBPACK_IMPORTED_MODULE_3__["InternalTexture"].DATASOURCE_CUBERAW_RGBD;
        internalTexture._bufferViewArrayArray = data;
        internalTexture._lodGenerationScale = lodScale;
        internalTexture._lodGenerationOffset = lodOffset;
        internalTexture._sphericalPolynomial = sphericalPolynomial;
        return _Misc_environmentTextureTools__WEBPACK_IMPORTED_MODULE_2__["EnvironmentTextureTools"].UploadLevelsAsync(internalTexture, data).then(function () {
            internalTexture.isReady = true;
        });
    };
    return RawCubeTexture;
}(_cubeTexture__WEBPACK_IMPORTED_MODULE_4__["CubeTexture"]));



/***/ }),

/***/ "./Materials/Textures/rawTexture.ts":
/*!******************************************!*\
  !*** ./Materials/Textures/rawTexture.ts ***!
  \******************************************/
/*! exports provided: RawTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RawTexture", function() { return RawTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_Extensions_engine_rawTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Engines/Extensions/engine.rawTexture */ "./Engines/Extensions/engine.rawTexture.ts");




/**
 * Raw texture can help creating a texture directly from an array of data.
 * This can be super useful if you either get the data from an uncompressed source or
 * if you wish to create your texture pixel by pixel.
 */
var RawTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RawTexture, _super);
    /**
     * Instantiates a new RawTexture.
     * Raw texture can help creating a texture directly from an array of data.
     * This can be super useful if you either get the data from an uncompressed source or
     * if you wish to create your texture pixel by pixel.
     * @param data define the array of data to use to create the texture
     * @param width define the width of the texture
     * @param height define the height of the texture
     * @param format define the format of the data (RGB, RGBA... Engine.TEXTUREFORMAT_xxx)
     * @param scene  define the scene the texture belongs to
     * @param generateMipMaps define whether mip maps should be generated or not
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)
     */
    function RawTexture(data, width, height,
    /**
     * Define the format of the data (RGB, RGBA... Engine.TEXTUREFORMAT_xxx)
     */
    format, scene, generateMipMaps, invertY, samplingMode, type) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        var _this = _super.call(this, null, scene, !generateMipMaps, invertY) || this;
        _this.format = format;
        _this._engine = scene.getEngine();
        _this._texture = scene.getEngine().createRawTexture(data, width, height, format, generateMipMaps, invertY, samplingMode, null, type);
        _this.wrapU = _texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].CLAMP_ADDRESSMODE;
        _this.wrapV = _texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].CLAMP_ADDRESSMODE;
        return _this;
    }
    /**
     * Updates the texture underlying data.
     * @param data Define the new data of the texture
     */
    RawTexture.prototype.update = function (data) {
        this._engine.updateRawTexture(this._texture, data, this._texture.format, this._texture.invertY, null, this._texture.type);
    };
    /**
     * Creates a luminance texture from some data.
     * @param data Define the texture data
     * @param width Define the width of the texture
     * @param height Define the height of the texture
     * @param scene Define the scene the texture belongs to
     * @param generateMipMaps Define whether or not to create mip maps for the texture
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @returns the luminance texture
     */
    RawTexture.CreateLuminanceTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        return new RawTexture(data, width, height, _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_LUMINANCE, scene, generateMipMaps, invertY, samplingMode);
    };
    /**
     * Creates a luminance alpha texture from some data.
     * @param data Define the texture data
     * @param width Define the width of the texture
     * @param height Define the height of the texture
     * @param scene Define the scene the texture belongs to
     * @param generateMipMaps Define whether or not to create mip maps for the texture
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @returns the luminance alpha texture
     */
    RawTexture.CreateLuminanceAlphaTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        return new RawTexture(data, width, height, _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_LUMINANCE_ALPHA, scene, generateMipMaps, invertY, samplingMode);
    };
    /**
     * Creates an alpha texture from some data.
     * @param data Define the texture data
     * @param width Define the width of the texture
     * @param height Define the height of the texture
     * @param scene Define the scene the texture belongs to
     * @param generateMipMaps Define whether or not to create mip maps for the texture
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @returns the alpha texture
     */
    RawTexture.CreateAlphaTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        return new RawTexture(data, width, height, _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_ALPHA, scene, generateMipMaps, invertY, samplingMode);
    };
    /**
     * Creates a RGB texture from some data.
     * @param data Define the texture data
     * @param width Define the width of the texture
     * @param height Define the height of the texture
     * @param scene Define the scene the texture belongs to
     * @param generateMipMaps Define whether or not to create mip maps for the texture
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)
     * @returns the RGB alpha texture
     */
    RawTexture.CreateRGBTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode, type) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        return new RawTexture(data, width, height, _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_RGB, scene, generateMipMaps, invertY, samplingMode, type);
    };
    /**
     * Creates a RGBA texture from some data.
     * @param data Define the texture data
     * @param width Define the width of the texture
     * @param height Define the height of the texture
     * @param scene Define the scene the texture belongs to
     * @param generateMipMaps Define whether or not to create mip maps for the texture
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)
     * @returns the RGBA texture
     */
    RawTexture.CreateRGBATexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode, type) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE; }
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        return new RawTexture(data, width, height, _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_RGBA, scene, generateMipMaps, invertY, samplingMode, type);
    };
    /**
     * Creates a R texture from some data.
     * @param data Define the texture data
     * @param width Define the width of the texture
     * @param height Define the height of the texture
     * @param scene Define the scene the texture belongs to
     * @param generateMipMaps Define whether or not to create mip maps for the texture
     * @param invertY define if the data should be flipped on Y when uploaded to the GPU
     * @param samplingMode define the texture sampling mode (Texture.xxx_SAMPLINGMODE)
     * @param type define the format of the data (int, float... Engine.TEXTURETYPE_xxx)
     * @returns the R texture
     */
    RawTexture.CreateRTexture = function (data, width, height, scene, generateMipMaps, invertY, samplingMode, type) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].TRILINEAR_SAMPLINGMODE; }
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT; }
        return new RawTexture(data, width, height, _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_R, scene, generateMipMaps, invertY, samplingMode, type);
    };
    return RawTexture;
}(_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"]));



/***/ }),

/***/ "./Materials/Textures/rawTexture3D.ts":
/*!********************************************!*\
  !*** ./Materials/Textures/rawTexture3D.ts ***!
  \********************************************/
/*! exports provided: RawTexture3D */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RawTexture3D", function() { return RawTexture3D; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_Extensions_engine_rawTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Engines/Extensions/engine.rawTexture */ "./Engines/Extensions/engine.rawTexture.ts");




/**
 * Class used to store 3D textures containing user data
 */
var RawTexture3D = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RawTexture3D, _super);
    /**
     * Create a new RawTexture3D
     * @param data defines the data of the texture
     * @param width defines the width of the texture
     * @param height defines the height of the texture
     * @param depth defines the depth of the texture
     * @param format defines the texture format to use
     * @param scene defines the hosting scene
     * @param generateMipMaps defines a boolean indicating if mip levels should be generated (true by default)
     * @param invertY defines if texture must be stored with Y axis inverted
     * @param samplingMode defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default)
     * @param textureType defines the texture Type (Engine.TEXTURETYPE_UNSIGNED_INT, Engine.TEXTURETYPE_FLOAT...)
     */
    function RawTexture3D(data, width, height, depth,
    /** Gets or sets the texture format to use */
    format, scene, generateMipMaps, invertY, samplingMode, textureType) {
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].TRILINEAR_SAMPLINGMODE; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        var _this = _super.call(this, null, scene, !generateMipMaps, invertY) || this;
        _this.format = format;
        _this._engine = scene.getEngine();
        _this._texture = scene.getEngine().createRawTexture3D(data, width, height, depth, format, generateMipMaps, invertY, samplingMode, undefined, textureType);
        _this.is3D = true;
        return _this;
    }
    /**
     * Update the texture with new data
     * @param data defines the data to store in the texture
     */
    RawTexture3D.prototype.update = function (data) {
        if (!this._texture) {
            return;
        }
        this._engine.updateRawTexture3D(this._texture, data, this._texture.format, this._texture.invertY, null, this._texture.type);
    };
    return RawTexture3D;
}(_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"]));



/***/ }),

/***/ "./Materials/Textures/refractionTexture.ts":
/*!*************************************************!*\
  !*** ./Materials/Textures/refractionTexture.ts ***!
  \*************************************************/
/*! exports provided: RefractionTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RefractionTexture", function() { return RefractionTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_plane__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.plane */ "./Maths/math.plane.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");



/**
 * Creates a refraction texture used by refraction channel of the standard material.
 * It is like a mirror but to see through a material.
 * @see https://doc.babylonjs.com/how_to/reflect#refraction
 */
var RefractionTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RefractionTexture, _super);
    /**
     * Creates a refraction texture used by refraction channel of the standard material.
     * It is like a mirror but to see through a material.
     * @see https://doc.babylonjs.com/how_to/reflect#refraction
     * @param name Define the texture name
     * @param size Define the size of the underlying texture
     * @param scene Define the scene the refraction belongs to
     * @param generateMipMaps Define if we need to generate mips level for the refraction
     */
    function RefractionTexture(name, size, scene, generateMipMaps) {
        var _this = _super.call(this, name, size, scene, generateMipMaps, true) || this;
        /**
         * Define the reflection plane we want to use. The refractionPlane is usually set to the constructed refractor.
         * It is possible to directly set the refractionPlane by directly using a Plane(a, b, c, d) where a, b and c give the plane normal vector (a, b, c) and d is a scalar displacement from the refractionPlane to the origin. However in all but the very simplest of situations it is more straight forward to set it to the refractor as stated in the doc.
         * @see https://doc.babylonjs.com/how_to/reflect#refraction
         */
        _this.refractionPlane = new _Maths_math_plane__WEBPACK_IMPORTED_MODULE_1__["Plane"](0, 1, 0, 1);
        /**
         * Define how deep under the surface we should see.
         */
        _this.depth = 2.0;
        _this.onBeforeRenderObservable.add(function () {
            scene.clipPlane = _this.refractionPlane;
        });
        _this.onAfterRenderObservable.add(function () {
            scene.clipPlane = null;
        });
        return _this;
    }
    /**
     * Clone the refraction texture.
     * @returns the cloned texture
     */
    RefractionTexture.prototype.clone = function () {
        var scene = this.getScene();
        if (!scene) {
            return this;
        }
        var textureSize = this.getSize();
        var newTexture = new RefractionTexture(this.name, textureSize.width, scene, this._generateMipMaps);
        // Base texture
        newTexture.hasAlpha = this.hasAlpha;
        newTexture.level = this.level;
        // Refraction Texture
        newTexture.refractionPlane = this.refractionPlane.clone();
        if (this.renderList) {
            newTexture.renderList = this.renderList.slice(0);
        }
        newTexture.depth = this.depth;
        return newTexture;
    };
    /**
     * Serialize the texture to a JSON representation you could use in Parse later on
     * @returns the serialized JSON representation
     */
    RefractionTexture.prototype.serialize = function () {
        if (!this.name) {
            return null;
        }
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.mirrorPlane = this.refractionPlane.asArray();
        serializationObject.depth = this.depth;
        return serializationObject;
    };
    return RefractionTexture;
}(_Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_2__["RenderTargetTexture"]));



/***/ }),

/***/ "./Materials/Textures/renderTargetCreationOptions.ts":
/*!***********************************************************!*\
  !*** ./Materials/Textures/renderTargetCreationOptions.ts ***!
  \***********************************************************/
/*! exports provided: RenderTargetCreationOptions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderTargetCreationOptions", function() { return RenderTargetCreationOptions; });
/**
 * Define options used to create a render target texture
 */
var RenderTargetCreationOptions = /** @class */ (function () {
    function RenderTargetCreationOptions() {
    }
    return RenderTargetCreationOptions;
}());



/***/ }),

/***/ "./Materials/Textures/renderTargetTexture.ts":
/*!***************************************************!*\
  !*** ./Materials/Textures/renderTargetTexture.ts ***!
  \***************************************************/
/*! exports provided: RenderTargetTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderTargetTexture", function() { return RenderTargetTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _PostProcesses_postProcessManager__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../PostProcesses/postProcessManager */ "./PostProcesses/postProcessManager.ts");
/* harmony import */ var _Rendering_renderingManager__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Rendering/renderingManager */ "./Rendering/renderingManager.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_Extensions_engine_renderTarget__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Engines/Extensions/engine.renderTarget */ "./Engines/Extensions/engine.renderTarget.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Engines/engine */ "./Engines/engine.ts");










/**
 * This Helps creating a texture that will be created from a camera in your scene.
 * It is basically a dynamic texture that could be used to create special effects for instance.
 * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
 */
var RenderTargetTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RenderTargetTexture, _super);
    /**
     * Instantiate a render target texture. This is mainly used to render of screen the scene to for instance apply post processse
     * or used a shadow, depth texture...
     * @param name The friendly name of the texture
     * @param size The size of the RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
     * @param scene The scene the RTT belongs to. The latest created scene will be used if not precised.
     * @param generateMipMaps True if mip maps need to be generated after render.
     * @param doNotChangeAspectRatio True to not change the aspect ratio of the scene in the RTT
     * @param type The type of the buffer in the RTT (int, half float, float...)
     * @param isCube True if a cube texture needs to be created
     * @param samplingMode The sampling mode to be usedwith the render target (Linear, Nearest...)
     * @param generateDepthBuffer True to generate a depth buffer
     * @param generateStencilBuffer True to generate a stencil buffer
     * @param isMulti True if multiple textures need to be created (Draw Buffers)
     * @param format The internal format of the buffer in the RTT (RED, RG, RGB, RGBA, ALPHA...)
     * @param delayAllocation if the texture allocation should be delayed (default: false)
     */
    function RenderTargetTexture(name, size, scene, generateMipMaps, doNotChangeAspectRatio, type, isCube, samplingMode, generateDepthBuffer, generateStencilBuffer, isMulti, format, delayAllocation) {
        if (doNotChangeAspectRatio === void 0) { doNotChangeAspectRatio = true; }
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (isCube === void 0) { isCube = false; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE; }
        if (generateDepthBuffer === void 0) { generateDepthBuffer = true; }
        if (generateStencilBuffer === void 0) { generateStencilBuffer = false; }
        if (isMulti === void 0) { isMulti = false; }
        if (format === void 0) { format = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].TEXTUREFORMAT_RGBA; }
        if (delayAllocation === void 0) { delayAllocation = false; }
        var _this = _super.call(this, null, scene, !generateMipMaps) || this;
        _this.isCube = isCube;
        /**
         * Define if particles should be rendered in your texture.
         */
        _this.renderParticles = true;
        /**
         * Define if sprites should be rendered in your texture.
         */
        _this.renderSprites = false;
        /**
         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
         */
        _this.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].PROJECTION_MODE;
        /**
         * Define if the camera viewport should be respected while rendering the texture or if the render should be done to the entire texture.
         */
        _this.ignoreCameraViewport = false;
        /**
        * An event triggered when the texture is unbind.
        */
        _this.onBeforeBindObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered when the texture is unbind.
        */
        _this.onAfterUnbindObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered before rendering the texture
        */
        _this.onBeforeRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered after rendering the texture
        */
        _this.onAfterRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered after the texture clear
        */
        _this.onClearObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
         * An event triggered when the texture is resized.
         */
        _this.onResizeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        _this._currentRefreshId = -1;
        _this._refreshRate = 1;
        _this._samples = 1;
        /**
         * Gets or sets the center of the bounding box associated with the texture (when in cube mode)
         * It must define where the camera used to render the texture is set
         */
        _this.boundingBoxPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        scene = _this.getScene();
        if (!scene) {
            return _this;
        }
        _this.renderList = new Array();
        _this._engine = scene.getEngine();
        _this.name = name;
        _this.isRenderTarget = true;
        _this._initialSizeParameter = size;
        _this._processSizeParameter(size);
        _this._resizeObserver = _this.getScene().getEngine().onResizeObservable.add(function () {
        });
        _this._generateMipMaps = generateMipMaps ? true : false;
        _this._doNotChangeAspectRatio = doNotChangeAspectRatio;
        // Rendering groups
        _this._renderingManager = new _Rendering_renderingManager__WEBPACK_IMPORTED_MODULE_6__["RenderingManager"](scene);
        _this._renderingManager._useSceneAutoClearSetup = true;
        if (isMulti) {
            return _this;
        }
        _this._renderTargetOptions = {
            generateMipMaps: generateMipMaps,
            type: type,
            format: format,
            samplingMode: samplingMode,
            generateDepthBuffer: generateDepthBuffer,
            generateStencilBuffer: generateStencilBuffer
        };
        if (samplingMode === _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].NEAREST_SAMPLINGMODE) {
            _this.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
            _this.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
        }
        if (!delayAllocation) {
            if (isCube) {
                _this._texture = scene.getEngine().createRenderTargetCubeTexture(_this.getRenderSize(), _this._renderTargetOptions);
                _this.coordinatesMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].INVCUBIC_MODE;
                _this._textureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
            }
            else {
                _this._texture = scene.getEngine().createRenderTargetTexture(_this._size, _this._renderTargetOptions);
            }
        }
        return _this;
    }
    Object.defineProperty(RenderTargetTexture.prototype, "renderList", {
        /**
        * Use this list to define the list of mesh you want to render.
        */
        get: function () {
            return this._renderList;
        },
        set: function (value) {
            this._renderList = value;
            if (this._renderList) {
                this._hookArray(this._renderList);
            }
        },
        enumerable: true,
        configurable: true
    });
    RenderTargetTexture.prototype._hookArray = function (array) {
        var _this = this;
        var oldPush = array.push;
        array.push = function () {
            var items = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                items[_i] = arguments[_i];
            }
            var wasEmpty = array.length === 0;
            var result = oldPush.apply(array, items);
            if (wasEmpty) {
                _this.getScene().meshes.forEach(function (mesh) {
                    mesh._markSubMeshesAsLightDirty();
                });
            }
            return result;
        };
        var oldSplice = array.splice;
        array.splice = function (index, deleteCount) {
            var deleted = oldSplice.apply(array, [index, deleteCount]);
            if (array.length === 0) {
                _this.getScene().meshes.forEach(function (mesh) {
                    mesh._markSubMeshesAsLightDirty();
                });
            }
            return deleted;
        };
    };
    Object.defineProperty(RenderTargetTexture.prototype, "onAfterUnbind", {
        /**
         * Set a after unbind callback in the texture.
         * This has been kept for backward compatibility and use of onAfterUnbindObservable is recommended.
         */
        set: function (callback) {
            if (this._onAfterUnbindObserver) {
                this.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);
            }
            this._onAfterUnbindObserver = this.onAfterUnbindObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RenderTargetTexture.prototype, "onBeforeRender", {
        /**
         * Set a before render callback in the texture.
         * This has been kept for backward compatibility and use of onBeforeRenderObservable is recommended.
         */
        set: function (callback) {
            if (this._onBeforeRenderObserver) {
                this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
            }
            this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RenderTargetTexture.prototype, "onAfterRender", {
        /**
         * Set a after render callback in the texture.
         * This has been kept for backward compatibility and use of onAfterRenderObservable is recommended.
         */
        set: function (callback) {
            if (this._onAfterRenderObserver) {
                this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
            }
            this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RenderTargetTexture.prototype, "onClear", {
        /**
         * Set a clear callback in the texture.
         * This has been kept for backward compatibility and use of onClearObservable is recommended.
         */
        set: function (callback) {
            if (this._onClearObserver) {
                this.onClearObservable.remove(this._onClearObserver);
            }
            this._onClearObserver = this.onClearObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RenderTargetTexture.prototype, "renderTargetOptions", {
        /**
         * Gets render target creation options that were used.
         */
        get: function () {
            return this._renderTargetOptions;
        },
        enumerable: true,
        configurable: true
    });
    RenderTargetTexture.prototype._onRatioRescale = function () {
        if (this._sizeRatio) {
            this.resize(this._initialSizeParameter);
        }
    };
    Object.defineProperty(RenderTargetTexture.prototype, "boundingBoxSize", {
        get: function () {
            return this._boundingBoxSize;
        },
        /**
         * Gets or sets the size of the bounding box associated with the texture (when in cube mode)
         * When defined, the cubemap will switch to local mode
         * @see https://community.arm.com/graphics/b/blog/posts/reflections-based-on-local-cubemaps-in-unity
         * @example https://www.babylonjs-playground.com/#RNASML
         */
        set: function (value) {
            if (this._boundingBoxSize && this._boundingBoxSize.equals(value)) {
                return;
            }
            this._boundingBoxSize = value;
            var scene = this.getScene();
            if (scene) {
                scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TextureDirtyFlag);
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Creates a depth stencil texture.
     * This is only available in WebGL 2 or with the depth texture extension available.
     * @param comparisonFunction Specifies the comparison function to set on the texture. If 0 or undefined, the texture is not in comparison mode
     * @param bilinearFiltering Specifies whether or not bilinear filtering is enable on the texture
     * @param generateStencil Specifies whether or not a stencil should be allocated in the texture
     */
    RenderTargetTexture.prototype.createDepthStencilTexture = function (comparisonFunction, bilinearFiltering, generateStencil) {
        if (comparisonFunction === void 0) { comparisonFunction = 0; }
        if (bilinearFiltering === void 0) { bilinearFiltering = true; }
        if (generateStencil === void 0) { generateStencil = false; }
        if (!this.getScene()) {
            return;
        }
        var engine = this.getScene().getEngine();
        this.depthStencilTexture = engine.createDepthStencilTexture(this._size, {
            bilinearFiltering: bilinearFiltering,
            comparisonFunction: comparisonFunction,
            generateStencil: generateStencil,
            isCube: this.isCube
        });
        engine.setFrameBufferDepthStencilTexture(this);
    };
    RenderTargetTexture.prototype._processSizeParameter = function (size) {
        if (size.ratio) {
            this._sizeRatio = size.ratio;
            this._size = {
                width: this._bestReflectionRenderTargetDimension(this._engine.getRenderWidth(), this._sizeRatio),
                height: this._bestReflectionRenderTargetDimension(this._engine.getRenderHeight(), this._sizeRatio)
            };
        }
        else {
            this._size = size;
        }
    };
    Object.defineProperty(RenderTargetTexture.prototype, "samples", {
        /**
         * Define the number of samples to use in case of MSAA.
         * It defaults to one meaning no MSAA has been enabled.
         */
        get: function () {
            return this._samples;
        },
        set: function (value) {
            if (this._samples === value) {
                return;
            }
            var scene = this.getScene();
            if (!scene) {
                return;
            }
            this._samples = scene.getEngine().updateRenderTargetTextureSampleCount(this._texture, value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resets the refresh counter of the texture and start bak from scratch.
     * Could be useful to regenerate the texture if it is setup to render only once.
     */
    RenderTargetTexture.prototype.resetRefreshCounter = function () {
        this._currentRefreshId = -1;
    };
    Object.defineProperty(RenderTargetTexture.prototype, "refreshRate", {
        /**
         * Define the refresh rate of the texture or the rendering frequency.
         * Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
         */
        get: function () {
            return this._refreshRate;
        },
        set: function (value) {
            this._refreshRate = value;
            this.resetRefreshCounter();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Adds a post process to the render target rendering passes.
     * @param postProcess define the post process to add
     */
    RenderTargetTexture.prototype.addPostProcess = function (postProcess) {
        if (!this._postProcessManager) {
            var scene = this.getScene();
            if (!scene) {
                return;
            }
            this._postProcessManager = new _PostProcesses_postProcessManager__WEBPACK_IMPORTED_MODULE_5__["PostProcessManager"](scene);
            this._postProcesses = new Array();
        }
        this._postProcesses.push(postProcess);
        this._postProcesses[0].autoClear = false;
    };
    /**
     * Clear all the post processes attached to the render target
     * @param dispose define if the cleared post processesshould also be disposed (false by default)
     */
    RenderTargetTexture.prototype.clearPostProcesses = function (dispose) {
        if (dispose === void 0) { dispose = false; }
        if (!this._postProcesses) {
            return;
        }
        if (dispose) {
            for (var _i = 0, _a = this._postProcesses; _i < _a.length; _i++) {
                var postProcess = _a[_i];
                postProcess.dispose();
            }
        }
        this._postProcesses = [];
    };
    /**
     * Remove one of the post process from the list of attached post processes to the texture
     * @param postProcess define the post process to remove from the list
     */
    RenderTargetTexture.prototype.removePostProcess = function (postProcess) {
        if (!this._postProcesses) {
            return;
        }
        var index = this._postProcesses.indexOf(postProcess);
        if (index === -1) {
            return;
        }
        this._postProcesses.splice(index, 1);
        if (this._postProcesses.length > 0) {
            this._postProcesses[0].autoClear = false;
        }
    };
    /** @hidden */
    RenderTargetTexture.prototype._shouldRender = function () {
        if (this._currentRefreshId === -1) { // At least render once
            this._currentRefreshId = 1;
            return true;
        }
        if (this.refreshRate === this._currentRefreshId) {
            this._currentRefreshId = 1;
            return true;
        }
        this._currentRefreshId++;
        return false;
    };
    /**
     * Gets the actual render size of the texture.
     * @returns the width of the render size
     */
    RenderTargetTexture.prototype.getRenderSize = function () {
        return this.getRenderWidth();
    };
    /**
     * Gets the actual render width of the texture.
     * @returns the width of the render size
     */
    RenderTargetTexture.prototype.getRenderWidth = function () {
        if (this._size.width) {
            return this._size.width;
        }
        return this._size;
    };
    /**
     * Gets the actual render height of the texture.
     * @returns the height of the render size
     */
    RenderTargetTexture.prototype.getRenderHeight = function () {
        if (this._size.width) {
            return this._size.height;
        }
        return this._size;
    };
    Object.defineProperty(RenderTargetTexture.prototype, "canRescale", {
        /**
         * Get if the texture can be rescaled or not.
         */
        get: function () {
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resize the texture using a ratio.
     * @param ratio the ratio to apply to the texture size in order to compute the new target size
     */
    RenderTargetTexture.prototype.scale = function (ratio) {
        var newSize = this.getRenderSize() * ratio;
        this.resize(newSize);
    };
    /**
     * Get the texture reflection matrix used to rotate/transform the reflection.
     * @returns the reflection matrix
     */
    RenderTargetTexture.prototype.getReflectionTextureMatrix = function () {
        if (this.isCube) {
            return this._textureMatrix;
        }
        return _super.prototype.getReflectionTextureMatrix.call(this);
    };
    /**
     * Resize the texture to a new desired size.
     * Be carrefull as it will recreate all the data in the new texture.
     * @param size Define the new size. It can be:
     *   - a number for squared texture,
     *   - an object containing { width: number, height: number }
     *   - or an object containing a ratio { ratio: number }
     */
    RenderTargetTexture.prototype.resize = function (size) {
        var wasCube = this.isCube;
        this.releaseInternalTexture();
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        this._processSizeParameter(size);
        if (wasCube) {
            this._texture = scene.getEngine().createRenderTargetCubeTexture(this.getRenderSize(), this._renderTargetOptions);
        }
        else {
            this._texture = scene.getEngine().createRenderTargetTexture(this._size, this._renderTargetOptions);
        }
        if (this.onResizeObservable.hasObservers()) {
            this.onResizeObservable.notifyObservers(this);
        }
    };
    /**
     * Renders all the objects from the render list into the texture.
     * @param useCameraPostProcess Define if camera post processes should be used during the rendering
     * @param dumpForDebug Define if the rendering result should be dumped (copied) for debugging purpose
     */
    RenderTargetTexture.prototype.render = function (useCameraPostProcess, dumpForDebug) {
        if (useCameraPostProcess === void 0) { useCameraPostProcess = false; }
        if (dumpForDebug === void 0) { dumpForDebug = false; }
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        var engine = scene.getEngine();
        if (this.useCameraPostProcesses !== undefined) {
            useCameraPostProcess = this.useCameraPostProcesses;
        }
        if (this._waitingRenderList) {
            this.renderList = [];
            for (var index = 0; index < this._waitingRenderList.length; index++) {
                var id = this._waitingRenderList[index];
                var mesh_1 = scene.getMeshByID(id);
                if (mesh_1) {
                    this.renderList.push(mesh_1);
                }
            }
            delete this._waitingRenderList;
        }
        // Is predicate defined?
        if (this.renderListPredicate) {
            if (this.renderList) {
                this.renderList.length = 0; // Clear previous renderList
            }
            else {
                this.renderList = [];
            }
            var scene = this.getScene();
            if (!scene) {
                return;
            }
            var sceneMeshes = scene.meshes;
            for (var index = 0; index < sceneMeshes.length; index++) {
                var mesh = sceneMeshes[index];
                if (this.renderListPredicate(mesh)) {
                    this.renderList.push(mesh);
                }
            }
        }
        this.onBeforeBindObservable.notifyObservers(this);
        // Set custom projection.
        // Needs to be before binding to prevent changing the aspect ratio.
        var camera;
        if (this.activeCamera) {
            camera = this.activeCamera;
            engine.setViewport(this.activeCamera.viewport, this.getRenderWidth(), this.getRenderHeight());
            if (this.activeCamera !== scene.activeCamera) {
                scene.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(true));
            }
        }
        else {
            camera = scene.activeCamera;
            if (camera) {
                engine.setViewport(camera.viewport, this.getRenderWidth(), this.getRenderHeight());
            }
        }
        // Prepare renderingManager
        this._renderingManager.reset();
        var currentRenderList = this.renderList ? this.renderList : scene.getActiveMeshes().data;
        var currentRenderListLength = this.renderList ? this.renderList.length : scene.getActiveMeshes().length;
        var sceneRenderId = scene.getRenderId();
        for (var meshIndex = 0; meshIndex < currentRenderListLength; meshIndex++) {
            var mesh = currentRenderList[meshIndex];
            if (mesh) {
                if (!mesh.isReady(this.refreshRate === 0)) {
                    this.resetRefreshCounter();
                    continue;
                }
                mesh._preActivateForIntermediateRendering(sceneRenderId);
                var isMasked = void 0;
                if (!this.renderList && camera) {
                    isMasked = ((mesh.layerMask & camera.layerMask) === 0);
                }
                else {
                    isMasked = false;
                }
                if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && !isMasked) {
                    if (mesh._activate(sceneRenderId, true)) {
                        if (!mesh.isAnInstance) {
                            mesh._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = false;
                        }
                        else {
                            mesh = mesh.sourceMesh;
                        }
                        mesh._internalAbstractMeshDataInfo._isActiveIntermediate = true;
                        for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                            var subMesh = mesh.subMeshes[subIndex];
                            scene._activeIndices.addCount(subMesh.indexCount, false);
                            this._renderingManager.dispatch(subMesh, mesh);
                        }
                    }
                }
            }
        }
        for (var particleIndex = 0; particleIndex < scene.particleSystems.length; particleIndex++) {
            var particleSystem = scene.particleSystems[particleIndex];
            var emitter = particleSystem.emitter;
            if (!particleSystem.isStarted() || !emitter || !emitter.position || !emitter.isEnabled()) {
                continue;
            }
            if (currentRenderList.indexOf(emitter) >= 0) {
                this._renderingManager.dispatchParticles(particleSystem);
            }
        }
        if (this.isCube) {
            for (var face = 0; face < 6; face++) {
                this.renderToTarget(face, currentRenderList, useCameraPostProcess, dumpForDebug);
                scene.incrementRenderId();
                scene.resetCachedMaterial();
            }
        }
        else {
            this.renderToTarget(0, currentRenderList, useCameraPostProcess, dumpForDebug);
        }
        this.onAfterUnbindObservable.notifyObservers(this);
        if (scene.activeCamera) {
            // Do not avoid setting uniforms when multiple scenes are active as another camera may have overwrite these
            if (scene.getEngine().scenes.length > 1 || (this.activeCamera && this.activeCamera !== scene.activeCamera)) {
                scene.setTransformMatrix(scene.activeCamera.getViewMatrix(), scene.activeCamera.getProjectionMatrix(true));
            }
            engine.setViewport(scene.activeCamera.viewport);
        }
        scene.resetCachedMaterial();
    };
    RenderTargetTexture.prototype._bestReflectionRenderTargetDimension = function (renderDimension, scale) {
        var minimum = 128;
        var x = renderDimension * scale;
        var curved = _Engines_engine__WEBPACK_IMPORTED_MODULE_9__["Engine"].NearestPOT(x + (minimum * minimum / (minimum + x)));
        // Ensure we don't exceed the render dimension (while staying POT)
        return Math.min(_Engines_engine__WEBPACK_IMPORTED_MODULE_9__["Engine"].FloorPOT(renderDimension), curved);
    };
    /**
     * @hidden
     * @param faceIndex face index to bind to if this is a cubetexture
     */
    RenderTargetTexture.prototype._bindFrameBuffer = function (faceIndex) {
        if (faceIndex === void 0) { faceIndex = 0; }
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        var engine = scene.getEngine();
        if (this._texture) {
            engine.bindFramebuffer(this._texture, this.isCube ? faceIndex : undefined, undefined, undefined, this.ignoreCameraViewport, this.depthStencilTexture ? this.depthStencilTexture : undefined);
        }
    };
    RenderTargetTexture.prototype.unbindFrameBuffer = function (engine, faceIndex) {
        var _this = this;
        if (!this._texture) {
            return;
        }
        engine.unBindFramebuffer(this._texture, this.isCube, function () {
            _this.onAfterRenderObservable.notifyObservers(faceIndex);
        });
    };
    RenderTargetTexture.prototype.renderToTarget = function (faceIndex, currentRenderList, useCameraPostProcess, dumpForDebug) {
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        var engine = scene.getEngine();
        if (!this._texture) {
            return;
        }
        // Bind
        if (this._postProcessManager) {
            this._postProcessManager._prepareFrame(this._texture, this._postProcesses);
        }
        else if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
            this._bindFrameBuffer(faceIndex);
        }
        this.onBeforeRenderObservable.notifyObservers(faceIndex);
        // Clear
        if (this.onClearObservable.hasObservers()) {
            this.onClearObservable.notifyObservers(engine);
        }
        else {
            engine.clear(this.clearColor || scene.clearColor, true, true, true);
        }
        if (!this._doNotChangeAspectRatio) {
            scene.updateTransformMatrix(true);
        }
        // Before Camera Draw
        for (var _i = 0, _a = scene._beforeRenderTargetDrawStage; _i < _a.length; _i++) {
            var step = _a[_i];
            step.action(this);
        }
        // Render
        this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
        // After Camera Draw
        for (var _b = 0, _c = scene._afterRenderTargetDrawStage; _b < _c.length; _b++) {
            var step = _c[_b];
            step.action(this);
        }
        if (this._postProcessManager) {
            this._postProcessManager._finalizeFrame(false, this._texture, faceIndex, this._postProcesses, this.ignoreCameraViewport);
        }
        else if (useCameraPostProcess) {
            scene.postProcessManager._finalizeFrame(false, this._texture, faceIndex);
        }
        if (!this._doNotChangeAspectRatio) {
            scene.updateTransformMatrix(true);
        }
        // Dump ?
        if (dumpForDebug) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].DumpFramebuffer(this.getRenderWidth(), this.getRenderHeight(), engine);
        }
        // Unbind
        if (!this.isCube || faceIndex === 5) {
            if (this.isCube) {
                if (faceIndex === 5) {
                    engine.generateMipMapsForCubemap(this._texture);
                }
            }
            this.unbindFrameBuffer(engine, faceIndex);
        }
        else {
            this.onAfterRenderObservable.notifyObservers(faceIndex);
        }
    };
    /**
     * Overrides the default sort function applied in the renderging group to prepare the meshes.
     * This allowed control for front to back rendering or reversly depending of the special needs.
     *
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.
     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.
     * @param transparentSortCompareFn The transparent queue comparison function use to sort.
     */
    RenderTargetTexture.prototype.setRenderingOrder = function (renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn) {
        if (opaqueSortCompareFn === void 0) { opaqueSortCompareFn = null; }
        if (alphaTestSortCompareFn === void 0) { alphaTestSortCompareFn = null; }
        if (transparentSortCompareFn === void 0) { transparentSortCompareFn = null; }
        this._renderingManager.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);
    };
    /**
     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.
     *
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
     */
    RenderTargetTexture.prototype.setRenderingAutoClearDepthStencil = function (renderingGroupId, autoClearDepthStencil) {
        this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
        this._renderingManager._useSceneAutoClearSetup = false;
    };
    /**
     * Clones the texture.
     * @returns the cloned texture
     */
    RenderTargetTexture.prototype.clone = function () {
        var textureSize = this.getSize();
        var newTexture = new RenderTargetTexture(this.name, textureSize, this.getScene(), this._renderTargetOptions.generateMipMaps, this._doNotChangeAspectRatio, this._renderTargetOptions.type, this.isCube, this._renderTargetOptions.samplingMode, this._renderTargetOptions.generateDepthBuffer, this._renderTargetOptions.generateStencilBuffer);
        // Base texture
        newTexture.hasAlpha = this.hasAlpha;
        newTexture.level = this.level;
        // RenderTarget Texture
        newTexture.coordinatesMode = this.coordinatesMode;
        if (this.renderList) {
            newTexture.renderList = this.renderList.slice(0);
        }
        return newTexture;
    };
    /**
     * Serialize the texture to a JSON representation we can easily use in the resepective Parse function.
     * @returns The JSON representation of the texture
     */
    RenderTargetTexture.prototype.serialize = function () {
        if (!this.name) {
            return null;
        }
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.renderTargetSize = this.getRenderSize();
        serializationObject.renderList = [];
        if (this.renderList) {
            for (var index = 0; index < this.renderList.length; index++) {
                serializationObject.renderList.push(this.renderList[index].id);
            }
        }
        return serializationObject;
    };
    /**
     *  This will remove the attached framebuffer objects. The texture will not be able to be used as render target anymore
     */
    RenderTargetTexture.prototype.disposeFramebufferObjects = function () {
        var objBuffer = this.getInternalTexture();
        var scene = this.getScene();
        if (objBuffer && scene) {
            scene.getEngine()._releaseFramebufferObjects(objBuffer);
        }
    };
    /**
     * Dispose the texture and release its associated resources.
     */
    RenderTargetTexture.prototype.dispose = function () {
        this.onResizeObservable.clear();
        this.onClearObservable.clear();
        this.onAfterRenderObservable.clear();
        this.onAfterUnbindObservable.clear();
        this.onBeforeBindObservable.clear();
        this.onBeforeRenderObservable.clear();
        if (this._postProcessManager) {
            this._postProcessManager.dispose();
            this._postProcessManager = null;
        }
        this.clearPostProcesses(true);
        if (this._resizeObserver) {
            this.getScene().getEngine().onResizeObservable.remove(this._resizeObserver);
            this._resizeObserver = null;
        }
        this.renderList = null;
        // Remove from custom render targets
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        var index = scene.customRenderTargets.indexOf(this);
        if (index >= 0) {
            scene.customRenderTargets.splice(index, 1);
        }
        for (var _i = 0, _a = scene.cameras; _i < _a.length; _i++) {
            var camera = _a[_i];
            index = camera.customRenderTargets.indexOf(this);
            if (index >= 0) {
                camera.customRenderTargets.splice(index, 1);
            }
        }
        if (this.depthStencilTexture) {
            this.getScene().getEngine()._releaseTexture(this.depthStencilTexture);
        }
        _super.prototype.dispose.call(this);
    };
    /** @hidden */
    RenderTargetTexture.prototype._rebuild = function () {
        if (this.refreshRate === RenderTargetTexture.REFRESHRATE_RENDER_ONCE) {
            this.refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
        }
        if (this._postProcessManager) {
            this._postProcessManager._rebuild();
        }
    };
    /**
     * Clear the info related to rendering groups preventing retention point in material dispose.
     */
    RenderTargetTexture.prototype.freeRenderingGroups = function () {
        if (this._renderingManager) {
            this._renderingManager.freeRenderingGroups();
        }
    };
    /**
     * Gets the number of views the corresponding to the texture (eg. a MultiviewRenderTarget will have > 1)
     * @returns the view count
     */
    RenderTargetTexture.prototype.getViewCount = function () {
        return 1;
    };
    /**
     * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
     */
    RenderTargetTexture.REFRESHRATE_RENDER_ONCE = 0;
    /**
     * The texture will only be rendered rendered every frame and is recomended for dynamic contents.
     */
    RenderTargetTexture.REFRESHRATE_RENDER_ONEVERYFRAME = 1;
    /**
     * The texture will be rendered every 2 frames which could be enough if your dynamic objects are not
     * the central point of your effect and can save a lot of performances.
     */
    RenderTargetTexture.REFRESHRATE_RENDER_ONEVERYTWOFRAMES = 2;
    return RenderTargetTexture;
}(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"]));

_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"]._CreateRenderTargetTexture = function (name, renderTargetSize, scene, generateMipMaps) {
    return new RenderTargetTexture(name, renderTargetSize, scene, generateMipMaps);
};


/***/ }),

/***/ "./Materials/Textures/texture.ts":
/*!***************************************!*\
  !*** ./Materials/Textures/texture.ts ***!
  \***************************************/
/*! exports provided: Texture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Texture", function() { return Texture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Misc_timingTools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../Misc/timingTools */ "./Misc/timingTools.ts");
/* harmony import */ var _Misc_instantiationTools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Misc/instantiationTools */ "./Misc/instantiationTools.ts");
/* harmony import */ var _Maths_math_plane__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../Maths/math.plane */ "./Maths/math.plane.ts");











/**
 * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.
 * @see http://doc.babylonjs.com/babylon101/materials#texture
 */
var Texture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Texture, _super);
    /**
     * Instantiates a new texture.
     * This represents a texture in babylon. It can be easily loaded from a network, base64 or html input.
     * @see http://doc.babylonjs.com/babylon101/materials#texture
     * @param url define the url of the picture to load as a texture
     * @param scene define the scene or engine the texture will belong to
     * @param noMipmap define if the texture will require mip maps or not
     * @param invertY define if the texture needs to be inverted on the y axis during loading
     * @param samplingMode define the sampling mode we want for the texture while fectching from it (Texture.NEAREST_SAMPLINGMODE...)
     * @param onLoad define a callback triggered when the texture has been loaded
     * @param onError define a callback triggered when an error occurred during the loading session
     * @param buffer define the buffer to load the texture from in case the texture is loaded from a buffer representation
     * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load
     * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
     */
    function Texture(url, sceneOrEngine, noMipmap, invertY, samplingMode, onLoad, onError, buffer, deleteBuffer, format) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (invertY === void 0) { invertY = true; }
        if (samplingMode === void 0) { samplingMode = Texture.TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (buffer === void 0) { buffer = null; }
        if (deleteBuffer === void 0) { deleteBuffer = false; }
        var _this = _super.call(this, (sceneOrEngine && sceneOrEngine.getClassName() === "Scene") ? sceneOrEngine : null) || this;
        /**
         * Define the url of the texture.
         */
        _this.url = null;
        /**
         * Define an offset on the texture to offset the u coordinates of the UVs
         * @see http://doc.babylonjs.com/how_to/more_materials#offsetting
         */
        _this.uOffset = 0;
        /**
         * Define an offset on the texture to offset the v coordinates of the UVs
         * @see http://doc.babylonjs.com/how_to/more_materials#offsetting
         */
        _this.vOffset = 0;
        /**
         * Define an offset on the texture to scale the u coordinates of the UVs
         * @see http://doc.babylonjs.com/how_to/more_materials#tiling
         */
        _this.uScale = 1.0;
        /**
         * Define an offset on the texture to scale the v coordinates of the UVs
         * @see http://doc.babylonjs.com/how_to/more_materials#tiling
         */
        _this.vScale = 1.0;
        /**
         * Define an offset on the texture to rotate around the u coordinates of the UVs
         * @see http://doc.babylonjs.com/how_to/more_materials
         */
        _this.uAng = 0;
        /**
         * Define an offset on the texture to rotate around the v coordinates of the UVs
         * @see http://doc.babylonjs.com/how_to/more_materials
         */
        _this.vAng = 0;
        /**
         * Define an offset on the texture to rotate around the w coordinates of the UVs (in case of 3d texture)
         * @see http://doc.babylonjs.com/how_to/more_materials
         */
        _this.wAng = 0;
        /**
         * Defines the center of rotation (U)
         */
        _this.uRotationCenter = 0.5;
        /**
         * Defines the center of rotation (V)
         */
        _this.vRotationCenter = 0.5;
        /**
         * Defines the center of rotation (W)
         */
        _this.wRotationCenter = 0.5;
        /**
         * List of inspectable custom properties (used by the Inspector)
         * @see https://doc.babylonjs.com/how_to/debug_layer#extensibility
         */
        _this.inspectableCustomProperties = null;
        _this._noMipmap = false;
        /** @hidden */
        _this._invertY = false;
        _this._rowGenerationMatrix = null;
        _this._cachedTextureMatrix = null;
        _this._projectionModeMatrix = null;
        _this._t0 = null;
        _this._t1 = null;
        _this._t2 = null;
        _this._cachedUOffset = -1;
        _this._cachedVOffset = -1;
        _this._cachedUScale = 0;
        _this._cachedVScale = 0;
        _this._cachedUAng = -1;
        _this._cachedVAng = -1;
        _this._cachedWAng = -1;
        _this._cachedProjectionMatrixId = -1;
        _this._cachedCoordinatesMode = -1;
        /** @hidden */
        _this._initialSamplingMode = Texture.BILINEAR_SAMPLINGMODE;
        /** @hidden */
        _this._buffer = null;
        _this._deleteBuffer = false;
        _this._format = null;
        _this._delayedOnLoad = null;
        _this._delayedOnError = null;
        /**
         * Observable triggered once the texture has been loaded.
         */
        _this.onLoadObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this._isBlocking = true;
        _this.name = url || "";
        _this.url = url;
        _this._noMipmap = noMipmap;
        _this._invertY = invertY;
        _this._initialSamplingMode = samplingMode;
        _this._buffer = buffer;
        _this._deleteBuffer = deleteBuffer;
        if (format) {
            _this._format = format;
        }
        var scene = _this.getScene();
        var engine = (sceneOrEngine && sceneOrEngine.getCaps) ? sceneOrEngine : (scene ? scene.getEngine() : null);
        if (!engine) {
            return _this;
        }
        engine.onBeforeTextureInitObservable.notifyObservers(_this);
        var load = function () {
            if (_this._texture) {
                if (_this._texture._invertVScale) {
                    _this.vScale *= -1;
                    _this.vOffset += 1;
                }
                // Update texutre to match internal texture's wrapping
                if (_this._texture._cachedWrapU !== null) {
                    _this.wrapU = _this._texture._cachedWrapU;
                    _this._texture._cachedWrapU = null;
                }
                if (_this._texture._cachedWrapV !== null) {
                    _this.wrapV = _this._texture._cachedWrapV;
                    _this._texture._cachedWrapV = null;
                }
                if (_this._texture._cachedWrapR !== null) {
                    _this.wrapR = _this._texture._cachedWrapR;
                    _this._texture._cachedWrapR = null;
                }
            }
            if (_this.onLoadObservable.hasObservers()) {
                _this.onLoadObservable.notifyObservers(_this);
            }
            if (onLoad) {
                onLoad();
            }
            if (!_this.isBlocking && scene) {
                scene.resetCachedMaterial();
            }
        };
        if (!_this.url) {
            _this._delayedOnLoad = load;
            _this._delayedOnError = onError;
            return _this;
        }
        _this._texture = _this._getFromCache(_this.url, noMipmap, samplingMode, invertY);
        if (!_this._texture) {
            if (!scene || !scene.useDelayedTextureLoading) {
                _this._texture = engine.createTexture(_this.url, noMipmap, invertY, scene, samplingMode, load, onError, _this._buffer, undefined, _this._format);
                if (deleteBuffer) {
                    delete _this._buffer;
                }
            }
            else {
                _this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].DELAYLOADSTATE_NOTLOADED;
                _this._delayedOnLoad = load;
                _this._delayedOnError = onError;
            }
        }
        else {
            if (_this._texture.isReady) {
                _Misc_timingTools__WEBPACK_IMPORTED_MODULE_8__["TimingTools"].SetImmediate(function () { return load(); });
            }
            else {
                _this._texture.onLoadedObservable.add(load);
            }
        }
        return _this;
    }
    Object.defineProperty(Texture.prototype, "noMipmap", {
        /**
         * Are mip maps generated for this texture or not.
         */
        get: function () {
            return this._noMipmap;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Texture.prototype, "isBlocking", {
        get: function () {
            return this._isBlocking;
        },
        /**
         * Is the texture preventing material to render while loading.
         * If false, a default texture will be used instead of the loading one during the preparation step.
         */
        set: function (value) {
            this._isBlocking = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Texture.prototype, "samplingMode", {
        /**
         * Get the current sampling mode associated with the texture.
         */
        get: function () {
            if (!this._texture) {
                return this._initialSamplingMode;
            }
            return this._texture.samplingMode;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Texture.prototype, "invertY", {
        /**
         * Gets a boolean indicating if the texture needs to be inverted on the y axis during loading
         */
        get: function () {
            return this._invertY;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Update the url (and optional buffer) of this texture if url was null during construction.
     * @param url the url of the texture
     * @param buffer the buffer of the texture (defaults to null)
     * @param onLoad callback called when the texture is loaded  (defaults to null)
     */
    Texture.prototype.updateURL = function (url, buffer, onLoad) {
        if (buffer === void 0) { buffer = null; }
        if (this.url) {
            this.releaseInternalTexture();
            this.getScene().markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].MATERIAL_TextureDirtyFlag);
        }
        this.name = url;
        this.url = url;
        this._buffer = buffer;
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].DELAYLOADSTATE_NOTLOADED;
        if (onLoad) {
            this._delayedOnLoad = onLoad;
        }
        this.delayLoad();
    };
    /**
     * Finish the loading sequence of a texture flagged as delayed load.
     * @hidden
     */
    Texture.prototype.delayLoad = function () {
        if (this.delayLoadState !== _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].DELAYLOADSTATE_NOTLOADED) {
            return;
        }
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].DELAYLOADSTATE_LOADED;
        this._texture = this._getFromCache(this.url, this._noMipmap, this.samplingMode, this._invertY);
        if (!this._texture) {
            this._texture = scene.getEngine().createTexture(this.url, this._noMipmap, this._invertY, scene, this.samplingMode, this._delayedOnLoad, this._delayedOnError, this._buffer, null, this._format);
            if (this._deleteBuffer) {
                delete this._buffer;
            }
        }
        else {
            if (this._delayedOnLoad) {
                if (this._texture.isReady) {
                    _Misc_timingTools__WEBPACK_IMPORTED_MODULE_8__["TimingTools"].SetImmediate(this._delayedOnLoad);
                }
                else {
                    this._texture.onLoadedObservable.add(this._delayedOnLoad);
                }
            }
        }
        this._delayedOnLoad = null;
        this._delayedOnError = null;
    };
    Texture.prototype._prepareRowForTextureGeneration = function (x, y, z, t) {
        x *= this.uScale;
        y *= this.vScale;
        x -= this.uRotationCenter * this.uScale;
        y -= this.vRotationCenter * this.vScale;
        z -= this.wRotationCenter;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix, t);
        t.x += this.uRotationCenter * this.uScale + this.uOffset;
        t.y += this.vRotationCenter * this.vScale + this.vOffset;
        t.z += this.wRotationCenter;
    };
    /**
     * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
     * @returns the transform matrix of the texture.
     */
    Texture.prototype.getTextureMatrix = function () {
        var _this = this;
        if (this.uOffset === this._cachedUOffset &&
            this.vOffset === this._cachedVOffset &&
            this.uScale === this._cachedUScale &&
            this.vScale === this._cachedVScale &&
            this.uAng === this._cachedUAng &&
            this.vAng === this._cachedVAng &&
            this.wAng === this._cachedWAng) {
            return this._cachedTextureMatrix;
        }
        this._cachedUOffset = this.uOffset;
        this._cachedVOffset = this.vOffset;
        this._cachedUScale = this.uScale;
        this._cachedVScale = this.vScale;
        this._cachedUAng = this.uAng;
        this._cachedVAng = this.vAng;
        this._cachedWAng = this.wAng;
        if (!this._cachedTextureMatrix) {
            this._cachedTextureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
            this._rowGenerationMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
            this._t0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
            this._t1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
            this._t2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationYawPitchRollToRef(this.vAng, this.uAng, this.wAng, this._rowGenerationMatrix);
        this._prepareRowForTextureGeneration(0, 0, 0, this._t0);
        this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1);
        this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2);
        this._t1.subtractInPlace(this._t0);
        this._t2.subtractInPlace(this._t0);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromValuesToRef(this._t1.x, this._t1.y, this._t1.z, 0.0, this._t2.x, this._t2.y, this._t2.z, 0.0, this._t0.x, this._t0.y, this._t0.z, 0.0, 0.0, 0.0, 0.0, 1.0, this._cachedTextureMatrix);
        var scene = this.getScene();
        if (!scene) {
            return this._cachedTextureMatrix;
        }
        scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].MATERIAL_TextureDirtyFlag, function (mat) {
            return mat.hasTexture(_this);
        });
        return this._cachedTextureMatrix;
    };
    /**
     * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
     * @returns The reflection texture transform
     */
    Texture.prototype.getReflectionTextureMatrix = function () {
        var _this = this;
        var scene = this.getScene();
        if (!scene) {
            return this._cachedTextureMatrix;
        }
        if (this.uOffset === this._cachedUOffset &&
            this.vOffset === this._cachedVOffset &&
            this.uScale === this._cachedUScale &&
            this.vScale === this._cachedVScale &&
            this.coordinatesMode === this._cachedCoordinatesMode) {
            if (this.coordinatesMode === Texture.PROJECTION_MODE) {
                if (this._cachedProjectionMatrixId === scene.getProjectionMatrix().updateFlag) {
                    return this._cachedTextureMatrix;
                }
            }
            else {
                return this._cachedTextureMatrix;
            }
        }
        if (!this._cachedTextureMatrix) {
            this._cachedTextureMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        }
        if (!this._projectionModeMatrix) {
            this._projectionModeMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        }
        this._cachedUOffset = this.uOffset;
        this._cachedVOffset = this.vOffset;
        this._cachedUScale = this.uScale;
        this._cachedVScale = this.vScale;
        this._cachedCoordinatesMode = this.coordinatesMode;
        switch (this.coordinatesMode) {
            case Texture.PLANAR_MODE:
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].IdentityToRef(this._cachedTextureMatrix);
                this._cachedTextureMatrix[0] = this.uScale;
                this._cachedTextureMatrix[5] = this.vScale;
                this._cachedTextureMatrix[12] = this.uOffset;
                this._cachedTextureMatrix[13] = this.vOffset;
                break;
            case Texture.PROJECTION_MODE:
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromValuesToRef(0.5, 0.0, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0, 1.0, this._projectionModeMatrix);
                var projectionMatrix = scene.getProjectionMatrix();
                this._cachedProjectionMatrixId = projectionMatrix.updateFlag;
                projectionMatrix.multiplyToRef(this._projectionModeMatrix, this._cachedTextureMatrix);
                break;
            default:
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].IdentityToRef(this._cachedTextureMatrix);
                break;
        }
        scene.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].MATERIAL_TextureDirtyFlag, function (mat) {
            return (mat.getActiveTextures().indexOf(_this) !== -1);
        });
        return this._cachedTextureMatrix;
    };
    /**
     * Clones the texture.
     * @returns the cloned texture
     */
    Texture.prototype.clone = function () {
        var _this = this;
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () {
            return new Texture(_this._texture ? _this._texture.url : null, _this.getScene(), _this._noMipmap, _this._invertY, _this.samplingMode, undefined, undefined, _this._texture ? _this._texture._buffer : undefined);
        }, this);
    };
    /**
     * Serialize the texture to a JSON representation we can easily use in the resepective Parse function.
     * @returns The JSON representation of the texture
     */
    Texture.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        if (!serializationObject) {
            return null;
        }
        if (typeof this._buffer === "string" && this._buffer.substr(0, 5) === "data:") {
            serializationObject.base64String = this._buffer;
            serializationObject.name = serializationObject.name.replace("data:", "");
        }
        serializationObject.invertY = this._invertY;
        serializationObject.samplingMode = this.samplingMode;
        return serializationObject;
    };
    /**
     * Get the current class name of the texture useful for serialization or dynamic coding.
     * @returns "Texture"
     */
    Texture.prototype.getClassName = function () {
        return "Texture";
    };
    /**
     * Dispose the texture and release its associated resources.
     */
    Texture.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.onLoadObservable.clear();
        this._delayedOnLoad = null;
        this._delayedOnError = null;
    };
    /**
     * Parse the JSON representation of a texture in order to recreate the texture in the given scene.
     * @param parsedTexture Define the JSON representation of the texture
     * @param scene Define the scene the parsed texture should be instantiated in
     * @param rootUrl Define the root url of the parsing sequence in the case of relative dependencies
     * @returns The parsed texture if successful
     */
    Texture.Parse = function (parsedTexture, scene, rootUrl) {
        if (parsedTexture.customType) {
            var customTexture = _Misc_instantiationTools__WEBPACK_IMPORTED_MODULE_9__["InstantiationTools"].Instantiate(parsedTexture.customType);
            // Update Sampling Mode
            var parsedCustomTexture = customTexture.Parse(parsedTexture, scene, rootUrl);
            if (parsedTexture.samplingMode && parsedCustomTexture.updateSamplingMode && parsedCustomTexture._samplingMode) {
                if (parsedCustomTexture._samplingMode !== parsedTexture.samplingMode) {
                    parsedCustomTexture.updateSamplingMode(parsedTexture.samplingMode);
                }
            }
            return parsedCustomTexture;
        }
        if (parsedTexture.isCube && !parsedTexture.isRenderTarget) {
            return Texture._CubeTextureParser(parsedTexture, scene, rootUrl);
        }
        if (!parsedTexture.name && !parsedTexture.isRenderTarget) {
            return null;
        }
        var texture = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () {
            var generateMipMaps = true;
            if (parsedTexture.noMipmap) {
                generateMipMaps = false;
            }
            if (parsedTexture.mirrorPlane) {
                var mirrorTexture = Texture._CreateMirror(parsedTexture.name, parsedTexture.renderTargetSize, scene, generateMipMaps);
                mirrorTexture._waitingRenderList = parsedTexture.renderList;
                mirrorTexture.mirrorPlane = _Maths_math_plane__WEBPACK_IMPORTED_MODULE_10__["Plane"].FromArray(parsedTexture.mirrorPlane);
                return mirrorTexture;
            }
            else if (parsedTexture.isRenderTarget) {
                var renderTargetTexture = null;
                if (parsedTexture.isCube) {
                    // Search for an existing reflection probe (which contains a cube render target texture)
                    if (scene.reflectionProbes) {
                        for (var index = 0; index < scene.reflectionProbes.length; index++) {
                            var probe = scene.reflectionProbes[index];
                            if (probe.name === parsedTexture.name) {
                                return probe.cubeTexture;
                            }
                        }
                    }
                }
                else {
                    renderTargetTexture = Texture._CreateRenderTargetTexture(parsedTexture.name, parsedTexture.renderTargetSize, scene, generateMipMaps);
                    renderTargetTexture._waitingRenderList = parsedTexture.renderList;
                }
                return renderTargetTexture;
            }
            else {
                var texture;
                if (parsedTexture.base64String) {
                    texture = Texture.CreateFromBase64String(parsedTexture.base64String, parsedTexture.name, scene, !generateMipMaps);
                }
                else {
                    var url = rootUrl + parsedTexture.name;
                    if (Texture.UseSerializedUrlIfAny && parsedTexture.url) {
                        url = parsedTexture.url;
                    }
                    texture = new Texture(url, scene, !generateMipMaps, parsedTexture.invertY);
                }
                return texture;
            }
        }, parsedTexture, scene);
        // Update Sampling Mode
        if (parsedTexture.samplingMode) {
            var sampling = parsedTexture.samplingMode;
            if (texture && texture.samplingMode !== sampling) {
                texture.updateSamplingMode(sampling);
            }
        }
        // Animations
        if (texture && parsedTexture.animations) {
            for (var animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {
                var parsedAnimation = parsedTexture.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_6__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    texture.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
        }
        return texture;
    };
    /**
     * Creates a texture from its base 64 representation.
     * @param data Define the base64 payload without the data: prefix
     * @param name Define the name of the texture in the scene useful fo caching purpose for instance
     * @param scene Define the scene the texture should belong to
     * @param noMipmap Forces the texture to not create mip map information if true
     * @param invertY define if the texture needs to be inverted on the y axis during loading
     * @param samplingMode define the sampling mode we want for the texture while fectching from it (Texture.NEAREST_SAMPLINGMODE...)
     * @param onLoad define a callback triggered when the texture has been loaded
     * @param onError define a callback triggered when an error occurred during the loading session
     * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
     * @returns the created texture
     */
    Texture.CreateFromBase64String = function (data, name, scene, noMipmap, invertY, samplingMode, onLoad, onError, format) {
        if (samplingMode === void 0) { samplingMode = Texture.TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (format === void 0) { format = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTUREFORMAT_RGBA; }
        return new Texture("data:" + name, scene, noMipmap, invertY, samplingMode, onLoad, onError, data, false, format);
    };
    /**
     * Creates a texture from its data: representation. (data: will be added in case only the payload has been passed in)
     * @param data Define the base64 payload without the data: prefix
     * @param name Define the name of the texture in the scene useful fo caching purpose for instance
     * @param buffer define the buffer to load the texture from in case the texture is loaded from a buffer representation
     * @param scene Define the scene the texture should belong to
     * @param deleteBuffer define if the buffer we are loading the texture from should be deleted after load
     * @param noMipmap Forces the texture to not create mip map information if true
     * @param invertY define if the texture needs to be inverted on the y axis during loading
     * @param samplingMode define the sampling mode we want for the texture while fectching from it (Texture.NEAREST_SAMPLINGMODE...)
     * @param onLoad define a callback triggered when the texture has been loaded
     * @param onError define a callback triggered when an error occurred during the loading session
     * @param format define the format of the texture we are trying to load (Engine.TEXTUREFORMAT_RGBA...)
     * @returns the created texture
     */
    Texture.LoadFromDataString = function (name, buffer, scene, deleteBuffer, noMipmap, invertY, samplingMode, onLoad, onError, format) {
        if (deleteBuffer === void 0) { deleteBuffer = false; }
        if (noMipmap === void 0) { noMipmap = false; }
        if (invertY === void 0) { invertY = true; }
        if (samplingMode === void 0) { samplingMode = Texture.TRILINEAR_SAMPLINGMODE; }
        if (onLoad === void 0) { onLoad = null; }
        if (onError === void 0) { onError = null; }
        if (format === void 0) { format = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTUREFORMAT_RGBA; }
        if (name.substr(0, 5) !== "data:") {
            name = "data:" + name;
        }
        return new Texture(name, scene, noMipmap, invertY, samplingMode, onLoad, onError, buffer, deleteBuffer, format);
    };
    /** @hidden */
    Texture._CubeTextureParser = function (jsonTexture, scene, rootUrl) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_7__["_DevTools"].WarnImport("CubeTexture");
    };
    /** @hidden */
    Texture._CreateMirror = function (name, renderTargetSize, scene, generateMipMaps) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_7__["_DevTools"].WarnImport("MirrorTexture");
    };
    /** @hidden */
    Texture._CreateRenderTargetTexture = function (name, renderTargetSize, scene, generateMipMaps) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_7__["_DevTools"].WarnImport("RenderTargetTexture");
    };
    /** nearest is mag = nearest and min = nearest and mip = linear */
    Texture.NEAREST_SAMPLINGMODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE;
    /** nearest is mag = nearest and min = nearest and mip = linear */
    Texture.NEAREST_NEAREST_MIPLINEAR = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_NEAREST_MIPLINEAR; // nearest is mag = nearest and min = nearest and mip = linear
    /** Bilinear is mag = linear and min = linear and mip = nearest */
    Texture.BILINEAR_SAMPLINGMODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE;
    /** Bilinear is mag = linear and min = linear and mip = nearest */
    Texture.LINEAR_LINEAR_MIPNEAREST = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_LINEAR_LINEAR_MIPNEAREST; // Bilinear is mag = linear and min = linear and mip = nearest
    /** Trilinear is mag = linear and min = linear and mip = linear */
    Texture.TRILINEAR_SAMPLINGMODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE;
    /** Trilinear is mag = linear and min = linear and mip = linear */
    Texture.LINEAR_LINEAR_MIPLINEAR = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_LINEAR_LINEAR_MIPLINEAR; // Trilinear is mag = linear and min = linear and mip = linear
    /** mag = nearest and min = nearest and mip = nearest */
    Texture.NEAREST_NEAREST_MIPNEAREST = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_NEAREST_MIPNEAREST;
    /** mag = nearest and min = linear and mip = nearest */
    Texture.NEAREST_LINEAR_MIPNEAREST = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_LINEAR_MIPNEAREST;
    /** mag = nearest and min = linear and mip = linear */
    Texture.NEAREST_LINEAR_MIPLINEAR = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_LINEAR_MIPLINEAR;
    /** mag = nearest and min = linear and mip = none */
    Texture.NEAREST_LINEAR = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_LINEAR;
    /** mag = nearest and min = nearest and mip = none */
    Texture.NEAREST_NEAREST = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_NEAREST_NEAREST;
    /** mag = linear and min = nearest and mip = nearest */
    Texture.LINEAR_NEAREST_MIPNEAREST = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_LINEAR_NEAREST_MIPNEAREST;
    /** mag = linear and min = nearest and mip = linear */
    Texture.LINEAR_NEAREST_MIPLINEAR = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_LINEAR_NEAREST_MIPLINEAR;
    /** mag = linear and min = linear and mip = none */
    Texture.LINEAR_LINEAR = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_LINEAR_LINEAR;
    /** mag = linear and min = nearest and mip = none */
    Texture.LINEAR_NEAREST = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_LINEAR_NEAREST;
    /** Explicit coordinates mode */
    Texture.EXPLICIT_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_EXPLICIT_MODE;
    /** Spherical coordinates mode */
    Texture.SPHERICAL_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_SPHERICAL_MODE;
    /** Planar coordinates mode */
    Texture.PLANAR_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_PLANAR_MODE;
    /** Cubic coordinates mode */
    Texture.CUBIC_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_CUBIC_MODE;
    /** Projection coordinates mode */
    Texture.PROJECTION_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_PROJECTION_MODE;
    /** Inverse Cubic coordinates mode */
    Texture.SKYBOX_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_SKYBOX_MODE;
    /** Inverse Cubic coordinates mode */
    Texture.INVCUBIC_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_INVCUBIC_MODE;
    /** Equirectangular coordinates mode */
    Texture.EQUIRECTANGULAR_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_EQUIRECTANGULAR_MODE;
    /** Equirectangular Fixed coordinates mode */
    Texture.FIXED_EQUIRECTANGULAR_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_FIXED_EQUIRECTANGULAR_MODE;
    /** Equirectangular Fixed Mirrored coordinates mode */
    Texture.FIXED_EQUIRECTANGULAR_MIRRORED_MODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_FIXED_EQUIRECTANGULAR_MIRRORED_MODE;
    /** Texture is not repeating outside of 0..1 UVs */
    Texture.CLAMP_ADDRESSMODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_CLAMP_ADDRESSMODE;
    /** Texture is repeating outside of 0..1 UVs */
    Texture.WRAP_ADDRESSMODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_WRAP_ADDRESSMODE;
    /** Texture is repeating and mirrored */
    Texture.MIRROR_ADDRESSMODE = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURE_MIRROR_ADDRESSMODE;
    /**
     * Gets or sets a boolean which defines if the texture url must be build from the serialized URL instead of just using the name and loading them side by side with the scene file
     */
    Texture.UseSerializedUrlIfAny = false;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "url", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "uOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "vOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "uScale", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "vScale", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "uAng", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "vAng", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "wAng", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "uRotationCenter", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "vRotationCenter", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "wRotationCenter", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Texture.prototype, "isBlocking", null);
    return Texture;
}(_Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_4__["BaseTexture"]));

// References the dependencies.
_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"]._TextureParser = Texture.Parse;


/***/ }),

/***/ "./Materials/Textures/videoTexture.ts":
/*!********************************************!*\
  !*** ./Materials/Textures/videoTexture.ts ***!
  \********************************************/
/*! exports provided: VideoTexture */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VideoTexture", function() { return VideoTexture; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");





/**
 * If you want to display a video in your scene, this is the special texture for that.
 * This special texture works similar to other textures, with the exception of a few parameters.
 * @see https://doc.babylonjs.com/how_to/video_texture
 */
var VideoTexture = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VideoTexture, _super);
    /**
     * Creates a video texture.
     * If you want to display a video in your scene, this is the special texture for that.
     * This special texture works similar to other textures, with the exception of a few parameters.
     * @see https://doc.babylonjs.com/how_to/video_texture
     * @param name optional name, will detect from video source, if not defined
     * @param src can be used to provide an url, array of urls or an already setup HTML video element.
     * @param scene is obviously the current scene.
     * @param generateMipMaps can be used to turn on mipmaps (Can be expensive for videoTextures because they are often updated).
     * @param invertY is false by default but can be used to invert video on Y axis
     * @param samplingMode controls the sampling method and is set to TRILINEAR_SAMPLINGMODE by default
     * @param settings allows finer control over video usage
     */
    function VideoTexture(name, src, scene, generateMipMaps, invertY, samplingMode, settings) {
        if (generateMipMaps === void 0) { generateMipMaps = false; }
        if (invertY === void 0) { invertY = false; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE; }
        if (settings === void 0) { settings = {
            autoPlay: true,
            loop: true,
            autoUpdateTexture: true,
        }; }
        var _this = _super.call(this, null, scene, !generateMipMaps, invertY) || this;
        _this._onUserActionRequestedObservable = null;
        _this._stillImageCaptured = false;
        _this._displayingPosterTexture = false;
        _this._frameId = -1;
        _this._createInternalTexture = function () {
            if (_this._texture != null) {
                if (_this._displayingPosterTexture) {
                    _this._texture.dispose();
                    _this._displayingPosterTexture = false;
                }
                else {
                    return;
                }
            }
            if (!_this._engine.needPOTTextures ||
                (_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].IsExponentOfTwo(_this.video.videoWidth) && _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].IsExponentOfTwo(_this.video.videoHeight))) {
                _this.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].WRAP_ADDRESSMODE;
                _this.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].WRAP_ADDRESSMODE;
            }
            else {
                _this.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
                _this.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].CLAMP_ADDRESSMODE;
                _this._generateMipMaps = false;
            }
            _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this.samplingMode);
            if (!_this.video.autoplay && !_this._settings.poster) {
                var oldHandler_1 = _this.video.onplaying;
                var error_1 = false;
                var oldMuted_1 = _this.video.muted;
                _this.video.muted = true;
                _this.video.onplaying = function () {
                    _this.video.muted = oldMuted_1;
                    _this.video.onplaying = oldHandler_1;
                    _this._texture.isReady = true;
                    _this._updateInternalTexture();
                    if (!error_1) {
                        _this.video.pause();
                    }
                    if (_this.onLoadObservable.hasObservers()) {
                        _this.onLoadObservable.notifyObservers(_this);
                    }
                };
                var playing = _this.video.play();
                if (playing) {
                    playing.then(function () {
                        // Everything is good.
                    })
                        .catch(function () {
                        error_1 = true;
                        // On Chrome for instance, new policies might prevent playing without user interaction.
                        if (_this._onUserActionRequestedObservable && _this._onUserActionRequestedObservable.hasObservers()) {
                            _this._onUserActionRequestedObservable.notifyObservers(_this);
                        }
                    });
                }
                else {
                    _this.video.onplaying = oldHandler_1;
                    _this._texture.isReady = true;
                    _this._updateInternalTexture();
                    if (_this.onLoadObservable.hasObservers()) {
                        _this.onLoadObservable.notifyObservers(_this);
                    }
                }
            }
            else {
                _this._texture.isReady = true;
                _this._updateInternalTexture();
                if (_this.onLoadObservable.hasObservers()) {
                    _this.onLoadObservable.notifyObservers(_this);
                }
            }
        };
        _this.reset = function () {
            if (_this._texture == null) {
                return;
            }
            if (!_this._displayingPosterTexture) {
                _this._texture.dispose();
                _this._texture = null;
            }
        };
        _this._updateInternalTexture = function () {
            if (_this._texture == null || !_this._texture.isReady) {
                return;
            }
            if (_this.video.readyState < _this.video.HAVE_CURRENT_DATA) {
                return;
            }
            if (_this._displayingPosterTexture) {
                return;
            }
            var frameId = _this.getScene().getFrameId();
            if (_this._frameId === frameId) {
                return;
            }
            _this._frameId = frameId;
            _this._engine.updateVideoTexture(_this._texture, _this.video, _this._invertY);
        };
        _this._engine = _this.getScene().getEngine();
        _this._generateMipMaps = generateMipMaps;
        _this._initialSamplingMode = samplingMode;
        _this.autoUpdateTexture = settings.autoUpdateTexture;
        _this.name = name || _this._getName(src);
        _this.video = _this._getVideo(src);
        _this._settings = settings;
        if (settings.poster) {
            _this.video.poster = settings.poster;
        }
        if (settings.autoPlay !== undefined) {
            _this.video.autoplay = settings.autoPlay;
        }
        if (settings.loop !== undefined) {
            _this.video.loop = settings.loop;
        }
        _this.video.setAttribute("playsinline", "");
        _this.video.addEventListener("paused", _this._updateInternalTexture);
        _this.video.addEventListener("seeked", _this._updateInternalTexture);
        _this.video.addEventListener("emptied", _this.reset);
        _this._createInternalTextureOnEvent = (settings.poster && !settings.autoPlay) ? "play" : "canplay";
        _this.video.addEventListener(_this._createInternalTextureOnEvent, _this._createInternalTexture);
        var videoHasEnoughData = (_this.video.readyState >= _this.video.HAVE_CURRENT_DATA);
        if (settings.poster &&
            (!settings.autoPlay || !videoHasEnoughData)) {
            _this._texture = _this._engine.createTexture(settings.poster, false, true, scene);
            _this._displayingPosterTexture = true;
        }
        else if (videoHasEnoughData) {
            _this._createInternalTexture();
        }
        return _this;
    }
    Object.defineProperty(VideoTexture.prototype, "onUserActionRequestedObservable", {
        /**
         * Event triggerd when a dom action is required by the user to play the video.
         * This happens due to recent changes in browser policies preventing video to auto start.
         */
        get: function () {
            if (!this._onUserActionRequestedObservable) {
                this._onUserActionRequestedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
            }
            return this._onUserActionRequestedObservable;
        },
        enumerable: true,
        configurable: true
    });
    VideoTexture.prototype._getName = function (src) {
        if (src instanceof HTMLVideoElement) {
            return src.currentSrc;
        }
        if (typeof src === "object") {
            return src.toString();
        }
        return src;
    };
    VideoTexture.prototype._getVideo = function (src) {
        if (src instanceof HTMLVideoElement) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].SetCorsBehavior(src.currentSrc, src);
            return src;
        }
        var video = document.createElement("video");
        if (typeof src === "string") {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].SetCorsBehavior(src, video);
            video.src = src;
        }
        else {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].SetCorsBehavior(src[0], video);
            src.forEach(function (url) {
                var source = document.createElement("source");
                source.src = url;
                video.appendChild(source);
            });
        }
        return video;
    };
    /**
     * @hidden Internal method to initiate `update`.
     */
    VideoTexture.prototype._rebuild = function () {
        this.update();
    };
    /**
     * Update Texture in the `auto` mode. Does not do anything if `settings.autoUpdateTexture` is false.
     */
    VideoTexture.prototype.update = function () {
        if (!this.autoUpdateTexture) {
            // Expecting user to call `updateTexture` manually
            return;
        }
        this.updateTexture(true);
    };
    /**
     * Update Texture in `manual` mode. Does not do anything if not visible or paused.
     * @param isVisible Visibility state, detected by user using `scene.getActiveMeshes()` or othervise.
     */
    VideoTexture.prototype.updateTexture = function (isVisible) {
        if (!isVisible) {
            return;
        }
        if (this.video.paused && this._stillImageCaptured) {
            return;
        }
        this._stillImageCaptured = true;
        this._updateInternalTexture();
    };
    /**
     * Change video content. Changing video instance or setting multiple urls (as in constructor) is not supported.
     * @param url New url.
     */
    VideoTexture.prototype.updateURL = function (url) {
        this.video.src = url;
    };
    /**
     * Dispose the texture and release its associated resources.
     */
    VideoTexture.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        if (this._onUserActionRequestedObservable) {
            this._onUserActionRequestedObservable.clear();
            this._onUserActionRequestedObservable = null;
        }
        this.video.removeEventListener(this._createInternalTextureOnEvent, this._createInternalTexture);
        this.video.removeEventListener("paused", this._updateInternalTexture);
        this.video.removeEventListener("seeked", this._updateInternalTexture);
        this.video.removeEventListener("emptied", this.reset);
        this.video.pause();
    };
    /**
     * Creates a video texture straight from a stream.
     * @param scene Define the scene the texture should be created in
     * @param stream Define the stream the texture should be created from
     * @returns The created video texture as a promise
     */
    VideoTexture.CreateFromStreamAsync = function (scene, stream) {
        var video = document.createElement("video");
        video.setAttribute('autoplay', '');
        video.setAttribute('muted', 'true');
        video.setAttribute('playsinline', '');
        video.muted = true;
        if (video.mozSrcObject !== undefined) {
            // hack for Firefox < 19
            video.mozSrcObject = stream;
        }
        else {
            if (typeof video.srcObject == "object") {
                video.srcObject = stream;
            }
            else {
                window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
                video.src = (window.URL && window.URL.createObjectURL(stream));
            }
        }
        return new Promise(function (resolve) {
            var onPlaying = function () {
                resolve(new VideoTexture("video", video, scene, true, true));
                video.removeEventListener("playing", onPlaying);
            };
            video.addEventListener("playing", onPlaying);
            video.play();
        });
    };
    /**
     * Creates a video texture straight from your WebCam video feed.
     * @param scene Define the scene the texture should be created in
     * @param constraints Define the constraints to use to create the web cam feed from WebRTC
     * @param audioConstaints Define the audio constraints to use to create the web cam feed from WebRTC
     * @returns The created video texture as a promise
     */
    VideoTexture.CreateFromWebCamAsync = function (scene, constraints, audioConstaints) {
        var _this = this;
        if (audioConstaints === void 0) { audioConstaints = false; }
        var constraintsDeviceId;
        if (constraints && constraints.deviceId) {
            constraintsDeviceId = {
                exact: constraints.deviceId,
            };
        }
        if (navigator.mediaDevices) {
            return navigator.mediaDevices.getUserMedia({
                video: constraints,
                audio: audioConstaints
            })
                .then(function (stream) {
                return _this.CreateFromStreamAsync(scene, stream);
            });
        }
        else {
            navigator.getUserMedia =
                navigator.getUserMedia ||
                    navigator.webkitGetUserMedia ||
                    navigator.mozGetUserMedia ||
                    navigator.msGetUserMedia;
            if (navigator.getUserMedia) {
                navigator.getUserMedia({
                    video: {
                        deviceId: constraintsDeviceId,
                        width: {
                            min: (constraints && constraints.minWidth) || 256,
                            max: (constraints && constraints.maxWidth) || 640,
                        },
                        height: {
                            min: (constraints && constraints.minHeight) || 256,
                            max: (constraints && constraints.maxHeight) || 480,
                        },
                    },
                    audio: audioConstaints
                }, function (stream) {
                    return _this.CreateFromStreamAsync(scene, stream);
                }, function (e) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error(e.name);
                });
            }
        }
        return Promise.reject("No support for userMedia on this device");
    };
    /**
     * Creates a video texture straight from your WebCam video feed.
     * @param scene Define the scene the texture should be created in
     * @param onReady Define a callback to triggered once the texture will be ready
     * @param constraints Define the constraints to use to create the web cam feed from WebRTC
     * @param audioConstaints Define the audio constraints to use to create the web cam feed from WebRTC
     */
    VideoTexture.CreateFromWebCam = function (scene, onReady, constraints, audioConstaints) {
        if (audioConstaints === void 0) { audioConstaints = false; }
        this.CreateFromWebCamAsync(scene, constraints, audioConstaints)
            .then(function (videoTexture) {
            if (onReady) {
                onReady(videoTexture);
            }
        })
            .catch(function (err) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error(err.name);
        });
    };
    return VideoTexture;
}(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"]));



/***/ }),

/***/ "./Materials/colorCurves.ts":
/*!**********************************!*\
  !*** ./Materials/colorCurves.ts ***!
  \**********************************/
/*! exports provided: ColorCurves */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorCurves", function() { return ColorCurves; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");



/**
 * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
 * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
 * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
 * corresponding to low luminance, medium luminance, and high luminance areas respectively.
 */
var ColorCurves = /** @class */ (function () {
    function ColorCurves() {
        this._dirty = true;
        this._tempColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._globalCurve = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._highlightsCurve = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._midtonesCurve = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._shadowsCurve = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._positiveCurve = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._negativeCurve = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_2__["Color4"](0, 0, 0, 0);
        this._globalHue = 30;
        this._globalDensity = 0;
        this._globalSaturation = 0;
        this._globalExposure = 0;
        this._highlightsHue = 30;
        this._highlightsDensity = 0;
        this._highlightsSaturation = 0;
        this._highlightsExposure = 0;
        this._midtonesHue = 30;
        this._midtonesDensity = 0;
        this._midtonesSaturation = 0;
        this._midtonesExposure = 0;
        this._shadowsHue = 30;
        this._shadowsDensity = 0;
        this._shadowsSaturation = 0;
        this._shadowsExposure = 0;
    }
    Object.defineProperty(ColorCurves.prototype, "globalHue", {
        /**
         * Gets the global Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        get: function () {
            return this._globalHue;
        },
        /**
         * Sets the global Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        set: function (value) {
            this._globalHue = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "globalDensity", {
        /**
         * Gets the global Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        get: function () {
            return this._globalDensity;
        },
        /**
         * Sets the global Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        set: function (value) {
            this._globalDensity = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "globalSaturation", {
        /**
         * Gets the global Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        get: function () {
            return this._globalSaturation;
        },
        /**
         * Sets the global Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        set: function (value) {
            this._globalSaturation = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "globalExposure", {
        /**
         * Gets the global Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        get: function () {
            return this._globalExposure;
        },
        /**
         * Sets the global Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        set: function (value) {
            this._globalExposure = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "highlightsHue", {
        /**
         * Gets the highlights Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        get: function () {
            return this._highlightsHue;
        },
        /**
         * Sets the highlights Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        set: function (value) {
            this._highlightsHue = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "highlightsDensity", {
        /**
         * Gets the highlights Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        get: function () {
            return this._highlightsDensity;
        },
        /**
         * Sets the highlights Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        set: function (value) {
            this._highlightsDensity = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "highlightsSaturation", {
        /**
         * Gets the highlights Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        get: function () {
            return this._highlightsSaturation;
        },
        /**
         * Sets the highlights Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        set: function (value) {
            this._highlightsSaturation = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "highlightsExposure", {
        /**
         * Gets the highlights Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        get: function () {
            return this._highlightsExposure;
        },
        /**
         * Sets the highlights Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        set: function (value) {
            this._highlightsExposure = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "midtonesHue", {
        /**
         * Gets the midtones Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        get: function () {
            return this._midtonesHue;
        },
        /**
         * Sets the midtones Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        set: function (value) {
            this._midtonesHue = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "midtonesDensity", {
        /**
         * Gets the midtones Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        get: function () {
            return this._midtonesDensity;
        },
        /**
         * Sets the midtones Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        set: function (value) {
            this._midtonesDensity = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "midtonesSaturation", {
        /**
         * Gets the midtones Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        get: function () {
            return this._midtonesSaturation;
        },
        /**
         * Sets the midtones Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        set: function (value) {
            this._midtonesSaturation = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "midtonesExposure", {
        /**
         * Gets the midtones Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        get: function () {
            return this._midtonesExposure;
        },
        /**
         * Sets the midtones Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        set: function (value) {
            this._midtonesExposure = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "shadowsHue", {
        /**
         * Gets the shadows Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        get: function () {
            return this._shadowsHue;
        },
        /**
         * Sets the shadows Hue value.
         * The hue value is a standard HSB hue in the range [0,360] where 0=red, 120=green and 240=blue. The default value is 30 degrees (orange).
         */
        set: function (value) {
            this._shadowsHue = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "shadowsDensity", {
        /**
         * Gets the shadows Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        get: function () {
            return this._shadowsDensity;
        },
        /**
         * Sets the shadows Density value.
         * The density value is in range [-100,+100] where 0 means the color filter has no effect and +100 means the color filter has maximum effect.
         * Values less than zero provide a filter of opposite hue.
         */
        set: function (value) {
            this._shadowsDensity = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "shadowsSaturation", {
        /**
         * Gets the shadows Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        get: function () {
            return this._shadowsSaturation;
        },
        /**
         * Sets the shadows Saturation value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase saturation and negative values decrease saturation.
         */
        set: function (value) {
            this._shadowsSaturation = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ColorCurves.prototype, "shadowsExposure", {
        /**
         * Gets the shadows Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        get: function () {
            return this._shadowsExposure;
        },
        /**
         * Sets the shadows Exposure value.
         * This is an adjustment value in the range [-100,+100], where the default value of 0.0 makes no adjustment, positive values increase exposure and negative values decrease exposure.
         */
        set: function (value) {
            this._shadowsExposure = value;
            this._dirty = true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the class name
     * @returns The class name
     */
    ColorCurves.prototype.getClassName = function () {
        return "ColorCurves";
    };
    /**
     * Binds the color curves to the shader.
     * @param colorCurves The color curve to bind
     * @param effect The effect to bind to
     * @param positiveUniform The positive uniform shader parameter
     * @param neutralUniform The neutral uniform shader parameter
     * @param negativeUniform The negative uniform shader parameter
     */
    ColorCurves.Bind = function (colorCurves, effect, positiveUniform, neutralUniform, negativeUniform) {
        if (positiveUniform === void 0) { positiveUniform = "vCameraColorCurvePositive"; }
        if (neutralUniform === void 0) { neutralUniform = "vCameraColorCurveNeutral"; }
        if (negativeUniform === void 0) { negativeUniform = "vCameraColorCurveNegative"; }
        if (colorCurves._dirty) {
            colorCurves._dirty = false;
            // Fill in global info.
            colorCurves.getColorGradingDataToRef(colorCurves._globalHue, colorCurves._globalDensity, colorCurves._globalSaturation, colorCurves._globalExposure, colorCurves._globalCurve);
            // Compute highlights info.
            colorCurves.getColorGradingDataToRef(colorCurves._highlightsHue, colorCurves._highlightsDensity, colorCurves._highlightsSaturation, colorCurves._highlightsExposure, colorCurves._tempColor);
            colorCurves._tempColor.multiplyToRef(colorCurves._globalCurve, colorCurves._highlightsCurve);
            // Compute midtones info.
            colorCurves.getColorGradingDataToRef(colorCurves._midtonesHue, colorCurves._midtonesDensity, colorCurves._midtonesSaturation, colorCurves._midtonesExposure, colorCurves._tempColor);
            colorCurves._tempColor.multiplyToRef(colorCurves._globalCurve, colorCurves._midtonesCurve);
            // Compute shadows info.
            colorCurves.getColorGradingDataToRef(colorCurves._shadowsHue, colorCurves._shadowsDensity, colorCurves._shadowsSaturation, colorCurves._shadowsExposure, colorCurves._tempColor);
            colorCurves._tempColor.multiplyToRef(colorCurves._globalCurve, colorCurves._shadowsCurve);
            // Compute deltas (neutral is midtones).
            colorCurves._highlightsCurve.subtractToRef(colorCurves._midtonesCurve, colorCurves._positiveCurve);
            colorCurves._midtonesCurve.subtractToRef(colorCurves._shadowsCurve, colorCurves._negativeCurve);
        }
        if (effect) {
            effect.setFloat4(positiveUniform, colorCurves._positiveCurve.r, colorCurves._positiveCurve.g, colorCurves._positiveCurve.b, colorCurves._positiveCurve.a);
            effect.setFloat4(neutralUniform, colorCurves._midtonesCurve.r, colorCurves._midtonesCurve.g, colorCurves._midtonesCurve.b, colorCurves._midtonesCurve.a);
            effect.setFloat4(negativeUniform, colorCurves._negativeCurve.r, colorCurves._negativeCurve.g, colorCurves._negativeCurve.b, colorCurves._negativeCurve.a);
        }
    };
    /**
     * Prepare the list of uniforms associated with the ColorCurves effects.
     * @param uniformsList The list of uniforms used in the effect
     */
    ColorCurves.PrepareUniforms = function (uniformsList) {
        uniformsList.push("vCameraColorCurveNeutral", "vCameraColorCurvePositive", "vCameraColorCurveNegative");
    };
    /**
     * Returns color grading data based on a hue, density, saturation and exposure value.
     * @param filterHue The hue of the color filter.
     * @param filterDensity The density of the color filter.
     * @param saturation The saturation.
     * @param exposure The exposure.
     * @param result The result data container.
     */
    ColorCurves.prototype.getColorGradingDataToRef = function (hue, density, saturation, exposure, result) {
        if (hue == null) {
            return;
        }
        hue = ColorCurves.clamp(hue, 0, 360);
        density = ColorCurves.clamp(density, -100, 100);
        saturation = ColorCurves.clamp(saturation, -100, 100);
        exposure = ColorCurves.clamp(exposure, -100, 100);
        // Remap the slider/config filter density with non-linear mapping and also scale by half
        // so that the maximum filter density is only 50% control. This provides fine control
        // for small values and reasonable range.
        density = ColorCurves.applyColorGradingSliderNonlinear(density);
        density *= 0.5;
        exposure = ColorCurves.applyColorGradingSliderNonlinear(exposure);
        if (density < 0) {
            density *= -1;
            hue = (hue + 180) % 360;
        }
        ColorCurves.fromHSBToRef(hue, density, 50 + 0.25 * exposure, result);
        result.scaleToRef(2, result);
        result.a = 1 + 0.01 * saturation;
    };
    /**
     * Takes an input slider value and returns an adjusted value that provides extra control near the centre.
     * @param value The input slider value in range [-100,100].
     * @returns Adjusted value.
     */
    ColorCurves.applyColorGradingSliderNonlinear = function (value) {
        value /= 100;
        var x = Math.abs(value);
        x = Math.pow(x, 2);
        if (value < 0) {
            x *= -1;
        }
        x *= 100;
        return x;
    };
    /**
     * Returns an RGBA Color4 based on Hue, Saturation and Brightness (also referred to as value, HSV).
     * @param hue The hue (H) input.
     * @param saturation The saturation (S) input.
     * @param brightness The brightness (B) input.
     * @result An RGBA color represented as Vector4.
     */
    ColorCurves.fromHSBToRef = function (hue, saturation, brightness, result) {
        var h = ColorCurves.clamp(hue, 0, 360);
        var s = ColorCurves.clamp(saturation / 100, 0, 1);
        var v = ColorCurves.clamp(brightness / 100, 0, 1);
        if (s === 0) {
            result.r = v;
            result.g = v;
            result.b = v;
        }
        else {
            // sector 0 to 5
            h /= 60;
            var i = Math.floor(h);
            // fractional part of h
            var f = h - i;
            var p = v * (1 - s);
            var q = v * (1 - s * f);
            var t = v * (1 - s * (1 - f));
            switch (i) {
                case 0:
                    result.r = v;
                    result.g = t;
                    result.b = p;
                    break;
                case 1:
                    result.r = q;
                    result.g = v;
                    result.b = p;
                    break;
                case 2:
                    result.r = p;
                    result.g = v;
                    result.b = t;
                    break;
                case 3:
                    result.r = p;
                    result.g = q;
                    result.b = v;
                    break;
                case 4:
                    result.r = t;
                    result.g = p;
                    result.b = v;
                    break;
                default: // case 5:
                    result.r = v;
                    result.g = p;
                    result.b = q;
                    break;
            }
        }
        result.a = 1;
    };
    /**
     * Returns a value clamped between min and max
     * @param value The value to clamp
     * @param min The minimum of value
     * @param max The maximum of value
     * @returns The clamped value.
     */
    ColorCurves.clamp = function (value, min, max) {
        return Math.min(Math.max(value, min), max);
    };
    /**
     * Clones the current color curve instance.
     * @return The cloned curves
     */
    ColorCurves.prototype.clone = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new ColorCurves(); }, this);
    };
    /**
     * Serializes the current color curve instance to a json representation.
     * @return a JSON representation
     */
    ColorCurves.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses the color curve from a json representation.
     * @param source the JSON source to parse
     * @return The parsed curves
     */
    ColorCurves.Parse = function (source) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new ColorCurves(); }, source, null, null);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_globalHue", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_globalDensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_globalSaturation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_globalExposure", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_highlightsHue", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_highlightsDensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_highlightsSaturation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_highlightsExposure", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_midtonesHue", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_midtonesDensity", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_midtonesSaturation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ColorCurves.prototype, "_midtonesExposure", void 0);
    return ColorCurves;
}());

// References the dependencies.
_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"]._ColorCurvesParser = ColorCurves.Parse;


/***/ }),

/***/ "./Materials/effect.ts":
/*!*****************************!*\
  !*** ./Materials/effect.ts ***!
  \*****************************/
/*! exports provided: EffectFallbacks, EffectCreationOptions, Effect */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EffectFallbacks", function() { return EffectFallbacks; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EffectCreationOptions", function() { return EffectCreationOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Effect", function() { return Effect; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_domManagement__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/domManagement */ "./Misc/domManagement.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_Processors_shaderProcessor__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/Processors/shaderProcessor */ "./Engines/Processors/shaderProcessor.ts");





/**
 * EffectFallbacks can be used to add fallbacks (properties to disable) to certain properties when desired to improve performance.
 * (Eg. Start at high quality with reflection and fog, if fps is low, remove reflection, if still low remove fog)
 */
var EffectFallbacks = /** @class */ (function () {
    function EffectFallbacks() {
        this._defines = {};
        this._currentRank = 32;
        this._maxRank = -1;
        this._mesh = null;
    }
    /**
     * Removes the fallback from the bound mesh.
     */
    EffectFallbacks.prototype.unBindMesh = function () {
        this._mesh = null;
    };
    /**
     * Adds a fallback on the specified property.
     * @param rank The rank of the fallback (Lower ranks will be fallbacked to first)
     * @param define The name of the define in the shader
     */
    EffectFallbacks.prototype.addFallback = function (rank, define) {
        if (!this._defines[rank]) {
            if (rank < this._currentRank) {
                this._currentRank = rank;
            }
            if (rank > this._maxRank) {
                this._maxRank = rank;
            }
            this._defines[rank] = new Array();
        }
        this._defines[rank].push(define);
    };
    /**
     * Sets the mesh to use CPU skinning when needing to fallback.
     * @param rank The rank of the fallback (Lower ranks will be fallbacked to first)
     * @param mesh The mesh to use the fallbacks.
     */
    EffectFallbacks.prototype.addCPUSkinningFallback = function (rank, mesh) {
        this._mesh = mesh;
        if (rank < this._currentRank) {
            this._currentRank = rank;
        }
        if (rank > this._maxRank) {
            this._maxRank = rank;
        }
    };
    Object.defineProperty(EffectFallbacks.prototype, "hasMoreFallbacks", {
        /**
         * Checks to see if more fallbacks are still availible.
         */
        get: function () {
            return this._currentRank <= this._maxRank;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Removes the defines that should be removed when falling back.
     * @param currentDefines defines the current define statements for the shader.
     * @param effect defines the current effect we try to compile
     * @returns The resulting defines with defines of the current rank removed.
     */
    EffectFallbacks.prototype.reduce = function (currentDefines, effect) {
        // First we try to switch to CPU skinning
        if (this._mesh && this._mesh.computeBonesUsingShaders && this._mesh.numBoneInfluencers > 0) {
            this._mesh.computeBonesUsingShaders = false;
            currentDefines = currentDefines.replace("#define NUM_BONE_INFLUENCERS " + this._mesh.numBoneInfluencers, "#define NUM_BONE_INFLUENCERS 0");
            effect._bonesComputationForcedToCPU = true;
            var scene = this._mesh.getScene();
            for (var index = 0; index < scene.meshes.length; index++) {
                var otherMesh = scene.meshes[index];
                if (!otherMesh.material) {
                    if (!this._mesh.material && otherMesh.computeBonesUsingShaders && otherMesh.numBoneInfluencers > 0) {
                        otherMesh.computeBonesUsingShaders = false;
                    }
                    continue;
                }
                if (!otherMesh.computeBonesUsingShaders || otherMesh.numBoneInfluencers === 0) {
                    continue;
                }
                if (otherMesh.material.getEffect() === effect) {
                    otherMesh.computeBonesUsingShaders = false;
                }
                else if (otherMesh.subMeshes) {
                    for (var _i = 0, _a = otherMesh.subMeshes; _i < _a.length; _i++) {
                        var subMesh = _a[_i];
                        var subMeshEffect = subMesh.effect;
                        if (subMeshEffect === effect) {
                            otherMesh.computeBonesUsingShaders = false;
                            break;
                        }
                    }
                }
            }
        }
        else {
            var currentFallbacks = this._defines[this._currentRank];
            if (currentFallbacks) {
                for (var index = 0; index < currentFallbacks.length; index++) {
                    currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
                }
            }
            this._currentRank++;
        }
        return currentDefines;
    };
    return EffectFallbacks;
}());

/**
 * Options to be used when creating an effect.
 */
var EffectCreationOptions = /** @class */ (function () {
    function EffectCreationOptions() {
    }
    return EffectCreationOptions;
}());

/**
 * Effect containing vertex and fragment shader that can be executed on an object.
 */
var Effect = /** @class */ (function () {
    /**
     * Instantiates an effect.
     * An effect can be used to create/manage/execute vertex and fragment shaders.
     * @param baseName Name of the effect.
     * @param attributesNamesOrOptions List of attribute names that will be passed to the shader or set of all options to create the effect.
     * @param uniformsNamesOrEngine List of uniform variable names that will be passed to the shader or the engine that will be used to render effect.
     * @param samplers List of sampler variables that will be passed to the shader.
     * @param engine Engine to be used to render the effect
     * @param defines Define statements to be added to the shader.
     * @param fallbacks Possible fallbacks for this effect to improve performance when needed.
     * @param onCompiled Callback that will be called when the shader is compiled.
     * @param onError Callback that will be called if an error occurs during shader compilation.
     * @param indexParameters Parameters to be used with Babylons include syntax to iterate over an array (eg. {lights: 10})
     * @param key Effect Key identifying uniquely compiled shader variants
     * @param sources Already processed sources for the current key.
     */
    function Effect(baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, engine, defines, fallbacks, onCompiled, onError, indexParameters, key, sources) {
        var _this = this;
        if (samplers === void 0) { samplers = null; }
        if (defines === void 0) { defines = null; }
        if (fallbacks === void 0) { fallbacks = null; }
        if (onCompiled === void 0) { onCompiled = null; }
        if (onError === void 0) { onError = null; }
        if (key === void 0) { key = ""; }
        /**
         * Name of the effect.
         */
        this.name = null;
        /**
         * String container all the define statements that should be set on the shader.
         */
        this.defines = "";
        /**
         * Callback that will be called when the shader is compiled.
         */
        this.onCompiled = null;
        /**
         * Callback that will be called if an error occurs during shader compilation.
         */
        this.onError = null;
        /**
         * Callback that will be called when effect is bound.
         */
        this.onBind = null;
        /**
         * Unique ID of the effect.
         */
        this.uniqueId = 0;
        /**
         * Observable that will be called when the shader is compiled.
         * It is recommended to use executeWhenCompile() or to make sure that scene.isReady() is called to get this observable raised.
         */
        this.onCompileObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /**
         * Observable that will be called if an error occurs during shader compilation.
         */
        this.onErrorObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        /** @hidden */
        this._onBindObservable = null;
        /** @hidden */
        this._bonesComputationForcedToCPU = false;
        /** @hidden */
        this._uniformBuffersNames = {};
        this._samplers = {};
        this._isReady = false;
        this._compilationError = "";
        this._uniforms = {};
        /**
         * Key for the effect.
         * @hidden
         */
        this._key = "";
        this._fallbacks = null;
        this._vertexSourceCodeOverride = "";
        this._fragmentSourceCodeOverride = "";
        this._transformFeedbackVaryings = null;
        /**
         * Compiled shader to webGL program.
         * @hidden
         */
        this._pipelineContext = null;
        /** @hidden */
        this._vertexSourceCode = "";
        /** @hidden */
        this._fragmentSourceCode = "";
        this.name = baseName;
        this._key = key;
        if (attributesNamesOrOptions.attributes) {
            var options = attributesNamesOrOptions;
            this._engine = uniformsNamesOrEngine;
            this._attributesNames = options.attributes;
            this._uniformsNames = options.uniformsNames.concat(options.samplers);
            this._samplerList = options.samplers.slice();
            this.defines = options.defines;
            this.onError = options.onError;
            this.onCompiled = options.onCompiled;
            this._fallbacks = options.fallbacks;
            this._indexParameters = options.indexParameters;
            this._transformFeedbackVaryings = options.transformFeedbackVaryings;
            if (options.uniformBuffersNames) {
                for (var i = 0; i < options.uniformBuffersNames.length; i++) {
                    this._uniformBuffersNames[options.uniformBuffersNames[i]] = i;
                }
            }
        }
        else {
            this._engine = engine;
            this.defines = (defines == null ? "" : defines);
            this._uniformsNames = uniformsNamesOrEngine.concat(samplers);
            this._samplerList = samplers ? samplers.slice() : [];
            this._attributesNames = attributesNamesOrOptions;
            this.onError = onError;
            this.onCompiled = onCompiled;
            this._indexParameters = indexParameters;
            this._fallbacks = fallbacks;
        }
        this.uniqueId = Effect._uniqueIdSeed++;
        if (sources) {
            this._fragmentSourceCode = sources.fragment;
            this._vertexSourceCode = sources.vertex;
            this._prepareEffect();
            return;
        }
        var vertexSource;
        var fragmentSource;
        if (baseName.vertexSource) {
            vertexSource = "source:" + baseName.vertexSource;
        }
        else if (baseName.vertexElement) {
            vertexSource = document.getElementById(baseName.vertexElement);
            if (!vertexSource) {
                vertexSource = baseName.vertexElement;
            }
        }
        else {
            vertexSource = baseName.vertex || baseName;
        }
        if (baseName.fragmentSource) {
            fragmentSource = "source:" + baseName.fragmentSource;
        }
        else if (baseName.fragmentElement) {
            fragmentSource = document.getElementById(baseName.fragmentElement);
            if (!fragmentSource) {
                fragmentSource = baseName.fragmentElement;
            }
        }
        else {
            fragmentSource = baseName.fragment || baseName;
        }
        this._processingContext = engine._getShaderProcessingContext();
        var processorOptions = {
            defines: this.defines.split("\n"),
            indexParameters: this._indexParameters,
            isFragment: false,
            shouldUseHighPrecisionShader: this._engine._shouldUseHighPrecisionShader,
            processor: this._engine._shaderProcessor,
            supportsUniformBuffers: this._engine.supportsUniformBuffers,
            shadersRepository: Effect.ShadersRepository,
            includesShadersStore: Effect.IncludesShadersStore,
            version: (this._engine.webGLVersion * 100).toString(),
            platformName: this._engine.shaderPlatformName,
            processingContext: this._processingContext
        };
        this._loadVertexShader(vertexSource, function (vertexCode) {
            _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
                _Engines_Processors_shaderProcessor__WEBPACK_IMPORTED_MODULE_4__["ShaderProcessor"].Process(vertexCode, processorOptions, function (migratedVertexCode) {
                    processorOptions.isFragment = true;
                    _Engines_Processors_shaderProcessor__WEBPACK_IMPORTED_MODULE_4__["ShaderProcessor"].Process(fragmentCode, processorOptions, function (migratedFragmentCode) {
                        var finalShaders = _Engines_Processors_shaderProcessor__WEBPACK_IMPORTED_MODULE_4__["ShaderProcessor"].Finalize(migratedVertexCode, migratedFragmentCode, processorOptions);
                        _this._useFinalCode(finalShaders.vertexCode, finalShaders.fragmentCode, baseName);
                    });
                });
            });
        });
    }
    Object.defineProperty(Effect.prototype, "onBindObservable", {
        /**
         * Observable that will be called when effect is bound.
         */
        get: function () {
            if (!this._onBindObservable) {
                this._onBindObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
            }
            return this._onBindObservable;
        },
        enumerable: true,
        configurable: true
    });
    Effect.prototype._useFinalCode = function (migratedVertexCode, migratedFragmentCode, baseName) {
        if (baseName) {
            var vertex = baseName.vertexElement || baseName.vertex || baseName.spectorName || baseName;
            var fragment = baseName.fragmentElement || baseName.fragment || baseName.spectorName || baseName;
            this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
            this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
        }
        else {
            this._vertexSourceCode = migratedVertexCode;
            this._fragmentSourceCode = migratedFragmentCode;
        }
        this._prepareEffect();
    };
    Object.defineProperty(Effect.prototype, "key", {
        /**
         * Unique key for this effect
         */
        get: function () {
            return this._key;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * If the effect has been compiled and prepared.
     * @returns if the effect is compiled and prepared.
     */
    Effect.prototype.isReady = function () {
        try {
            return this._isReadyInternal();
        }
        catch (_a) {
            return false;
        }
    };
    Effect.prototype._isReadyInternal = function () {
        if (this._isReady) {
            return true;
        }
        if (this._pipelineContext) {
            return this._pipelineContext.isReady;
        }
        return false;
    };
    /**
     * The engine the effect was initialized with.
     * @returns the engine.
     */
    Effect.prototype.getEngine = function () {
        return this._engine;
    };
    /**
     * The pipeline context for this effect
     * @returns the associated pipeline context
     */
    Effect.prototype.getPipelineContext = function () {
        return this._pipelineContext;
    };
    /**
     * The set of names of attribute variables for the shader.
     * @returns An array of attribute names.
     */
    Effect.prototype.getAttributesNames = function () {
        return this._attributesNames;
    };
    /**
     * Returns the attribute at the given index.
     * @param index The index of the attribute.
     * @returns The location of the attribute.
     */
    Effect.prototype.getAttributeLocation = function (index) {
        return this._attributes[index];
    };
    /**
     * Returns the attribute based on the name of the variable.
     * @param name of the attribute to look up.
     * @returns the attribute location.
     */
    Effect.prototype.getAttributeLocationByName = function (name) {
        var index = this._attributesNames.indexOf(name);
        return this._attributes[index];
    };
    /**
     * The number of attributes.
     * @returns the numnber of attributes.
     */
    Effect.prototype.getAttributesCount = function () {
        return this._attributes.length;
    };
    /**
     * Gets the index of a uniform variable.
     * @param uniformName of the uniform to look up.
     * @returns the index.
     */
    Effect.prototype.getUniformIndex = function (uniformName) {
        return this._uniformsNames.indexOf(uniformName);
    };
    /**
     * Returns the attribute based on the name of the variable.
     * @param uniformName of the uniform to look up.
     * @returns the location of the uniform.
     */
    Effect.prototype.getUniform = function (uniformName) {
        return this._uniforms[uniformName];
    };
    /**
     * Returns an array of sampler variable names
     * @returns The array of sampler variable neames.
     */
    Effect.prototype.getSamplers = function () {
        return this._samplerList;
    };
    /**
     * The error from the last compilation.
     * @returns the error string.
     */
    Effect.prototype.getCompilationError = function () {
        return this._compilationError;
    };
    /**
     * Adds a callback to the onCompiled observable and call the callback imediatly if already ready.
     * @param func The callback to be used.
     */
    Effect.prototype.executeWhenCompiled = function (func) {
        var _this = this;
        if (this.isReady()) {
            func(this);
            return;
        }
        this.onCompileObservable.add(function (effect) {
            func(effect);
        });
        if (!this._pipelineContext || this._pipelineContext.isAsync) {
            setTimeout(function () {
                _this._checkIsReady();
            }, 16);
        }
    };
    Effect.prototype._checkIsReady = function () {
        var _this = this;
        try {
            if (this._isReadyInternal()) {
                return;
            }
        }
        catch (e) {
            this._processCompilationErrors(e);
            return;
        }
        setTimeout(function () {
            _this._checkIsReady();
        }, 16);
    };
    /** @hidden */
    Effect.prototype._loadVertexShader = function (vertex, callback) {
        if (typeof (HTMLElement) !== "undefined") {
            // DOM element ?
            if (vertex instanceof HTMLElement) {
                var vertexCode = _Misc_domManagement__WEBPACK_IMPORTED_MODULE_2__["DomManagement"].GetDOMTextContent(vertex);
                callback(vertexCode);
                return;
            }
        }
        // Direct source ?
        if (vertex.substr(0, 7) === "source:") {
            callback(vertex.substr(7));
            return;
        }
        // Base64 encoded ?
        if (vertex.substr(0, 7) === "base64:") {
            var vertexBinary = window.atob(vertex.substr(7));
            callback(vertexBinary);
            return;
        }
        // Is in local store ?
        if (Effect.ShadersStore[vertex + "VertexShader"]) {
            callback(Effect.ShadersStore[vertex + "VertexShader"]);
            return;
        }
        var vertexShaderUrl;
        if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
            vertexShaderUrl = vertex;
        }
        else {
            vertexShaderUrl = Effect.ShadersRepository + vertex;
        }
        // Vertex shader
        this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
    };
    /** @hidden */
    Effect.prototype._loadFragmentShader = function (fragment, callback) {
        if (typeof (HTMLElement) !== "undefined") {
            // DOM element ?
            if (fragment instanceof HTMLElement) {
                var fragmentCode = _Misc_domManagement__WEBPACK_IMPORTED_MODULE_2__["DomManagement"].GetDOMTextContent(fragment);
                callback(fragmentCode);
                return;
            }
        }
        // Direct source ?
        if (fragment.substr(0, 7) === "source:") {
            callback(fragment.substr(7));
            return;
        }
        // Base64 encoded ?
        if (fragment.substr(0, 7) === "base64:") {
            var fragmentBinary = window.atob(fragment.substr(7));
            callback(fragmentBinary);
            return;
        }
        // Is in local store ?
        if (Effect.ShadersStore[fragment + "PixelShader"]) {
            callback(Effect.ShadersStore[fragment + "PixelShader"]);
            return;
        }
        if (Effect.ShadersStore[fragment + "FragmentShader"]) {
            callback(Effect.ShadersStore[fragment + "FragmentShader"]);
            return;
        }
        var fragmentShaderUrl;
        if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
            fragmentShaderUrl = fragment;
        }
        else {
            fragmentShaderUrl = Effect.ShadersRepository + fragment;
        }
        // Fragment shader
        this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
    };
    /** @hidden */
    Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
        // Rebuild shaders source code
        var shaderVersion = (this._engine.webGLVersion > 1) ? "#version 300 es\n#define WEBGL2 \n" : "";
        var prefix = shaderVersion + (defines ? defines + "\n" : "");
        vertexCode = prefix + vertexCode;
        fragmentCode = prefix + fragmentCode;
        // Number lines of shaders source code
        var i = 2;
        var regex = /\n/gm;
        var formattedVertexCode = "\n1\t" + vertexCode.replace(regex, function () { return "\n" + (i++) + "\t"; });
        i = 2;
        var formattedFragmentCode = "\n1\t" + fragmentCode.replace(regex, function () { return "\n" + (i++) + "\t"; });
        // Dump shaders name and formatted source code
        if (this.name.vertexElement) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Vertex shader: " + this.name.vertexElement + formattedVertexCode);
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Fragment shader: " + this.name.fragmentElement + formattedFragmentCode);
        }
        else if (this.name.vertex) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Vertex shader: " + this.name.vertex + formattedVertexCode);
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Fragment shader: " + this.name.fragment + formattedFragmentCode);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Vertex shader: " + this.name + formattedVertexCode);
            _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Fragment shader: " + this.name + formattedFragmentCode);
        }
    };
    /**
     * Recompiles the webGL program
     * @param vertexSourceCode The source code for the vertex shader.
     * @param fragmentSourceCode The source code for the fragment shader.
     * @param onCompiled Callback called when completed.
     * @param onError Callback called on error.
     * @hidden
     */
    Effect.prototype._rebuildProgram = function (vertexSourceCode, fragmentSourceCode, onCompiled, onError) {
        var _this = this;
        this._isReady = false;
        this._vertexSourceCodeOverride = vertexSourceCode;
        this._fragmentSourceCodeOverride = fragmentSourceCode;
        this.onError = function (effect, error) {
            if (onError) {
                onError(error);
            }
        };
        this.onCompiled = function () {
            var scenes = _this.getEngine().scenes;
            for (var i = 0; i < scenes.length; i++) {
                scenes[i].markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_AllDirtyFlag);
            }
            _this._pipelineContext._handlesSpectorRebuildCallback(onCompiled);
        };
        this._fallbacks = null;
        this._prepareEffect();
    };
    /**
     * Prepares the effect
     * @hidden
     */
    Effect.prototype._prepareEffect = function () {
        var _this = this;
        var attributesNames = this._attributesNames;
        var defines = this.defines;
        var previousPipelineContext = this._pipelineContext;
        try {
            var engine = this._engine;
            this._pipelineContext = engine.createPipelineContext(this._processingContext);
            var rebuildRebind = this._rebuildProgram.bind(this);
            if (this._vertexSourceCodeOverride && this._fragmentSourceCodeOverride) {
                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCodeOverride, this._fragmentSourceCodeOverride, true, rebuildRebind, null, this._transformFeedbackVaryings, this._key);
            }
            else {
                engine._preparePipelineContext(this._pipelineContext, this._vertexSourceCode, this._fragmentSourceCode, false, rebuildRebind, defines, this._transformFeedbackVaryings, this._key);
            }
            engine._executeWhenRenderingStateIsCompiled(this._pipelineContext, function () {
                _this._attributes = [];
                _this._pipelineContext._fillEffectInformation(_this, _this._uniformBuffersNames, _this._uniformsNames, _this._uniforms, _this._samplerList, _this._samplers, attributesNames, _this._attributes);
                _this._compilationError = "";
                _this._isReady = true;
                if (_this.onCompiled) {
                    _this.onCompiled(_this);
                }
                _this.onCompileObservable.notifyObservers(_this);
                _this.onCompileObservable.clear();
                // Unbind mesh reference in fallbacks
                if (_this._fallbacks) {
                    _this._fallbacks.unBindMesh();
                }
                if (previousPipelineContext) {
                    _this.getEngine()._deletePipelineContext(previousPipelineContext);
                }
            });
            if (this._pipelineContext.isAsync) {
                this._checkIsReady();
            }
        }
        catch (e) {
            this._processCompilationErrors(e, previousPipelineContext);
        }
    };
    Effect.prototype._processCompilationErrors = function (e, previousPipelineContext) {
        if (previousPipelineContext === void 0) { previousPipelineContext = null; }
        this._compilationError = e.message;
        var attributesNames = this._attributesNames;
        var fallbacks = this._fallbacks;
        // Let's go through fallbacks then
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Unable to compile effect:");
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Uniforms: " + this._uniformsNames.map(function (uniform) {
            return " " + uniform;
        }));
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Attributes: " + attributesNames.map(function (attribute) {
            return " " + attribute;
        }));
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Defines:\r\n" + this.defines);
        _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Error: " + this._compilationError);
        if (previousPipelineContext) {
            this._pipelineContext = previousPipelineContext;
            this._isReady = true;
            if (this.onError) {
                this.onError(this, this._compilationError);
            }
            this.onErrorObservable.notifyObservers(this);
        }
        if (fallbacks) {
            this._pipelineContext = null;
            if (fallbacks.hasMoreFallbacks) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_3__["Logger"].Error("Trying next fallback.");
                this.defines = fallbacks.reduce(this.defines, this);
                this._prepareEffect();
            }
            else { // Sorry we did everything we can
                if (this.onError) {
                    this.onError(this, this._compilationError);
                }
                this.onErrorObservable.notifyObservers(this);
                this.onErrorObservable.clear();
                // Unbind mesh reference in fallbacks
                if (this._fallbacks) {
                    this._fallbacks.unBindMesh();
                }
            }
        }
    };
    Object.defineProperty(Effect.prototype, "isSupported", {
        /**
         * Checks if the effect is supported. (Must be called after compilation)
         */
        get: function () {
            return this._compilationError === "";
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Binds a texture to the engine to be used as output of the shader.
     * @param channel Name of the output variable.
     * @param texture Texture to bind.
     * @hidden
     */
    Effect.prototype._bindTexture = function (channel, texture) {
        this._engine._bindTexture(this._samplers[channel], texture);
    };
    /**
     * Sets a texture on the engine to be used in the shader.
     * @param channel Name of the sampler variable.
     * @param texture Texture to set.
     */
    Effect.prototype.setTexture = function (channel, texture) {
        this._engine.setTexture(this._samplers[channel], this._uniforms[channel], texture, channel);
    };
    /**
     * Sets a depth stencil texture from a render target on the engine to be used in the shader.
     * @param channel Name of the sampler variable.
     * @param texture Texture to set.
     */
    Effect.prototype.setDepthStencilTexture = function (channel, texture) {
        this._engine.setDepthStencilTexture(this._samplers[channel], this._uniforms[channel], texture);
    };
    /**
     * Sets an array of textures on the engine to be used in the shader.
     * @param channel Name of the variable.
     * @param textures Textures to set.
     */
    Effect.prototype.setTextureArray = function (channel, textures) {
        var exName = channel + "Ex";
        if (this._samplerList.indexOf(exName + "0") === -1) {
            var initialPos = this._samplerList.indexOf(channel);
            for (var index = 1; index < textures.length; index++) {
                var currentExName = exName + (index - 1).toString();
                this._samplerList.splice(initialPos + index, 0, currentExName);
            }
            // Reset every channels
            var channelIndex = 0;
            for (var _i = 0, _a = this._samplerList; _i < _a.length; _i++) {
                var key = _a[_i];
                this._samplers[key] = channelIndex;
                channelIndex += 1;
            }
        }
        this._engine.setTextureArray(this._samplers[channel], this._uniforms[channel], textures);
    };
    /**
     * Sets a texture to be the input of the specified post process. (To use the output, pass in the next post process in the pipeline)
     * @param channel Name of the sampler variable.
     * @param postProcess Post process to get the input texture from.
     */
    Effect.prototype.setTextureFromPostProcess = function (channel, postProcess) {
        this._engine.setTextureFromPostProcess(this._samplers[channel], postProcess);
    };
    /**
     * (Warning! setTextureFromPostProcessOutput may be desired instead)
     * Sets the input texture of the passed in post process to be input of this effect. (To use the output of the passed in post process use setTextureFromPostProcessOutput)
     * @param channel Name of the sampler variable.
     * @param postProcess Post process to get the output texture from.
     */
    Effect.prototype.setTextureFromPostProcessOutput = function (channel, postProcess) {
        this._engine.setTextureFromPostProcessOutput(this._samplers[channel], postProcess);
    };
    /**
     * Binds a buffer to a uniform.
     * @param buffer Buffer to bind.
     * @param name Name of the uniform variable to bind to.
     */
    Effect.prototype.bindUniformBuffer = function (buffer, name) {
        var bufferName = this._uniformBuffersNames[name];
        if (bufferName === undefined || Effect._baseCache[bufferName] === buffer) {
            return;
        }
        Effect._baseCache[bufferName] = buffer;
        this._engine.bindUniformBufferBase(buffer, bufferName, name);
    };
    /**
     * Binds block to a uniform.
     * @param blockName Name of the block to bind.
     * @param index Index to bind.
     */
    Effect.prototype.bindUniformBlock = function (blockName, index) {
        this._engine.bindUniformBlock(this._pipelineContext, blockName, index);
    };
    /**
     * Sets an interger value on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value Value to be set.
     * @returns this effect.
     */
    Effect.prototype.setInt = function (uniformName, value) {
        this._pipelineContext.setInt(uniformName, value);
        return this;
    };
    /**
     * Sets an int array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setIntArray = function (uniformName, array) {
        this._pipelineContext.setIntArray(uniformName, array);
        return this;
    };
    /**
     * Sets an int array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setIntArray2 = function (uniformName, array) {
        this._pipelineContext.setIntArray2(uniformName, array);
        return this;
    };
    /**
     * Sets an int array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setIntArray3 = function (uniformName, array) {
        this._pipelineContext.setIntArray3(uniformName, array);
        return this;
    };
    /**
     * Sets an int array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setIntArray4 = function (uniformName, array) {
        this._pipelineContext.setIntArray4(uniformName, array);
        return this;
    };
    /**
     * Sets an float array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setFloatArray = function (uniformName, array) {
        this._pipelineContext.setFloatArray(uniformName, array);
        return this;
    };
    /**
     * Sets an float array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setFloatArray2 = function (uniformName, array) {
        this._pipelineContext.setFloatArray2(uniformName, array);
        return this;
    };
    /**
     * Sets an float array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setFloatArray3 = function (uniformName, array) {
        this._pipelineContext.setFloatArray3(uniformName, array);
        return this;
    };
    /**
     * Sets an float array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setFloatArray4 = function (uniformName, array) {
        this._pipelineContext.setFloatArray4(uniformName, array);
        return this;
    };
    /**
     * Sets an array on a uniform variable.
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setArray = function (uniformName, array) {
        this._pipelineContext.setArray(uniformName, array);
        return this;
    };
    /**
     * Sets an array 2 on a uniform variable. (Array is specified as single array eg. [1,2,3,4] will result in [[1,2],[3,4]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setArray2 = function (uniformName, array) {
        this._pipelineContext.setArray2(uniformName, array);
        return this;
    };
    /**
     * Sets an array 3 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6] will result in [[1,2,3],[4,5,6]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setArray3 = function (uniformName, array) {
        this._pipelineContext.setArray3(uniformName, array);
        return this;
    };
    /**
     * Sets an array 4 on a uniform variable. (Array is specified as single array eg. [1,2,3,4,5,6,7,8] will result in [[1,2,3,4],[5,6,7,8]] in the shader)
     * @param uniformName Name of the variable.
     * @param array array to be set.
     * @returns this effect.
     */
    Effect.prototype.setArray4 = function (uniformName, array) {
        this._pipelineContext.setArray4(uniformName, array);
        return this;
    };
    /**
     * Sets matrices on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrices matrices to be set.
     * @returns this effect.
     */
    Effect.prototype.setMatrices = function (uniformName, matrices) {
        this._pipelineContext.setMatrices(uniformName, matrices);
        return this;
    };
    /**
     * Sets matrix on a uniform variable.
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     * @returns this effect.
     */
    Effect.prototype.setMatrix = function (uniformName, matrix) {
        this._pipelineContext.setMatrix(uniformName, matrix);
        return this;
    };
    /**
     * Sets a 3x3 matrix on a uniform variable. (Speicified as [1,2,3,4,5,6,7,8,9] will result in [1,2,3][4,5,6][7,8,9] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     * @returns this effect.
     */
    Effect.prototype.setMatrix3x3 = function (uniformName, matrix) {
        this._pipelineContext.setMatrix3x3(uniformName, matrix);
        return this;
    };
    /**
     * Sets a 2x2 matrix on a uniform variable. (Speicified as [1,2,3,4] will result in [1,2][3,4] matrix)
     * @param uniformName Name of the variable.
     * @param matrix matrix to be set.
     * @returns this effect.
     */
    Effect.prototype.setMatrix2x2 = function (uniformName, matrix) {
        this._pipelineContext.setMatrix2x2(uniformName, matrix);
        return this;
    };
    /**
     * Sets a float on a uniform variable.
     * @param uniformName Name of the variable.
     * @param value value to be set.
     * @returns this effect.
     */
    Effect.prototype.setFloat = function (uniformName, value) {
        this._pipelineContext.setFloat(uniformName, value);
        return this;
    };
    /**
     * Sets a boolean on a uniform variable.
     * @param uniformName Name of the variable.
     * @param bool value to be set.
     * @returns this effect.
     */
    Effect.prototype.setBool = function (uniformName, bool) {
        this._pipelineContext.setBool(uniformName, bool);
        return this;
    };
    /**
     * Sets a Vector2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector2 vector2 to be set.
     * @returns this effect.
     */
    Effect.prototype.setVector2 = function (uniformName, vector2) {
        this._pipelineContext.setVector2(uniformName, vector2);
        return this;
    };
    /**
     * Sets a float2 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float2.
     * @param y Second float in float2.
     * @returns this effect.
     */
    Effect.prototype.setFloat2 = function (uniformName, x, y) {
        this._pipelineContext.setFloat2(uniformName, x, y);
        return this;
    };
    /**
     * Sets a Vector3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector3 Value to be set.
     * @returns this effect.
     */
    Effect.prototype.setVector3 = function (uniformName, vector3) {
        this._pipelineContext.setVector3(uniformName, vector3);
        return this;
    };
    /**
     * Sets a float3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float3.
     * @param y Second float in float3.
     * @param z Third float in float3.
     * @returns this effect.
     */
    Effect.prototype.setFloat3 = function (uniformName, x, y, z) {
        this._pipelineContext.setFloat3(uniformName, x, y, z);
        return this;
    };
    /**
     * Sets a Vector4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param vector4 Value to be set.
     * @returns this effect.
     */
    Effect.prototype.setVector4 = function (uniformName, vector4) {
        this._pipelineContext.setVector4(uniformName, vector4);
        return this;
    };
    /**
     * Sets a float4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param x First float in float4.
     * @param y Second float in float4.
     * @param z Third float in float4.
     * @param w Fourth float in float4.
     * @returns this effect.
     */
    Effect.prototype.setFloat4 = function (uniformName, x, y, z, w) {
        this._pipelineContext.setFloat4(uniformName, x, y, z, w);
        return this;
    };
    /**
     * Sets a Color3 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     * @returns this effect.
     */
    Effect.prototype.setColor3 = function (uniformName, color3) {
        this._pipelineContext.setColor3(uniformName, color3);
        return this;
    };
    /**
     * Sets a Color4 on a uniform variable.
     * @param uniformName Name of the variable.
     * @param color3 Value to be set.
     * @param alpha Alpha value to be set.
     * @returns this effect.
     */
    Effect.prototype.setColor4 = function (uniformName, color3, alpha) {
        this._pipelineContext.setColor4(uniformName, color3, alpha);
        return this;
    };
    /**
     * Sets a Color4 on a uniform variable
     * @param uniformName defines the name of the variable
     * @param color4 defines the value to be set
     * @returns this effect.
     */
    Effect.prototype.setDirectColor4 = function (uniformName, color4) {
        this._pipelineContext.setDirectColor4(uniformName, color4);
        return this;
    };
    /**
     * Release all associated resources.
     **/
    Effect.prototype.dispose = function () {
        if (this._pipelineContext) {
            this._pipelineContext.dispose();
        }
        this._engine._releaseEffect(this);
    };
    /**
     * This function will add a new shader to the shader store
     * @param name the name of the shader
     * @param pixelShader optional pixel shader content
     * @param vertexShader optional vertex shader content
     */
    Effect.RegisterShader = function (name, pixelShader, vertexShader) {
        if (pixelShader) {
            Effect.ShadersStore[name + "PixelShader"] = pixelShader;
        }
        if (vertexShader) {
            Effect.ShadersStore[name + "VertexShader"] = vertexShader;
        }
    };
    /**
     * Resets the cache of effects.
     */
    Effect.ResetCache = function () {
        Effect._baseCache = {};
    };
    /**
     * Gets or sets the relative url used to load shaders if using the engine in non-minified mode
     */
    Effect.ShadersRepository = "src/Shaders/";
    Effect._uniqueIdSeed = 0;
    Effect._baseCache = {};
    /**
     * Store of each shader (The can be looked up using effect.key)
     */
    Effect.ShadersStore = {};
    /**
     * Store of each included file for a shader (The can be looked up using effect.key)
     */
    Effect.IncludesShadersStore = {};
    return Effect;
}());



/***/ }),

/***/ "./Materials/effectRenderer.ts":
/*!*************************************!*\
  !*** ./Materials/effectRenderer.ts ***!
  \*************************************/
/*! exports provided: EffectRenderer, EffectWrapper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EffectRenderer", function() { return EffectRenderer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EffectWrapper", function() { return EffectWrapper; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.viewport */ "./Maths/math.viewport.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _effect__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./effect */ "./Materials/effect.ts");
/* harmony import */ var _Shaders_postprocess_vertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Shaders/postprocess.vertex */ "./Shaders/postprocess.vertex.ts");







// Prevents ES6 Crash if not imported.

/**
 * Helper class to render one or more effects
 */
var EffectRenderer = /** @class */ (function () {
    /**
     * Creates an effect renderer
     * @param engine the engine to use for rendering
     * @param options defines the options of the effect renderer
     */
    function EffectRenderer(engine, options) {
        var _a;
        if (options === void 0) { options = EffectRenderer._DefaultOptions; }
        this.engine = engine;
        this._ringBufferIndex = 0;
        this._ringScreenBuffer = null;
        this._fullscreenViewport = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_3__["Viewport"](0, 0, 1, 1);
        options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, EffectRenderer._DefaultOptions, options);
        this._vertexBuffers = (_a = {},
            _a[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"](engine, options.positions, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, false, false, 2),
            _a);
        this._indexBuffer = engine.createIndexBuffer(options.indices);
        // No need here for full screen render.
        engine.setDepthBuffer(false);
        engine.setStencilBuffer(false);
    }
    EffectRenderer.prototype._getNextFrameBuffer = function (incrementIndex) {
        if (incrementIndex === void 0) { incrementIndex = true; }
        if (!this._ringScreenBuffer) {
            this._ringScreenBuffer = [];
            for (var i = 0; i < 2; i++) {
                var internalTexture = this.engine.createRenderTargetTexture({
                    width: this.engine.getRenderWidth(true),
                    height: this.engine.getRenderHeight(true),
                }, {
                    generateDepthBuffer: false,
                    generateStencilBuffer: false,
                    generateMipMaps: false,
                    samplingMode: _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].TEXTURE_NEAREST_NEAREST,
                });
                var texture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"]("", null);
                texture._texture = internalTexture;
                this._ringScreenBuffer.push(texture);
            }
        }
        var ret = this._ringScreenBuffer[this._ringBufferIndex];
        if (incrementIndex) {
            this._ringBufferIndex = (this._ringBufferIndex + 1) % 2;
        }
        return ret;
    };
    /**
     * Sets the current viewport in normalized coordinates 0-1
     * @param viewport Defines the viewport to set (defaults to 0 0 1 1)
     */
    EffectRenderer.prototype.setViewport = function (viewport) {
        if (viewport === void 0) { viewport = this._fullscreenViewport; }
        this.engine.setViewport(viewport);
    };
    /**
     * Binds the embedded attributes buffer to the effect.
     * @param effect Defines the effect to bind the attributes for
     */
    EffectRenderer.prototype.bindBuffers = function (effect) {
        this.engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
    };
    /**
     * Sets the current effect wrapper to use during draw.
     * The effect needs to be ready before calling this api.
     * This also sets the default full screen position attribute.
     * @param effectWrapper Defines the effect to draw with
     */
    EffectRenderer.prototype.applyEffectWrapper = function (effectWrapper) {
        this.engine.enableEffect(effectWrapper.effect);
        this.bindBuffers(effectWrapper.effect);
        effectWrapper.onApplyObservable.notifyObservers({});
    };
    /**
     * Draws a full screen quad.
     */
    EffectRenderer.prototype.draw = function () {
        this.engine.drawElementsType(_Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_TriangleFillMode, 0, 6);
    };
    /**
     * renders one or more effects to a specified texture
     * @param effectWrappers list of effects to renderer
     * @param outputTexture texture to draw to, if null it will render to the screen
     */
    EffectRenderer.prototype.render = function (effectWrappers, outputTexture) {
        var _this = this;
        if (outputTexture === void 0) { outputTexture = null; }
        if (!Array.isArray(effectWrappers)) {
            effectWrappers = [effectWrappers];
        }
        // Ensure all effects are ready
        for (var _i = 0, effectWrappers_1 = effectWrappers; _i < effectWrappers_1.length; _i++) {
            var wrapper = effectWrappers_1[_i];
            if (!wrapper.effect.isReady()) {
                return;
            }
        }
        effectWrappers.forEach(function (effectWrapper, i) {
            var renderTo = outputTexture;
            // for any next effect make it's input the output of the previous effect
            if (i !== 0) {
                effectWrapper.effect.onBindObservable.addOnce(function () {
                    effectWrapper.effect.setTexture("textureSampler", _this._getNextFrameBuffer(false));
                });
            }
            // Set the output to the next screenbuffer
            if (effectWrappers.length > 1 && i != effectWrappers.length - 1) {
                renderTo = _this._getNextFrameBuffer();
            }
            else {
                renderTo = outputTexture;
            }
            // Reset state
            _this.setViewport();
            _this.applyEffectWrapper(effectWrapper);
            if (renderTo) {
                _this.engine.bindFramebuffer(renderTo.getInternalTexture());
            }
            _this.draw();
            if (renderTo) {
                _this.engine.unBindFramebuffer(renderTo.getInternalTexture());
            }
        });
    };
    /**
     * Disposes of the effect renderer
     */
    EffectRenderer.prototype.dispose = function () {
        if (this._ringScreenBuffer) {
            this._ringScreenBuffer.forEach(function (b) {
                b.dispose();
            });
            this._ringScreenBuffer = null;
        }
        var vertexBuffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind];
        if (vertexBuffer) {
            vertexBuffer.dispose();
            delete this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind];
        }
        if (this._indexBuffer) {
            this.engine._releaseBuffer(this._indexBuffer);
        }
    };
    // Fullscreen quad buffers by default.
    EffectRenderer._DefaultOptions = {
        positions: [1, 1, -1, 1, -1, -1, 1, -1],
        indices: [0, 1, 2, 0, 2, 3]
    };
    return EffectRenderer;
}());

/**
 * Wraps an effect to be used for rendering
 */
var EffectWrapper = /** @class */ (function () {
    /**
     * Creates an effect to be renderer
     * @param creationOptions options to create the effect
     */
    function EffectWrapper(creationOptions) {
        var _this = this;
        /**
         * Event that is fired right before the effect is drawn (should be used to update uniforms)
         */
        this.onApplyObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_5__["Observable"]();
        var effectCreationOptions;
        var uniformNames = creationOptions.uniformNames || [];
        if (creationOptions.vertexShader) {
            effectCreationOptions = {
                fragmentSource: creationOptions.fragmentShader,
                vertexSource: creationOptions.vertexShader,
                spectorName: creationOptions.name || "effectWrapper"
            };
        }
        else {
            // Default scale to use in post process vertex shader.
            uniformNames.push("scale");
            effectCreationOptions = {
                fragmentSource: creationOptions.fragmentShader,
                vertex: "postprocess",
                spectorName: creationOptions.name || "effectWrapper"
            };
            // Sets the default scale to identity for the post process vertex shader.
            this.onApplyObservable.add(function () {
                _this.effect.setFloat2("scale", 1, 1);
            });
        }
        this.effect = new _effect__WEBPACK_IMPORTED_MODULE_6__["Effect"](effectCreationOptions, creationOptions.attributeNames || ["position"], uniformNames, creationOptions.samplerNames, creationOptions.engine);
    }
    /**
    * Disposes of the effect wrapper
    */
    EffectWrapper.prototype.dispose = function () {
        this.effect.dispose();
    };
    return EffectWrapper;
}());



/***/ }),

/***/ "./Materials/fresnelParameters.ts":
/*!****************************************!*\
  !*** ./Materials/fresnelParameters.ts ***!
  \****************************************/
/*! exports provided: FresnelParameters */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FresnelParameters", function() { return FresnelParameters; });
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");





/**
 * This represents all the required information to add a fresnel effect on a material:
 * @see http://doc.babylonjs.com/how_to/how_to_use_fresnelparameters
 */
var FresnelParameters = /** @class */ (function () {
    function FresnelParameters() {
        this._isEnabled = true;
        /**
         * Define the color used on edges (grazing angle)
         */
        this.leftColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].White();
        /**
         * Define the color used on center
         */
        this.rightColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].Black();
        /**
         * Define bias applied to computed fresnel term
         */
        this.bias = 0;
        /**
         * Defined the power exponent applied to fresnel term
         */
        this.power = 1;
    }
    Object.defineProperty(FresnelParameters.prototype, "isEnabled", {
        /**
         * Define if the fresnel effect is enable or not.
         */
        get: function () {
            return this._isEnabled;
        },
        set: function (value) {
            if (this._isEnabled === value) {
                return;
            }
            this._isEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_2__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_FresnelDirtyFlag | _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Clones the current fresnel and its valuues
     * @returns a clone fresnel configuration
     */
    FresnelParameters.prototype.clone = function () {
        var newFresnelParameters = new FresnelParameters();
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__["DeepCopier"].DeepCopy(this, newFresnelParameters);
        return newFresnelParameters;
    };
    /**
     * Serializes the current fresnel parameters to a JSON representation.
     * @return the JSON serialization
     */
    FresnelParameters.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.isEnabled = this.isEnabled;
        serializationObject.leftColor = this.leftColor.asArray();
        serializationObject.rightColor = this.rightColor.asArray();
        serializationObject.bias = this.bias;
        serializationObject.power = this.power;
        return serializationObject;
    };
    /**
     * Parse a JSON object and deserialize it to a new Fresnel parameter object.
     * @param parsedFresnelParameters Define the JSON representation
     * @returns the parsed parameters
     */
    FresnelParameters.Parse = function (parsedFresnelParameters) {
        var fresnelParameters = new FresnelParameters();
        fresnelParameters.isEnabled = parsedFresnelParameters.isEnabled;
        fresnelParameters.leftColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].FromArray(parsedFresnelParameters.leftColor);
        fresnelParameters.rightColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"].FromArray(parsedFresnelParameters.rightColor);
        fresnelParameters.bias = parsedFresnelParameters.bias;
        fresnelParameters.power = parsedFresnelParameters.power || 1.0;
        return fresnelParameters;
    };
    return FresnelParameters;
}());

// References the dependencies.
_Misc_decorators__WEBPACK_IMPORTED_MODULE_3__["SerializationHelper"]._FresnelParametersParser = FresnelParameters.Parse;


/***/ }),

/***/ "./Materials/imageProcessingConfiguration.ts":
/*!***************************************************!*\
  !*** ./Materials/imageProcessingConfiguration.ts ***!
  \***************************************************/
/*! exports provided: ImageProcessingConfigurationDefines, ImageProcessingConfiguration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfigurationDefines", function() { return ImageProcessingConfigurationDefines; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfiguration", function() { return ImageProcessingConfiguration; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Materials_materialDefines__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/materialDefines */ "./Materials/materialDefines.ts");
/* harmony import */ var _Materials_colorCurves__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/colorCurves */ "./Materials/colorCurves.ts");







/**
 * @hidden
 */
var ImageProcessingConfigurationDefines = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ImageProcessingConfigurationDefines, _super);
    function ImageProcessingConfigurationDefines() {
        var _this = _super.call(this) || this;
        _this.IMAGEPROCESSING = false;
        _this.VIGNETTE = false;
        _this.VIGNETTEBLENDMODEMULTIPLY = false;
        _this.VIGNETTEBLENDMODEOPAQUE = false;
        _this.TONEMAPPING = false;
        _this.TONEMAPPING_ACES = false;
        _this.CONTRAST = false;
        _this.COLORCURVES = false;
        _this.COLORGRADING = false;
        _this.COLORGRADING3D = false;
        _this.SAMPLER3DGREENDEPTH = false;
        _this.SAMPLER3DBGRMAP = false;
        _this.IMAGEPROCESSINGPOSTPROCESS = false;
        _this.EXPOSURE = false;
        _this.rebuild();
        return _this;
    }
    return ImageProcessingConfigurationDefines;
}(_Materials_materialDefines__WEBPACK_IMPORTED_MODULE_5__["MaterialDefines"]));

/**
 * This groups together the common properties used for image processing either in direct forward pass
 * or through post processing effect depending on the use of the image processing pipeline in your scene
 * or not.
 */
var ImageProcessingConfiguration = /** @class */ (function () {
    function ImageProcessingConfiguration() {
        /**
         * Color curves setup used in the effect if colorCurvesEnabled is set to true
         */
        this.colorCurves = new _Materials_colorCurves__WEBPACK_IMPORTED_MODULE_6__["ColorCurves"]();
        this._colorCurvesEnabled = false;
        this._colorGradingEnabled = false;
        this._colorGradingWithGreenDepth = true;
        this._colorGradingBGR = true;
        /** @hidden */
        this._exposure = 1.0;
        this._toneMappingEnabled = false;
        this._toneMappingType = ImageProcessingConfiguration.TONEMAPPING_STANDARD;
        this._contrast = 1.0;
        /**
         * Vignette stretch size.
         */
        this.vignetteStretch = 0;
        /**
         * Vignette centre X Offset.
         */
        this.vignetteCentreX = 0;
        /**
         * Vignette centre Y Offset.
         */
        this.vignetteCentreY = 0;
        /**
         * Vignette weight or intensity of the vignette effect.
         */
        this.vignetteWeight = 1.5;
        /**
         * Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)
         * if vignetteEnabled is set to true.
         */
        this.vignetteColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](0, 0, 0, 0);
        /**
         * Camera field of view used by the Vignette effect.
         */
        this.vignetteCameraFov = 0.5;
        this._vignetteBlendMode = ImageProcessingConfiguration.VIGNETTEMODE_MULTIPLY;
        this._vignetteEnabled = false;
        this._applyByPostProcess = false;
        this._isEnabled = true;
        /**
        * An event triggered when the configuration changes and requires Shader to Update some parameters.
        */
        this.onUpdateParameters = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
    }
    Object.defineProperty(ImageProcessingConfiguration.prototype, "colorCurvesEnabled", {
        /**
         * Gets wether the color curves effect is enabled.
         */
        get: function () {
            return this._colorCurvesEnabled;
        },
        /**
         * Sets wether the color curves effect is enabled.
         */
        set: function (value) {
            if (this._colorCurvesEnabled === value) {
                return;
            }
            this._colorCurvesEnabled = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "colorGradingTexture", {
        /**
         * Color grading LUT texture used in the effect if colorGradingEnabled is set to true
         */
        get: function () {
            return this._colorGradingTexture;
        },
        /**
         * Color grading LUT texture used in the effect if colorGradingEnabled is set to true
         */
        set: function (value) {
            if (this._colorGradingTexture === value) {
                return;
            }
            this._colorGradingTexture = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "colorGradingEnabled", {
        /**
         * Gets wether the color grading effect is enabled.
         */
        get: function () {
            return this._colorGradingEnabled;
        },
        /**
         * Sets wether the color grading effect is enabled.
         */
        set: function (value) {
            if (this._colorGradingEnabled === value) {
                return;
            }
            this._colorGradingEnabled = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "colorGradingWithGreenDepth", {
        /**
         * Gets wether the color grading effect is using a green depth for the 3d Texture.
         */
        get: function () {
            return this._colorGradingWithGreenDepth;
        },
        /**
         * Sets wether the color grading effect is using a green depth for the 3d Texture.
         */
        set: function (value) {
            if (this._colorGradingWithGreenDepth === value) {
                return;
            }
            this._colorGradingWithGreenDepth = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "colorGradingBGR", {
        /**
         * Gets wether the color grading texture contains BGR values.
         */
        get: function () {
            return this._colorGradingBGR;
        },
        /**
         * Sets wether the color grading texture contains BGR values.
         */
        set: function (value) {
            if (this._colorGradingBGR === value) {
                return;
            }
            this._colorGradingBGR = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "exposure", {
        /**
         * Gets the Exposure used in the effect.
         */
        get: function () {
            return this._exposure;
        },
        /**
         * Sets the Exposure used in the effect.
         */
        set: function (value) {
            if (this._exposure === value) {
                return;
            }
            this._exposure = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "toneMappingEnabled", {
        /**
         * Gets wether the tone mapping effect is enabled.
         */
        get: function () {
            return this._toneMappingEnabled;
        },
        /**
         * Sets wether the tone mapping effect is enabled.
         */
        set: function (value) {
            if (this._toneMappingEnabled === value) {
                return;
            }
            this._toneMappingEnabled = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "toneMappingType", {
        /**
         * Gets the type of tone mapping effect.
         */
        get: function () {
            return this._toneMappingType;
        },
        /**
         * Sets the type of tone mapping effect used in BabylonJS.
         */
        set: function (value) {
            if (this._toneMappingType === value) {
                return;
            }
            this._toneMappingType = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "contrast", {
        /**
         * Gets the contrast used in the effect.
         */
        get: function () {
            return this._contrast;
        },
        /**
         * Sets the contrast used in the effect.
         */
        set: function (value) {
            if (this._contrast === value) {
                return;
            }
            this._contrast = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "vignetteBlendMode", {
        /**
         * Gets the vignette blend mode allowing different kind of effect.
         */
        get: function () {
            return this._vignetteBlendMode;
        },
        /**
         * Sets the vignette blend mode allowing different kind of effect.
         */
        set: function (value) {
            if (this._vignetteBlendMode === value) {
                return;
            }
            this._vignetteBlendMode = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "vignetteEnabled", {
        /**
         * Gets wether the vignette effect is enabled.
         */
        get: function () {
            return this._vignetteEnabled;
        },
        /**
         * Sets wether the vignette effect is enabled.
         */
        set: function (value) {
            if (this._vignetteEnabled === value) {
                return;
            }
            this._vignetteEnabled = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "applyByPostProcess", {
        /**
         * Gets wether the image processing is applied through a post process or not.
         */
        get: function () {
            return this._applyByPostProcess;
        },
        /**
         * Sets wether the image processing is applied through a post process or not.
         */
        set: function (value) {
            if (this._applyByPostProcess === value) {
                return;
            }
            this._applyByPostProcess = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration.prototype, "isEnabled", {
        /**
         * Gets wether the image processing is enabled or not.
         */
        get: function () {
            return this._isEnabled;
        },
        /**
         * Sets wether the image processing is enabled or not.
         */
        set: function (value) {
            if (this._isEnabled === value) {
                return;
            }
            this._isEnabled = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Method called each time the image processing information changes requires to recompile the effect.
     */
    ImageProcessingConfiguration.prototype._updateParameters = function () {
        this.onUpdateParameters.notifyObservers(this);
    };
    /**
     * Gets the current class name.
     * @return "ImageProcessingConfiguration"
     */
    ImageProcessingConfiguration.prototype.getClassName = function () {
        return "ImageProcessingConfiguration";
    };
    /**
     * Prepare the list of uniforms associated with the Image Processing effects.
     * @param uniforms The list of uniforms used in the effect
     * @param defines the list of defines currently in use
     */
    ImageProcessingConfiguration.PrepareUniforms = function (uniforms, defines) {
        if (defines.EXPOSURE) {
            uniforms.push("exposureLinear");
        }
        if (defines.CONTRAST) {
            uniforms.push("contrast");
        }
        if (defines.COLORGRADING) {
            uniforms.push("colorTransformSettings");
        }
        if (defines.VIGNETTE) {
            uniforms.push("vInverseScreenSize");
            uniforms.push("vignetteSettings1");
            uniforms.push("vignetteSettings2");
        }
        if (defines.COLORCURVES) {
            _Materials_colorCurves__WEBPACK_IMPORTED_MODULE_6__["ColorCurves"].PrepareUniforms(uniforms);
        }
    };
    /**
     * Prepare the list of samplers associated with the Image Processing effects.
     * @param samplersList The list of uniforms used in the effect
     * @param defines the list of defines currently in use
     */
    ImageProcessingConfiguration.PrepareSamplers = function (samplersList, defines) {
        if (defines.COLORGRADING) {
            samplersList.push("txColorTransform");
        }
    };
    /**
     * Prepare the list of defines associated to the shader.
     * @param defines the list of defines to complete
     * @param forPostProcess Define if we are currently in post process mode or not
     */
    ImageProcessingConfiguration.prototype.prepareDefines = function (defines, forPostProcess) {
        if (forPostProcess === void 0) { forPostProcess = false; }
        if (forPostProcess !== this.applyByPostProcess || !this._isEnabled) {
            defines.VIGNETTE = false;
            defines.TONEMAPPING = false;
            defines.TONEMAPPING_ACES = false;
            defines.CONTRAST = false;
            defines.EXPOSURE = false;
            defines.COLORCURVES = false;
            defines.COLORGRADING = false;
            defines.COLORGRADING3D = false;
            defines.IMAGEPROCESSING = false;
            defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess && this._isEnabled;
            return;
        }
        defines.VIGNETTE = this.vignetteEnabled;
        defines.VIGNETTEBLENDMODEMULTIPLY = (this.vignetteBlendMode === ImageProcessingConfiguration._VIGNETTEMODE_MULTIPLY);
        defines.VIGNETTEBLENDMODEOPAQUE = !defines.VIGNETTEBLENDMODEMULTIPLY;
        defines.TONEMAPPING = this.toneMappingEnabled;
        switch (this._toneMappingType) {
            case ImageProcessingConfiguration.TONEMAPPING_ACES:
                defines.TONEMAPPING_ACES = true;
                break;
            default:
                defines.TONEMAPPING_ACES = false;
                break;
        }
        defines.CONTRAST = (this.contrast !== 1.0);
        defines.EXPOSURE = (this.exposure !== 1.0);
        defines.COLORCURVES = (this.colorCurvesEnabled && !!this.colorCurves);
        defines.COLORGRADING = (this.colorGradingEnabled && !!this.colorGradingTexture);
        if (defines.COLORGRADING) {
            defines.COLORGRADING3D = this.colorGradingTexture.is3D;
        }
        else {
            defines.COLORGRADING3D = false;
        }
        defines.SAMPLER3DGREENDEPTH = this.colorGradingWithGreenDepth;
        defines.SAMPLER3DBGRMAP = this.colorGradingBGR;
        defines.IMAGEPROCESSINGPOSTPROCESS = this.applyByPostProcess;
        defines.IMAGEPROCESSING = defines.VIGNETTE || defines.TONEMAPPING || defines.CONTRAST || defines.EXPOSURE || defines.COLORCURVES || defines.COLORGRADING;
    };
    /**
     * Returns true if all the image processing information are ready.
     * @returns True if ready, otherwise, false
     */
    ImageProcessingConfiguration.prototype.isReady = function () {
        // Color Grading texure can not be none blocking.
        return !this.colorGradingEnabled || !this.colorGradingTexture || this.colorGradingTexture.isReady();
    };
    /**
     * Binds the image processing to the shader.
     * @param effect The effect to bind to
     * @param aspectRatio Define the current aspect ratio of the effect
     */
    ImageProcessingConfiguration.prototype.bind = function (effect, aspectRatio) {
        if (aspectRatio === void 0) { aspectRatio = 1; }
        // Color Curves
        if (this._colorCurvesEnabled && this.colorCurves) {
            _Materials_colorCurves__WEBPACK_IMPORTED_MODULE_6__["ColorCurves"].Bind(this.colorCurves, effect);
        }
        // Vignette
        if (this._vignetteEnabled) {
            var inverseWidth = 1 / effect.getEngine().getRenderWidth();
            var inverseHeight = 1 / effect.getEngine().getRenderHeight();
            effect.setFloat2("vInverseScreenSize", inverseWidth, inverseHeight);
            var vignetteScaleY = Math.tan(this.vignetteCameraFov * 0.5);
            var vignetteScaleX = vignetteScaleY * aspectRatio;
            var vignetteScaleGeometricMean = Math.sqrt(vignetteScaleX * vignetteScaleY);
            vignetteScaleX = _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].Mix(vignetteScaleX, vignetteScaleGeometricMean, this.vignetteStretch);
            vignetteScaleY = _Misc_tools__WEBPACK_IMPORTED_MODULE_3__["Tools"].Mix(vignetteScaleY, vignetteScaleGeometricMean, this.vignetteStretch);
            effect.setFloat4("vignetteSettings1", vignetteScaleX, vignetteScaleY, -vignetteScaleX * this.vignetteCentreX, -vignetteScaleY * this.vignetteCentreY);
            var vignettePower = -2.0 * this.vignetteWeight;
            effect.setFloat4("vignetteSettings2", this.vignetteColor.r, this.vignetteColor.g, this.vignetteColor.b, vignettePower);
        }
        // Exposure
        effect.setFloat("exposureLinear", this.exposure);
        // Contrast
        effect.setFloat("contrast", this.contrast);
        // Color transform settings
        if (this.colorGradingTexture) {
            effect.setTexture("txColorTransform", this.colorGradingTexture);
            var textureSize = this.colorGradingTexture.getSize().height;
            effect.setFloat4("colorTransformSettings", (textureSize - 1) / textureSize, // textureScale
            0.5 / textureSize, // textureOffset
            textureSize, // textureSize
            this.colorGradingTexture.level // weight
            );
        }
    };
    /**
     * Clones the current image processing instance.
     * @return The cloned image processing
     */
    ImageProcessingConfiguration.prototype.clone = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new ImageProcessingConfiguration(); }, this);
    };
    /**
     * Serializes the current image processing instance to a json representation.
     * @return a JSON representation
     */
    ImageProcessingConfiguration.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Parses the image processing from a json representation.
     * @param source the JSON source to parse
     * @return The parsed image processing
     */
    ImageProcessingConfiguration.Parse = function (source) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new ImageProcessingConfiguration(); }, source, null, null);
    };
    Object.defineProperty(ImageProcessingConfiguration, "VIGNETTEMODE_MULTIPLY", {
        /**
         * Used to apply the vignette as a mix with the pixel color.
         */
        get: function () {
            return this._VIGNETTEMODE_MULTIPLY;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingConfiguration, "VIGNETTEMODE_OPAQUE", {
        /**
         * Used to apply the vignette as a replacement of the pixel color.
         */
        get: function () {
            return this._VIGNETTEMODE_OPAQUE;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Default tone mapping applied in BabylonJS.
     */
    ImageProcessingConfiguration.TONEMAPPING_STANDARD = 0;
    /**
     * ACES Tone mapping (used by default in unreal and unity). This can help getting closer
     * to other engines rendering to increase portability.
     */
    ImageProcessingConfiguration.TONEMAPPING_ACES = 1;
    // Static constants associated to the image processing.
    ImageProcessingConfiguration._VIGNETTEMODE_MULTIPLY = 0;
    ImageProcessingConfiguration._VIGNETTEMODE_OPAQUE = 1;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColorCurves"])()
    ], ImageProcessingConfiguration.prototype, "colorCurves", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_colorCurvesEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("colorGradingTexture")
    ], ImageProcessingConfiguration.prototype, "_colorGradingTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_colorGradingEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_colorGradingWithGreenDepth", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_colorGradingBGR", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_exposure", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_toneMappingEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_toneMappingType", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_contrast", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "vignetteStretch", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "vignetteCentreX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "vignetteCentreY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "vignetteWeight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor4"])()
    ], ImageProcessingConfiguration.prototype, "vignetteColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "vignetteCameraFov", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_vignetteBlendMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_vignetteEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_applyByPostProcess", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingConfiguration.prototype, "_isEnabled", void 0);
    return ImageProcessingConfiguration;
}());

// References the dependencies.
_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"]._ImageProcessingConfigurationParser = ImageProcessingConfiguration.Parse;


/***/ }),

/***/ "./Materials/index.ts":
/*!****************************!*\
  !*** ./Materials/index.ts ***!
  \****************************/
/*! exports provided: ColorCurves, EffectFallbacks, EffectCreationOptions, Effect, FresnelParameters, ImageProcessingConfigurationDefines, ImageProcessingConfiguration, Material, MaterialDefines, MaterialHelper, MultiMaterial, PushMaterial, ShaderMaterial, StandardMaterialDefines, StandardMaterial, BaseTexture, CubeTexture, DynamicTexture, EquiRectangularCubeTexture, HDRCubeTexture, InternalTexture, MirrorTexture, MultiRenderTarget, RawTexture, RenderTargetTexture, Texture, UniformBuffer, MaterialFlags, EffectRenderer, EffectWrapper, BackgroundMaterial, PBRMaterialDefines, PBRBaseMaterial, PBRBaseSimpleMaterial, PBRMaterial, PBRMetallicRoughnessMaterial, PBRSpecularGlossinessMaterial, ColorGradingTexture, RawCubeTexture, RawTexture3D, RefractionTexture, VideoTexture, HtmlElementTexture, NodeMaterialBlockTargets, NodeMaterialBlockConnectionPointTypes, NodeMaterialConnectionPoint, NodeMaterialBlock, NodeMaterialDefines, NodeMaterial, NodeMaterialSystemValues, _DDSTextureLoader, _ENVTextureLoader, _KTXTextureLoader, _TGATextureLoader, _BasisTextureLoader, CustomProceduralTexture, NoiseProceduralTexture, ProceduralTexture, ProceduralTextureSceneComponent, MultiplyBlock, AddBlock, ScaleBlock, ClampBlock, CrossBlock, DotBlock, TransformBlock, RemapBlock, NormalizeBlock, TrigonometryBlockOperations, TrigonometryBlock, ColorMergerBlock, VectorMergerBlock, ColorSplitterBlock, VectorSplitterBlock, LerpBlock, DivideBlock, SubtractBlock, StepBlock, OppositeBlock, ViewDirectionBlock, FresnelBlock, MaxBlock, MinBlock, NodeMaterialOptimizer, VertexOutputBlock, BonesBlock, InstancesBlock, MorphTargetsBlock, LightInformationBlock, FragmentOutputBlock, AlphaTestBlock, ImageProcessingBlock, PerturbNormalBlock, FogBlock, LightBlock, TextureBlock, ReflectionTextureBlock, InputBlock, AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Background_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Background/index */ "./Materials/Background/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackgroundMaterial", function() { return _Background_index__WEBPACK_IMPORTED_MODULE_0__["BackgroundMaterial"]; });

/* harmony import */ var _colorCurves__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./colorCurves */ "./Materials/colorCurves.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorCurves", function() { return _colorCurves__WEBPACK_IMPORTED_MODULE_1__["ColorCurves"]; });

/* harmony import */ var _effect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./effect */ "./Materials/effect.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectFallbacks", function() { return _effect__WEBPACK_IMPORTED_MODULE_2__["EffectFallbacks"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectCreationOptions", function() { return _effect__WEBPACK_IMPORTED_MODULE_2__["EffectCreationOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Effect", function() { return _effect__WEBPACK_IMPORTED_MODULE_2__["Effect"]; });

/* harmony import */ var _fresnelParameters__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fresnelParameters */ "./Materials/fresnelParameters.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelParameters", function() { return _fresnelParameters__WEBPACK_IMPORTED_MODULE_3__["FresnelParameters"]; });

/* harmony import */ var _imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfigurationDefines", function() { return _imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_4__["ImageProcessingConfigurationDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfiguration", function() { return _imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_4__["ImageProcessingConfiguration"]; });

/* harmony import */ var _material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./material */ "./Materials/material.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Material", function() { return _material__WEBPACK_IMPORTED_MODULE_5__["Material"]; });

/* harmony import */ var _materialDefines__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./materialDefines */ "./Materials/materialDefines.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialDefines", function() { return _materialDefines__WEBPACK_IMPORTED_MODULE_6__["MaterialDefines"]; });

/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./materialHelper */ "./Materials/materialHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialHelper", function() { return _materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"]; });

/* harmony import */ var _multiMaterial__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./multiMaterial */ "./Materials/multiMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiMaterial", function() { return _multiMaterial__WEBPACK_IMPORTED_MODULE_8__["MultiMaterial"]; });

/* harmony import */ var _PBR_index__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./PBR/index */ "./Materials/PBR/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterialDefines", function() { return _PBR_index__WEBPACK_IMPORTED_MODULE_9__["PBRMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseMaterial", function() { return _PBR_index__WEBPACK_IMPORTED_MODULE_9__["PBRBaseMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseSimpleMaterial", function() { return _PBR_index__WEBPACK_IMPORTED_MODULE_9__["PBRBaseSimpleMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterial", function() { return _PBR_index__WEBPACK_IMPORTED_MODULE_9__["PBRMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMetallicRoughnessMaterial", function() { return _PBR_index__WEBPACK_IMPORTED_MODULE_9__["PBRMetallicRoughnessMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRSpecularGlossinessMaterial", function() { return _PBR_index__WEBPACK_IMPORTED_MODULE_9__["PBRSpecularGlossinessMaterial"]; });

/* harmony import */ var _pushMaterial__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./pushMaterial */ "./Materials/pushMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PushMaterial", function() { return _pushMaterial__WEBPACK_IMPORTED_MODULE_10__["PushMaterial"]; });

/* harmony import */ var _shaderMaterial__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./shaderMaterial */ "./Materials/shaderMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShaderMaterial", function() { return _shaderMaterial__WEBPACK_IMPORTED_MODULE_11__["ShaderMaterial"]; });

/* harmony import */ var _standardMaterial__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardMaterialDefines", function() { return _standardMaterial__WEBPACK_IMPORTED_MODULE_12__["StandardMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardMaterial", function() { return _standardMaterial__WEBPACK_IMPORTED_MODULE_12__["StandardMaterial"]; });

/* harmony import */ var _Textures_index__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Textures/index */ "./Materials/Textures/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["BaseTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["CubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DynamicTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["DynamicTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["EquiRectangularCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["HDRCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InternalTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["InternalTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MirrorTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["MirrorTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiRenderTarget", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["MultiRenderTarget"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["RawTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["RenderTargetTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Texture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["Texture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradingTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["ColorGradingTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawCubeTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["RawCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture3D", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["RawTexture3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["RefractionTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["VideoTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HtmlElementTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["HtmlElementTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DDSTextureLoader", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["_DDSTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_ENVTextureLoader", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["_ENVTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_KTXTextureLoader", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["_KTXTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TGATextureLoader", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["_TGATextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BasisTextureLoader", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["_BasisTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomProceduralTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["CustomProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NoiseProceduralTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["NoiseProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTexture", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["ProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTextureSceneComponent", function() { return _Textures_index__WEBPACK_IMPORTED_MODULE_13__["ProceduralTextureSceneComponent"]; });

/* harmony import */ var _uniformBuffer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./uniformBuffer */ "./Materials/uniformBuffer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UniformBuffer", function() { return _uniformBuffer__WEBPACK_IMPORTED_MODULE_14__["UniformBuffer"]; });

/* harmony import */ var _materialFlags__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./materialFlags */ "./Materials/materialFlags.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialFlags", function() { return _materialFlags__WEBPACK_IMPORTED_MODULE_15__["MaterialFlags"]; });

/* harmony import */ var _Node_index__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Node/index */ "./Materials/Node/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockTargets", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialBlockTargets"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockConnectionPointTypes", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialBlockConnectionPointTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialConnectionPoint", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialConnectionPoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialDefines", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterial", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialSystemValues", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialSystemValues"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["MultiplyBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AddBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["AddBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ScaleBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClampBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ClampBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CrossBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["CrossBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DotBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["DotBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["TransformBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RemapBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["RemapBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NormalizeBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NormalizeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlockOperations", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["TrigonometryBlockOperations"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["TrigonometryBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorMergerBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ColorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorMergerBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["VectorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorSplitterBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ColorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorSplitterBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["VectorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LerpBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["LerpBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DivideBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["DivideBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubtractBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["SubtractBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StepBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["StepBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OppositeBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["OppositeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViewDirectionBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ViewDirectionBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["FresnelBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaxBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["MaxBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MinBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["MinBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialOptimizer", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["NodeMaterialOptimizer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["VertexOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["BonesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["InstancesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["MorphTargetsBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["LightInformationBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["FragmentOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["AlphaTestBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ImageProcessingBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["PerturbNormalBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["FogBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["LightBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["TextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["ReflectionTextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["InputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return _Node_index__WEBPACK_IMPORTED_MODULE_16__["AnimatedInputBlockTypes"]; });

/* harmony import */ var _effectRenderer__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./effectRenderer */ "./Materials/effectRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectRenderer", function() { return _effectRenderer__WEBPACK_IMPORTED_MODULE_17__["EffectRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectWrapper", function() { return _effectRenderer__WEBPACK_IMPORTED_MODULE_17__["EffectWrapper"]; });





















/***/ }),

/***/ "./Materials/material.ts":
/*!*******************************!*\
  !*** ./Materials/material.ts ***!
  \*******************************/
/*! exports provided: Material */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Material", function() { return Material; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/subMesh */ "./Meshes/subMesh.ts");
/* harmony import */ var _uniformBuffer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./uniformBuffer */ "./Materials/uniformBuffer.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_plane__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Maths/math.plane */ "./Maths/math.plane.ts");










/**
 * Base class for the main features of a material in Babylon.js
 */
var Material = /** @class */ (function () {
    /**
     * Creates a material instance
     * @param name defines the name of the material
     * @param scene defines the scene to reference
     * @param doNotAdd specifies if the material should be added to the scene
     */
    function Material(name, scene, doNotAdd) {
        /**
         * Gets or sets user defined metadata
         */
        this.metadata = null;
        /**
         * For internal use only. Please do not use.
         */
        this.reservedDataStore = null;
        /**
         * Specifies if the ready state should be checked on each call
         */
        this.checkReadyOnEveryCall = false;
        /**
         * Specifies if the ready state should be checked once
         */
        this.checkReadyOnlyOnce = false;
        /**
         * The state of the material
         */
        this.state = "";
        /**
         * The alpha value of the material
         */
        this._alpha = 1.0;
        /**
         * Specifies if back face culling is enabled
         */
        this._backFaceCulling = true;
        /**
         * Callback triggered when the material is compiled
         */
        this.onCompiled = null;
        /**
         * Callback triggered when an error occurs
         */
        this.onError = null;
        /**
         * Callback triggered to get the render target textures
         */
        this.getRenderTargetTextures = null;
        /**
         * Specifies if the material should be serialized
         */
        this.doNotSerialize = false;
        /**
         * @hidden
         */
        this._storeEffectOnSubMeshes = false;
        /**
         * Stores the animations for the material
         */
        this.animations = null;
        /**
        * An event triggered when the material is disposed
        */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An observer which watches for dispose events
         */
        this._onDisposeObserver = null;
        this._onUnBindObservable = null;
        /**
         * An observer which watches for bind events
         */
        this._onBindObserver = null;
        /**
         * Stores the value of the alpha mode
         */
        this._alphaMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].ALPHA_COMBINE;
        /**
         * Stores the state of the need depth pre-pass value
         */
        this._needDepthPrePass = false;
        /**
         * Specifies if depth writing should be disabled
         */
        this.disableDepthWrite = false;
        /**
         * Specifies if depth writing should be forced
         */
        this.forceDepthWrite = false;
        /**
         * Specifies if there should be a separate pass for culling
         */
        this.separateCullingPass = false;
        /**
         * Stores the state specifing if fog should be enabled
         */
        this._fogEnabled = true;
        /**
         * Stores the size of points
         */
        this.pointSize = 1.0;
        /**
         * Stores the z offset value
         */
        this.zOffset = 0;
        /**
         * @hidden
         * Stores the effects for the material
         */
        this._effect = null;
        /**
         * @hidden
         * Specifies if the material was previously ready
         */
        this._wasPreviouslyReady = false;
        /**
         * Specifies if uniform buffers should be used
         */
        this._useUBO = false;
        /**
         * Stores the fill mode state
         */
        this._fillMode = Material.TriangleFillMode;
        /**
         * Specifies if the depth write state should be cached
         */
        this._cachedDepthWriteState = false;
        /** @hidden */
        this._indexInSceneMaterialArray = -1;
        /** @hidden */
        this.meshMap = null;
        this.name = name;
        this.id = name || _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].RandomId();
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene;
        this.uniqueId = this._scene.getUniqueId();
        if (this._scene.useRightHandedSystem) {
            this.sideOrientation = Material.ClockWiseSideOrientation;
        }
        else {
            this.sideOrientation = Material.CounterClockWiseSideOrientation;
        }
        this._uniformBuffer = new _uniformBuffer__WEBPACK_IMPORTED_MODULE_6__["UniformBuffer"](this._scene.getEngine());
        this._useUBO = this.getScene().getEngine().supportsUniformBuffers;
        if (!doNotAdd) {
            this._scene.addMaterial(this);
        }
        if (this._scene.useMaterialMeshMap) {
            this.meshMap = {};
        }
    }
    Object.defineProperty(Material.prototype, "alpha", {
        /**
         * Gets the alpha value of the material
         */
        get: function () {
            return this._alpha;
        },
        /**
         * Sets the alpha value of the material
         */
        set: function (value) {
            if (this._alpha === value) {
                return;
            }
            this._alpha = value;
            this.markAsDirty(Material.MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "backFaceCulling", {
        /**
         * Gets the back-face culling state
         */
        get: function () {
            return this._backFaceCulling;
        },
        /**
         * Sets the back-face culling state
         */
        set: function (value) {
            if (this._backFaceCulling === value) {
                return;
            }
            this._backFaceCulling = value;
            this.markAsDirty(Material.TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "hasRenderTargetTextures", {
        /**
         * Gets a boolean indicating that current material needs to register RTT
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "onDispose", {
        /**
         * Called during a dispose event
         */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "onBindObservable", {
        /**
        * An event triggered when the material is bound
        */
        get: function () {
            if (!this._onBindObservable) {
                this._onBindObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
            }
            return this._onBindObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "onBind", {
        /**
         * Called during a bind event
         */
        set: function (callback) {
            if (this._onBindObserver) {
                this.onBindObservable.remove(this._onBindObserver);
            }
            this._onBindObserver = this.onBindObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "onUnBindObservable", {
        /**
        * An event triggered when the material is unbound
        */
        get: function () {
            if (!this._onUnBindObservable) {
                this._onUnBindObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
            }
            return this._onUnBindObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "alphaMode", {
        /**
         * Gets the value of the alpha mode
         */
        get: function () {
            return this._alphaMode;
        },
        /**
         * Sets the value of the alpha mode.
         *
         * | Value | Type | Description |
         * | --- | --- | --- |
         * | 0 | ALPHA_DISABLE |   |
         * | 1 | ALPHA_ADD |   |
         * | 2 | ALPHA_COMBINE |   |
         * | 3 | ALPHA_SUBTRACT |   |
         * | 4 | ALPHA_MULTIPLY |   |
         * | 5 | ALPHA_MAXIMIZED |   |
         * | 6 | ALPHA_ONEONE |   |
         * | 7 | ALPHA_PREMULTIPLIED |   |
         * | 8 | ALPHA_PREMULTIPLIED_PORTERDUFF |   |
         * | 9 | ALPHA_INTERPOLATE |   |
         * | 10 | ALPHA_SCREENMODE |   |
         *
         */
        set: function (value) {
            if (this._alphaMode === value) {
                return;
            }
            this._alphaMode = value;
            this.markAsDirty(Material.TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "needDepthPrePass", {
        /**
         * Gets the depth pre-pass value
         */
        get: function () {
            return this._needDepthPrePass;
        },
        /**
         * Sets the need depth pre-pass value
         */
        set: function (value) {
            if (this._needDepthPrePass === value) {
                return;
            }
            this._needDepthPrePass = value;
            if (this._needDepthPrePass) {
                this.checkReadyOnEveryCall = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "fogEnabled", {
        /**
         * Gets the value of the fog enabled state
         */
        get: function () {
            return this._fogEnabled;
        },
        /**
         * Sets the state for enabling fog
         */
        set: function (value) {
            if (this._fogEnabled === value) {
                return;
            }
            this._fogEnabled = value;
            this.markAsDirty(Material.MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "wireframe", {
        /**
         * Gets a value specifying if wireframe mode is enabled
         */
        get: function () {
            switch (this._fillMode) {
                case Material.WireFrameFillMode:
                case Material.LineListDrawMode:
                case Material.LineLoopDrawMode:
                case Material.LineStripDrawMode:
                    return true;
            }
            return this._scene.forceWireframe;
        },
        /**
         * Sets the state of wireframe mode
         */
        set: function (value) {
            this.fillMode = (value ? Material.WireFrameFillMode : Material.TriangleFillMode);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "pointsCloud", {
        /**
         * Gets the value specifying if point clouds are enabled
         */
        get: function () {
            switch (this._fillMode) {
                case Material.PointFillMode:
                case Material.PointListDrawMode:
                    return true;
            }
            return this._scene.forcePointsCloud;
        },
        /**
         * Sets the state of point cloud mode
         */
        set: function (value) {
            this.fillMode = (value ? Material.PointFillMode : Material.TriangleFillMode);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Material.prototype, "fillMode", {
        /**
         * Gets the material fill mode
         */
        get: function () {
            return this._fillMode;
        },
        /**
         * Sets the material fill mode
         */
        set: function (value) {
            if (this._fillMode === value) {
                return;
            }
            this._fillMode = value;
            this.markAsDirty(Material.MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns a string representation of the current material
     * @param fullDetails defines a boolean indicating which levels of logging is desired
     * @returns a string with material information
     */
    Material.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name;
        if (fullDetails) {
        }
        return ret;
    };
    /**
     * Gets the class name of the material
     * @returns a string with the class name of the material
     */
    Material.prototype.getClassName = function () {
        return "Material";
    };
    Object.defineProperty(Material.prototype, "isFrozen", {
        /**
         * Specifies if updates for the material been locked
         */
        get: function () {
            return this.checkReadyOnlyOnce;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Locks updates for the material
     */
    Material.prototype.freeze = function () {
        this.checkReadyOnlyOnce = true;
    };
    /**
     * Unlocks updates for the material
     */
    Material.prototype.unfreeze = function () {
        this.checkReadyOnlyOnce = false;
    };
    /**
     * Specifies if the material is ready to be used
     * @param mesh defines the mesh to check
     * @param useInstances specifies if instances should be used
     * @returns a boolean indicating if the material is ready to be used
     */
    Material.prototype.isReady = function (mesh, useInstances) {
        return true;
    };
    /**
     * Specifies that the submesh is ready to be used
     * @param mesh defines the mesh to check
     * @param subMesh defines which submesh to check
     * @param useInstances specifies that instances should be used
     * @returns a boolean indicating that the submesh is ready or not
     */
    Material.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        return false;
    };
    /**
     * Returns the material effect
     * @returns the effect associated with the material
     */
    Material.prototype.getEffect = function () {
        return this._effect;
    };
    /**
     * Returns the current scene
     * @returns a Scene
     */
    Material.prototype.getScene = function () {
        return this._scene;
    };
    /**
     * Specifies if the material will require alpha blending
     * @returns a boolean specifying if alpha blending is needed
     */
    Material.prototype.needAlphaBlending = function () {
        return (this.alpha < 1.0);
    };
    /**
     * Specifies if the mesh will require alpha blending
     * @param mesh defines the mesh to check
     * @returns a boolean specifying if alpha blending is needed for the mesh
     */
    Material.prototype.needAlphaBlendingForMesh = function (mesh) {
        return this.needAlphaBlending() || (mesh.visibility < 1.0) || mesh.hasVertexAlpha;
    };
    /**
     * Specifies if this material should be rendered in alpha test mode
     * @returns a boolean specifying if an alpha test is needed.
     */
    Material.prototype.needAlphaTesting = function () {
        return false;
    };
    /**
     * Gets the texture used for the alpha test
     * @returns the texture to use for alpha testing
     */
    Material.prototype.getAlphaTestTexture = function () {
        return null;
    };
    /**
     * Marks the material to indicate that it needs to be re-calculated
     */
    Material.prototype.markDirty = function () {
        this._wasPreviouslyReady = false;
    };
    /** @hidden */
    Material.prototype._preBind = function (effect, overrideOrientation) {
        if (overrideOrientation === void 0) { overrideOrientation = null; }
        var engine = this._scene.getEngine();
        var orientation = (overrideOrientation == null) ? this.sideOrientation : overrideOrientation;
        var reverse = orientation === Material.ClockWiseSideOrientation;
        engine.enableEffect(effect ? effect : this._effect);
        engine.setState(this.backFaceCulling, this.zOffset, false, reverse);
        return reverse;
    };
    /**
     * Binds the material to the mesh
     * @param world defines the world transformation matrix
     * @param mesh defines the mesh to bind the material to
     */
    Material.prototype.bind = function (world, mesh) {
    };
    /**
     * Binds the submesh to the material
     * @param world defines the world transformation matrix
     * @param mesh defines the mesh containing the submesh
     * @param subMesh defines the submesh to bind the material to
     */
    Material.prototype.bindForSubMesh = function (world, mesh, subMesh) {
    };
    /**
     * Binds the world matrix to the material
     * @param world defines the world transformation matrix
     */
    Material.prototype.bindOnlyWorldMatrix = function (world) {
    };
    /**
     * Binds the scene's uniform buffer to the effect.
     * @param effect defines the effect to bind to the scene uniform buffer
     * @param sceneUbo defines the uniform buffer storing scene data
     */
    Material.prototype.bindSceneUniformBuffer = function (effect, sceneUbo) {
        sceneUbo.bindToEffect(effect, "Scene");
    };
    /**
     * Binds the view matrix to the effect
     * @param effect defines the effect to bind the view matrix to
     */
    Material.prototype.bindView = function (effect) {
        if (!this._useUBO) {
            effect.setMatrix("view", this.getScene().getViewMatrix());
        }
        else {
            this.bindSceneUniformBuffer(effect, this.getScene().getSceneUniformBuffer());
        }
    };
    /**
     * Binds the view projection matrix to the effect
     * @param effect defines the effect to bind the view projection matrix to
     */
    Material.prototype.bindViewProjection = function (effect) {
        if (!this._useUBO) {
            effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
        }
        else {
            this.bindSceneUniformBuffer(effect, this.getScene().getSceneUniformBuffer());
        }
    };
    /**
     * Specifies if material alpha testing should be turned on for the mesh
     * @param mesh defines the mesh to check
     */
    Material.prototype._shouldTurnAlphaTestOn = function (mesh) {
        return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
    };
    /**
     * Processes to execute after binding the material to a mesh
     * @param mesh defines the rendered mesh
     */
    Material.prototype._afterBind = function (mesh) {
        this._scene._cachedMaterial = this;
        if (mesh) {
            this._scene._cachedVisibility = mesh.visibility;
        }
        else {
            this._scene._cachedVisibility = 1;
        }
        if (this._onBindObservable && mesh) {
            this._onBindObservable.notifyObservers(mesh);
        }
        if (this.disableDepthWrite) {
            var engine = this._scene.getEngine();
            this._cachedDepthWriteState = engine.getDepthWrite();
            engine.setDepthWrite(false);
        }
    };
    /**
     * Unbinds the material from the mesh
     */
    Material.prototype.unbind = function () {
        if (this._onUnBindObservable) {
            this._onUnBindObservable.notifyObservers(this);
        }
        if (this.disableDepthWrite) {
            var engine = this._scene.getEngine();
            engine.setDepthWrite(this._cachedDepthWriteState);
        }
    };
    /**
     * Gets the active textures from the material
     * @returns an array of textures
     */
    Material.prototype.getActiveTextures = function () {
        return [];
    };
    /**
     * Specifies if the material uses a texture
     * @param texture defines the texture to check against the material
     * @returns a boolean specifying if the material uses the texture
     */
    Material.prototype.hasTexture = function (texture) {
        return false;
    };
    /**
     * Makes a duplicate of the material, and gives it a new name
     * @param name defines the new name for the duplicated material
     * @returns the cloned material
     */
    Material.prototype.clone = function (name) {
        return null;
    };
    /**
     * Gets the meshes bound to the material
     * @returns an array of meshes bound to the material
     */
    Material.prototype.getBindedMeshes = function () {
        var _this = this;
        if (this.meshMap) {
            var result = new Array();
            for (var meshId in this.meshMap) {
                var mesh = this.meshMap[meshId];
                if (mesh) {
                    result.push(mesh);
                }
            }
            return result;
        }
        else {
            var meshes = this._scene.meshes;
            return meshes.filter(function (mesh) { return mesh.material === _this; });
        }
    };
    /**
     * Force shader compilation
     * @param mesh defines the mesh associated with this material
     * @param onCompiled defines a function to execute once the material is compiled
     * @param options defines the options to configure the compilation
     */
    Material.prototype.forceCompilation = function (mesh, onCompiled, options) {
        var _this = this;
        var localOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ clipPlane: false }, options);
        var subMesh = new _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_5__["BaseSubMesh"]();
        var scene = this.getScene();
        var checkReady = function () {
            if (!_this._scene || !_this._scene.getEngine()) {
                return;
            }
            if (subMesh._materialDefines) {
                subMesh._materialDefines._renderId = -1;
            }
            var clipPlaneState = scene.clipPlane;
            if (localOptions.clipPlane) {
                scene.clipPlane = new _Maths_math_plane__WEBPACK_IMPORTED_MODULE_9__["Plane"](0, 0, 0, 1);
            }
            if (_this._storeEffectOnSubMeshes) {
                if (_this.isReadyForSubMesh(mesh, subMesh)) {
                    if (onCompiled) {
                        onCompiled(_this);
                    }
                }
                else {
                    setTimeout(checkReady, 16);
                }
            }
            else {
                if (_this.isReady()) {
                    if (onCompiled) {
                        onCompiled(_this);
                    }
                }
                else {
                    setTimeout(checkReady, 16);
                }
            }
            if (localOptions.clipPlane) {
                scene.clipPlane = clipPlaneState;
            }
        };
        checkReady();
    };
    /**
     * Force shader compilation
     * @param mesh defines the mesh that will use this material
     * @param options defines additional options for compiling the shaders
     * @returns a promise that resolves when the compilation completes
     */
    Material.prototype.forceCompilationAsync = function (mesh, options) {
        var _this = this;
        return new Promise(function (resolve) {
            _this.forceCompilation(mesh, function () {
                resolve();
            }, options);
        });
    };
    /**
     * Marks a define in the material to indicate that it needs to be re-computed
     * @param flag defines a flag used to determine which parts of the material have to be marked as dirty
     */
    Material.prototype.markAsDirty = function (flag) {
        if (this.getScene().blockMaterialDirtyMechanism) {
            return;
        }
        Material._DirtyCallbackArray.length = 0;
        if (flag & Material.TextureDirtyFlag) {
            Material._DirtyCallbackArray.push(Material._TextureDirtyCallBack);
        }
        if (flag & Material.LightDirtyFlag) {
            Material._DirtyCallbackArray.push(Material._LightsDirtyCallBack);
        }
        if (flag & Material.FresnelDirtyFlag) {
            Material._DirtyCallbackArray.push(Material._FresnelDirtyCallBack);
        }
        if (flag & Material.AttributesDirtyFlag) {
            Material._DirtyCallbackArray.push(Material._AttributeDirtyCallBack);
        }
        if (flag & Material.MiscDirtyFlag) {
            Material._DirtyCallbackArray.push(Material._MiscDirtyCallBack);
        }
        if (Material._DirtyCallbackArray.length) {
            this._markAllSubMeshesAsDirty(Material._RunDirtyCallBacks);
        }
        this.getScene().resetCachedMaterial();
    };
    /**
     * Marks all submeshes of a material to indicate that their material defines need to be re-calculated
     * @param func defines a function which checks material defines against the submeshes
     */
    Material.prototype._markAllSubMeshesAsDirty = function (func) {
        if (this.getScene().blockMaterialDirtyMechanism) {
            return;
        }
        var meshes = this.getScene().meshes;
        for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
            var mesh = meshes_1[_i];
            if (!mesh.subMeshes) {
                continue;
            }
            for (var _a = 0, _b = mesh.subMeshes; _a < _b.length; _a++) {
                var subMesh = _b[_a];
                if (subMesh.getMaterial() !== this) {
                    continue;
                }
                if (!subMesh._materialDefines) {
                    continue;
                }
                func(subMesh._materialDefines);
            }
        }
    };
    /**
 * Indicates that we need to re-calculated for all submeshes
 */
    Material.prototype._markAllSubMeshesAsAllDirty = function () {
        this._markAllSubMeshesAsDirty(Material._AllDirtyCallBack);
    };
    /**
     * Indicates that image processing needs to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsImageProcessingDirty = function () {
        this._markAllSubMeshesAsDirty(Material._ImageProcessingDirtyCallBack);
    };
    /**
     * Indicates that textures need to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsTexturesDirty = function () {
        this._markAllSubMeshesAsDirty(Material._TextureDirtyCallBack);
    };
    /**
     * Indicates that fresnel needs to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsFresnelDirty = function () {
        this._markAllSubMeshesAsDirty(Material._FresnelDirtyCallBack);
    };
    /**
     * Indicates that fresnel and misc need to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsFresnelAndMiscDirty = function () {
        this._markAllSubMeshesAsDirty(Material._FresnelAndMiscDirtyCallBack);
    };
    /**
     * Indicates that lights need to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsLightsDirty = function () {
        this._markAllSubMeshesAsDirty(Material._LightsDirtyCallBack);
    };
    /**
     * Indicates that attributes need to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsAttributesDirty = function () {
        this._markAllSubMeshesAsDirty(Material._AttributeDirtyCallBack);
    };
    /**
     * Indicates that misc needs to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsMiscDirty = function () {
        this._markAllSubMeshesAsDirty(Material._MiscDirtyCallBack);
    };
    /**
     * Indicates that textures and misc need to be re-calculated for all submeshes
     */
    Material.prototype._markAllSubMeshesAsTexturesAndMiscDirty = function () {
        this._markAllSubMeshesAsDirty(Material._TextureAndMiscDirtyCallBack);
    };
    /**
     * Disposes the material
     * @param forceDisposeEffect specifies if effects should be forcefully disposed
     * @param forceDisposeTextures specifies if textures should be forcefully disposed
     * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh
     */
    Material.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures, notBoundToMesh) {
        var scene = this.getScene();
        // Animations
        scene.stopAnimation(this);
        scene.freeProcessedMaterials();
        // Remove from scene
        scene.removeMaterial(this);
        if (notBoundToMesh !== true) {
            // Remove from meshes
            if (this.meshMap) {
                for (var meshId in this.meshMap) {
                    var mesh = this.meshMap[meshId];
                    if (mesh) {
                        mesh.material = null; // will set the entry in the map to undefined
                        this.releaseVertexArrayObject(mesh, forceDisposeEffect);
                    }
                }
            }
            else {
                var meshes = scene.meshes;
                for (var _i = 0, meshes_2 = meshes; _i < meshes_2.length; _i++) {
                    var mesh = meshes_2[_i];
                    if (mesh.material === this && !mesh.sourceMesh) {
                        mesh.material = null;
                        this.releaseVertexArrayObject(mesh, forceDisposeEffect);
                    }
                }
            }
        }
        this._uniformBuffer.dispose();
        // Shader are kept in cache for further use but we can get rid of this by using forceDisposeEffect
        if (forceDisposeEffect && this._effect) {
            if (!this._storeEffectOnSubMeshes) {
                this._effect.dispose();
            }
            this._effect = null;
        }
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
        if (this._onBindObservable) {
            this._onBindObservable.clear();
        }
        if (this._onUnBindObservable) {
            this._onUnBindObservable.clear();
        }
    };
    /** @hidden */
    Material.prototype.releaseVertexArrayObject = function (mesh, forceDisposeEffect) {
        if (mesh.geometry) {
            var geometry = (mesh.geometry);
            if (this._storeEffectOnSubMeshes) {
                for (var _i = 0, _a = mesh.subMeshes; _i < _a.length; _i++) {
                    var subMesh = _a[_i];
                    geometry._releaseVertexArrayObject(subMesh._materialEffect);
                    if (forceDisposeEffect && subMesh._materialEffect) {
                        subMesh._materialEffect.dispose();
                    }
                }
            }
            else {
                geometry._releaseVertexArrayObject(this._effect);
            }
        }
    };
    /**
     * Serializes this material
     * @returns the serialized material object
     */
    Material.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Creates a material from parsed material data
     * @param parsedMaterial defines parsed material data
     * @param scene defines the hosting scene
     * @param rootUrl defines the root URL to use to load textures
     * @returns a new material
     */
    Material.Parse = function (parsedMaterial, scene, rootUrl) {
        if (!parsedMaterial.customType) {
            parsedMaterial.customType = "BABYLON.StandardMaterial";
        }
        else if (parsedMaterial.customType === "BABYLON.PBRMaterial" && parsedMaterial.overloadedAlbedo) {
            parsedMaterial.customType = "BABYLON.LegacyPBRMaterial";
            if (!BABYLON.LegacyPBRMaterial) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_8__["Logger"].Error("Your scene is trying to load a legacy version of the PBRMaterial, please, include it from the materials library.");
                return null;
            }
        }
        var materialType = _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].Instantiate(parsedMaterial.customType);
        return materialType.Parse(parsedMaterial, scene, rootUrl);
    };
    /**
     * Returns the triangle fill mode
     */
    Material.TriangleFillMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleFillMode;
    /**
     * Returns the wireframe mode
     */
    Material.WireFrameFillMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_WireFrameFillMode;
    /**
     * Returns the point fill mode
     */
    Material.PointFillMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_PointFillMode;
    /**
     * Returns the point list draw mode
     */
    Material.PointListDrawMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_PointListDrawMode;
    /**
     * Returns the line list draw mode
     */
    Material.LineListDrawMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LineListDrawMode;
    /**
     * Returns the line loop draw mode
     */
    Material.LineLoopDrawMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LineLoopDrawMode;
    /**
     * Returns the line strip draw mode
     */
    Material.LineStripDrawMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LineStripDrawMode;
    /**
     * Returns the triangle strip draw mode
     */
    Material.TriangleStripDrawMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleStripDrawMode;
    /**
     * Returns the triangle fan draw mode
     */
    Material.TriangleFanDrawMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TriangleFanDrawMode;
    /**
     * Stores the clock-wise side orientation
     */
    Material.ClockWiseSideOrientation = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_ClockWiseSideOrientation;
    /**
     * Stores the counter clock-wise side orientation
     */
    Material.CounterClockWiseSideOrientation = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_CounterClockWiseSideOrientation;
    /**
     * The dirty texture flag value
     */
    Material.TextureDirtyFlag = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_TextureDirtyFlag;
    /**
     * The dirty light flag value
     */
    Material.LightDirtyFlag = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_LightDirtyFlag;
    /**
     * The dirty fresnel flag value
     */
    Material.FresnelDirtyFlag = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_FresnelDirtyFlag;
    /**
     * The dirty attribute flag value
     */
    Material.AttributesDirtyFlag = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_AttributesDirtyFlag;
    /**
     * The dirty misc flag value
     */
    Material.MiscDirtyFlag = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_MiscDirtyFlag;
    /**
     * The all dirty flag value
     */
    Material.AllDirtyFlag = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].MATERIAL_AllDirtyFlag;
    Material._AllDirtyCallBack = function (defines) { return defines.markAllAsDirty(); };
    Material._ImageProcessingDirtyCallBack = function (defines) { return defines.markAsImageProcessingDirty(); };
    Material._TextureDirtyCallBack = function (defines) { return defines.markAsTexturesDirty(); };
    Material._FresnelDirtyCallBack = function (defines) { return defines.markAsFresnelDirty(); };
    Material._MiscDirtyCallBack = function (defines) { return defines.markAsMiscDirty(); };
    Material._LightsDirtyCallBack = function (defines) { return defines.markAsLightDirty(); };
    Material._AttributeDirtyCallBack = function (defines) { return defines.markAsAttributesDirty(); };
    Material._FresnelAndMiscDirtyCallBack = function (defines) {
        Material._FresnelDirtyCallBack(defines);
        Material._MiscDirtyCallBack(defines);
    };
    Material._TextureAndMiscDirtyCallBack = function (defines) {
        Material._TextureDirtyCallBack(defines);
        Material._MiscDirtyCallBack(defines);
    };
    Material._DirtyCallbackArray = [];
    Material._RunDirtyCallBacks = function (defines) {
        for (var _i = 0, _a = Material._DirtyCallbackArray; _i < _a.length; _i++) {
            var cb = _a[_i];
            cb(defines);
        }
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "id", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "uniqueId", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "name", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "checkReadyOnEveryCall", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "checkReadyOnlyOnce", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "state", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("alpha")
    ], Material.prototype, "_alpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("backFaceCulling")
    ], Material.prototype, "_backFaceCulling", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "sideOrientation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("alphaMode")
    ], Material.prototype, "_alphaMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "_needDepthPrePass", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "disableDepthWrite", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "forceDepthWrite", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "separateCullingPass", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("fogEnabled")
    ], Material.prototype, "_fogEnabled", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "pointSize", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "zOffset", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "wireframe", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "pointsCloud", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], Material.prototype, "fillMode", null);
    return Material;
}());



/***/ }),

/***/ "./Materials/materialDefines.ts":
/*!**************************************!*\
  !*** ./Materials/materialDefines.ts ***!
  \**************************************/
/*! exports provided: MaterialDefines */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MaterialDefines", function() { return MaterialDefines; });
/**
 * Manages the defines for the Material
 */
var MaterialDefines = /** @class */ (function () {
    function MaterialDefines() {
        this._isDirty = true;
        /** @hidden */
        this._areLightsDirty = true;
        /** @hidden */
        this._areLightsDisposed = false;
        /** @hidden */
        this._areAttributesDirty = true;
        /** @hidden */
        this._areTexturesDirty = true;
        /** @hidden */
        this._areFresnelDirty = true;
        /** @hidden */
        this._areMiscDirty = true;
        /** @hidden */
        this._areImageProcessingDirty = true;
        /** @hidden */
        this._normals = false;
        /** @hidden */
        this._uvs = false;
        /** @hidden */
        this._needNormals = false;
        /** @hidden */
        this._needUVs = false;
    }
    Object.defineProperty(MaterialDefines.prototype, "isDirty", {
        /**
         * Specifies if the material needs to be re-calculated
         */
        get: function () {
            return this._isDirty;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Marks the material to indicate that it has been re-calculated
     */
    MaterialDefines.prototype.markAsProcessed = function () {
        this._isDirty = false;
        this._areAttributesDirty = false;
        this._areTexturesDirty = false;
        this._areFresnelDirty = false;
        this._areLightsDirty = false;
        this._areLightsDisposed = false;
        this._areMiscDirty = false;
        this._areImageProcessingDirty = false;
    };
    /**
     * Marks the material to indicate that it needs to be re-calculated
     */
    MaterialDefines.prototype.markAsUnprocessed = function () {
        this._isDirty = true;
    };
    /**
     * Marks the material to indicate all of its defines need to be re-calculated
     */
    MaterialDefines.prototype.markAllAsDirty = function () {
        this._areTexturesDirty = true;
        this._areAttributesDirty = true;
        this._areLightsDirty = true;
        this._areFresnelDirty = true;
        this._areMiscDirty = true;
        this._areImageProcessingDirty = true;
        this._isDirty = true;
    };
    /**
     * Marks the material to indicate that image processing needs to be re-calculated
     */
    MaterialDefines.prototype.markAsImageProcessingDirty = function () {
        this._areImageProcessingDirty = true;
        this._isDirty = true;
    };
    /**
     * Marks the material to indicate the lights need to be re-calculated
     * @param disposed Defines whether the light is dirty due to dispose or not
     */
    MaterialDefines.prototype.markAsLightDirty = function (disposed) {
        if (disposed === void 0) { disposed = false; }
        this._areLightsDirty = true;
        this._areLightsDisposed = this._areLightsDisposed || disposed;
        this._isDirty = true;
    };
    /**
     * Marks the attribute state as changed
     */
    MaterialDefines.prototype.markAsAttributesDirty = function () {
        this._areAttributesDirty = true;
        this._isDirty = true;
    };
    /**
     * Marks the texture state as changed
     */
    MaterialDefines.prototype.markAsTexturesDirty = function () {
        this._areTexturesDirty = true;
        this._isDirty = true;
    };
    /**
     * Marks the fresnel state as changed
     */
    MaterialDefines.prototype.markAsFresnelDirty = function () {
        this._areFresnelDirty = true;
        this._isDirty = true;
    };
    /**
     * Marks the misc state as changed
     */
    MaterialDefines.prototype.markAsMiscDirty = function () {
        this._areMiscDirty = true;
        this._isDirty = true;
    };
    /**
     * Rebuilds the material defines
     */
    MaterialDefines.prototype.rebuild = function () {
        if (this._keys) {
            delete this._keys;
        }
        this._keys = [];
        for (var _i = 0, _a = Object.keys(this); _i < _a.length; _i++) {
            var key = _a[_i];
            if (key[0] === "_") {
                continue;
            }
            this._keys.push(key);
        }
    };
    /**
     * Specifies if two material defines are equal
     * @param other - A material define instance to compare to
     * @returns - Boolean indicating if the material defines are equal (true) or not (false)
     */
    MaterialDefines.prototype.isEqual = function (other) {
        if (this._keys.length !== other._keys.length) {
            return false;
        }
        for (var index = 0; index < this._keys.length; index++) {
            var prop = this._keys[index];
            if (this[prop] !== other[prop]) {
                return false;
            }
        }
        return true;
    };
    /**
     * Clones this instance's defines to another instance
     * @param other - material defines to clone values to
     */
    MaterialDefines.prototype.cloneTo = function (other) {
        if (this._keys.length !== other._keys.length) {
            other._keys = this._keys.slice(0);
        }
        for (var index = 0; index < this._keys.length; index++) {
            var prop = this._keys[index];
            other[prop] = this[prop];
        }
    };
    /**
     * Resets the material define values
     */
    MaterialDefines.prototype.reset = function () {
        for (var index = 0; index < this._keys.length; index++) {
            var prop = this._keys[index];
            var type = typeof this[prop];
            switch (type) {
                case "number":
                    this[prop] = 0;
                    break;
                case "string":
                    this[prop] = "";
                    break;
                default:
                    this[prop] = false;
                    break;
            }
        }
    };
    /**
     * Converts the material define values to a string
     * @returns - String of material define information
     */
    MaterialDefines.prototype.toString = function () {
        var result = "";
        for (var index = 0; index < this._keys.length; index++) {
            var prop = this._keys[index];
            var value = this[prop];
            var type = typeof value;
            switch (type) {
                case "number":
                case "string":
                    result += "#define " + prop + " " + value + "\n";
                    break;
                default:
                    if (value) {
                        result += "#define " + prop + "\n";
                    }
                    break;
            }
        }
        return result;
    };
    return MaterialDefines;
}());



/***/ }),

/***/ "./Materials/materialFlags.ts":
/*!************************************!*\
  !*** ./Materials/materialFlags.ts ***!
  \************************************/
/*! exports provided: MaterialFlags */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MaterialFlags", function() { return MaterialFlags; });
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");


/**
 * This groups all the flags used to control the materials channel.
 */
var MaterialFlags = /** @class */ (function () {
    function MaterialFlags() {
    }
    Object.defineProperty(MaterialFlags, "DiffuseTextureEnabled", {
        /**
         * Are diffuse textures enabled in the application.
         */
        get: function () {
            return this._DiffuseTextureEnabled;
        },
        set: function (value) {
            if (this._DiffuseTextureEnabled === value) {
                return;
            }
            this._DiffuseTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "AmbientTextureEnabled", {
        /**
         * Are ambient textures enabled in the application.
         */
        get: function () {
            return this._AmbientTextureEnabled;
        },
        set: function (value) {
            if (this._AmbientTextureEnabled === value) {
                return;
            }
            this._AmbientTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "OpacityTextureEnabled", {
        /**
         * Are opacity textures enabled in the application.
         */
        get: function () {
            return this._OpacityTextureEnabled;
        },
        set: function (value) {
            if (this._OpacityTextureEnabled === value) {
                return;
            }
            this._OpacityTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "ReflectionTextureEnabled", {
        /**
         * Are reflection textures enabled in the application.
         */
        get: function () {
            return this._ReflectionTextureEnabled;
        },
        set: function (value) {
            if (this._ReflectionTextureEnabled === value) {
                return;
            }
            this._ReflectionTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "EmissiveTextureEnabled", {
        /**
         * Are emissive textures enabled in the application.
         */
        get: function () {
            return this._EmissiveTextureEnabled;
        },
        set: function (value) {
            if (this._EmissiveTextureEnabled === value) {
                return;
            }
            this._EmissiveTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "SpecularTextureEnabled", {
        /**
         * Are specular textures enabled in the application.
         */
        get: function () {
            return this._SpecularTextureEnabled;
        },
        set: function (value) {
            if (this._SpecularTextureEnabled === value) {
                return;
            }
            this._SpecularTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "BumpTextureEnabled", {
        /**
         * Are bump textures enabled in the application.
         */
        get: function () {
            return this._BumpTextureEnabled;
        },
        set: function (value) {
            if (this._BumpTextureEnabled === value) {
                return;
            }
            this._BumpTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "LightmapTextureEnabled", {
        /**
         * Are lightmap textures enabled in the application.
         */
        get: function () {
            return this._LightmapTextureEnabled;
        },
        set: function (value) {
            if (this._LightmapTextureEnabled === value) {
                return;
            }
            this._LightmapTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "RefractionTextureEnabled", {
        /**
         * Are refraction textures enabled in the application.
         */
        get: function () {
            return this._RefractionTextureEnabled;
        },
        set: function (value) {
            if (this._RefractionTextureEnabled === value) {
                return;
            }
            this._RefractionTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "ColorGradingTextureEnabled", {
        /**
         * Are color grading textures enabled in the application.
         */
        get: function () {
            return this._ColorGradingTextureEnabled;
        },
        set: function (value) {
            if (this._ColorGradingTextureEnabled === value) {
                return;
            }
            this._ColorGradingTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "FresnelEnabled", {
        /**
         * Are fresnels enabled in the application.
         */
        get: function () {
            return this._FresnelEnabled;
        },
        set: function (value) {
            if (this._FresnelEnabled === value) {
                return;
            }
            this._FresnelEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_FresnelDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "ClearCoatTextureEnabled", {
        /**
         * Are clear coat textures enabled in the application.
         */
        get: function () {
            return this._ClearCoatTextureEnabled;
        },
        set: function (value) {
            if (this._ClearCoatTextureEnabled === value) {
                return;
            }
            this._ClearCoatTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "ClearCoatBumpTextureEnabled", {
        /**
         * Are clear coat bump textures enabled in the application.
         */
        get: function () {
            return this._ClearCoatBumpTextureEnabled;
        },
        set: function (value) {
            if (this._ClearCoatBumpTextureEnabled === value) {
                return;
            }
            this._ClearCoatBumpTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "ClearCoatTintTextureEnabled", {
        /**
         * Are clear coat tint textures enabled in the application.
         */
        get: function () {
            return this._ClearCoatTintTextureEnabled;
        },
        set: function (value) {
            if (this._ClearCoatTintTextureEnabled === value) {
                return;
            }
            this._ClearCoatTintTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "SheenTextureEnabled", {
        /**
         * Are sheen textures enabled in the application.
         */
        get: function () {
            return this._SheenTextureEnabled;
        },
        set: function (value) {
            if (this._SheenTextureEnabled === value) {
                return;
            }
            this._SheenTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "AnisotropicTextureEnabled", {
        /**
         * Are anisotropic textures enabled in the application.
         */
        get: function () {
            return this._AnisotropicTextureEnabled;
        },
        set: function (value) {
            if (this._AnisotropicTextureEnabled === value) {
                return;
            }
            this._AnisotropicTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MaterialFlags, "ThicknessTextureEnabled", {
        /**
         * Are thickness textures enabled in the application.
         */
        get: function () {
            return this._ThicknessTextureEnabled;
        },
        set: function (value) {
            if (this._ThicknessTextureEnabled === value) {
                return;
            }
            this._ThicknessTextureEnabled = value;
            _Engines_engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].MarkAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    // Flags used to enable or disable a type of texture for all Standard Materials
    MaterialFlags._DiffuseTextureEnabled = true;
    MaterialFlags._AmbientTextureEnabled = true;
    MaterialFlags._OpacityTextureEnabled = true;
    MaterialFlags._ReflectionTextureEnabled = true;
    MaterialFlags._EmissiveTextureEnabled = true;
    MaterialFlags._SpecularTextureEnabled = true;
    MaterialFlags._BumpTextureEnabled = true;
    MaterialFlags._LightmapTextureEnabled = true;
    MaterialFlags._RefractionTextureEnabled = true;
    MaterialFlags._ColorGradingTextureEnabled = true;
    MaterialFlags._FresnelEnabled = true;
    MaterialFlags._ClearCoatTextureEnabled = true;
    MaterialFlags._ClearCoatBumpTextureEnabled = true;
    MaterialFlags._ClearCoatTintTextureEnabled = true;
    MaterialFlags._SheenTextureEnabled = true;
    MaterialFlags._AnisotropicTextureEnabled = true;
    MaterialFlags._ThicknessTextureEnabled = true;
    return MaterialFlags;
}());



/***/ }),

/***/ "./Materials/materialHelper.ts":
/*!*************************************!*\
  !*** ./Materials/materialHelper.ts ***!
  \*************************************/
/*! exports provided: MaterialHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MaterialHelper", function() { return MaterialHelper; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Lights_light__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Lights/light */ "./Lights/light.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");






/**
 * "Static Class" containing the most commonly used helper while dealing with material for
 * rendering purpose.
 *
 * It contains the basic tools to help defining defines, binding uniform for the common part of the materials.
 *
 * This works by convention in BabylonJS but is meant to be use only with shader following the in place naming rules and conventions.
 */
var MaterialHelper = /** @class */ (function () {
    function MaterialHelper() {
    }
    /**
     * Bind the current view position to an effect.
     * @param effect The effect to be bound
     * @param scene The scene the eyes position is used from
     */
    MaterialHelper.BindEyePosition = function (effect, scene) {
        if (scene._forcedViewPosition) {
            effect.setVector3("vEyePosition", scene._forcedViewPosition);
            return;
        }
        var globalPosition = scene.activeCamera.globalPosition;
        if (!globalPosition) {
            // Use WebVRFreecamera's device position as global position is not it's actual position in babylon space
            globalPosition = scene.activeCamera.devicePosition;
        }
        effect.setVector3("vEyePosition", scene._mirroredCameraPosition ? scene._mirroredCameraPosition : globalPosition);
    };
    /**
     * Helps preparing the defines values about the UVs in used in the effect.
     * UVs are shared as much as we can accross channels in the shaders.
     * @param texture The texture we are preparing the UVs for
     * @param defines The defines to update
     * @param key The channel key "diffuse", "specular"... used in the shader
     */
    MaterialHelper.PrepareDefinesForMergedUV = function (texture, defines, key) {
        defines._needUVs = true;
        defines[key] = true;
        if (texture.getTextureMatrix().isIdentityAs3x2()) {
            defines[key + "DIRECTUV"] = texture.coordinatesIndex + 1;
            if (texture.coordinatesIndex === 0) {
                defines["MAINUV1"] = true;
            }
            else {
                defines["MAINUV2"] = true;
            }
        }
        else {
            defines[key + "DIRECTUV"] = 0;
        }
    };
    /**
     * Binds a texture matrix value to its corrsponding uniform
     * @param texture The texture to bind the matrix for
     * @param uniformBuffer The uniform buffer receivin the data
     * @param key The channel key "diffuse", "specular"... used in the shader
     */
    MaterialHelper.BindTextureMatrix = function (texture, uniformBuffer, key) {
        var matrix = texture.getTextureMatrix();
        uniformBuffer.updateMatrix(key + "Matrix", matrix);
    };
    /**
     * Gets the current status of the fog (should it be enabled?)
     * @param mesh defines the mesh to evaluate for fog support
     * @param scene defines the hosting scene
     * @returns true if fog must be enabled
     */
    MaterialHelper.GetFogState = function (mesh, scene) {
        return (scene.fogEnabled && mesh.applyFog && scene.fogMode !== _scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].FOGMODE_NONE);
    };
    /**
     * Helper used to prepare the list of defines associated with misc. values for shader compilation
     * @param mesh defines the current mesh
     * @param scene defines the current scene
     * @param useLogarithmicDepth defines if logarithmic depth has to be turned on
     * @param pointsCloud defines if point cloud rendering has to be turned on
     * @param fogEnabled defines if fog has to be turned on
     * @param alphaTest defines if alpha testing has to be turned on
     * @param defines defines the current list of defines
     */
    MaterialHelper.PrepareDefinesForMisc = function (mesh, scene, useLogarithmicDepth, pointsCloud, fogEnabled, alphaTest, defines) {
        if (defines._areMiscDirty) {
            defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
            defines["POINTSIZE"] = pointsCloud;
            defines["FOG"] = fogEnabled && this.GetFogState(mesh, scene);
            defines["NONUNIFORMSCALING"] = mesh.nonUniformScaling;
            defines["ALPHATEST"] = alphaTest;
        }
    };
    /**
     * Helper used to prepare the list of defines associated with frame values for shader compilation
     * @param scene defines the current scene
     * @param engine defines the current engine
     * @param defines specifies the list of active defines
     * @param useInstances defines if instances have to be turned on
     * @param useClipPlane defines if clip plane have to be turned on
     */
    MaterialHelper.PrepareDefinesForFrameBoundValues = function (scene, engine, defines, useInstances, useClipPlane) {
        if (useClipPlane === void 0) { useClipPlane = null; }
        var changed = false;
        var useClipPlane1 = false;
        var useClipPlane2 = false;
        var useClipPlane3 = false;
        var useClipPlane4 = false;
        useClipPlane1 = useClipPlane == null ? (scene.clipPlane !== undefined && scene.clipPlane !== null) : useClipPlane;
        useClipPlane2 = useClipPlane == null ? (scene.clipPlane2 !== undefined && scene.clipPlane2 !== null) : useClipPlane;
        useClipPlane3 = useClipPlane == null ? (scene.clipPlane3 !== undefined && scene.clipPlane3 !== null) : useClipPlane;
        useClipPlane4 = useClipPlane == null ? (scene.clipPlane4 !== undefined && scene.clipPlane4 !== null) : useClipPlane;
        if (defines["CLIPPLANE"] !== useClipPlane1) {
            defines["CLIPPLANE"] = useClipPlane1;
            changed = true;
        }
        if (defines["CLIPPLANE2"] !== useClipPlane2) {
            defines["CLIPPLANE2"] = useClipPlane2;
            changed = true;
        }
        if (defines["CLIPPLANE3"] !== useClipPlane3) {
            defines["CLIPPLANE3"] = useClipPlane3;
            changed = true;
        }
        if (defines["CLIPPLANE4"] !== useClipPlane4) {
            defines["CLIPPLANE4"] = useClipPlane4;
            changed = true;
        }
        if (defines["DEPTHPREPASS"] !== !engine.getColorWrite()) {
            defines["DEPTHPREPASS"] = !defines["DEPTHPREPASS"];
            changed = true;
        }
        if (defines["INSTANCES"] !== useInstances) {
            defines["INSTANCES"] = useInstances;
            changed = true;
        }
        if (changed) {
            defines.markAsUnprocessed();
        }
    };
    /**
     * Prepares the defines for bones
     * @param mesh The mesh containing the geometry data we will draw
     * @param defines The defines to update
     */
    MaterialHelper.PrepareDefinesForBones = function (mesh, defines) {
        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
            defines["NUM_BONE_INFLUENCERS"] = mesh.numBoneInfluencers;
            var materialSupportsBoneTexture = defines["BONETEXTURE"] !== undefined;
            if (mesh.skeleton.isUsingTextureForMatrices && materialSupportsBoneTexture) {
                defines["BONETEXTURE"] = true;
            }
            else {
                defines["BonesPerMesh"] = (mesh.skeleton.bones.length + 1);
                defines["BONETEXTURE"] = materialSupportsBoneTexture ? false : undefined;
            }
        }
        else {
            defines["NUM_BONE_INFLUENCERS"] = 0;
            defines["BonesPerMesh"] = 0;
        }
    };
    /**
     * Prepares the defines for morph targets
     * @param mesh The mesh containing the geometry data we will draw
     * @param defines The defines to update
     */
    MaterialHelper.PrepareDefinesForMorphTargets = function (mesh, defines) {
        var manager = mesh.morphTargetManager;
        if (manager) {
            defines["MORPHTARGETS_UV"] = manager.supportsUVs && defines["UV1"];
            defines["MORPHTARGETS_TANGENT"] = manager.supportsTangents && defines["TANGENT"];
            defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"];
            defines["MORPHTARGETS"] = (manager.numInfluencers > 0);
            defines["NUM_MORPH_INFLUENCERS"] = manager.numInfluencers;
        }
        else {
            defines["MORPHTARGETS_UV"] = false;
            defines["MORPHTARGETS_TANGENT"] = false;
            defines["MORPHTARGETS_NORMAL"] = false;
            defines["MORPHTARGETS"] = false;
            defines["NUM_MORPH_INFLUENCERS"] = 0;
        }
    };
    /**
     * Prepares the defines used in the shader depending on the attributes data available in the mesh
     * @param mesh The mesh containing the geometry data we will draw
     * @param defines The defines to update
     * @param useVertexColor Precise whether vertex colors should be used or not (override mesh info)
     * @param useBones Precise whether bones should be used or not (override mesh info)
     * @param useMorphTargets Precise whether morph targets should be used or not (override mesh info)
     * @param useVertexAlpha Precise whether vertex alpha should be used or not (override mesh info)
     * @returns false if defines are considered not dirty and have not been checked
     */
    MaterialHelper.PrepareDefinesForAttributes = function (mesh, defines, useVertexColor, useBones, useMorphTargets, useVertexAlpha) {
        if (useMorphTargets === void 0) { useMorphTargets = false; }
        if (useVertexAlpha === void 0) { useVertexAlpha = true; }
        if (!defines._areAttributesDirty && defines._needNormals === defines._normals && defines._needUVs === defines._uvs) {
            return false;
        }
        defines._normals = defines._needNormals;
        defines._uvs = defines._needUVs;
        defines["NORMAL"] = (defines._needNormals && mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind));
        if (defines._needNormals && mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind)) {
            defines["TANGENT"] = true;
        }
        if (defines._needUVs) {
            defines["UV1"] = mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind);
            defines["UV2"] = mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind);
        }
        else {
            defines["UV1"] = false;
            defines["UV2"] = false;
        }
        if (useVertexColor) {
            var hasVertexColors = mesh.useVertexColors && mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind);
            defines["VERTEXCOLOR"] = hasVertexColors;
            defines["VERTEXALPHA"] = mesh.hasVertexAlpha && hasVertexColors && useVertexAlpha;
        }
        if (useBones) {
            this.PrepareDefinesForBones(mesh, defines);
        }
        if (useMorphTargets) {
            this.PrepareDefinesForMorphTargets(mesh, defines);
        }
        return true;
    };
    /**
     * Prepares the defines related to multiview
     * @param scene The scene we are intending to draw
     * @param defines The defines to update
     */
    MaterialHelper.PrepareDefinesForMultiview = function (scene, defines) {
        if (scene.activeCamera) {
            var previousMultiview = defines.MULTIVIEW;
            defines.MULTIVIEW = (scene.activeCamera.outputRenderTarget !== null && scene.activeCamera.outputRenderTarget.getViewCount() > 1);
            if (defines.MULTIVIEW != previousMultiview) {
                defines.markAsUnprocessed();
            }
        }
    };
    /**
     * Prepares the defines related to the light information passed in parameter
     * @param scene The scene we are intending to draw
     * @param mesh The mesh the effect is compiling for
     * @param light The light the effect is compiling for
     * @param lightIndex The index of the light
     * @param defines The defines to update
     * @param specularSupported Specifies whether specular is supported or not (override lights data)
     * @param state Defines the current state regarding what is needed (normals, etc...)
     */
    MaterialHelper.PrepareDefinesForLight = function (scene, mesh, light, lightIndex, defines, specularSupported, state) {
        state.needNormals = true;
        if (defines["LIGHT" + lightIndex] === undefined) {
            state.needRebuild = true;
        }
        defines["LIGHT" + lightIndex] = true;
        defines["SPOTLIGHT" + lightIndex] = false;
        defines["HEMILIGHT" + lightIndex] = false;
        defines["POINTLIGHT" + lightIndex] = false;
        defines["DIRLIGHT" + lightIndex] = false;
        light.prepareLightSpecificDefines(defines, lightIndex);
        // FallOff.
        defines["LIGHT_FALLOFF_PHYSICAL" + lightIndex] = false;
        defines["LIGHT_FALLOFF_GLTF" + lightIndex] = false;
        defines["LIGHT_FALLOFF_STANDARD" + lightIndex] = false;
        switch (light.falloffType) {
            case _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].FALLOFF_GLTF:
                defines["LIGHT_FALLOFF_GLTF" + lightIndex] = true;
                break;
            case _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].FALLOFF_PHYSICAL:
                defines["LIGHT_FALLOFF_PHYSICAL" + lightIndex] = true;
                break;
            case _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].FALLOFF_STANDARD:
                defines["LIGHT_FALLOFF_STANDARD" + lightIndex] = true;
                break;
        }
        // Specular
        if (specularSupported && !light.specular.equalsFloats(0, 0, 0)) {
            state.specularEnabled = true;
        }
        // Shadows
        defines["SHADOW" + lightIndex] = false;
        defines["SHADOWPCF" + lightIndex] = false;
        defines["SHADOWPCSS" + lightIndex] = false;
        defines["SHADOWPOISSON" + lightIndex] = false;
        defines["SHADOWESM" + lightIndex] = false;
        defines["SHADOWCUBE" + lightIndex] = false;
        defines["SHADOWLOWQUALITY" + lightIndex] = false;
        defines["SHADOWMEDIUMQUALITY" + lightIndex] = false;
        if (mesh && mesh.receiveShadows && scene.shadowsEnabled && light.shadowEnabled) {
            var shadowGenerator = light.getShadowGenerator();
            if (shadowGenerator) {
                var shadowMap = shadowGenerator.getShadowMap();
                if (shadowMap) {
                    if (shadowMap.renderList && shadowMap.renderList.length > 0) {
                        state.shadowEnabled = true;
                        shadowGenerator.prepareDefines(defines, lightIndex);
                    }
                }
            }
        }
        if (light.lightmapMode != _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTMAP_DEFAULT) {
            state.lightmapMode = true;
            defines["LIGHTMAPEXCLUDED" + lightIndex] = true;
            defines["LIGHTMAPNOSPECULAR" + lightIndex] = (light.lightmapMode == _Lights_light__WEBPACK_IMPORTED_MODULE_4__["Light"].LIGHTMAP_SHADOWSONLY);
        }
        else {
            defines["LIGHTMAPEXCLUDED" + lightIndex] = false;
            defines["LIGHTMAPNOSPECULAR" + lightIndex] = false;
        }
    };
    /**
     * Prepares the defines related to the light information passed in parameter
     * @param scene The scene we are intending to draw
     * @param mesh The mesh the effect is compiling for
     * @param defines The defines to update
     * @param specularSupported Specifies whether specular is supported or not (override lights data)
     * @param maxSimultaneousLights Specfies how manuy lights can be added to the effect at max
     * @param disableLighting Specifies whether the lighting is disabled (override scene and light)
     * @returns true if normals will be required for the rest of the effect
     */
    MaterialHelper.PrepareDefinesForLights = function (scene, mesh, defines, specularSupported, maxSimultaneousLights, disableLighting) {
        if (maxSimultaneousLights === void 0) { maxSimultaneousLights = 4; }
        if (disableLighting === void 0) { disableLighting = false; }
        if (!defines._areLightsDirty) {
            return defines._needNormals;
        }
        var lightIndex = 0;
        var state = {
            needNormals: false,
            needRebuild: false,
            lightmapMode: false,
            shadowEnabled: false,
            specularEnabled: false
        };
        if (scene.lightsEnabled && !disableLighting) {
            for (var _i = 0, _a = mesh.lightSources; _i < _a.length; _i++) {
                var light = _a[_i];
                this.PrepareDefinesForLight(scene, mesh, light, lightIndex, defines, specularSupported, state);
                lightIndex++;
                if (lightIndex === maxSimultaneousLights) {
                    break;
                }
            }
        }
        defines["SPECULARTERM"] = state.specularEnabled;
        defines["SHADOWS"] = state.shadowEnabled;
        // Resetting all other lights if any
        for (var index = lightIndex; index < maxSimultaneousLights; index++) {
            if (defines["LIGHT" + index] !== undefined) {
                defines["LIGHT" + index] = false;
                defines["HEMILIGHT" + index] = false;
                defines["POINTLIGHT" + index] = false;
                defines["DIRLIGHT" + index] = false;
                defines["SPOTLIGHT" + index] = false;
                defines["SHADOW" + index] = false;
                defines["SHADOWPCF" + index] = false;
                defines["SHADOWPCSS" + index] = false;
                defines["SHADOWPOISSON" + index] = false;
                defines["SHADOWESM" + index] = false;
                defines["SHADOWCUBE" + index] = false;
                defines["SHADOWLOWQUALITY" + index] = false;
                defines["SHADOWMEDIUMQUALITY" + index] = false;
            }
        }
        var caps = scene.getEngine().getCaps();
        if (defines["SHADOWFLOAT"] === undefined) {
            state.needRebuild = true;
        }
        defines["SHADOWFLOAT"] = state.shadowEnabled &&
            ((caps.textureFloatRender && caps.textureFloatLinearFiltering) ||
                (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering));
        defines["LIGHTMAPEXCLUDED"] = state.lightmapMode;
        if (state.needRebuild) {
            defines.rebuild();
        }
        return state.needNormals;
    };
    /**
     * Prepares the uniforms and samplers list to be used in the effect (for a specific light)
     * @param lightIndex defines the light index
     * @param uniformsList The uniform list
     * @param samplersList The sampler list
     * @param projectedLightTexture defines if projected texture must be used
     * @param uniformBuffersList defines an optional list of uniform buffers
     */
    MaterialHelper.PrepareUniformsAndSamplersForLight = function (lightIndex, uniformsList, samplersList, projectedLightTexture, uniformBuffersList) {
        if (uniformBuffersList === void 0) { uniformBuffersList = null; }
        uniformsList.push("vLightData" + lightIndex, "vLightDiffuse" + lightIndex, "vLightSpecular" + lightIndex, "vLightDirection" + lightIndex, "vLightFalloff" + lightIndex, "vLightGround" + lightIndex, "lightMatrix" + lightIndex, "shadowsInfo" + lightIndex, "depthValues" + lightIndex);
        if (uniformBuffersList) {
            uniformBuffersList.push("Light" + lightIndex);
        }
        samplersList.push("shadowSampler" + lightIndex);
        samplersList.push("depthSampler" + lightIndex);
        if (projectedLightTexture) {
            samplersList.push("projectionLightSampler" + lightIndex);
            uniformsList.push("textureProjectionMatrix" + lightIndex);
        }
    };
    /**
     * Prepares the uniforms and samplers list to be used in the effect
     * @param uniformsListOrOptions The uniform names to prepare or an EffectCreationOptions containing the liist and extra information
     * @param samplersList The sampler list
     * @param defines The defines helping in the list generation
     * @param maxSimultaneousLights The maximum number of simultanous light allowed in the effect
     */
    MaterialHelper.PrepareUniformsAndSamplersList = function (uniformsListOrOptions, samplersList, defines, maxSimultaneousLights) {
        if (maxSimultaneousLights === void 0) { maxSimultaneousLights = 4; }
        var uniformsList;
        var uniformBuffersList = null;
        if (uniformsListOrOptions.uniformsNames) {
            var options = uniformsListOrOptions;
            uniformsList = options.uniformsNames;
            uniformBuffersList = options.uniformBuffersNames;
            samplersList = options.samplers;
            defines = options.defines;
            maxSimultaneousLights = options.maxSimultaneousLights;
        }
        else {
            uniformsList = uniformsListOrOptions;
            if (!samplersList) {
                samplersList = [];
            }
        }
        for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
            if (!defines["LIGHT" + lightIndex]) {
                break;
            }
            this.PrepareUniformsAndSamplersForLight(lightIndex, uniformsList, samplersList, defines["PROJECTEDLIGHTTEXTURE" + lightIndex], uniformBuffersList);
        }
        if (defines["NUM_MORPH_INFLUENCERS"]) {
            uniformsList.push("morphTargetInfluences");
        }
    };
    /**
     * This helps decreasing rank by rank the shadow quality (0 being the highest rank and quality)
     * @param defines The defines to update while falling back
     * @param fallbacks The authorized effect fallbacks
     * @param maxSimultaneousLights The maximum number of lights allowed
     * @param rank the current rank of the Effect
     * @returns The newly affected rank
     */
    MaterialHelper.HandleFallbacksForShadows = function (defines, fallbacks, maxSimultaneousLights, rank) {
        if (maxSimultaneousLights === void 0) { maxSimultaneousLights = 4; }
        if (rank === void 0) { rank = 0; }
        var lightFallbackRank = 0;
        for (var lightIndex = 0; lightIndex < maxSimultaneousLights; lightIndex++) {
            if (!defines["LIGHT" + lightIndex]) {
                break;
            }
            if (lightIndex > 0) {
                lightFallbackRank = rank + lightIndex;
                fallbacks.addFallback(lightFallbackRank, "LIGHT" + lightIndex);
            }
            if (!defines["SHADOWS"]) {
                if (defines["SHADOW" + lightIndex]) {
                    fallbacks.addFallback(rank, "SHADOW" + lightIndex);
                }
                if (defines["SHADOWPCF" + lightIndex]) {
                    fallbacks.addFallback(rank, "SHADOWPCF" + lightIndex);
                }
                if (defines["SHADOWPCSS" + lightIndex]) {
                    fallbacks.addFallback(rank, "SHADOWPCSS" + lightIndex);
                }
                if (defines["SHADOWPOISSON" + lightIndex]) {
                    fallbacks.addFallback(rank, "SHADOWPOISSON" + lightIndex);
                }
                if (defines["SHADOWESM" + lightIndex]) {
                    fallbacks.addFallback(rank, "SHADOWESM" + lightIndex);
                }
            }
        }
        return lightFallbackRank++;
    };
    /**
     * Prepares the list of attributes required for morph targets according to the effect defines.
     * @param attribs The current list of supported attribs
     * @param mesh The mesh to prepare the morph targets attributes for
     * @param influencers The number of influencers
     */
    MaterialHelper.PrepareAttributesForMorphTargetsInfluencers = function (attribs, mesh, influencers) {
        this._TmpMorphInfluencers.NUM_MORPH_INFLUENCERS = influencers;
        this.PrepareAttributesForMorphTargets(attribs, mesh, this._TmpMorphInfluencers);
    };
    /**
     * Prepares the list of attributes required for morph targets according to the effect defines.
     * @param attribs The current list of supported attribs
     * @param mesh The mesh to prepare the morph targets attributes for
     * @param defines The current Defines of the effect
     */
    MaterialHelper.PrepareAttributesForMorphTargets = function (attribs, mesh, defines) {
        var influencers = defines["NUM_MORPH_INFLUENCERS"];
        if (influencers > 0 && _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["EngineStore"].LastCreatedEngine) {
            var maxAttributesCount = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["EngineStore"].LastCreatedEngine.getCaps().maxVertexAttribs;
            var manager = mesh.morphTargetManager;
            var normal = manager && manager.supportsNormals && defines["NORMAL"];
            var tangent = manager && manager.supportsTangents && defines["TANGENT"];
            var uv = manager && manager.supportsUVs && defines["UV1"];
            for (var index = 0; index < influencers; index++) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind + index);
                if (normal) {
                    attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind + index);
                }
                if (tangent) {
                    attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind + index);
                }
                if (uv) {
                    attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind + "_" + index);
                }
                if (attribs.length > maxAttributesCount) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Cannot add more vertex attributes for mesh " + mesh.name);
                }
            }
        }
    };
    /**
     * Prepares the list of attributes required for bones according to the effect defines.
     * @param attribs The current list of supported attribs
     * @param mesh The mesh to prepare the bones attributes for
     * @param defines The current Defines of the effect
     * @param fallbacks The current efffect fallback strategy
     */
    MaterialHelper.PrepareAttributesForBones = function (attribs, mesh, defines, fallbacks) {
        if (defines["NUM_BONE_INFLUENCERS"] > 0) {
            fallbacks.addCPUSkinningFallback(0, mesh);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind);
            if (defines["NUM_BONE_INFLUENCERS"] > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsExtraKind);
            }
        }
    };
    /**
     * Check and prepare the list of attributes required for instances according to the effect defines.
     * @param attribs The current list of supported attribs
     * @param defines The current MaterialDefines of the effect
     */
    MaterialHelper.PrepareAttributesForInstances = function (attribs, defines) {
        if (defines["INSTANCES"]) {
            this.PushAttributesForInstances(attribs);
        }
    };
    /**
     * Add the list of attributes required for instances to the attribs array.
     * @param attribs The current list of supported attribs
     */
    MaterialHelper.PushAttributesForInstances = function (attribs) {
        attribs.push("world0");
        attribs.push("world1");
        attribs.push("world2");
        attribs.push("world3");
    };
    /**
     * Binds the light shadow information to the effect for the given mesh.
     * @param light The light containing the generator
     * @param scene The scene the lights belongs to
     * @param mesh The mesh we are binding the information to render
     * @param lightIndex The light index in the effect used to render the mesh
     * @param effect The effect we are binding the data to
     */
    MaterialHelper.BindLightShadow = function (light, mesh, lightIndex, effect) {
        if (light.shadowEnabled && mesh.receiveShadows) {
            var shadowGenerator = light.getShadowGenerator();
            if (shadowGenerator) {
                shadowGenerator.bindShadowLight(lightIndex, effect);
            }
        }
    };
    /**
     * Binds the light information to the effect.
     * @param light The light containing the generator
     * @param effect The effect we are binding the data to
     * @param lightIndex The light index in the effect used to render
     */
    MaterialHelper.BindLightProperties = function (light, effect, lightIndex) {
        light.transferToEffect(effect, lightIndex + "");
    };
    /**
     * Binds the lights information from the scene to the effect for the given mesh.
     * @param light Light to bind
     * @param lightIndex Light index
     * @param scene The scene where the light belongs to
     * @param mesh The mesh we are binding the information to render
     * @param effect The effect we are binding the data to
     * @param useSpecular Defines if specular is supported
     * @param usePhysicalLightFalloff Specifies whether the light falloff is defined physically or not
     * @param rebuildInParallel Specifies whether the shader is rebuilding in parallel
     */
    MaterialHelper.BindLight = function (light, lightIndex, scene, mesh, effect, useSpecular, usePhysicalLightFalloff, rebuildInParallel) {
        if (usePhysicalLightFalloff === void 0) { usePhysicalLightFalloff = false; }
        if (rebuildInParallel === void 0) { rebuildInParallel = false; }
        var iAsString = lightIndex.toString();
        var scaledIntensity = light.getScaledIntensity();
        if (!rebuildInParallel) {
            light._uniformBuffer.bindToEffect(effect, "Light" + iAsString);
        }
        MaterialHelper.BindLightProperties(light, effect, lightIndex);
        light.diffuse.scaleToRef(scaledIntensity, _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["TmpColors"].Color3[0]);
        light._uniformBuffer.updateColor4("vLightDiffuse", _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["TmpColors"].Color3[0], usePhysicalLightFalloff ? light.radius : light.range, iAsString);
        if (useSpecular) {
            light.specular.scaleToRef(scaledIntensity, _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["TmpColors"].Color3[1]);
            light._uniformBuffer.updateColor3("vLightSpecular", _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["TmpColors"].Color3[1], iAsString);
        }
        // Shadows
        if (scene.shadowsEnabled) {
            this.BindLightShadow(light, mesh, iAsString, effect);
        }
        light._uniformBuffer.update();
    };
    /**
     * Binds the lights information from the scene to the effect for the given mesh.
     * @param scene The scene the lights belongs to
     * @param mesh The mesh we are binding the information to render
     * @param effect The effect we are binding the data to
     * @param defines The generated defines for the effect
     * @param maxSimultaneousLights The maximum number of light that can be bound to the effect
     * @param usePhysicalLightFalloff Specifies whether the light falloff is defined physically or not
     * @param rebuildInParallel Specifies whether the shader is rebuilding in parallel
     */
    MaterialHelper.BindLights = function (scene, mesh, effect, defines, maxSimultaneousLights, usePhysicalLightFalloff, rebuildInParallel) {
        if (maxSimultaneousLights === void 0) { maxSimultaneousLights = 4; }
        if (usePhysicalLightFalloff === void 0) { usePhysicalLightFalloff = false; }
        if (rebuildInParallel === void 0) { rebuildInParallel = false; }
        var len = Math.min(mesh.lightSources.length, maxSimultaneousLights);
        for (var i = 0; i < len; i++) {
            var light = mesh.lightSources[i];
            this.BindLight(light, i, scene, mesh, effect, typeof defines === "boolean" ? defines : defines["SPECULARTERM"], usePhysicalLightFalloff, rebuildInParallel);
        }
    };
    /**
     * Binds the fog information from the scene to the effect for the given mesh.
     * @param scene The scene the lights belongs to
     * @param mesh The mesh we are binding the information to render
     * @param effect The effect we are binding the data to
     * @param linearSpace Defines if the fog effect is applied in linear space
     */
    MaterialHelper.BindFogParameters = function (scene, mesh, effect, linearSpace) {
        if (linearSpace === void 0) { linearSpace = false; }
        if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== _scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].FOGMODE_NONE) {
            effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
            // Convert fog color to linear space if used in a linear space computed shader.
            if (linearSpace) {
                scene.fogColor.toLinearSpaceToRef(this._tempFogColor);
                effect.setColor3("vFogColor", this._tempFogColor);
            }
            else {
                effect.setColor3("vFogColor", scene.fogColor);
            }
        }
    };
    /**
     * Binds the bones information from the mesh to the effect.
     * @param mesh The mesh we are binding the information to render
     * @param effect The effect we are binding the data to
     */
    MaterialHelper.BindBonesParameters = function (mesh, effect) {
        if (!effect || !mesh) {
            return;
        }
        if (mesh.computeBonesUsingShaders && effect._bonesComputationForcedToCPU) {
            mesh.computeBonesUsingShaders = false;
        }
        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
            var skeleton = mesh.skeleton;
            if (skeleton.isUsingTextureForMatrices && effect.getUniformIndex("boneTextureWidth") > -1) {
                var boneTexture = skeleton.getTransformMatrixTexture(mesh);
                effect.setTexture("boneSampler", boneTexture);
                effect.setFloat("boneTextureWidth", 4.0 * (skeleton.bones.length + 1));
            }
            else {
                var matrices = skeleton.getTransformMatrices(mesh);
                if (matrices) {
                    effect.setMatrices("mBones", matrices);
                }
            }
        }
    };
    /**
     * Binds the morph targets information from the mesh to the effect.
     * @param abstractMesh The mesh we are binding the information to render
     * @param effect The effect we are binding the data to
     */
    MaterialHelper.BindMorphTargetParameters = function (abstractMesh, effect) {
        var manager = abstractMesh.morphTargetManager;
        if (!abstractMesh || !manager) {
            return;
        }
        effect.setFloatArray("morphTargetInfluences", manager.influences);
    };
    /**
     * Binds the logarithmic depth information from the scene to the effect for the given defines.
     * @param defines The generated defines used in the effect
     * @param effect The effect we are binding the data to
     * @param scene The scene we are willing to render with logarithmic scale for
     */
    MaterialHelper.BindLogDepth = function (defines, effect, scene) {
        if (defines["LOGARITHMICDEPTH"]) {
            effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
        }
    };
    /**
     * Binds the clip plane information from the scene to the effect.
     * @param scene The scene the clip plane information are extracted from
     * @param effect The effect we are binding the data to
     */
    MaterialHelper.BindClipPlane = function (effect, scene) {
        if (scene.clipPlane) {
            var clipPlane = scene.clipPlane;
            effect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
        }
        if (scene.clipPlane2) {
            var clipPlane = scene.clipPlane2;
            effect.setFloat4("vClipPlane2", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
        }
        if (scene.clipPlane3) {
            var clipPlane = scene.clipPlane3;
            effect.setFloat4("vClipPlane3", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
        }
        if (scene.clipPlane4) {
            var clipPlane = scene.clipPlane4;
            effect.setFloat4("vClipPlane4", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
        }
    };
    MaterialHelper._TmpMorphInfluencers = { "NUM_MORPH_INFLUENCERS": 0 };
    MaterialHelper._tempFogColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"].Black();
    return MaterialHelper;
}());



/***/ }),

/***/ "./Materials/multiMaterial.ts":
/*!************************************!*\
  !*** ./Materials/multiMaterial.ts ***!
  \************************************/
/*! exports provided: MultiMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiMaterial", function() { return MultiMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Misc_tags__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/tags */ "./Misc/tags.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");




/**
 * A multi-material is used to apply different materials to different parts of the same object without the need of
 * separate meshes. This can be use to improve performances.
 * @see http://doc.babylonjs.com/how_to/multi_materials
 */
var MultiMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MultiMaterial, _super);
    /**
     * Instantiates a new Multi Material
     * A multi-material is used to apply different materials to different parts of the same object without the need of
     * separate meshes. This can be use to improve performances.
     * @see http://doc.babylonjs.com/how_to/multi_materials
     * @param name Define the name in the scene
     * @param scene Define the scene the material belongs to
     */
    function MultiMaterial(name, scene) {
        var _this = _super.call(this, name, scene, true) || this;
        scene.multiMaterials.push(_this);
        _this.subMaterials = new Array();
        _this._storeEffectOnSubMeshes = true; // multimaterial is considered like a push material
        return _this;
    }
    Object.defineProperty(MultiMaterial.prototype, "subMaterials", {
        /**
         * Gets or Sets the list of Materials used within the multi material.
         * They need to be ordered according to the submeshes order in the associated mesh
         */
        get: function () {
            return this._subMaterials;
        },
        set: function (value) {
            this._subMaterials = value;
            this._hookArray(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Function used to align with Node.getChildren()
     * @returns the list of Materials used within the multi material
     */
    MultiMaterial.prototype.getChildren = function () {
        return this.subMaterials;
    };
    MultiMaterial.prototype._hookArray = function (array) {
        var _this = this;
        var oldPush = array.push;
        array.push = function () {
            var items = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                items[_i] = arguments[_i];
            }
            var result = oldPush.apply(array, items);
            _this._markAllSubMeshesAsTexturesDirty();
            return result;
        };
        var oldSplice = array.splice;
        array.splice = function (index, deleteCount) {
            var deleted = oldSplice.apply(array, [index, deleteCount]);
            _this._markAllSubMeshesAsTexturesDirty();
            return deleted;
        };
    };
    /**
     * Get one of the submaterial by its index in the submaterials array
     * @param index The index to look the sub material at
     * @returns The Material if the index has been defined
     */
    MultiMaterial.prototype.getSubMaterial = function (index) {
        if (index < 0 || index >= this.subMaterials.length) {
            return this.getScene().defaultMaterial;
        }
        return this.subMaterials[index];
    };
    /**
     * Get the list of active textures for the whole sub materials list.
     * @returns All the textures that will be used during the rendering
     */
    MultiMaterial.prototype.getActiveTextures = function () {
        var _a;
        return (_a = _super.prototype.getActiveTextures.call(this)).concat.apply(_a, this.subMaterials.map(function (subMaterial) {
            if (subMaterial) {
                return subMaterial.getActiveTextures();
            }
            else {
                return [];
            }
        }));
    };
    /**
     * Gets the current class name of the material e.g. "MultiMaterial"
     * Mainly use in serialization.
     * @returns the class name
     */
    MultiMaterial.prototype.getClassName = function () {
        return "MultiMaterial";
    };
    /**
     * Checks if the material is ready to render the requested sub mesh
     * @param mesh Define the mesh the submesh belongs to
     * @param subMesh Define the sub mesh to look readyness for
     * @param useInstances Define whether or not the material is used with instances
     * @returns true if ready, otherwise false
     */
    MultiMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        for (var index = 0; index < this.subMaterials.length; index++) {
            var subMaterial = this.subMaterials[index];
            if (subMaterial) {
                if (subMaterial._storeEffectOnSubMeshes) {
                    if (!subMaterial.isReadyForSubMesh(mesh, subMesh, useInstances)) {
                        return false;
                    }
                    continue;
                }
                if (!subMaterial.isReady(mesh)) {
                    return false;
                }
            }
        }
        return true;
    };
    /**
     * Clones the current material and its related sub materials
     * @param name Define the name of the newly cloned material
     * @param cloneChildren Define if submaterial will be cloned or shared with the parent instance
     * @returns the cloned material
     */
    MultiMaterial.prototype.clone = function (name, cloneChildren) {
        var newMultiMaterial = new MultiMaterial(name, this.getScene());
        for (var index = 0; index < this.subMaterials.length; index++) {
            var subMaterial = null;
            var current = this.subMaterials[index];
            if (cloneChildren && current) {
                subMaterial = current.clone(name + "-" + current.name);
            }
            else {
                subMaterial = this.subMaterials[index];
            }
            newMultiMaterial.subMaterials.push(subMaterial);
        }
        return newMultiMaterial;
    };
    /**
     * Serializes the materials into a JSON representation.
     * @returns the JSON representation
     */
    MultiMaterial.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.id = this.id;
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_2__["Tags"]) {
            serializationObject.tags = _Misc_tags__WEBPACK_IMPORTED_MODULE_2__["Tags"].GetTags(this);
        }
        serializationObject.materials = [];
        for (var matIndex = 0; matIndex < this.subMaterials.length; matIndex++) {
            var subMat = this.subMaterials[matIndex];
            if (subMat) {
                serializationObject.materials.push(subMat.id);
            }
            else {
                serializationObject.materials.push(null);
            }
        }
        return serializationObject;
    };
    /**
     * Dispose the material and release its associated resources
     * @param forceDisposeEffect Define if we want to force disposing the associated effect (if false the shader is not released and could be reuse later on)
     * @param forceDisposeTextures Define if we want to force disposing the associated textures (if false, they will not be disposed and can still be use elsewhere in the app)
     * @param forceDisposeChildren Define if we want to force disposing the associated submaterials (if false, they will not be disposed and can still be use elsewhere in the app)
     */
    MultiMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures, forceDisposeChildren) {
        var scene = this.getScene();
        if (!scene) {
            return;
        }
        if (forceDisposeChildren) {
            for (var index = 0; index < this.subMaterials.length; index++) {
                var subMaterial = this.subMaterials[index];
                if (subMaterial) {
                    subMaterial.dispose(forceDisposeEffect, forceDisposeTextures);
                }
            }
        }
        var index = scene.multiMaterials.indexOf(this);
        if (index >= 0) {
            scene.multiMaterials.splice(index, 1);
        }
        _super.prototype.dispose.call(this, forceDisposeEffect, forceDisposeTextures);
    };
    /**
     * Creates a MultiMaterial from parsed MultiMaterial data.
     * @param parsedMultiMaterial defines parsed MultiMaterial data.
     * @param scene defines the hosting scene
     * @returns a new MultiMaterial
     */
    MultiMaterial.ParseMultiMaterial = function (parsedMultiMaterial, scene) {
        var multiMaterial = new MultiMaterial(parsedMultiMaterial.name, scene);
        multiMaterial.id = parsedMultiMaterial.id;
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_2__["Tags"]) {
            _Misc_tags__WEBPACK_IMPORTED_MODULE_2__["Tags"].AddTagsTo(multiMaterial, parsedMultiMaterial.tags);
        }
        for (var matIndex = 0; matIndex < parsedMultiMaterial.materials.length; matIndex++) {
            var subMatId = parsedMultiMaterial.materials[matIndex];
            if (subMatId) {
                // If the same multimaterial is loaded twice, the 2nd multimaterial needs to reference the latest material by that id which
                // is why this lookup should use getLastMaterialByID instead of getMaterialByID
                multiMaterial.subMaterials.push(scene.getLastMaterialByID(subMatId));
            }
            else {
                multiMaterial.subMaterials.push(null);
            }
        }
        return multiMaterial;
    };
    return MultiMaterial;
}(_Materials_material__WEBPACK_IMPORTED_MODULE_1__["Material"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.MultiMaterial"] = MultiMaterial;


/***/ }),

/***/ "./Materials/pushMaterial.ts":
/*!***********************************!*\
  !*** ./Materials/pushMaterial.ts ***!
  \***********************************/
/*! exports provided: PushMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PushMaterial", function() { return PushMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");



/**
 * Base class of materials working in push mode in babylon JS
 * @hidden
 */
var PushMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PushMaterial, _super);
    function PushMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._normalMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"]();
        /**
         * Gets or sets a boolean indicating that the material is allowed to do shader hot swapping.
         * This means that the material can keep using a previous shader while a new one is being compiled.
         * This is mostly used when shader parallel compilation is supported (true by default)
         */
        _this.allowShaderHotSwapping = true;
        _this._storeEffectOnSubMeshes = true;
        return _this;
    }
    PushMaterial.prototype.getEffect = function () {
        return this._activeEffect;
    };
    PushMaterial.prototype.isReady = function (mesh, useInstances) {
        if (!mesh) {
            return false;
        }
        if (!mesh.subMeshes || mesh.subMeshes.length === 0) {
            return true;
        }
        return this.isReadyForSubMesh(mesh, mesh.subMeshes[0], useInstances);
    };
    /**
    * Binds the given world matrix to the active effect
    *
    * @param world the matrix to bind
    */
    PushMaterial.prototype.bindOnlyWorldMatrix = function (world) {
        this._activeEffect.setMatrix("world", world);
    };
    /**
     * Binds the given normal matrix to the active effect
     *
     * @param normalMatrix the matrix to bind
     */
    PushMaterial.prototype.bindOnlyNormalMatrix = function (normalMatrix) {
        this._activeEffect.setMatrix("normalMatrix", normalMatrix);
    };
    PushMaterial.prototype.bind = function (world, mesh) {
        if (!mesh) {
            return;
        }
        this.bindForSubMesh(world, mesh, mesh.subMeshes[0]);
    };
    PushMaterial.prototype._afterBind = function (mesh, effect) {
        if (effect === void 0) { effect = null; }
        _super.prototype._afterBind.call(this, mesh);
        this.getScene()._cachedEffect = effect;
    };
    PushMaterial.prototype._mustRebind = function (scene, effect, visibility) {
        if (visibility === void 0) { visibility = 1; }
        return scene.isCachedMaterialInvalid(this, effect, visibility);
    };
    return PushMaterial;
}(_Materials_material__WEBPACK_IMPORTED_MODULE_2__["Material"]));



/***/ }),

/***/ "./Materials/shaderMaterial.ts":
/*!*************************************!*\
  !*** ./Materials/shaderMaterial.ts ***!
  \*************************************/
/*! exports provided: ShaderMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShaderMaterial", function() { return ShaderMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _effect__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./effect */ "./Materials/effect.ts");
/* harmony import */ var _material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./material */ "./Materials/material.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");










/**
 * The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh.
 *
 * This returned material effects how the mesh will look based on the code in the shaders.
 *
 * @see http://doc.babylonjs.com/how_to/shader_material
 */
var ShaderMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShaderMaterial, _super);
    /**
     * Instantiate a new shader material.
     * The ShaderMaterial object has the necessary methods to pass data from your scene to the Vertex and Fragment Shaders and returns a material that can be applied to any mesh.
     * This returned material effects how the mesh will look based on the code in the shaders.
     * @see http://doc.babylonjs.com/how_to/shader_material
     * @param name Define the name of the material in the scene
     * @param scene Define the scene the material belongs to
     * @param shaderPath Defines  the route to the shader code in one of three ways:
     *  * object: { vertex: "custom", fragment: "custom" }, used with Effect.ShadersStore["customVertexShader"] and Effect.ShadersStore["customFragmentShader"]
     *  * object: { vertexElement: "vertexShaderCode", fragmentElement: "fragmentShaderCode" }, used with shader code in script tags
     *  * object: { vertexSource: "vertex shader code string", fragmentSource: "fragment shader code string" } using with strings containing the shaders code
     *  * string: "./COMMON_NAME", used with external files COMMON_NAME.vertex.fx and COMMON_NAME.fragment.fx in index.html folder.
     * @param options Define the options used to create the shader
     */
    function ShaderMaterial(name, scene, shaderPath, options) {
        if (options === void 0) { options = {}; }
        var _this = _super.call(this, name, scene) || this;
        _this._textures = {};
        _this._textureArrays = {};
        _this._floats = {};
        _this._ints = {};
        _this._floatsArrays = {};
        _this._colors3 = {};
        _this._colors3Arrays = {};
        _this._colors4 = {};
        _this._colors4Arrays = {};
        _this._vectors2 = {};
        _this._vectors3 = {};
        _this._vectors4 = {};
        _this._matrices = {};
        _this._matrices3x3 = {};
        _this._matrices2x2 = {};
        _this._vectors2Arrays = {};
        _this._vectors3Arrays = {};
        _this._vectors4Arrays = {};
        _this._cachedWorldViewMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        _this._cachedWorldViewProjectionMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"]();
        _this._shaderPath = shaderPath;
        _this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ needAlphaBlending: false, needAlphaTesting: false, attributes: ["position", "normal", "uv"], uniforms: ["worldViewProjection"], uniformBuffers: [], samplers: [], defines: [] }, options);
        return _this;
    }
    Object.defineProperty(ShaderMaterial.prototype, "options", {
        /**
         * Gets the options used to compile the shader.
         * They can be modified to trigger a new compilation
         */
        get: function () {
            return this._options;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current class name of the material e.g. "ShaderMaterial"
     * Mainly use in serialization.
     * @returns the class name
     */
    ShaderMaterial.prototype.getClassName = function () {
        return "ShaderMaterial";
    };
    /**
     * Specifies if the material will require alpha blending
     * @returns a boolean specifying if alpha blending is needed
     */
    ShaderMaterial.prototype.needAlphaBlending = function () {
        return (this.alpha < 1.0) || this._options.needAlphaBlending;
    };
    /**
     * Specifies if this material should be rendered in alpha test mode
     * @returns a boolean specifying if an alpha test is needed.
     */
    ShaderMaterial.prototype.needAlphaTesting = function () {
        return this._options.needAlphaTesting;
    };
    ShaderMaterial.prototype._checkUniform = function (uniformName) {
        if (this._options.uniforms.indexOf(uniformName) === -1) {
            this._options.uniforms.push(uniformName);
        }
    };
    /**
     * Set a texture in the shader.
     * @param name Define the name of the uniform samplers as defined in the shader
     * @param texture Define the texture to bind to this sampler
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setTexture = function (name, texture) {
        if (this._options.samplers.indexOf(name) === -1) {
            this._options.samplers.push(name);
        }
        this._textures[name] = texture;
        return this;
    };
    /**
     * Set a texture array in the shader.
     * @param name Define the name of the uniform sampler array as defined in the shader
     * @param textures Define the list of textures to bind to this sampler
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setTextureArray = function (name, textures) {
        if (this._options.samplers.indexOf(name) === -1) {
            this._options.samplers.push(name);
        }
        this._checkUniform(name);
        this._textureArrays[name] = textures;
        return this;
    };
    /**
     * Set a float in the shader.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setFloat = function (name, value) {
        this._checkUniform(name);
        this._floats[name] = value;
        return this;
    };
    /**
     * Set a int in the shader.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setInt = function (name, value) {
        this._checkUniform(name);
        this._ints[name] = value;
        return this;
    };
    /**
     * Set an array of floats in the shader.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setFloats = function (name, value) {
        this._checkUniform(name);
        this._floatsArrays[name] = value;
        return this;
    };
    /**
     * Set a vec3 in the shader from a Color3.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setColor3 = function (name, value) {
        this._checkUniform(name);
        this._colors3[name] = value;
        return this;
    };
    /**
     * Set a vec3 array in the shader from a Color3 array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setColor3Array = function (name, value) {
        this._checkUniform(name);
        this._colors3Arrays[name] = value.reduce(function (arr, color) {
            color.toArray(arr, arr.length);
            return arr;
        }, []);
        return this;
    };
    /**
     * Set a vec4 in the shader from a Color4.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setColor4 = function (name, value) {
        this._checkUniform(name);
        this._colors4[name] = value;
        return this;
    };
    /**
     * Set a vec4 array in the shader from a Color4 array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setColor4Array = function (name, value) {
        this._checkUniform(name);
        this._colors4Arrays[name] = value.reduce(function (arr, color) {
            color.toArray(arr, arr.length);
            return arr;
        }, []);
        return this;
    };
    /**
     * Set a vec2 in the shader from a Vector2.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setVector2 = function (name, value) {
        this._checkUniform(name);
        this._vectors2[name] = value;
        return this;
    };
    /**
     * Set a vec3 in the shader from a Vector3.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setVector3 = function (name, value) {
        this._checkUniform(name);
        this._vectors3[name] = value;
        return this;
    };
    /**
     * Set a vec4 in the shader from a Vector4.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setVector4 = function (name, value) {
        this._checkUniform(name);
        this._vectors4[name] = value;
        return this;
    };
    /**
     * Set a mat4 in the shader from a Matrix.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setMatrix = function (name, value) {
        this._checkUniform(name);
        this._matrices[name] = value;
        return this;
    };
    /**
     * Set a mat3 in the shader from a Float32Array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setMatrix3x3 = function (name, value) {
        this._checkUniform(name);
        this._matrices3x3[name] = value;
        return this;
    };
    /**
     * Set a mat2 in the shader from a Float32Array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setMatrix2x2 = function (name, value) {
        this._checkUniform(name);
        this._matrices2x2[name] = value;
        return this;
    };
    /**
     * Set a vec2 array in the shader from a number array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setArray2 = function (name, value) {
        this._checkUniform(name);
        this._vectors2Arrays[name] = value;
        return this;
    };
    /**
     * Set a vec3 array in the shader from a number array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setArray3 = function (name, value) {
        this._checkUniform(name);
        this._vectors3Arrays[name] = value;
        return this;
    };
    /**
     * Set a vec4 array in the shader from a number array.
     * @param name Define the name of the uniform as defined in the shader
     * @param value Define the value to give to the uniform
     * @return the material itself allowing "fluent" like uniform updates
     */
    ShaderMaterial.prototype.setArray4 = function (name, value) {
        this._checkUniform(name);
        this._vectors4Arrays[name] = value;
        return this;
    };
    ShaderMaterial.prototype._checkCache = function (mesh, useInstances) {
        if (!mesh) {
            return true;
        }
        if (this._effect && (this._effect.defines.indexOf("#define INSTANCES") !== -1) !== useInstances) {
            return false;
        }
        return false;
    };
    /**
     * Specifies that the submesh is ready to be used
     * @param mesh defines the mesh to check
     * @param subMesh defines which submesh to check
     * @param useInstances specifies that instances should be used
     * @returns a boolean indicating that the submesh is ready or not
     */
    ShaderMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        return this.isReady(mesh, useInstances);
    };
    /**
     * Checks if the material is ready to render the requested mesh
     * @param mesh Define the mesh to render
     * @param useInstances Define whether or not the material is used with instances
     * @returns true if ready, otherwise false
     */
    ShaderMaterial.prototype.isReady = function (mesh, useInstances) {
        var scene = this.getScene();
        var engine = scene.getEngine();
        if (!this.checkReadyOnEveryCall) {
            if (this._renderId === scene.getRenderId()) {
                if (this._checkCache(mesh, useInstances)) {
                    return true;
                }
            }
        }
        // Instances
        var defines = [];
        var attribs = [];
        var fallbacks = new _effect__WEBPACK_IMPORTED_MODULE_6__["EffectFallbacks"]();
        for (var index = 0; index < this._options.defines.length; index++) {
            defines.push(this._options.defines[index]);
        }
        for (var index = 0; index < this._options.attributes.length; index++) {
            attribs.push(this._options.attributes[index]);
        }
        if (mesh && mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind)) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind);
            defines.push("#define VERTEXCOLOR");
        }
        if (useInstances) {
            defines.push("#define INSTANCES");
            _materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        // Bones
        if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind);
            if (mesh.numBoneInfluencers > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsExtraKind);
            }
            var skeleton = mesh.skeleton;
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            fallbacks.addCPUSkinningFallback(0, mesh);
            if (skeleton.isUsingTextureForMatrices) {
                defines.push("#define BONETEXTURE");
                if (this._options.uniforms.indexOf("boneTextureWidth") === -1) {
                    this._options.uniforms.push("boneTextureWidth");
                }
                if (this._options.samplers.indexOf("boneSampler") === -1) {
                    this._options.samplers.push("boneSampler");
                }
            }
            else {
                defines.push("#define BonesPerMesh " + (skeleton.bones.length + 1));
                if (this._options.uniforms.indexOf("mBones") === -1) {
                    this._options.uniforms.push("mBones");
                }
            }
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Textures
        for (var name in this._textures) {
            if (!this._textures[name].isReady()) {
                return false;
            }
        }
        // Alpha test
        if (mesh && this._shouldTurnAlphaTestOn(mesh)) {
            defines.push("#define ALPHATEST");
        }
        var previousEffect = this._effect;
        var join = defines.join("\n");
        this._effect = engine.createEffect(this._shaderPath, {
            attributes: attribs,
            uniformsNames: this._options.uniforms,
            uniformBuffersNames: this._options.uniformBuffers,
            samplers: this._options.samplers,
            defines: join,
            fallbacks: fallbacks,
            onCompiled: this.onCompiled,
            onError: this.onError
        }, engine);
        if (!this._effect.isReady()) {
            return false;
        }
        if (previousEffect !== this._effect) {
            scene.resetCachedMaterial();
        }
        this._renderId = scene.getRenderId();
        return true;
    };
    /**
     * Binds the world matrix to the material
     * @param world defines the world transformation matrix
     */
    ShaderMaterial.prototype.bindOnlyWorldMatrix = function (world) {
        var scene = this.getScene();
        if (!this._effect) {
            return;
        }
        if (this._options.uniforms.indexOf("world") !== -1) {
            this._effect.setMatrix("world", world);
        }
        if (this._options.uniforms.indexOf("worldView") !== -1) {
            world.multiplyToRef(scene.getViewMatrix(), this._cachedWorldViewMatrix);
            this._effect.setMatrix("worldView", this._cachedWorldViewMatrix);
        }
        if (this._options.uniforms.indexOf("worldViewProjection") !== -1) {
            world.multiplyToRef(scene.getTransformMatrix(), this._cachedWorldViewProjectionMatrix);
            this._effect.setMatrix("worldViewProjection", this._cachedWorldViewProjectionMatrix);
        }
    };
    /**
     * Binds the material to the mesh
     * @param world defines the world transformation matrix
     * @param mesh defines the mesh to bind the material to
     */
    ShaderMaterial.prototype.bind = function (world, mesh) {
        // Std values
        this.bindOnlyWorldMatrix(world);
        if (this._effect && this.getScene().getCachedMaterial() !== this) {
            if (this._options.uniforms.indexOf("view") !== -1) {
                this._effect.setMatrix("view", this.getScene().getViewMatrix());
            }
            if (this._options.uniforms.indexOf("projection") !== -1) {
                this._effect.setMatrix("projection", this.getScene().getProjectionMatrix());
            }
            if (this._options.uniforms.indexOf("viewProjection") !== -1) {
                this._effect.setMatrix("viewProjection", this.getScene().getTransformMatrix());
            }
            // Bones
            _materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].BindBonesParameters(mesh, this._effect);
            var name;
            // Texture
            for (name in this._textures) {
                this._effect.setTexture(name, this._textures[name]);
            }
            // Texture arrays
            for (name in this._textureArrays) {
                this._effect.setTextureArray(name, this._textureArrays[name]);
            }
            // Int
            for (name in this._ints) {
                this._effect.setInt(name, this._ints[name]);
            }
            // Float
            for (name in this._floats) {
                this._effect.setFloat(name, this._floats[name]);
            }
            // Floats
            for (name in this._floatsArrays) {
                this._effect.setArray(name, this._floatsArrays[name]);
            }
            // Color3
            for (name in this._colors3) {
                this._effect.setColor3(name, this._colors3[name]);
            }
            // Color3Array
            for (name in this._colors3Arrays) {
                this._effect.setArray3(name, this._colors3Arrays[name]);
            }
            // Color4
            for (name in this._colors4) {
                var color = this._colors4[name];
                this._effect.setFloat4(name, color.r, color.g, color.b, color.a);
            }
            // Color4Array
            for (name in this._colors4Arrays) {
                this._effect.setArray4(name, this._colors4Arrays[name]);
            }
            // Vector2
            for (name in this._vectors2) {
                this._effect.setVector2(name, this._vectors2[name]);
            }
            // Vector3
            for (name in this._vectors3) {
                this._effect.setVector3(name, this._vectors3[name]);
            }
            // Vector4
            for (name in this._vectors4) {
                this._effect.setVector4(name, this._vectors4[name]);
            }
            // Matrix
            for (name in this._matrices) {
                this._effect.setMatrix(name, this._matrices[name]);
            }
            // Matrix 3x3
            for (name in this._matrices3x3) {
                this._effect.setMatrix3x3(name, this._matrices3x3[name]);
            }
            // Matrix 2x2
            for (name in this._matrices2x2) {
                this._effect.setMatrix2x2(name, this._matrices2x2[name]);
            }
            // Vector2Array
            for (name in this._vectors2Arrays) {
                this._effect.setArray2(name, this._vectors2Arrays[name]);
            }
            // Vector3Array
            for (name in this._vectors3Arrays) {
                this._effect.setArray3(name, this._vectors3Arrays[name]);
            }
            // Vector4Array
            for (name in this._vectors4Arrays) {
                this._effect.setArray4(name, this._vectors4Arrays[name]);
            }
        }
        this._afterBind(mesh);
    };
    /**
     * Gets the active textures from the material
     * @returns an array of textures
     */
    ShaderMaterial.prototype.getActiveTextures = function () {
        var activeTextures = _super.prototype.getActiveTextures.call(this);
        for (var name in this._textures) {
            activeTextures.push(this._textures[name]);
        }
        for (var name in this._textureArrays) {
            var array = this._textureArrays[name];
            for (var index = 0; index < array.length; index++) {
                activeTextures.push(array[index]);
            }
        }
        return activeTextures;
    };
    /**
     * Specifies if the material uses a texture
     * @param texture defines the texture to check against the material
     * @returns a boolean specifying if the material uses the texture
     */
    ShaderMaterial.prototype.hasTexture = function (texture) {
        if (_super.prototype.hasTexture.call(this, texture)) {
            return true;
        }
        for (var name in this._textures) {
            if (this._textures[name] === texture) {
                return true;
            }
        }
        for (var name in this._textureArrays) {
            var array = this._textureArrays[name];
            for (var index = 0; index < array.length; index++) {
                if (array[index] === texture) {
                    return true;
                }
            }
        }
        return false;
    };
    /**
     * Makes a duplicate of the material, and gives it a new name
     * @param name defines the new name for the duplicated material
     * @returns the cloned material
     */
    ShaderMaterial.prototype.clone = function (name) {
        var newShaderMaterial = new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options);
        return newShaderMaterial;
    };
    /**
     * Disposes the material
     * @param forceDisposeEffect specifies if effects should be forcefully disposed
     * @param forceDisposeTextures specifies if textures should be forcefully disposed
     * @param notBoundToMesh specifies if the material that is being disposed is known to be not bound to any mesh
     */
    ShaderMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures, notBoundToMesh) {
        if (forceDisposeTextures) {
            var name;
            for (name in this._textures) {
                this._textures[name].dispose();
            }
            for (name in this._textureArrays) {
                var array = this._textureArrays[name];
                for (var index = 0; index < array.length; index++) {
                    array[index].dispose();
                }
            }
        }
        this._textures = {};
        _super.prototype.dispose.call(this, forceDisposeEffect, forceDisposeTextures, notBoundToMesh);
    };
    /**
     * Serializes this material in a JSON representation
     * @returns the serialized material object
     */
    ShaderMaterial.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "BABYLON.ShaderMaterial";
        serializationObject.options = this._options;
        serializationObject.shaderPath = this._shaderPath;
        var name;
        // Texture
        serializationObject.textures = {};
        for (name in this._textures) {
            serializationObject.textures[name] = this._textures[name].serialize();
        }
        // Texture arrays
        serializationObject.textureArrays = {};
        for (name in this._textureArrays) {
            serializationObject.textureArrays[name] = [];
            var array = this._textureArrays[name];
            for (var index = 0; index < array.length; index++) {
                serializationObject.textureArrays[name].push(array[index].serialize());
            }
        }
        // Float
        serializationObject.floats = {};
        for (name in this._floats) {
            serializationObject.floats[name] = this._floats[name];
        }
        // Float s
        serializationObject.FloatArrays = {};
        for (name in this._floatsArrays) {
            serializationObject.FloatArrays[name] = this._floatsArrays[name];
        }
        // Color3
        serializationObject.colors3 = {};
        for (name in this._colors3) {
            serializationObject.colors3[name] = this._colors3[name].asArray();
        }
        // Color3 array
        serializationObject.colors3Arrays = {};
        for (name in this._colors3Arrays) {
            serializationObject.colors3Arrays[name] = this._colors3Arrays[name];
        }
        // Color4
        serializationObject.colors4 = {};
        for (name in this._colors4) {
            serializationObject.colors4[name] = this._colors4[name].asArray();
        }
        // Color4 array
        serializationObject.colors4Arrays = {};
        for (name in this._colors4Arrays) {
            serializationObject.colors4Arrays[name] = this._colors4Arrays[name];
        }
        // Vector2
        serializationObject.vectors2 = {};
        for (name in this._vectors2) {
            serializationObject.vectors2[name] = this._vectors2[name].asArray();
        }
        // Vector3
        serializationObject.vectors3 = {};
        for (name in this._vectors3) {
            serializationObject.vectors3[name] = this._vectors3[name].asArray();
        }
        // Vector4
        serializationObject.vectors4 = {};
        for (name in this._vectors4) {
            serializationObject.vectors4[name] = this._vectors4[name].asArray();
        }
        // Matrix
        serializationObject.matrices = {};
        for (name in this._matrices) {
            serializationObject.matrices[name] = this._matrices[name].asArray();
        }
        // Matrix 3x3
        serializationObject.matrices3x3 = {};
        for (name in this._matrices3x3) {
            serializationObject.matrices3x3[name] = this._matrices3x3[name];
        }
        // Matrix 2x2
        serializationObject.matrices2x2 = {};
        for (name in this._matrices2x2) {
            serializationObject.matrices2x2[name] = this._matrices2x2[name];
        }
        // Vector2Array
        serializationObject.vectors2Arrays = {};
        for (name in this._vectors2Arrays) {
            serializationObject.vectors2Arrays[name] = this._vectors2Arrays[name];
        }
        // Vector3Array
        serializationObject.vectors3Arrays = {};
        for (name in this._vectors3Arrays) {
            serializationObject.vectors3Arrays[name] = this._vectors3Arrays[name];
        }
        // Vector4Array
        serializationObject.vectors4Arrays = {};
        for (name in this._vectors4Arrays) {
            serializationObject.vectors4Arrays[name] = this._vectors4Arrays[name];
        }
        return serializationObject;
    };
    /**
     * Creates a shader material from parsed shader material data
     * @param source defines the JSON represnetation of the material
     * @param scene defines the hosting scene
     * @param rootUrl defines the root URL to use to load textures and relative dependencies
     * @returns a new material
     */
    ShaderMaterial.Parse = function (source, scene, rootUrl) {
        var material = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new ShaderMaterial(source.name, scene, source.shaderPath, source.options); }, source, scene, rootUrl);
        var name;
        // Texture
        for (name in source.textures) {
            material.setTexture(name, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].Parse(source.textures[name], scene, rootUrl));
        }
        // Texture arrays
        for (name in source.textureArrays) {
            var array = source.textureArrays[name];
            var textureArray = new Array();
            for (var index = 0; index < array.length; index++) {
                textureArray.push(_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].Parse(array[index], scene, rootUrl));
            }
            material.setTextureArray(name, textureArray);
        }
        // Float
        for (name in source.floats) {
            material.setFloat(name, source.floats[name]);
        }
        // Float s
        for (name in source.floatsArrays) {
            material.setFloats(name, source.floatsArrays[name]);
        }
        // Color3
        for (name in source.colors3) {
            material.setColor3(name, _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color3"].FromArray(source.colors3[name]));
        }
        // Color3 arrays
        for (name in source.colors3Arrays) {
            var colors = source.colors3Arrays[name].reduce(function (arr, num, i) {
                if (i % 3 === 0) {
                    arr.push([num]);
                }
                else {
                    arr[arr.length - 1].push(num);
                }
                return arr;
            }, []).map(function (color) { return _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color3"].FromArray(color); });
            material.setColor3Array(name, colors);
        }
        // Color4
        for (name in source.colors4) {
            material.setColor4(name, _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color4"].FromArray(source.colors4[name]));
        }
        // Color4 arrays
        for (name in source.colors4Arrays) {
            var colors = source.colors4Arrays[name].reduce(function (arr, num, i) {
                if (i % 4 === 0) {
                    arr.push([num]);
                }
                else {
                    arr[arr.length - 1].push(num);
                }
                return arr;
            }, []).map(function (color) { return _Maths_math_color__WEBPACK_IMPORTED_MODULE_9__["Color4"].FromArray(color); });
            material.setColor4Array(name, colors);
        }
        // Vector2
        for (name in source.vectors2) {
            material.setVector2(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"].FromArray(source.vectors2[name]));
        }
        // Vector3
        for (name in source.vectors3) {
            material.setVector3(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].FromArray(source.vectors3[name]));
        }
        // Vector4
        for (name in source.vectors4) {
            material.setVector4(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector4"].FromArray(source.vectors4[name]));
        }
        // Matrix
        for (name in source.matrices) {
            material.setMatrix(name, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Matrix"].FromArray(source.matrices[name]));
        }
        // Matrix 3x3
        for (name in source.matrices3x3) {
            material.setMatrix3x3(name, source.matrices3x3[name]);
        }
        // Matrix 2x2
        for (name in source.matrices2x2) {
            material.setMatrix2x2(name, source.matrices2x2[name]);
        }
        // Vector2Array
        for (name in source.vectors2Arrays) {
            material.setArray2(name, source.vectors2Arrays[name]);
        }
        // Vector3Array
        for (name in source.vectors3Arrays) {
            material.setArray3(name, source.vectors3Arrays[name]);
        }
        // Vector4Array
        for (name in source.vectors4Arrays) {
            material.setArray4(name, source.vectors4Arrays[name]);
        }
        return material;
    };
    return ShaderMaterial;
}(_material__WEBPACK_IMPORTED_MODULE_7__["Material"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_8__["_TypeStore"].RegisteredTypes["BABYLON.ShaderMaterial"] = ShaderMaterial;


/***/ }),

/***/ "./Materials/standardMaterial.ts":
/*!***************************************!*\
  !*** ./Materials/standardMaterial.ts ***!
  \***************************************/
/*! exports provided: StandardMaterialDefines, StandardMaterial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StandardMaterialDefines", function() { return StandardMaterialDefines; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StandardMaterial", function() { return StandardMaterial; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _effect__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_materialDefines__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/materialDefines */ "./Materials/materialDefines.ts");
/* harmony import */ var _pushMaterial__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./pushMaterial */ "./Materials/pushMaterial.ts");
/* harmony import */ var _materialHelper__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _materialFlags__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./materialFlags */ "./Materials/materialFlags.ts");
/* harmony import */ var _Shaders_default_fragment__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Shaders/default.fragment */ "./Shaders/default.fragment.ts");
/* harmony import */ var _Shaders_default_vertex__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Shaders/default.vertex */ "./Shaders/default.vertex.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");


















/** @hidden */
var StandardMaterialDefines = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StandardMaterialDefines, _super);
    function StandardMaterialDefines() {
        var _this = _super.call(this) || this;
        _this.MAINUV1 = false;
        _this.MAINUV2 = false;
        _this.DIFFUSE = false;
        _this.DIFFUSEDIRECTUV = 0;
        _this.AMBIENT = false;
        _this.AMBIENTDIRECTUV = 0;
        _this.OPACITY = false;
        _this.OPACITYDIRECTUV = 0;
        _this.OPACITYRGB = false;
        _this.REFLECTION = false;
        _this.EMISSIVE = false;
        _this.EMISSIVEDIRECTUV = 0;
        _this.SPECULAR = false;
        _this.SPECULARDIRECTUV = 0;
        _this.BUMP = false;
        _this.BUMPDIRECTUV = 0;
        _this.PARALLAX = false;
        _this.PARALLAXOCCLUSION = false;
        _this.SPECULAROVERALPHA = false;
        _this.CLIPPLANE = false;
        _this.CLIPPLANE2 = false;
        _this.CLIPPLANE3 = false;
        _this.CLIPPLANE4 = false;
        _this.ALPHATEST = false;
        _this.DEPTHPREPASS = false;
        _this.ALPHAFROMDIFFUSE = false;
        _this.POINTSIZE = false;
        _this.FOG = false;
        _this.SPECULARTERM = false;
        _this.DIFFUSEFRESNEL = false;
        _this.OPACITYFRESNEL = false;
        _this.REFLECTIONFRESNEL = false;
        _this.REFRACTIONFRESNEL = false;
        _this.EMISSIVEFRESNEL = false;
        _this.FRESNEL = false;
        _this.NORMAL = false;
        _this.UV1 = false;
        _this.UV2 = false;
        _this.VERTEXCOLOR = false;
        _this.VERTEXALPHA = false;
        _this.NUM_BONE_INFLUENCERS = 0;
        _this.BonesPerMesh = 0;
        _this.BONETEXTURE = false;
        _this.INSTANCES = false;
        _this.GLOSSINESS = false;
        _this.ROUGHNESS = false;
        _this.EMISSIVEASILLUMINATION = false;
        _this.LINKEMISSIVEWITHDIFFUSE = false;
        _this.REFLECTIONFRESNELFROMSPECULAR = false;
        _this.LIGHTMAP = false;
        _this.LIGHTMAPDIRECTUV = 0;
        _this.OBJECTSPACE_NORMALMAP = false;
        _this.USELIGHTMAPASSHADOWMAP = false;
        _this.REFLECTIONMAP_3D = false;
        _this.REFLECTIONMAP_SPHERICAL = false;
        _this.REFLECTIONMAP_PLANAR = false;
        _this.REFLECTIONMAP_CUBIC = false;
        _this.USE_LOCAL_REFLECTIONMAP_CUBIC = false;
        _this.REFLECTIONMAP_PROJECTION = false;
        _this.REFLECTIONMAP_SKYBOX = false;
        _this.REFLECTIONMAP_SKYBOX_TRANSFORMED = false;
        _this.REFLECTIONMAP_EXPLICIT = false;
        _this.REFLECTIONMAP_EQUIRECTANGULAR = false;
        _this.REFLECTIONMAP_EQUIRECTANGULAR_FIXED = false;
        _this.REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED = false;
        _this.INVERTCUBICMAP = false;
        _this.LOGARITHMICDEPTH = false;
        _this.REFRACTION = false;
        _this.REFRACTIONMAP_3D = false;
        _this.REFLECTIONOVERALPHA = false;
        _this.TWOSIDEDLIGHTING = false;
        _this.SHADOWFLOAT = false;
        _this.MORPHTARGETS = false;
        _this.MORPHTARGETS_NORMAL = false;
        _this.MORPHTARGETS_TANGENT = false;
        _this.MORPHTARGETS_UV = false;
        _this.NUM_MORPH_INFLUENCERS = 0;
        _this.NONUNIFORMSCALING = false; // https://playground.babylonjs.com#V6DWIH
        _this.PREMULTIPLYALPHA = false; // https://playground.babylonjs.com#LNVJJ7
        _this.IMAGEPROCESSING = false;
        _this.VIGNETTE = false;
        _this.VIGNETTEBLENDMODEMULTIPLY = false;
        _this.VIGNETTEBLENDMODEOPAQUE = false;
        _this.TONEMAPPING = false;
        _this.TONEMAPPING_ACES = false;
        _this.CONTRAST = false;
        _this.COLORCURVES = false;
        _this.COLORGRADING = false;
        _this.COLORGRADING3D = false;
        _this.SAMPLER3DGREENDEPTH = false;
        _this.SAMPLER3DBGRMAP = false;
        _this.IMAGEPROCESSINGPOSTPROCESS = false;
        _this.MULTIVIEW = false;
        /**
         * If the reflection texture on this material is in linear color space
         * @hidden
         */
        _this.IS_REFLECTION_LINEAR = false;
        /**
         * If the refraction texture on this material is in linear color space
         * @hidden
         */
        _this.IS_REFRACTION_LINEAR = false;
        _this.EXPOSURE = false;
        _this.rebuild();
        return _this;
    }
    StandardMaterialDefines.prototype.setReflectionMode = function (modeToEnable) {
        var modes = [
            "REFLECTIONMAP_CUBIC", "REFLECTIONMAP_EXPLICIT", "REFLECTIONMAP_PLANAR",
            "REFLECTIONMAP_PROJECTION", "REFLECTIONMAP_PROJECTION", "REFLECTIONMAP_SKYBOX",
            "REFLECTIONMAP_SPHERICAL", "REFLECTIONMAP_EQUIRECTANGULAR", "REFLECTIONMAP_EQUIRECTANGULAR_FIXED",
            "REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED"
        ];
        for (var _i = 0, modes_1 = modes; _i < modes_1.length; _i++) {
            var mode = modes_1[_i];
            this[mode] = (mode === modeToEnable);
        }
    };
    return StandardMaterialDefines;
}(_Materials_materialDefines__WEBPACK_IMPORTED_MODULE_9__["MaterialDefines"]));

/**
 * This is the default material used in Babylon. It is the best trade off between quality
 * and performances.
 * @see http://doc.babylonjs.com/babylon101/materials
 */
var StandardMaterial = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StandardMaterial, _super);
    /**
     * Instantiates a new standard material.
     * This is the default material used in Babylon. It is the best trade off between quality
     * and performances.
     * @see http://doc.babylonjs.com/babylon101/materials
     * @param name Define the name of the material in the scene
     * @param scene Define the scene the material belong to
     */
    function StandardMaterial(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        _this._diffuseTexture = null;
        _this._ambientTexture = null;
        _this._opacityTexture = null;
        _this._reflectionTexture = null;
        _this._emissiveTexture = null;
        _this._specularTexture = null;
        _this._bumpTexture = null;
        _this._lightmapTexture = null;
        _this._refractionTexture = null;
        /**
         * The color of the material lit by the environmental background lighting.
         * @see http://doc.babylonjs.com/babylon101/materials#ambient-color-example
         */
        _this.ambientColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](0, 0, 0);
        /**
         * The basic color of the material as viewed under a light.
         */
        _this.diffuseColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](1, 1, 1);
        /**
         * Define how the color and intensity of the highlight given by the light in the material.
         */
        _this.specularColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](1, 1, 1);
        /**
         * Define the color of the material as if self lit.
         * This will be mixed in the final result even in the absence of light.
         */
        _this.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](0, 0, 0);
        /**
         * Defines how sharp are the highlights in the material.
         * The bigger the value the sharper giving a more glossy feeling to the result.
         * Reversely, the smaller the value the blurrier giving a more rough feeling to the result.
         */
        _this.specularPower = 64;
        _this._useAlphaFromDiffuseTexture = false;
        _this._useEmissiveAsIllumination = false;
        _this._linkEmissiveWithDiffuse = false;
        _this._useSpecularOverAlpha = false;
        _this._useReflectionOverAlpha = false;
        _this._disableLighting = false;
        _this._useObjectSpaceNormalMap = false;
        _this._useParallax = false;
        _this._useParallaxOcclusion = false;
        /**
         * Apply a scaling factor that determine which "depth" the height map should reprensent. A value between 0.05 and 0.1 is reasonnable in Parallax, you can reach 0.2 using Parallax Occlusion.
         */
        _this.parallaxScaleBias = 0.05;
        _this._roughness = 0;
        /**
         * In case of refraction, define the value of the index of refraction.
         * @see http://doc.babylonjs.com/how_to/reflect#how-to-obtain-reflections-and-refractions
         */
        _this.indexOfRefraction = 0.98;
        /**
         * Invert the refraction texture alongside the y axis.
         * It can be useful with procedural textures or probe for instance.
         * @see http://doc.babylonjs.com/how_to/reflect#how-to-obtain-reflections-and-refractions
         */
        _this.invertRefractionY = true;
        /**
         * Defines the alpha limits in alpha test mode.
         */
        _this.alphaCutOff = 0.4;
        _this._useLightmapAsShadowmap = false;
        _this._useReflectionFresnelFromSpecular = false;
        _this._useGlossinessFromSpecularMapAlpha = false;
        _this._maxSimultaneousLights = 4;
        _this._invertNormalMapX = false;
        _this._invertNormalMapY = false;
        _this._twoSidedLighting = false;
        _this._renderTargets = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_2__["SmartArray"](16);
        _this._worldViewProjectionMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Zero();
        _this._globalAmbientColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](0, 0, 0);
        _this._rebuildInParallel = false;
        // Setup the default processing configuration to the scene.
        _this._attachImageProcessingConfiguration(null);
        _this.getRenderTargetTextures = function () {
            _this._renderTargets.reset();
            if (StandardMaterial.ReflectionTextureEnabled && _this._reflectionTexture && _this._reflectionTexture.isRenderTarget) {
                _this._renderTargets.push(_this._reflectionTexture);
            }
            if (StandardMaterial.RefractionTextureEnabled && _this._refractionTexture && _this._refractionTexture.isRenderTarget) {
                _this._renderTargets.push(_this._refractionTexture);
            }
            return _this._renderTargets;
        };
        return _this;
    }
    Object.defineProperty(StandardMaterial.prototype, "imageProcessingConfiguration", {
        /**
         * Gets the image processing configuration used either in this material.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        /**
         * Sets the Default image processing configuration used either in the this material.
         *
         * If sets to null, the scene one is in use.
         */
        set: function (value) {
            this._attachImageProcessingConfiguration(value);
            // Ensure the effect will be rebuilt.
            this._markAllSubMeshesAsTexturesDirty();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attaches a new image processing configuration to the Standard Material.
     * @param configuration
     */
    StandardMaterial.prototype._attachImageProcessingConfiguration = function (configuration) {
        var _this = this;
        if (configuration === this._imageProcessingConfiguration) {
            return;
        }
        // Detaches observer
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        // Pick the scene configuration if needed
        if (!configuration) {
            this._imageProcessingConfiguration = this.getScene().imageProcessingConfiguration;
        }
        else {
            this._imageProcessingConfiguration = configuration;
        }
        // Attaches observer
        if (this._imageProcessingConfiguration) {
            this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(function () {
                _this._markAllSubMeshesAsImageProcessingDirty();
            });
        }
    };
    Object.defineProperty(StandardMaterial.prototype, "cameraColorCurvesEnabled", {
        /**
         * Gets wether the color curves effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorCurvesEnabled;
        },
        /**
         * Sets wether the color curves effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorCurvesEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "cameraColorGradingEnabled", {
        /**
         * Gets wether the color grading effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorGradingEnabled;
        },
        /**
         * Gets wether the color grading effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorGradingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "cameraToneMappingEnabled", {
        /**
         * Gets wether tonemapping is enabled or not.
         */
        get: function () {
            return this._imageProcessingConfiguration.toneMappingEnabled;
        },
        /**
         * Sets wether tonemapping is enabled or not
         */
        set: function (value) {
            this._imageProcessingConfiguration.toneMappingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "cameraExposure", {
        /**
         * The camera exposure used on this material.
         * This property is here and not in the camera to allow controlling exposure without full screen post process.
         * This corresponds to a photographic exposure.
         */
        get: function () {
            return this._imageProcessingConfiguration.exposure;
        },
        /**
         * The camera exposure used on this material.
         * This property is here and not in the camera to allow controlling exposure without full screen post process.
         * This corresponds to a photographic exposure.
         */
        set: function (value) {
            this._imageProcessingConfiguration.exposure = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "cameraContrast", {
        /**
         * Gets The camera contrast used on this material.
         */
        get: function () {
            return this._imageProcessingConfiguration.contrast;
        },
        /**
         * Sets The camera contrast used on this material.
         */
        set: function (value) {
            this._imageProcessingConfiguration.contrast = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "cameraColorGradingTexture", {
        /**
         * Gets the Color Grading 2D Lookup Texture.
         */
        get: function () {
            return this._imageProcessingConfiguration.colorGradingTexture;
        },
        /**
         * Sets the Color Grading 2D Lookup Texture.
         */
        set: function (value) {
            this._imageProcessingConfiguration.colorGradingTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "cameraColorCurves", {
        /**
         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
         */
        get: function () {
            return this._imageProcessingConfiguration.colorCurves;
        },
        /**
         * The color grading curves provide additional color adjustmnent that is applied after any color grading transform (3D LUT).
         * They allow basic adjustment of saturation and small exposure adjustments, along with color filter tinting to provide white balance adjustment or more stylistic effects.
         * These are similar to controls found in many professional imaging or colorist software. The global controls are applied to the entire image. For advanced tuning, extra controls are provided to adjust the shadow, midtone and highlight areas of the image;
         * corresponding to low luminance, medium luminance, and high luminance areas respectively.
         */
        set: function (value) {
            this._imageProcessingConfiguration.colorCurves = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial.prototype, "hasRenderTargetTextures", {
        /**
         * Gets a boolean indicating that current material needs to register RTT
         */
        get: function () {
            if (StandardMaterial.ReflectionTextureEnabled && this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                return true;
            }
            if (StandardMaterial.RefractionTextureEnabled && this._refractionTexture && this._refractionTexture.isRenderTarget) {
                return true;
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the current class name of the material e.g. "StandardMaterial"
     * Mainly use in serialization.
     * @returns the class name
     */
    StandardMaterial.prototype.getClassName = function () {
        return "StandardMaterial";
    };
    Object.defineProperty(StandardMaterial.prototype, "useLogarithmicDepth", {
        /**
         * In case the depth buffer does not allow enough depth precision for your scene (might be the case in large scenes)
         * You can try switching to logarithmic depth.
         * @see http://doc.babylonjs.com/how_to/using_logarithmic_depth_buffer
         */
        get: function () {
            return this._useLogarithmicDepth;
        },
        set: function (value) {
            this._useLogarithmicDepth = value && this.getScene().getEngine().getCaps().fragmentDepthSupported;
            this._markAllSubMeshesAsMiscDirty();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Specifies if the material will require alpha blending
     * @returns a boolean specifying if alpha blending is needed
     */
    StandardMaterial.prototype.needAlphaBlending = function () {
        return (this.alpha < 1.0) || (this._opacityTexture != null) || this._shouldUseAlphaFromDiffuseTexture() || this._opacityFresnelParameters && this._opacityFresnelParameters.isEnabled;
    };
    /**
     * Specifies if this material should be rendered in alpha test mode
     * @returns a boolean specifying if an alpha test is needed.
     */
    StandardMaterial.prototype.needAlphaTesting = function () {
        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha;
    };
    StandardMaterial.prototype._shouldUseAlphaFromDiffuseTexture = function () {
        return this._diffuseTexture != null && this._diffuseTexture.hasAlpha && this._useAlphaFromDiffuseTexture;
    };
    /**
     * Get the texture used for alpha test purpose.
     * @returns the diffuse texture in case of the standard material.
     */
    StandardMaterial.prototype.getAlphaTestTexture = function () {
        return this._diffuseTexture;
    };
    /**
     * Get if the submesh is ready to be used and all its information available.
     * Child classes can use it to update shaders
     * @param mesh defines the mesh to check
     * @param subMesh defines which submesh to check
     * @param useInstances specifies that instances should be used
     * @returns a boolean indicating that the submesh is ready or not
     */
    StandardMaterial.prototype.isReadyForSubMesh = function (mesh, subMesh, useInstances) {
        if (useInstances === void 0) { useInstances = false; }
        if (subMesh.effect && this.isFrozen) {
            if (this._wasPreviouslyReady) {
                return true;
            }
        }
        if (!subMesh._materialDefines) {
            subMesh._materialDefines = new StandardMaterialDefines();
        }
        var scene = this.getScene();
        var defines = subMesh._materialDefines;
        if (!this.checkReadyOnEveryCall && subMesh.effect) {
            if (defines._renderId === scene.getRenderId()) {
                return true;
            }
        }
        var engine = scene.getEngine();
        // Lights
        defines._needNormals = _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForLights(scene, mesh, defines, true, this._maxSimultaneousLights, this._disableLighting);
        // Multiview
        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMultiview(scene, defines);
        // Textures
        if (defines._areTexturesDirty) {
            defines._needUVs = false;
            defines.MAINUV1 = false;
            defines.MAINUV2 = false;
            if (scene.texturesEnabled) {
                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                    if (!this._diffuseTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._diffuseTexture, defines, "DIFFUSE");
                    }
                }
                else {
                    defines.DIFFUSE = false;
                }
                if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                    if (!this._ambientTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._ambientTexture, defines, "AMBIENT");
                    }
                }
                else {
                    defines.AMBIENT = false;
                }
                if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
                    if (!this._opacityTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._opacityTexture, defines, "OPACITY");
                        defines.OPACITYRGB = this._opacityTexture.getAlphaFromRGB;
                    }
                }
                else {
                    defines.OPACITY = false;
                }
                if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
                    if (!this._reflectionTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        defines._needNormals = true;
                        defines.REFLECTION = true;
                        defines.ROUGHNESS = (this._roughness > 0);
                        defines.REFLECTIONOVERALPHA = this._useReflectionOverAlpha;
                        defines.INVERTCUBICMAP = (this._reflectionTexture.coordinatesMode === _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].INVCUBIC_MODE);
                        defines.REFLECTIONMAP_3D = this._reflectionTexture.isCube;
                        switch (this._reflectionTexture.coordinatesMode) {
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].EXPLICIT_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_EXPLICIT");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].PLANAR_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_PLANAR");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].PROJECTION_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_PROJECTION");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].SKYBOX_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_SKYBOX");
                                defines.REFLECTIONMAP_SKYBOX_TRANSFORMED = !this._reflectionTexture.getReflectionTextureMatrix().isIdentity();
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].SPHERICAL_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_SPHERICAL");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].EQUIRECTANGULAR_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_EQUIRECTANGULAR");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].FIXED_EQUIRECTANGULAR_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_EQUIRECTANGULAR_FIXED");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].FIXED_EQUIRECTANGULAR_MIRRORED_MODE:
                                defines.setReflectionMode("REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED");
                                break;
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].CUBIC_MODE:
                            case _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_12__["Texture"].INVCUBIC_MODE:
                            default:
                                defines.setReflectionMode("REFLECTIONMAP_CUBIC");
                                break;
                        }
                        defines.USE_LOCAL_REFLECTIONMAP_CUBIC = this._reflectionTexture.boundingBoxSize ? true : false;
                    }
                }
                else {
                    defines.REFLECTION = false;
                }
                if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
                    if (!this._emissiveTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._emissiveTexture, defines, "EMISSIVE");
                    }
                }
                else {
                    defines.EMISSIVE = false;
                }
                if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
                    if (!this._lightmapTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._lightmapTexture, defines, "LIGHTMAP");
                        defines.USELIGHTMAPASSHADOWMAP = this._useLightmapAsShadowmap;
                    }
                }
                else {
                    defines.LIGHTMAP = false;
                }
                if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
                    if (!this._specularTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._specularTexture, defines, "SPECULAR");
                        defines.GLOSSINESS = this._useGlossinessFromSpecularMapAlpha;
                    }
                }
                else {
                    defines.SPECULAR = false;
                }
                if (scene.getEngine().getCaps().standardDerivatives && this._bumpTexture && StandardMaterial.BumpTextureEnabled) {
                    // Bump texure can not be not blocking.
                    if (!this._bumpTexture.isReady()) {
                        return false;
                    }
                    else {
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMergedUV(this._bumpTexture, defines, "BUMP");
                        defines.PARALLAX = this._useParallax;
                        defines.PARALLAXOCCLUSION = this._useParallaxOcclusion;
                    }
                    defines.OBJECTSPACE_NORMALMAP = this._useObjectSpaceNormalMap;
                }
                else {
                    defines.BUMP = false;
                }
                if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                    if (!this._refractionTexture.isReadyOrNotBlocking()) {
                        return false;
                    }
                    else {
                        defines._needUVs = true;
                        defines.REFRACTION = true;
                        defines.REFRACTIONMAP_3D = this._refractionTexture.isCube;
                    }
                }
                else {
                    defines.REFRACTION = false;
                }
                defines.TWOSIDEDLIGHTING = !this._backFaceCulling && this._twoSidedLighting;
            }
            else {
                defines.DIFFUSE = false;
                defines.AMBIENT = false;
                defines.OPACITY = false;
                defines.REFLECTION = false;
                defines.EMISSIVE = false;
                defines.LIGHTMAP = false;
                defines.BUMP = false;
                defines.REFRACTION = false;
            }
            defines.ALPHAFROMDIFFUSE = this._shouldUseAlphaFromDiffuseTexture();
            defines.EMISSIVEASILLUMINATION = this._useEmissiveAsIllumination;
            defines.LINKEMISSIVEWITHDIFFUSE = this._linkEmissiveWithDiffuse;
            defines.SPECULAROVERALPHA = this._useSpecularOverAlpha;
            defines.PREMULTIPLYALPHA = (this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].ALPHA_PREMULTIPLIED || this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].ALPHA_PREMULTIPLIED_PORTERDUFF);
        }
        if (defines._areImageProcessingDirty && this._imageProcessingConfiguration) {
            if (!this._imageProcessingConfiguration.isReady()) {
                return false;
            }
            this._imageProcessingConfiguration.prepareDefines(defines);
            defines.IS_REFLECTION_LINEAR = (this.reflectionTexture != null && !this.reflectionTexture.gammaSpace);
            defines.IS_REFRACTION_LINEAR = (this.refractionTexture != null && !this.refractionTexture.gammaSpace);
        }
        if (defines._areFresnelDirty) {
            if (StandardMaterial.FresnelEnabled) {
                // Fresnel
                if (this._diffuseFresnelParameters || this._opacityFresnelParameters ||
                    this._emissiveFresnelParameters || this._refractionFresnelParameters ||
                    this._reflectionFresnelParameters) {
                    defines.DIFFUSEFRESNEL = (this._diffuseFresnelParameters && this._diffuseFresnelParameters.isEnabled);
                    defines.OPACITYFRESNEL = (this._opacityFresnelParameters && this._opacityFresnelParameters.isEnabled);
                    defines.REFLECTIONFRESNEL = (this._reflectionFresnelParameters && this._reflectionFresnelParameters.isEnabled);
                    defines.REFLECTIONFRESNELFROMSPECULAR = this._useReflectionFresnelFromSpecular;
                    defines.REFRACTIONFRESNEL = (this._refractionFresnelParameters && this._refractionFresnelParameters.isEnabled);
                    defines.EMISSIVEFRESNEL = (this._emissiveFresnelParameters && this._emissiveFresnelParameters.isEnabled);
                    defines._needNormals = true;
                    defines.FRESNEL = true;
                }
            }
            else {
                defines.FRESNEL = false;
            }
        }
        // Misc.
        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
        // Attribs
        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForAttributes(mesh, defines, true, true, true);
        // Values that need to be evaluated on every frame
        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances);
        // Get correct effect
        if (defines.isDirty) {
            var lightDisposed = defines._areLightsDisposed;
            defines.markAsProcessed();
            // Fallbacks
            var fallbacks = new _effect__WEBPACK_IMPORTED_MODULE_8__["EffectFallbacks"]();
            if (defines.REFLECTION) {
                fallbacks.addFallback(0, "REFLECTION");
            }
            if (defines.SPECULAR) {
                fallbacks.addFallback(0, "SPECULAR");
            }
            if (defines.BUMP) {
                fallbacks.addFallback(0, "BUMP");
            }
            if (defines.PARALLAX) {
                fallbacks.addFallback(1, "PARALLAX");
            }
            if (defines.PARALLAXOCCLUSION) {
                fallbacks.addFallback(0, "PARALLAXOCCLUSION");
            }
            if (defines.SPECULAROVERALPHA) {
                fallbacks.addFallback(0, "SPECULAROVERALPHA");
            }
            if (defines.FOG) {
                fallbacks.addFallback(1, "FOG");
            }
            if (defines.POINTSIZE) {
                fallbacks.addFallback(0, "POINTSIZE");
            }
            if (defines.LOGARITHMICDEPTH) {
                fallbacks.addFallback(0, "LOGARITHMICDEPTH");
            }
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].HandleFallbacksForShadows(defines, fallbacks, this._maxSimultaneousLights);
            if (defines.SPECULARTERM) {
                fallbacks.addFallback(0, "SPECULARTERM");
            }
            if (defines.DIFFUSEFRESNEL) {
                fallbacks.addFallback(1, "DIFFUSEFRESNEL");
            }
            if (defines.OPACITYFRESNEL) {
                fallbacks.addFallback(2, "OPACITYFRESNEL");
            }
            if (defines.REFLECTIONFRESNEL) {
                fallbacks.addFallback(3, "REFLECTIONFRESNEL");
            }
            if (defines.EMISSIVEFRESNEL) {
                fallbacks.addFallback(4, "EMISSIVEFRESNEL");
            }
            if (defines.FRESNEL) {
                fallbacks.addFallback(4, "FRESNEL");
            }
            if (defines.MULTIVIEW) {
                fallbacks.addFallback(0, "MULTIVIEW");
            }
            //Attributes
            var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["VertexBuffer"].PositionKind];
            if (defines.NORMAL) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["VertexBuffer"].NormalKind);
            }
            if (defines.UV1) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["VertexBuffer"].UVKind);
            }
            if (defines.UV2) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["VertexBuffer"].UV2Kind);
            }
            if (defines.VERTEXCOLOR) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["VertexBuffer"].ColorKind);
            }
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareAttributesForBones(attribs, mesh, defines, fallbacks);
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareAttributesForInstances(attribs, defines);
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareAttributesForMorphTargets(attribs, mesh, defines);
            var shaderName = "default";
            var uniforms = ["world", "view", "viewProjection", "vEyePosition", "vLightsType", "vAmbientColor", "vDiffuseColor", "vSpecularColor", "vEmissiveColor", "visibility",
                "vFogInfos", "vFogColor", "pointSize",
                "vDiffuseInfos", "vAmbientInfos", "vOpacityInfos", "vReflectionInfos", "vEmissiveInfos", "vSpecularInfos", "vBumpInfos", "vLightmapInfos", "vRefractionInfos",
                "mBones",
                "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "diffuseMatrix", "ambientMatrix", "opacityMatrix", "reflectionMatrix", "emissiveMatrix", "specularMatrix", "bumpMatrix", "normalMatrix", "lightmapMatrix", "refractionMatrix",
                "diffuseLeftColor", "diffuseRightColor", "opacityParts", "reflectionLeftColor", "reflectionRightColor", "emissiveLeftColor", "emissiveRightColor", "refractionLeftColor", "refractionRightColor",
                "vReflectionPosition", "vReflectionSize",
                "logarithmicDepthConstant", "vTangentSpaceParams", "alphaCutOff", "boneTextureWidth"
            ];
            var samplers = ["diffuseSampler", "ambientSampler", "opacitySampler", "reflectionCubeSampler",
                "reflection2DSampler", "emissiveSampler", "specularSampler", "bumpSampler", "lightmapSampler",
                "refractionCubeSampler", "refraction2DSampler", "boneSampler"];
            var uniformBuffers = ["Material", "Scene"];
            if (_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_7__["ImageProcessingConfiguration"]) {
                _imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_7__["ImageProcessingConfiguration"].PrepareUniforms(uniforms, defines);
                _imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_7__["ImageProcessingConfiguration"].PrepareSamplers(samplers, defines);
            }
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].PrepareUniformsAndSamplersList({
                uniformsNames: uniforms,
                uniformBuffersNames: uniformBuffers,
                samplers: samplers,
                defines: defines,
                maxSimultaneousLights: this._maxSimultaneousLights
            });
            if (this.customShaderNameResolve) {
                shaderName = this.customShaderNameResolve(shaderName, uniforms, uniformBuffers, samplers, defines);
            }
            var join = defines.toString();
            var previousEffect = subMesh.effect;
            var effect = scene.getEngine().createEffect(shaderName, {
                attributes: attribs,
                uniformsNames: uniforms,
                uniformBuffersNames: uniformBuffers,
                samplers: samplers,
                defines: join,
                fallbacks: fallbacks,
                onCompiled: this.onCompiled,
                onError: this.onError,
                indexParameters: { maxSimultaneousLights: this._maxSimultaneousLights, maxSimultaneousMorphTargets: defines.NUM_MORPH_INFLUENCERS }
            }, engine);
            if (effect) {
                // Use previous effect while new one is compiling
                if (this.allowShaderHotSwapping && previousEffect && !effect.isReady()) {
                    effect = previousEffect;
                    this._rebuildInParallel = true;
                    defines.markAsUnprocessed();
                    if (lightDisposed) {
                        // re register in case it takes more than one frame.
                        defines._areLightsDisposed = true;
                        return false;
                    }
                }
                else {
                    this._rebuildInParallel = false;
                    scene.resetCachedMaterial();
                    subMesh.setEffect(effect, defines);
                    this.buildUniformLayout();
                }
            }
        }
        if (!subMesh.effect || !subMesh.effect.isReady()) {
            return false;
        }
        defines._renderId = scene.getRenderId();
        this._wasPreviouslyReady = true;
        return true;
    };
    /**
     * Builds the material UBO layouts.
     * Used internally during the effect preparation.
     */
    StandardMaterial.prototype.buildUniformLayout = function () {
        // Order is important !
        var ubo = this._uniformBuffer;
        ubo.addUniform("diffuseLeftColor", 4);
        ubo.addUniform("diffuseRightColor", 4);
        ubo.addUniform("opacityParts", 4);
        ubo.addUniform("reflectionLeftColor", 4);
        ubo.addUniform("reflectionRightColor", 4);
        ubo.addUniform("refractionLeftColor", 4);
        ubo.addUniform("refractionRightColor", 4);
        ubo.addUniform("emissiveLeftColor", 4);
        ubo.addUniform("emissiveRightColor", 4);
        ubo.addUniform("vDiffuseInfos", 2);
        ubo.addUniform("vAmbientInfos", 2);
        ubo.addUniform("vOpacityInfos", 2);
        ubo.addUniform("vReflectionInfos", 2);
        ubo.addUniform("vReflectionPosition", 3);
        ubo.addUniform("vReflectionSize", 3);
        ubo.addUniform("vEmissiveInfos", 2);
        ubo.addUniform("vLightmapInfos", 2);
        ubo.addUniform("vSpecularInfos", 2);
        ubo.addUniform("vBumpInfos", 3);
        ubo.addUniform("diffuseMatrix", 16);
        ubo.addUniform("ambientMatrix", 16);
        ubo.addUniform("opacityMatrix", 16);
        ubo.addUniform("reflectionMatrix", 16);
        ubo.addUniform("emissiveMatrix", 16);
        ubo.addUniform("lightmapMatrix", 16);
        ubo.addUniform("specularMatrix", 16);
        ubo.addUniform("bumpMatrix", 16);
        ubo.addUniform("vTangentSpaceParams", 2);
        ubo.addUniform("pointSize", 1);
        ubo.addUniform("refractionMatrix", 16);
        ubo.addUniform("vRefractionInfos", 4);
        ubo.addUniform("vSpecularColor", 4);
        ubo.addUniform("vEmissiveColor", 3);
        ubo.addUniform("visibility", 1);
        ubo.addUniform("vDiffuseColor", 4);
        ubo.create();
    };
    /**
     * Unbinds the material from the mesh
     */
    StandardMaterial.prototype.unbind = function () {
        if (this._activeEffect) {
            var needFlag = false;
            if (this._reflectionTexture && this._reflectionTexture.isRenderTarget) {
                this._activeEffect.setTexture("reflection2DSampler", null);
                needFlag = true;
            }
            if (this._refractionTexture && this._refractionTexture.isRenderTarget) {
                this._activeEffect.setTexture("refraction2DSampler", null);
                needFlag = true;
            }
            if (needFlag) {
                this._markAllSubMeshesAsTexturesDirty();
            }
        }
        _super.prototype.unbind.call(this);
    };
    /**
     * Binds the submesh to this material by preparing the effect and shader to draw
     * @param world defines the world transformation matrix
     * @param mesh defines the mesh containing the submesh
     * @param subMesh defines the submesh to bind the material to
     */
    StandardMaterial.prototype.bindForSubMesh = function (world, mesh, subMesh) {
        var scene = this.getScene();
        var defines = subMesh._materialDefines;
        if (!defines) {
            return;
        }
        var effect = subMesh.effect;
        if (!effect) {
            return;
        }
        this._activeEffect = effect;
        // Matrices
        if (!defines.INSTANCES) {
            this.bindOnlyWorldMatrix(world);
        }
        // Normal Matrix
        if (defines.OBJECTSPACE_NORMALMAP) {
            world.toNormalMatrix(this._normalMatrix);
            this.bindOnlyNormalMatrix(this._normalMatrix);
        }
        var mustRebind = this._mustRebind(scene, effect, mesh.visibility);
        // Bones
        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindBonesParameters(mesh, effect);
        var ubo = this._uniformBuffer;
        if (mustRebind) {
            ubo.bindToEffect(effect, "Material");
            this.bindViewProjection(effect);
            if (!ubo.useUbo || !this.isFrozen || !ubo.isSync) {
                if (StandardMaterial.FresnelEnabled && defines.FRESNEL) {
                    // Fresnel
                    if (this.diffuseFresnelParameters && this.diffuseFresnelParameters.isEnabled) {
                        ubo.updateColor4("diffuseLeftColor", this.diffuseFresnelParameters.leftColor, this.diffuseFresnelParameters.power);
                        ubo.updateColor4("diffuseRightColor", this.diffuseFresnelParameters.rightColor, this.diffuseFresnelParameters.bias);
                    }
                    if (this.opacityFresnelParameters && this.opacityFresnelParameters.isEnabled) {
                        ubo.updateColor4("opacityParts", new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](this.opacityFresnelParameters.leftColor.toLuminance(), this.opacityFresnelParameters.rightColor.toLuminance(), this.opacityFresnelParameters.bias), this.opacityFresnelParameters.power);
                    }
                    if (this.reflectionFresnelParameters && this.reflectionFresnelParameters.isEnabled) {
                        ubo.updateColor4("reflectionLeftColor", this.reflectionFresnelParameters.leftColor, this.reflectionFresnelParameters.power);
                        ubo.updateColor4("reflectionRightColor", this.reflectionFresnelParameters.rightColor, this.reflectionFresnelParameters.bias);
                    }
                    if (this.refractionFresnelParameters && this.refractionFresnelParameters.isEnabled) {
                        ubo.updateColor4("refractionLeftColor", this.refractionFresnelParameters.leftColor, this.refractionFresnelParameters.power);
                        ubo.updateColor4("refractionRightColor", this.refractionFresnelParameters.rightColor, this.refractionFresnelParameters.bias);
                    }
                    if (this.emissiveFresnelParameters && this.emissiveFresnelParameters.isEnabled) {
                        ubo.updateColor4("emissiveLeftColor", this.emissiveFresnelParameters.leftColor, this.emissiveFresnelParameters.power);
                        ubo.updateColor4("emissiveRightColor", this.emissiveFresnelParameters.rightColor, this.emissiveFresnelParameters.bias);
                    }
                }
                // Textures
                if (scene.texturesEnabled) {
                    if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                        ubo.updateFloat2("vDiffuseInfos", this._diffuseTexture.coordinatesIndex, this._diffuseTexture.level);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._diffuseTexture, ubo, "diffuse");
                        if (this._diffuseTexture.hasAlpha) {
                            effect.setFloat("alphaCutOff", this.alphaCutOff);
                        }
                    }
                    if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                        ubo.updateFloat2("vAmbientInfos", this._ambientTexture.coordinatesIndex, this._ambientTexture.level);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._ambientTexture, ubo, "ambient");
                    }
                    if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
                        ubo.updateFloat2("vOpacityInfos", this._opacityTexture.coordinatesIndex, this._opacityTexture.level);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._opacityTexture, ubo, "opacity");
                    }
                    if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
                        ubo.updateFloat2("vReflectionInfos", this._reflectionTexture.level, this.roughness);
                        ubo.updateMatrix("reflectionMatrix", this._reflectionTexture.getReflectionTextureMatrix());
                        if (this._reflectionTexture.boundingBoxSize) {
                            var cubeTexture = this._reflectionTexture;
                            ubo.updateVector3("vReflectionPosition", cubeTexture.boundingBoxPosition);
                            ubo.updateVector3("vReflectionSize", cubeTexture.boundingBoxSize);
                        }
                    }
                    if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
                        ubo.updateFloat2("vEmissiveInfos", this._emissiveTexture.coordinatesIndex, this._emissiveTexture.level);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._emissiveTexture, ubo, "emissive");
                    }
                    if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
                        ubo.updateFloat2("vLightmapInfos", this._lightmapTexture.coordinatesIndex, this._lightmapTexture.level);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._lightmapTexture, ubo, "lightmap");
                    }
                    if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
                        ubo.updateFloat2("vSpecularInfos", this._specularTexture.coordinatesIndex, this._specularTexture.level);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._specularTexture, ubo, "specular");
                    }
                    if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {
                        ubo.updateFloat3("vBumpInfos", this._bumpTexture.coordinatesIndex, 1.0 / this._bumpTexture.level, this.parallaxScaleBias);
                        _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindTextureMatrix(this._bumpTexture, ubo, "bump");
                        if (scene._mirroredCameraPosition) {
                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? 1.0 : -1.0, this._invertNormalMapY ? 1.0 : -1.0);
                        }
                        else {
                            ubo.updateFloat2("vTangentSpaceParams", this._invertNormalMapX ? -1.0 : 1.0, this._invertNormalMapY ? -1.0 : 1.0);
                        }
                    }
                    if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                        var depth = 1.0;
                        if (!this._refractionTexture.isCube) {
                            ubo.updateMatrix("refractionMatrix", this._refractionTexture.getReflectionTextureMatrix());
                            if (this._refractionTexture.depth) {
                                depth = this._refractionTexture.depth;
                            }
                        }
                        ubo.updateFloat4("vRefractionInfos", this._refractionTexture.level, this.indexOfRefraction, depth, this.invertRefractionY ? -1 : 1);
                    }
                }
                // Point size
                if (this.pointsCloud) {
                    ubo.updateFloat("pointSize", this.pointSize);
                }
                if (defines.SPECULARTERM) {
                    ubo.updateColor4("vSpecularColor", this.specularColor, this.specularPower);
                }
                ubo.updateColor3("vEmissiveColor", StandardMaterial.EmissiveTextureEnabled ? this.emissiveColor : _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"].BlackReadOnly);
                // Visibility
                ubo.updateFloat("visibility", mesh.visibility);
                // Diffuse
                ubo.updateColor4("vDiffuseColor", this.diffuseColor, this.alpha);
            }
            // Textures
            if (scene.texturesEnabled) {
                if (this._diffuseTexture && StandardMaterial.DiffuseTextureEnabled) {
                    effect.setTexture("diffuseSampler", this._diffuseTexture);
                }
                if (this._ambientTexture && StandardMaterial.AmbientTextureEnabled) {
                    effect.setTexture("ambientSampler", this._ambientTexture);
                }
                if (this._opacityTexture && StandardMaterial.OpacityTextureEnabled) {
                    effect.setTexture("opacitySampler", this._opacityTexture);
                }
                if (this._reflectionTexture && StandardMaterial.ReflectionTextureEnabled) {
                    if (this._reflectionTexture.isCube) {
                        effect.setTexture("reflectionCubeSampler", this._reflectionTexture);
                    }
                    else {
                        effect.setTexture("reflection2DSampler", this._reflectionTexture);
                    }
                }
                if (this._emissiveTexture && StandardMaterial.EmissiveTextureEnabled) {
                    effect.setTexture("emissiveSampler", this._emissiveTexture);
                }
                if (this._lightmapTexture && StandardMaterial.LightmapTextureEnabled) {
                    effect.setTexture("lightmapSampler", this._lightmapTexture);
                }
                if (this._specularTexture && StandardMaterial.SpecularTextureEnabled) {
                    effect.setTexture("specularSampler", this._specularTexture);
                }
                if (this._bumpTexture && scene.getEngine().getCaps().standardDerivatives && StandardMaterial.BumpTextureEnabled) {
                    effect.setTexture("bumpSampler", this._bumpTexture);
                }
                if (this._refractionTexture && StandardMaterial.RefractionTextureEnabled) {
                    var depth = 1.0;
                    if (this._refractionTexture.isCube) {
                        effect.setTexture("refractionCubeSampler", this._refractionTexture);
                    }
                    else {
                        effect.setTexture("refraction2DSampler", this._refractionTexture);
                    }
                }
            }
            // Clip plane
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindClipPlane(effect, scene);
            // Colors
            scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindEyePosition(effect, scene);
            effect.setColor3("vAmbientColor", this._globalAmbientColor);
        }
        if (mustRebind || !this.isFrozen) {
            // Lights
            if (scene.lightsEnabled && !this._disableLighting) {
                _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindLights(scene, mesh, effect, defines, this._maxSimultaneousLights, false, this._rebuildInParallel);
            }
            // View
            if (scene.fogEnabled && mesh.applyFog && scene.fogMode !== _scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].FOGMODE_NONE || this._reflectionTexture || this._refractionTexture) {
                this.bindView(effect);
            }
            // Fog
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindFogParameters(scene, mesh, effect);
            // Morph targets
            if (defines.NUM_MORPH_INFLUENCERS) {
                _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindMorphTargetParameters(mesh, effect);
            }
            // Log. depth
            _materialHelper__WEBPACK_IMPORTED_MODULE_11__["MaterialHelper"].BindLogDepth(defines, effect, scene);
            // image processing
            if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {
                this._imageProcessingConfiguration.bind(this._activeEffect);
            }
        }
        ubo.update();
        this._afterBind(mesh, this._activeEffect);
    };
    /**
     * Get the list of animatables in the material.
     * @returns the list of animatables object used in the material
     */
    StandardMaterial.prototype.getAnimatables = function () {
        var results = [];
        if (this._diffuseTexture && this._diffuseTexture.animations && this._diffuseTexture.animations.length > 0) {
            results.push(this._diffuseTexture);
        }
        if (this._ambientTexture && this._ambientTexture.animations && this._ambientTexture.animations.length > 0) {
            results.push(this._ambientTexture);
        }
        if (this._opacityTexture && this._opacityTexture.animations && this._opacityTexture.animations.length > 0) {
            results.push(this._opacityTexture);
        }
        if (this._reflectionTexture && this._reflectionTexture.animations && this._reflectionTexture.animations.length > 0) {
            results.push(this._reflectionTexture);
        }
        if (this._emissiveTexture && this._emissiveTexture.animations && this._emissiveTexture.animations.length > 0) {
            results.push(this._emissiveTexture);
        }
        if (this._specularTexture && this._specularTexture.animations && this._specularTexture.animations.length > 0) {
            results.push(this._specularTexture);
        }
        if (this._bumpTexture && this._bumpTexture.animations && this._bumpTexture.animations.length > 0) {
            results.push(this._bumpTexture);
        }
        if (this._lightmapTexture && this._lightmapTexture.animations && this._lightmapTexture.animations.length > 0) {
            results.push(this._lightmapTexture);
        }
        if (this._refractionTexture && this._refractionTexture.animations && this._refractionTexture.animations.length > 0) {
            results.push(this._refractionTexture);
        }
        return results;
    };
    /**
     * Gets the active textures from the material
     * @returns an array of textures
     */
    StandardMaterial.prototype.getActiveTextures = function () {
        var activeTextures = _super.prototype.getActiveTextures.call(this);
        if (this._diffuseTexture) {
            activeTextures.push(this._diffuseTexture);
        }
        if (this._ambientTexture) {
            activeTextures.push(this._ambientTexture);
        }
        if (this._opacityTexture) {
            activeTextures.push(this._opacityTexture);
        }
        if (this._reflectionTexture) {
            activeTextures.push(this._reflectionTexture);
        }
        if (this._emissiveTexture) {
            activeTextures.push(this._emissiveTexture);
        }
        if (this._specularTexture) {
            activeTextures.push(this._specularTexture);
        }
        if (this._bumpTexture) {
            activeTextures.push(this._bumpTexture);
        }
        if (this._lightmapTexture) {
            activeTextures.push(this._lightmapTexture);
        }
        if (this._refractionTexture) {
            activeTextures.push(this._refractionTexture);
        }
        return activeTextures;
    };
    /**
     * Specifies if the material uses a texture
     * @param texture defines the texture to check against the material
     * @returns a boolean specifying if the material uses the texture
     */
    StandardMaterial.prototype.hasTexture = function (texture) {
        if (_super.prototype.hasTexture.call(this, texture)) {
            return true;
        }
        if (this._diffuseTexture === texture) {
            return true;
        }
        if (this._ambientTexture === texture) {
            return true;
        }
        if (this._opacityTexture === texture) {
            return true;
        }
        if (this._reflectionTexture === texture) {
            return true;
        }
        if (this._emissiveTexture === texture) {
            return true;
        }
        if (this._specularTexture === texture) {
            return true;
        }
        if (this._bumpTexture === texture) {
            return true;
        }
        if (this._lightmapTexture === texture) {
            return true;
        }
        if (this._refractionTexture === texture) {
            return true;
        }
        return false;
    };
    /**
     * Disposes the material
     * @param forceDisposeEffect specifies if effects should be forcefully disposed
     * @param forceDisposeTextures specifies if textures should be forcefully disposed
     */
    StandardMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
        if (forceDisposeTextures) {
            if (this._diffuseTexture) {
                this._diffuseTexture.dispose();
            }
            if (this._ambientTexture) {
                this._ambientTexture.dispose();
            }
            if (this._opacityTexture) {
                this._opacityTexture.dispose();
            }
            if (this._reflectionTexture) {
                this._reflectionTexture.dispose();
            }
            if (this._emissiveTexture) {
                this._emissiveTexture.dispose();
            }
            if (this._specularTexture) {
                this._specularTexture.dispose();
            }
            if (this._bumpTexture) {
                this._bumpTexture.dispose();
            }
            if (this._lightmapTexture) {
                this._lightmapTexture.dispose();
            }
            if (this._refractionTexture) {
                this._refractionTexture.dispose();
            }
        }
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        _super.prototype.dispose.call(this, forceDisposeEffect, forceDisposeTextures);
    };
    /**
     * Makes a duplicate of the material, and gives it a new name
     * @param name defines the new name for the duplicated material
     * @returns the cloned material
     */
    StandardMaterial.prototype.clone = function (name) {
        var _this = this;
        var result = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new StandardMaterial(name, _this.getScene()); }, this);
        result.name = name;
        result.id = name;
        return result;
    };
    /**
     * Serializes this material in a JSON representation
     * @returns the serialized material object
     */
    StandardMaterial.prototype.serialize = function () {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
    };
    /**
     * Creates a standard material from parsed material data
     * @param source defines the JSON representation of the material
     * @param scene defines the hosting scene
     * @param rootUrl defines the root URL to use to load textures and relative dependencies
     * @returns a new standard material
     */
    StandardMaterial.Parse = function (source, scene, rootUrl) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new StandardMaterial(source.name, scene); }, source, scene, rootUrl);
    };
    Object.defineProperty(StandardMaterial, "DiffuseTextureEnabled", {
        // Flags used to enable or disable a type of texture for all Standard Materials
        /**
         * Are diffuse textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].DiffuseTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].DiffuseTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "AmbientTextureEnabled", {
        /**
         * Are ambient textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].AmbientTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].AmbientTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "OpacityTextureEnabled", {
        /**
         * Are opacity textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].OpacityTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].OpacityTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "ReflectionTextureEnabled", {
        /**
         * Are reflection textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ReflectionTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ReflectionTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "EmissiveTextureEnabled", {
        /**
         * Are emissive textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].EmissiveTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].EmissiveTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "SpecularTextureEnabled", {
        /**
         * Are specular textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].SpecularTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].SpecularTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "BumpTextureEnabled", {
        /**
         * Are bump textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].BumpTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].BumpTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "LightmapTextureEnabled", {
        /**
         * Are lightmap textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].LightmapTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].LightmapTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "RefractionTextureEnabled", {
        /**
         * Are refraction textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].RefractionTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].RefractionTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "ColorGradingTextureEnabled", {
        /**
         * Are color grading textures enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ColorGradingTextureEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].ColorGradingTextureEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardMaterial, "FresnelEnabled", {
        /**
         * Are fresnels enabled in the application.
         */
        get: function () {
            return _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].FresnelEnabled;
        },
        set: function (value) {
            _materialFlags__WEBPACK_IMPORTED_MODULE_14__["MaterialFlags"].FresnelEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("diffuseTexture")
    ], StandardMaterial.prototype, "_diffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesAndMiscDirty")
    ], StandardMaterial.prototype, "diffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("ambientTexture")
    ], StandardMaterial.prototype, "_ambientTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "ambientTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("opacityTexture")
    ], StandardMaterial.prototype, "_opacityTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesAndMiscDirty")
    ], StandardMaterial.prototype, "opacityTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("reflectionTexture")
    ], StandardMaterial.prototype, "_reflectionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "reflectionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("emissiveTexture")
    ], StandardMaterial.prototype, "_emissiveTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "emissiveTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("specularTexture")
    ], StandardMaterial.prototype, "_specularTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "specularTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("bumpTexture")
    ], StandardMaterial.prototype, "_bumpTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "bumpTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("lightmapTexture")
    ], StandardMaterial.prototype, "_lightmapTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "lightmapTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("refractionTexture")
    ], StandardMaterial.prototype, "_refractionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "refractionTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("ambient")
    ], StandardMaterial.prototype, "ambientColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("diffuse")
    ], StandardMaterial.prototype, "diffuseColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("specular")
    ], StandardMaterial.prototype, "specularColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])("emissive")
    ], StandardMaterial.prototype, "emissiveColor", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardMaterial.prototype, "specularPower", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useAlphaFromDiffuseTexture")
    ], StandardMaterial.prototype, "_useAlphaFromDiffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useAlphaFromDiffuseTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useEmissiveAsIllumination")
    ], StandardMaterial.prototype, "_useEmissiveAsIllumination", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useEmissiveAsIllumination", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("linkEmissiveWithDiffuse")
    ], StandardMaterial.prototype, "_linkEmissiveWithDiffuse", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "linkEmissiveWithDiffuse", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useSpecularOverAlpha")
    ], StandardMaterial.prototype, "_useSpecularOverAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useSpecularOverAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useReflectionOverAlpha")
    ], StandardMaterial.prototype, "_useReflectionOverAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useReflectionOverAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("disableLighting")
    ], StandardMaterial.prototype, "_disableLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], StandardMaterial.prototype, "disableLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useObjectSpaceNormalMap")
    ], StandardMaterial.prototype, "_useObjectSpaceNormalMap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useObjectSpaceNormalMap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useParallax")
    ], StandardMaterial.prototype, "_useParallax", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useParallax", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useParallaxOcclusion")
    ], StandardMaterial.prototype, "_useParallaxOcclusion", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useParallaxOcclusion", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardMaterial.prototype, "parallaxScaleBias", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("roughness")
    ], StandardMaterial.prototype, "_roughness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "roughness", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardMaterial.prototype, "indexOfRefraction", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardMaterial.prototype, "invertRefractionY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardMaterial.prototype, "alphaCutOff", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useLightmapAsShadowmap")
    ], StandardMaterial.prototype, "_useLightmapAsShadowmap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useLightmapAsShadowmap", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsFresnelParameters"])("diffuseFresnelParameters")
    ], StandardMaterial.prototype, "_diffuseFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsFresnelDirty")
    ], StandardMaterial.prototype, "diffuseFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsFresnelParameters"])("opacityFresnelParameters")
    ], StandardMaterial.prototype, "_opacityFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsFresnelAndMiscDirty")
    ], StandardMaterial.prototype, "opacityFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsFresnelParameters"])("reflectionFresnelParameters")
    ], StandardMaterial.prototype, "_reflectionFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsFresnelDirty")
    ], StandardMaterial.prototype, "reflectionFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsFresnelParameters"])("refractionFresnelParameters")
    ], StandardMaterial.prototype, "_refractionFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsFresnelDirty")
    ], StandardMaterial.prototype, "refractionFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsFresnelParameters"])("emissiveFresnelParameters")
    ], StandardMaterial.prototype, "_emissiveFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsFresnelDirty")
    ], StandardMaterial.prototype, "emissiveFresnelParameters", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useReflectionFresnelFromSpecular")
    ], StandardMaterial.prototype, "_useReflectionFresnelFromSpecular", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsFresnelDirty")
    ], StandardMaterial.prototype, "useReflectionFresnelFromSpecular", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("useGlossinessFromSpecularMapAlpha")
    ], StandardMaterial.prototype, "_useGlossinessFromSpecularMapAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "useGlossinessFromSpecularMapAlpha", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("maxSimultaneousLights")
    ], StandardMaterial.prototype, "_maxSimultaneousLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsLightsDirty")
    ], StandardMaterial.prototype, "maxSimultaneousLights", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("invertNormalMapX")
    ], StandardMaterial.prototype, "_invertNormalMapX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "invertNormalMapX", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("invertNormalMapY")
    ], StandardMaterial.prototype, "_invertNormalMapY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "invertNormalMapY", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("twoSidedLighting")
    ], StandardMaterial.prototype, "_twoSidedLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["expandToProperty"])("_markAllSubMeshesAsTexturesDirty")
    ], StandardMaterial.prototype, "twoSidedLighting", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardMaterial.prototype, "useLogarithmicDepth", null);
    return StandardMaterial;
}(_pushMaterial__WEBPACK_IMPORTED_MODULE_10__["PushMaterial"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_13__["_TypeStore"].RegisteredTypes["BABYLON.StandardMaterial"] = StandardMaterial;
_scene__WEBPACK_IMPORTED_MODULE_3__["Scene"].DefaultMaterialFactory = function (scene) {
    return new StandardMaterial("default material", scene);
};


/***/ }),

/***/ "./Materials/uniformBuffer.ts":
/*!************************************!*\
  !*** ./Materials/uniformBuffer.ts ***!
  \************************************/
/*! exports provided: UniformBuffer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UniformBuffer", function() { return UniformBuffer; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");

/**
 * Uniform buffer objects.
 *
 * Handles blocks of uniform on the GPU.
 *
 * If WebGL 2 is not available, this class falls back on traditionnal setUniformXXX calls.
 *
 * For more information, please refer to :
 * https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object
 */
var UniformBuffer = /** @class */ (function () {
    /**
     * Instantiates a new Uniform buffer objects.
     *
     * Handles blocks of uniform on the GPU.
     *
     * If WebGL 2 is not available, this class falls back on traditionnal setUniformXXX calls.
     *
     * For more information, please refer to :
     * @see https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object
     * @param engine Define the engine the buffer is associated with
     * @param data Define the data contained in the buffer
     * @param dynamic Define if the buffer is updatable
     */
    function UniformBuffer(engine, data, dynamic) {
        // Matrix cache
        this._valueCache = {};
        this._engine = engine;
        this._noUBO = !engine.supportsUniformBuffers;
        this._dynamic = dynamic;
        this._data = data || [];
        this._uniformLocations = {};
        this._uniformSizes = {};
        this._uniformArraySizes = {};
        this._uniformLocationPointer = 0;
        this._needSync = false;
        if (this._noUBO) {
            this.updateMatrix3x3 = this._updateMatrix3x3ForEffect;
            this.updateMatrix2x2 = this._updateMatrix2x2ForEffect;
            this.updateFloat = this._updateFloatForEffect;
            this.updateFloat2 = this._updateFloat2ForEffect;
            this.updateFloat3 = this._updateFloat3ForEffect;
            this.updateFloat4 = this._updateFloat4ForEffect;
            this.updateFloatArray = this._updateFloatArrayForEffect;
            this.updateMatrix = this._updateMatrixForEffect;
            this.updateMatrices = this._updateMatricesForEffect;
            this.updateVector3 = this._updateVector3ForEffect;
            this.updateVector4 = this._updateVector4ForEffect;
            this.updateColor3 = this._updateColor3ForEffect;
            this.updateColor4 = this._updateColor4ForEffect;
        }
        else {
            this._engine._uniformBuffers.push(this);
            this.updateMatrix3x3 = this._updateMatrix3x3ForUniform;
            this.updateMatrix2x2 = this._updateMatrix2x2ForUniform;
            this.updateFloat = this._updateFloatForUniform;
            this.updateFloat2 = this._updateFloat2ForUniform;
            this.updateFloat3 = this._updateFloat3ForUniform;
            this.updateFloat4 = this._updateFloat4ForUniform;
            this.updateFloatArray = this._updateFloatArrayForUniform;
            this.updateMatrix = this._updateMatrixForUniform;
            this.updateMatrices = this._updateMatricesForUniform;
            this.updateVector3 = this._updateVector3ForUniform;
            this.updateVector4 = this._updateVector4ForUniform;
            this.updateColor3 = this._updateColor3ForUniform;
            this.updateColor4 = this._updateColor4ForUniform;
        }
    }
    Object.defineProperty(UniformBuffer.prototype, "useUbo", {
        /**
         * Indicates if the buffer is using the WebGL2 UBO implementation,
         * or just falling back on setUniformXXX calls.
         */
        get: function () {
            return !this._noUBO;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(UniformBuffer.prototype, "isSync", {
        /**
         * Indicates if the WebGL underlying uniform buffer is in sync
         * with the javascript cache data.
         */
        get: function () {
            return !this._needSync;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Indicates if the WebGL underlying uniform buffer is dynamic.
     * Also, a dynamic UniformBuffer will disable cache verification and always
     * update the underlying WebGL uniform buffer to the GPU.
     * @returns if Dynamic, otherwise false
     */
    UniformBuffer.prototype.isDynamic = function () {
        return this._dynamic !== undefined;
    };
    /**
     * The data cache on JS side.
     * @returns the underlying data as a float array
     */
    UniformBuffer.prototype.getData = function () {
        return this._bufferData;
    };
    /**
     * The underlying WebGL Uniform buffer.
     * @returns the webgl buffer
     */
    UniformBuffer.prototype.getBuffer = function () {
        return this._buffer;
    };
    /**
     * std140 layout specifies how to align data within an UBO structure.
     * See https://khronos.org/registry/OpenGL/specs/gl/glspec45.core.pdf#page=159
     * for specs.
     */
    UniformBuffer.prototype._fillAlignment = function (size) {
        // This code has been simplified because we only use floats, vectors of 1, 2, 3, 4 components
        // and 4x4 matrices
        // TODO : change if other types are used
        var alignment;
        if (size <= 2) {
            alignment = size;
        }
        else {
            alignment = 4;
        }
        if ((this._uniformLocationPointer % alignment) !== 0) {
            var oldPointer = this._uniformLocationPointer;
            this._uniformLocationPointer += alignment - (this._uniformLocationPointer % alignment);
            var diff = this._uniformLocationPointer - oldPointer;
            for (var i = 0; i < diff; i++) {
                this._data.push(0);
            }
        }
    };
    /**
     * Adds an uniform in the buffer.
     * Warning : the subsequents calls of this function must be in the same order as declared in the shader
     * for the layout to be correct !
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param size Data size, or data directly.
     * @param arraySize The number of elements in the array, 0 if not an array.
     */
    UniformBuffer.prototype.addUniform = function (name, size, arraySize) {
        if (arraySize === void 0) { arraySize = 0; }
        if (this._noUBO) {
            return;
        }
        if (this._uniformLocations[name] !== undefined) {
            // Already existing uniform
            return;
        }
        // This function must be called in the order of the shader layout !
        // size can be the size of the uniform, or data directly
        var data;
        // std140 FTW...
        if (arraySize > 0) {
            if (size instanceof Array) {
                throw "addUniform should not be use with Array in UBO: " + name;
            }
            this._uniformArraySizes[name] = { strideSize: size, arraySize: arraySize };
            if (size == 16) {
                size = size * arraySize;
            }
            else {
                var perElementPadding = 4 - size;
                var totalPadding = perElementPadding * arraySize;
                size = size * arraySize + totalPadding;
            }
            data = [];
            // Fill with zeros
            for (var i = 0; i < size; i++) {
                data.push(0);
            }
        }
        else {
            if (size instanceof Array) {
                data = size;
                size = data.length;
            }
            else {
                size = size;
                data = [];
                // Fill with zeros
                for (var i = 0; i < size; i++) {
                    data.push(0);
                }
            }
            this._fillAlignment(size);
        }
        this._uniformSizes[name] = size;
        this._uniformLocations[name] = this._uniformLocationPointer;
        this._uniformLocationPointer += size;
        for (var i = 0; i < size; i++) {
            this._data.push(data[i]);
        }
        this._needSync = true;
    };
    /**
     * Adds a Matrix 4x4 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param mat A 4x4 matrix.
     */
    UniformBuffer.prototype.addMatrix = function (name, mat) {
        this.addUniform(name, Array.prototype.slice.call(mat.toArray()));
    };
    /**
     * Adds a vec2 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param x Define the x component value of the vec2
     * @param y Define the y component value of the vec2
     */
    UniformBuffer.prototype.addFloat2 = function (name, x, y) {
        var temp = [x, y];
        this.addUniform(name, temp);
    };
    /**
     * Adds a vec3 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param x Define the x component value of the vec3
     * @param y Define the y component value of the vec3
     * @param z Define the z component value of the vec3
     */
    UniformBuffer.prototype.addFloat3 = function (name, x, y, z) {
        var temp = [x, y, z];
        this.addUniform(name, temp);
    };
    /**
     * Adds a vec3 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param color Define the vec3 from a Color
     */
    UniformBuffer.prototype.addColor3 = function (name, color) {
        var temp = new Array();
        color.toArray(temp);
        this.addUniform(name, temp);
    };
    /**
     * Adds a vec4 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param color Define the rgb components from a Color
     * @param alpha Define the a component of the vec4
     */
    UniformBuffer.prototype.addColor4 = function (name, color, alpha) {
        var temp = new Array();
        color.toArray(temp);
        temp.push(alpha);
        this.addUniform(name, temp);
    };
    /**
     * Adds a vec3 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     * @param vector Define the vec3 components from a Vector
     */
    UniformBuffer.prototype.addVector3 = function (name, vector) {
        var temp = new Array();
        vector.toArray(temp);
        this.addUniform(name, temp);
    };
    /**
     * Adds a Matrix 3x3 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     */
    UniformBuffer.prototype.addMatrix3x3 = function (name) {
        this.addUniform(name, 12);
    };
    /**
     * Adds a Matrix 2x2 to the uniform buffer.
     * @param name Name of the uniform, as used in the uniform block in the shader.
     */
    UniformBuffer.prototype.addMatrix2x2 = function (name) {
        this.addUniform(name, 8);
    };
    /**
     * Effectively creates the WebGL Uniform Buffer, once layout is completed with `addUniform`.
     */
    UniformBuffer.prototype.create = function () {
        if (this._noUBO) {
            return;
        }
        if (this._buffer) {
            return; // nothing to do
        }
        // See spec, alignment must be filled as a vec4
        this._fillAlignment(4);
        this._bufferData = new Float32Array(this._data);
        this._rebuild();
        this._needSync = true;
    };
    /** @hidden */
    UniformBuffer.prototype._rebuild = function () {
        if (this._noUBO || !this._bufferData) {
            return;
        }
        if (this._dynamic) {
            this._buffer = this._engine.createDynamicUniformBuffer(this._bufferData);
        }
        else {
            this._buffer = this._engine.createUniformBuffer(this._bufferData);
        }
    };
    /**
     * Updates the WebGL Uniform Buffer on the GPU.
     * If the `dynamic` flag is set to true, no cache comparison is done.
     * Otherwise, the buffer will be updated only if the cache differs.
     */
    UniformBuffer.prototype.update = function () {
        if (!this._buffer) {
            this.create();
            return;
        }
        if (!this._dynamic && !this._needSync) {
            return;
        }
        this._engine.updateUniformBuffer(this._buffer, this._bufferData);
        this._needSync = false;
    };
    /**
     * Updates the value of an uniform. The `update` method must be called afterwards to make it effective in the GPU.
     * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.
     * @param data Define the flattened data
     * @param size Define the size of the data.
     */
    UniformBuffer.prototype.updateUniform = function (uniformName, data, size) {
        var location = this._uniformLocations[uniformName];
        if (location === undefined) {
            if (this._buffer) {
                // Cannot add an uniform if the buffer is already created
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Cannot add an uniform after UBO has been created.");
                return;
            }
            this.addUniform(uniformName, size);
            location = this._uniformLocations[uniformName];
        }
        if (!this._buffer) {
            this.create();
        }
        if (!this._dynamic) {
            // Cache for static uniform buffers
            var changed = false;
            for (var i = 0; i < size; i++) {
                if (size === 16 || this._bufferData[location + i] !== data[i]) {
                    changed = true;
                    this._bufferData[location + i] = data[i];
                }
            }
            this._needSync = this._needSync || changed;
        }
        else {
            // No cache for dynamic
            for (var i = 0; i < size; i++) {
                this._bufferData[location + i] = data[i];
            }
        }
    };
    /**
     * Updates the value of an uniform. The `update` method must be called afterwards to make it effective in the GPU.
     * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.
     * @param data Define the flattened data
     * @param size Define the size of the data.
     */
    UniformBuffer.prototype.updateUniformArray = function (uniformName, data, size) {
        var location = this._uniformLocations[uniformName];
        if (location === undefined) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Cannot add an uniform Array dynamically. Please, add it using addUniform.");
            return;
        }
        if (!this._buffer) {
            this.create();
        }
        var arraySizes = this._uniformArraySizes[uniformName];
        if (!this._dynamic) {
            // Cache for static uniform buffers
            var changed = false;
            var countToFour = 0;
            var baseStride = 0;
            for (var i = 0; i < size; i++) {
                if (this._bufferData[location + baseStride * 4 + countToFour] !== data[i]) {
                    changed = true;
                    this._bufferData[location + baseStride * 4 + countToFour] = data[i];
                }
                countToFour++;
                if (countToFour === arraySizes.strideSize) {
                    for (; countToFour < 4; countToFour++) {
                        this._bufferData[location + baseStride * 4 + countToFour] = 0;
                    }
                    countToFour = 0;
                    baseStride++;
                }
            }
            this._needSync = this._needSync || changed;
        }
        else {
            // No cache for dynamic
            for (var i = 0; i < size; i++) {
                this._bufferData[location + i] = data[i];
            }
        }
    };
    UniformBuffer.prototype._cacheMatrix = function (name, matrix) {
        var cache = this._valueCache[name];
        var flag = matrix.updateFlag;
        if (cache !== undefined && cache === flag) {
            return false;
        }
        this._valueCache[name] = flag;
        return true;
    };
    // Update methods
    UniformBuffer.prototype._updateMatrix3x3ForUniform = function (name, matrix) {
        // To match std140, matrix must be realigned
        for (var i = 0; i < 3; i++) {
            UniformBuffer._tempBuffer[i * 4] = matrix[i * 3];
            UniformBuffer._tempBuffer[i * 4 + 1] = matrix[i * 3 + 1];
            UniformBuffer._tempBuffer[i * 4 + 2] = matrix[i * 3 + 2];
            UniformBuffer._tempBuffer[i * 4 + 3] = 0.0;
        }
        this.updateUniform(name, UniformBuffer._tempBuffer, 12);
    };
    UniformBuffer.prototype._updateMatrix3x3ForEffect = function (name, matrix) {
        this._currentEffect.setMatrix3x3(name, matrix);
    };
    UniformBuffer.prototype._updateMatrix2x2ForEffect = function (name, matrix) {
        this._currentEffect.setMatrix2x2(name, matrix);
    };
    UniformBuffer.prototype._updateMatrix2x2ForUniform = function (name, matrix) {
        // To match std140, matrix must be realigned
        for (var i = 0; i < 2; i++) {
            UniformBuffer._tempBuffer[i * 4] = matrix[i * 2];
            UniformBuffer._tempBuffer[i * 4 + 1] = matrix[i * 2 + 1];
            UniformBuffer._tempBuffer[i * 4 + 2] = 0.0;
            UniformBuffer._tempBuffer[i * 4 + 3] = 0.0;
        }
        this.updateUniform(name, UniformBuffer._tempBuffer, 8);
    };
    UniformBuffer.prototype._updateFloatForEffect = function (name, x) {
        this._currentEffect.setFloat(name, x);
    };
    UniformBuffer.prototype._updateFloatForUniform = function (name, x) {
        UniformBuffer._tempBuffer[0] = x;
        this.updateUniform(name, UniformBuffer._tempBuffer, 1);
    };
    UniformBuffer.prototype._updateFloat2ForEffect = function (name, x, y, suffix) {
        if (suffix === void 0) { suffix = ""; }
        this._currentEffect.setFloat2(name + suffix, x, y);
    };
    UniformBuffer.prototype._updateFloat2ForUniform = function (name, x, y) {
        UniformBuffer._tempBuffer[0] = x;
        UniformBuffer._tempBuffer[1] = y;
        this.updateUniform(name, UniformBuffer._tempBuffer, 2);
    };
    UniformBuffer.prototype._updateFloat3ForEffect = function (name, x, y, z, suffix) {
        if (suffix === void 0) { suffix = ""; }
        this._currentEffect.setFloat3(name + suffix, x, y, z);
    };
    UniformBuffer.prototype._updateFloat3ForUniform = function (name, x, y, z) {
        UniformBuffer._tempBuffer[0] = x;
        UniformBuffer._tempBuffer[1] = y;
        UniformBuffer._tempBuffer[2] = z;
        this.updateUniform(name, UniformBuffer._tempBuffer, 3);
    };
    UniformBuffer.prototype._updateFloat4ForEffect = function (name, x, y, z, w, suffix) {
        if (suffix === void 0) { suffix = ""; }
        this._currentEffect.setFloat4(name + suffix, x, y, z, w);
    };
    UniformBuffer.prototype._updateFloat4ForUniform = function (name, x, y, z, w) {
        UniformBuffer._tempBuffer[0] = x;
        UniformBuffer._tempBuffer[1] = y;
        UniformBuffer._tempBuffer[2] = z;
        UniformBuffer._tempBuffer[3] = w;
        this.updateUniform(name, UniformBuffer._tempBuffer, 4);
    };
    UniformBuffer.prototype._updateFloatArrayForEffect = function (name, array) {
        this._currentEffect.setFloatArray(name, array);
    };
    UniformBuffer.prototype._updateFloatArrayForUniform = function (name, array) {
        this.updateUniformArray(name, array, array.length);
    };
    UniformBuffer.prototype._updateMatrixForEffect = function (name, mat) {
        this._currentEffect.setMatrix(name, mat);
    };
    UniformBuffer.prototype._updateMatrixForUniform = function (name, mat) {
        if (this._cacheMatrix(name, mat)) {
            this.updateUniform(name, mat.toArray(), 16);
        }
    };
    UniformBuffer.prototype._updateMatricesForEffect = function (name, mat) {
        this._currentEffect.setMatrices(name, mat);
    };
    UniformBuffer.prototype._updateMatricesForUniform = function (name, mat) {
        this.updateUniform(name, mat, mat.length);
    };
    UniformBuffer.prototype._updateVector3ForEffect = function (name, vector) {
        this._currentEffect.setVector3(name, vector);
    };
    UniformBuffer.prototype._updateVector3ForUniform = function (name, vector) {
        vector.toArray(UniformBuffer._tempBuffer);
        this.updateUniform(name, UniformBuffer._tempBuffer, 3);
    };
    UniformBuffer.prototype._updateVector4ForEffect = function (name, vector) {
        this._currentEffect.setVector4(name, vector);
    };
    UniformBuffer.prototype._updateVector4ForUniform = function (name, vector) {
        vector.toArray(UniformBuffer._tempBuffer);
        this.updateUniform(name, UniformBuffer._tempBuffer, 4);
    };
    UniformBuffer.prototype._updateColor3ForEffect = function (name, color, suffix) {
        if (suffix === void 0) { suffix = ""; }
        this._currentEffect.setColor3(name + suffix, color);
    };
    UniformBuffer.prototype._updateColor3ForUniform = function (name, color) {
        color.toArray(UniformBuffer._tempBuffer);
        this.updateUniform(name, UniformBuffer._tempBuffer, 3);
    };
    UniformBuffer.prototype._updateColor4ForEffect = function (name, color, alpha, suffix) {
        if (suffix === void 0) { suffix = ""; }
        this._currentEffect.setColor4(name + suffix, color, alpha);
    };
    UniformBuffer.prototype._updateColor4ForUniform = function (name, color, alpha) {
        color.toArray(UniformBuffer._tempBuffer);
        UniformBuffer._tempBuffer[3] = alpha;
        this.updateUniform(name, UniformBuffer._tempBuffer, 4);
    };
    /**
     * Sets a sampler uniform on the effect.
     * @param name Define the name of the sampler.
     * @param texture Define the texture to set in the sampler
     */
    UniformBuffer.prototype.setTexture = function (name, texture) {
        this._currentEffect.setTexture(name, texture);
    };
    /**
     * Directly updates the value of the uniform in the cache AND on the GPU.
     * @param uniformName Define the name of the uniform, as used in the uniform block in the shader.
     * @param data Define the flattened data
     */
    UniformBuffer.prototype.updateUniformDirectly = function (uniformName, data) {
        this.updateUniform(uniformName, data, data.length);
        this.update();
    };
    /**
     * Binds this uniform buffer to an effect.
     * @param effect Define the effect to bind the buffer to
     * @param name Name of the uniform block in the shader.
     */
    UniformBuffer.prototype.bindToEffect = function (effect, name) {
        this._currentEffect = effect;
        if (this._noUBO || !this._buffer) {
            return;
        }
        effect.bindUniformBuffer(this._buffer, name);
    };
    /**
     * Disposes the uniform buffer.
     */
    UniformBuffer.prototype.dispose = function () {
        if (this._noUBO) {
            return;
        }
        var uniformBuffers = this._engine._uniformBuffers;
        var index = uniformBuffers.indexOf(this);
        if (index !== -1) {
            uniformBuffers[index] = uniformBuffers[uniformBuffers.length - 1];
            uniformBuffers.pop();
        }
        if (!this._buffer) {
            return;
        }
        if (this._engine._releaseBuffer(this._buffer)) {
            this._buffer = null;
        }
    };
    // Pool for avoiding memory leaks
    UniformBuffer._MAX_UNIFORM_SIZE = 256;
    UniformBuffer._tempBuffer = new Float32Array(UniformBuffer._MAX_UNIFORM_SIZE);
    return UniformBuffer;
}());



/***/ }),

/***/ "./Maths/index.ts":
/*!************************!*\
  !*** ./Maths/index.ts ***!
  \************************/
/*! exports provided: Scalar, Space, Axis, Color3, Color4, TmpColors, ToGammaSpace, ToLinearSpace, Epsilon, Frustum, Plane, Size, Vector2, Vector3, Vector4, Quaternion, Matrix, TmpVectors, Viewport, SphericalHarmonics, SphericalPolynomial, Orientation, BezierCurve, Angle, Arc2, Path2, Path3D, Curve3, PositionNormalVertex, PositionNormalTextureVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _math_scalar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.scalar */ "./Maths/math.scalar.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scalar", function() { return _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"]; });

/* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math */ "./Maths/math.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Space", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Space"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Axis", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Axis"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Color3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color4", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Color4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpColors", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["TmpColors"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToGammaSpace", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToLinearSpace", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Epsilon", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Epsilon"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Frustum"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Plane", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Plane"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Size", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Size"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector2", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Vector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector3", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Vector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector4", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Vector4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quaternion", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Matrix", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Matrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpVectors", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Viewport", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Viewport"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Orientation", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Orientation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurve", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["BezierCurve"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Angle", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Angle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Arc2", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Arc2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path2", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Path2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path3D", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Path3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Curve3", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["Curve3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalVertex", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["PositionNormalVertex"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalTextureVertex", function() { return _math__WEBPACK_IMPORTED_MODULE_1__["PositionNormalTextureVertex"]; });

/* harmony import */ var _sphericalPolynomial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./sphericalPolynomial */ "./Maths/sphericalPolynomial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphericalHarmonics", function() { return _sphericalPolynomial__WEBPACK_IMPORTED_MODULE_2__["SphericalHarmonics"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphericalPolynomial", function() { return _sphericalPolynomial__WEBPACK_IMPORTED_MODULE_2__["SphericalPolynomial"]; });






/***/ }),

/***/ "./Maths/math.axis.ts":
/*!****************************!*\
  !*** ./Maths/math.axis.ts ***!
  \****************************/
/*! exports provided: Space, Axis */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Space", function() { return Space; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Axis", function() { return Axis; });
/* harmony import */ var _math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.vector */ "./Maths/math.vector.ts");

/** Defines supported spaces */
var Space;
(function (Space) {
    /** Local (object) space */
    Space[Space["LOCAL"] = 0] = "LOCAL";
    /** World space */
    Space[Space["WORLD"] = 1] = "WORLD";
    /** Bone space */
    Space[Space["BONE"] = 2] = "BONE";
})(Space || (Space = {}));
/** Defines the 3 main axes */
var Axis = /** @class */ (function () {
    function Axis() {
    }
    /** X axis */
    Axis.X = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 0.0, 0.0);
    /** Y axis */
    Axis.Y = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0.0, 1.0, 0.0);
    /** Z axis */
    Axis.Z = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0.0, 0.0, 1.0);
    return Axis;
}());



/***/ }),

/***/ "./Maths/math.color.ts":
/*!*****************************!*\
  !*** ./Maths/math.color.ts ***!
  \*****************************/
/*! exports provided: Color3, Color4, TmpColors */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Color3", function() { return Color3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Color4", function() { return Color4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TmpColors", function() { return TmpColors; });
/* harmony import */ var _math_scalar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _math_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math.constants */ "./Maths/math.constants.ts");
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");




/**
 * Class used to hold a RBG color
 */
var Color3 = /** @class */ (function () {
    /**
     * Creates a new Color3 object from red, green, blue values, all between 0 and 1
     * @param r defines the red component (between 0 and 1, default is 0)
     * @param g defines the green component (between 0 and 1, default is 0)
     * @param b defines the blue component (between 0 and 1, default is 0)
     */
    function Color3(
    /**
     * Defines the red component (between 0 and 1, default is 0)
     */
    r,
    /**
     * Defines the green component (between 0 and 1, default is 0)
     */
    g,
    /**
     * Defines the blue component (between 0 and 1, default is 0)
     */
    b) {
        if (r === void 0) { r = 0; }
        if (g === void 0) { g = 0; }
        if (b === void 0) { b = 0; }
        this.r = r;
        this.g = g;
        this.b = b;
    }
    /**
     * Creates a string with the Color3 current values
     * @returns the string representation of the Color3 object
     */
    Color3.prototype.toString = function () {
        return "{R: " + this.r + " G:" + this.g + " B:" + this.b + "}";
    };
    /**
     * Returns the string "Color3"
     * @returns "Color3"
     */
    Color3.prototype.getClassName = function () {
        return "Color3";
    };
    /**
     * Compute the Color3 hash code
     * @returns an unique number that can be used to hash Color3 objects
     */
    Color3.prototype.getHashCode = function () {
        var hash = (this.r * 255) | 0;
        hash = (hash * 397) ^ ((this.g * 255) | 0);
        hash = (hash * 397) ^ ((this.b * 255) | 0);
        return hash;
    };
    // Operators
    /**
     * Stores in the given array from the given starting index the red, green, blue values as successive elements
     * @param array defines the array where to store the r,g,b components
     * @param index defines an optional index in the target array to define where to start storing values
     * @returns the current Color3 object
     */
    Color3.prototype.toArray = function (array, index) {
        if (index === void 0) { index = 0; }
        array[index] = this.r;
        array[index + 1] = this.g;
        array[index + 2] = this.b;
        return this;
    };
    /**
     * Returns a new Color4 object from the current Color3 and the given alpha
     * @param alpha defines the alpha component on the new Color4 object (default is 1)
     * @returns a new Color4 object
     */
    Color3.prototype.toColor4 = function (alpha) {
        if (alpha === void 0) { alpha = 1; }
        return new Color4(this.r, this.g, this.b, alpha);
    };
    /**
     * Returns a new array populated with 3 numeric elements : red, green and blue values
     * @returns the new array
     */
    Color3.prototype.asArray = function () {
        var result = new Array();
        this.toArray(result, 0);
        return result;
    };
    /**
     * Returns the luminance value
     * @returns a float value
     */
    Color3.prototype.toLuminance = function () {
        return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;
    };
    /**
     * Multiply each Color3 rgb values by the given Color3 rgb values in a new Color3 object
     * @param otherColor defines the second operand
     * @returns the new Color3 object
     */
    Color3.prototype.multiply = function (otherColor) {
        return new Color3(this.r * otherColor.r, this.g * otherColor.g, this.b * otherColor.b);
    };
    /**
     * Multiply the rgb values of the Color3 and the given Color3 and stores the result in the object "result"
     * @param otherColor defines the second operand
     * @param result defines the Color3 object where to store the result
     * @returns the current Color3
     */
    Color3.prototype.multiplyToRef = function (otherColor, result) {
        result.r = this.r * otherColor.r;
        result.g = this.g * otherColor.g;
        result.b = this.b * otherColor.b;
        return this;
    };
    /**
     * Determines equality between Color3 objects
     * @param otherColor defines the second operand
     * @returns true if the rgb values are equal to the given ones
     */
    Color3.prototype.equals = function (otherColor) {
        return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b;
    };
    /**
     * Determines equality between the current Color3 object and a set of r,b,g values
     * @param r defines the red component to check
     * @param g defines the green component to check
     * @param b defines the blue component to check
     * @returns true if the rgb values are equal to the given ones
     */
    Color3.prototype.equalsFloats = function (r, g, b) {
        return this.r === r && this.g === g && this.b === b;
    };
    /**
     * Multiplies in place each rgb value by scale
     * @param scale defines the scaling factor
     * @returns the updated Color3
     */
    Color3.prototype.scale = function (scale) {
        return new Color3(this.r * scale, this.g * scale, this.b * scale);
    };
    /**
     * Multiplies the rgb values by scale and stores the result into "result"
     * @param scale defines the scaling factor
     * @param result defines the Color3 object where to store the result
     * @returns the unmodified current Color3
     */
    Color3.prototype.scaleToRef = function (scale, result) {
        result.r = this.r * scale;
        result.g = this.g * scale;
        result.b = this.b * scale;
        return this;
    };
    /**
     * Scale the current Color3 values by a factor and add the result to a given Color3
     * @param scale defines the scale factor
     * @param result defines color to store the result into
     * @returns the unmodified current Color3
     */
    Color3.prototype.scaleAndAddToRef = function (scale, result) {
        result.r += this.r * scale;
        result.g += this.g * scale;
        result.b += this.b * scale;
        return this;
    };
    /**
     * Clamps the rgb values by the min and max values and stores the result into "result"
     * @param min defines minimum clamping value (default is 0)
     * @param max defines maximum clamping value (default is 1)
     * @param result defines color to store the result into
     * @returns the original Color3
     */
    Color3.prototype.clampToRef = function (min, max, result) {
        if (min === void 0) { min = 0; }
        if (max === void 0) { max = 1; }
        result.r = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.r, min, max);
        result.g = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.g, min, max);
        result.b = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.b, min, max);
        return this;
    };
    /**
     * Creates a new Color3 set with the added values of the current Color3 and of the given one
     * @param otherColor defines the second operand
     * @returns the new Color3
     */
    Color3.prototype.add = function (otherColor) {
        return new Color3(this.r + otherColor.r, this.g + otherColor.g, this.b + otherColor.b);
    };
    /**
     * Stores the result of the addition of the current Color3 and given one rgb values into "result"
     * @param otherColor defines the second operand
     * @param result defines Color3 object to store the result into
     * @returns the unmodified current Color3
     */
    Color3.prototype.addToRef = function (otherColor, result) {
        result.r = this.r + otherColor.r;
        result.g = this.g + otherColor.g;
        result.b = this.b + otherColor.b;
        return this;
    };
    /**
     * Returns a new Color3 set with the subtracted values of the given one from the current Color3
     * @param otherColor defines the second operand
     * @returns the new Color3
     */
    Color3.prototype.subtract = function (otherColor) {
        return new Color3(this.r - otherColor.r, this.g - otherColor.g, this.b - otherColor.b);
    };
    /**
     * Stores the result of the subtraction of given one from the current Color3 rgb values into "result"
     * @param otherColor defines the second operand
     * @param result defines Color3 object to store the result into
     * @returns the unmodified current Color3
     */
    Color3.prototype.subtractToRef = function (otherColor, result) {
        result.r = this.r - otherColor.r;
        result.g = this.g - otherColor.g;
        result.b = this.b - otherColor.b;
        return this;
    };
    /**
     * Copy the current object
     * @returns a new Color3 copied the current one
     */
    Color3.prototype.clone = function () {
        return new Color3(this.r, this.g, this.b);
    };
    /**
     * Copies the rgb values from the source in the current Color3
     * @param source defines the source Color3 object
     * @returns the updated Color3 object
     */
    Color3.prototype.copyFrom = function (source) {
        this.r = source.r;
        this.g = source.g;
        this.b = source.b;
        return this;
    };
    /**
     * Updates the Color3 rgb values from the given floats
     * @param r defines the red component to read from
     * @param g defines the green component to read from
     * @param b defines the blue component to read from
     * @returns the current Color3 object
     */
    Color3.prototype.copyFromFloats = function (r, g, b) {
        this.r = r;
        this.g = g;
        this.b = b;
        return this;
    };
    /**
     * Updates the Color3 rgb values from the given floats
     * @param r defines the red component to read from
     * @param g defines the green component to read from
     * @param b defines the blue component to read from
     * @returns the current Color3 object
     */
    Color3.prototype.set = function (r, g, b) {
        return this.copyFromFloats(r, g, b);
    };
    /**
     * Compute the Color3 hexadecimal code as a string
     * @returns a string containing the hexadecimal representation of the Color3 object
     */
    Color3.prototype.toHexString = function () {
        var intR = (this.r * 255) | 0;
        var intG = (this.g * 255) | 0;
        var intB = (this.b * 255) | 0;
        return "#" + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intR) + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intG) + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intB);
    };
    /**
     * Computes a new Color3 converted from the current one to linear space
     * @returns a new Color3 object
     */
    Color3.prototype.toLinearSpace = function () {
        var convertedColor = new Color3();
        this.toLinearSpaceToRef(convertedColor);
        return convertedColor;
    };
    /**
     * Converts current color in rgb space to HSV values
     * @returns a new color3 representing the HSV values
     */
    Color3.prototype.toHSV = function () {
        var result = new Color3();
        this.toHSVToRef(result);
        return result;
    };
    /**
     * Converts current color in rgb space to HSV values
     * @param result defines the Color3 where to store the HSV values
     */
    Color3.prototype.toHSVToRef = function (result) {
        var r = this.r;
        var g = this.g;
        var b = this.b;
        var max = Math.max(r, g, b);
        var min = Math.min(r, g, b);
        var h = 0;
        var s = 0;
        var v = max;
        var dm = max - min;
        if (max !== 0) {
            s = dm / max;
        }
        if (max != min) {
            if (max == r) {
                h = (g - b) / dm;
                if (g < b) {
                    h += 6;
                }
            }
            else if (max == g) {
                h = (b - r) / dm + 2;
            }
            else if (max == b) {
                h = (r - g) / dm + 4;
            }
            h *= 60;
        }
        result.r = h;
        result.g = s;
        result.b = v;
    };
    /**
     * Converts the Color3 values to linear space and stores the result in "convertedColor"
     * @param convertedColor defines the Color3 object where to store the linear space version
     * @returns the unmodified Color3
     */
    Color3.prototype.toLinearSpaceToRef = function (convertedColor) {
        convertedColor.r = Math.pow(this.r, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]);
        convertedColor.g = Math.pow(this.g, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]);
        convertedColor.b = Math.pow(this.b, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]);
        return this;
    };
    /**
     * Computes a new Color3 converted from the current one to gamma space
     * @returns a new Color3 object
     */
    Color3.prototype.toGammaSpace = function () {
        var convertedColor = new Color3();
        this.toGammaSpaceToRef(convertedColor);
        return convertedColor;
    };
    /**
     * Converts the Color3 values to gamma space and stores the result in "convertedColor"
     * @param convertedColor defines the Color3 object where to store the gamma space version
     * @returns the unmodified Color3
     */
    Color3.prototype.toGammaSpaceToRef = function (convertedColor) {
        convertedColor.r = Math.pow(this.r, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]);
        convertedColor.g = Math.pow(this.g, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]);
        convertedColor.b = Math.pow(this.b, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]);
        return this;
    };
    /**
     * Convert Hue, saturation and value to a Color3 (RGB)
     * @param hue defines the hue
     * @param saturation defines the saturation
     * @param value defines the value
     * @param result defines the Color3 where to store the RGB values
     */
    Color3.HSVtoRGBToRef = function (hue, saturation, value, result) {
        var chroma = value * saturation;
        var h = hue / 60;
        var x = chroma * (1 - Math.abs((h % 2) - 1));
        var r = 0;
        var g = 0;
        var b = 0;
        if (h >= 0 && h <= 1) {
            r = chroma;
            g = x;
        }
        else if (h >= 1 && h <= 2) {
            r = x;
            g = chroma;
        }
        else if (h >= 2 && h <= 3) {
            g = chroma;
            b = x;
        }
        else if (h >= 3 && h <= 4) {
            g = x;
            b = chroma;
        }
        else if (h >= 4 && h <= 5) {
            r = x;
            b = chroma;
        }
        else if (h >= 5 && h <= 6) {
            r = chroma;
            b = x;
        }
        var m = value - chroma;
        result.set((r + m), (g + m), (b + m));
    };
    /**
     * Creates a new Color3 from the string containing valid hexadecimal values
     * @param hex defines a string containing valid hexadecimal values
     * @returns a new Color3 object
     */
    Color3.FromHexString = function (hex) {
        if (hex.substring(0, 1) !== "#" || hex.length !== 7) {
            return new Color3(0, 0, 0);
        }
        var r = parseInt(hex.substring(1, 3), 16);
        var g = parseInt(hex.substring(3, 5), 16);
        var b = parseInt(hex.substring(5, 7), 16);
        return Color3.FromInts(r, g, b);
    };
    /**
     * Creates a new Color3 from the starting index of the given array
     * @param array defines the source array
     * @param offset defines an offset in the source array
     * @returns a new Color3 object
     */
    Color3.FromArray = function (array, offset) {
        if (offset === void 0) { offset = 0; }
        return new Color3(array[offset], array[offset + 1], array[offset + 2]);
    };
    /**
     * Creates a new Color3 from integer values (< 256)
     * @param r defines the red component to read from (value between 0 and 255)
     * @param g defines the green component to read from (value between 0 and 255)
     * @param b defines the blue component to read from (value between 0 and 255)
     * @returns a new Color3 object
     */
    Color3.FromInts = function (r, g, b) {
        return new Color3(r / 255.0, g / 255.0, b / 255.0);
    };
    /**
     * Creates a new Color3 with values linearly interpolated of "amount" between the start Color3 and the end Color3
     * @param start defines the start Color3 value
     * @param end defines the end Color3 value
     * @param amount defines the gradient value between start and end
     * @returns a new Color3 object
     */
    Color3.Lerp = function (start, end, amount) {
        var result = new Color3(0.0, 0.0, 0.0);
        Color3.LerpToRef(start, end, amount, result);
        return result;
    };
    /**
     * Creates a new Color3 with values linearly interpolated of "amount" between the start Color3 and the end Color3
     * @param left defines the start value
     * @param right defines the end value
     * @param amount defines the gradient factor
     * @param result defines the Color3 object where to store the result
     */
    Color3.LerpToRef = function (left, right, amount, result) {
        result.r = left.r + ((right.r - left.r) * amount);
        result.g = left.g + ((right.g - left.g) * amount);
        result.b = left.b + ((right.b - left.b) * amount);
    };
    /**
     * Returns a Color3 value containing a red color
     * @returns a new Color3 object
     */
    Color3.Red = function () { return new Color3(1, 0, 0); };
    /**
     * Returns a Color3 value containing a green color
     * @returns a new Color3 object
     */
    Color3.Green = function () { return new Color3(0, 1, 0); };
    /**
     * Returns a Color3 value containing a blue color
     * @returns a new Color3 object
     */
    Color3.Blue = function () { return new Color3(0, 0, 1); };
    /**
     * Returns a Color3 value containing a black color
     * @returns a new Color3 object
     */
    Color3.Black = function () { return new Color3(0, 0, 0); };
    Object.defineProperty(Color3, "BlackReadOnly", {
        /**
          * Gets a Color3 value containing a black color that must not be updated
          */
        get: function () {
            return Color3._BlackReadOnly;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns a Color3 value containing a white color
     * @returns a new Color3 object
     */
    Color3.White = function () { return new Color3(1, 1, 1); };
    /**
     * Returns a Color3 value containing a purple color
     * @returns a new Color3 object
     */
    Color3.Purple = function () { return new Color3(0.5, 0, 0.5); };
    /**
     * Returns a Color3 value containing a magenta color
     * @returns a new Color3 object
     */
    Color3.Magenta = function () { return new Color3(1, 0, 1); };
    /**
     * Returns a Color3 value containing a yellow color
     * @returns a new Color3 object
     */
    Color3.Yellow = function () { return new Color3(1, 1, 0); };
    /**
     * Returns a Color3 value containing a gray color
     * @returns a new Color3 object
     */
    Color3.Gray = function () { return new Color3(0.5, 0.5, 0.5); };
    /**
     * Returns a Color3 value containing a teal color
     * @returns a new Color3 object
     */
    Color3.Teal = function () { return new Color3(0, 1.0, 1.0); };
    /**
     * Returns a Color3 value containing a random color
     * @returns a new Color3 object
     */
    Color3.Random = function () { return new Color3(Math.random(), Math.random(), Math.random()); };
    // Statics
    Color3._BlackReadOnly = Color3.Black();
    return Color3;
}());

/**
 * Class used to hold a RBGA color
 */
var Color4 = /** @class */ (function () {
    /**
     * Creates a new Color4 object from red, green, blue values, all between 0 and 1
     * @param r defines the red component (between 0 and 1, default is 0)
     * @param g defines the green component (between 0 and 1, default is 0)
     * @param b defines the blue component (between 0 and 1, default is 0)
     * @param a defines the alpha component (between 0 and 1, default is 1)
     */
    function Color4(
    /**
     * Defines the red component (between 0 and 1, default is 0)
     */
    r,
    /**
     * Defines the green component (between 0 and 1, default is 0)
     */
    g,
    /**
     * Defines the blue component (between 0 and 1, default is 0)
     */
    b,
    /**
     * Defines the alpha component (between 0 and 1, default is 1)
     */
    a) {
        if (r === void 0) { r = 0; }
        if (g === void 0) { g = 0; }
        if (b === void 0) { b = 0; }
        if (a === void 0) { a = 1; }
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }
    // Operators
    /**
     * Adds in place the given Color4 values to the current Color4 object
     * @param right defines the second operand
     * @returns the current updated Color4 object
     */
    Color4.prototype.addInPlace = function (right) {
        this.r += right.r;
        this.g += right.g;
        this.b += right.b;
        this.a += right.a;
        return this;
    };
    /**
     * Creates a new array populated with 4 numeric elements : red, green, blue, alpha values
     * @returns the new array
     */
    Color4.prototype.asArray = function () {
        var result = new Array();
        this.toArray(result, 0);
        return result;
    };
    /**
     * Stores from the starting index in the given array the Color4 successive values
     * @param array defines the array where to store the r,g,b components
     * @param index defines an optional index in the target array to define where to start storing values
     * @returns the current Color4 object
     */
    Color4.prototype.toArray = function (array, index) {
        if (index === void 0) { index = 0; }
        array[index] = this.r;
        array[index + 1] = this.g;
        array[index + 2] = this.b;
        array[index + 3] = this.a;
        return this;
    };
    /**
     * Determines equality between Color4 objects
     * @param otherColor defines the second operand
     * @returns true if the rgba values are equal to the given ones
     */
    Color4.prototype.equals = function (otherColor) {
        return otherColor && this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b && this.a === otherColor.a;
    };
    /**
     * Creates a new Color4 set with the added values of the current Color4 and of the given one
     * @param right defines the second operand
     * @returns a new Color4 object
     */
    Color4.prototype.add = function (right) {
        return new Color4(this.r + right.r, this.g + right.g, this.b + right.b, this.a + right.a);
    };
    /**
     * Creates a new Color4 set with the subtracted values of the given one from the current Color4
     * @param right defines the second operand
     * @returns a new Color4 object
     */
    Color4.prototype.subtract = function (right) {
        return new Color4(this.r - right.r, this.g - right.g, this.b - right.b, this.a - right.a);
    };
    /**
     * Subtracts the given ones from the current Color4 values and stores the results in "result"
     * @param right defines the second operand
     * @param result defines the Color4 object where to store the result
     * @returns the current Color4 object
     */
    Color4.prototype.subtractToRef = function (right, result) {
        result.r = this.r - right.r;
        result.g = this.g - right.g;
        result.b = this.b - right.b;
        result.a = this.a - right.a;
        return this;
    };
    /**
     * Creates a new Color4 with the current Color4 values multiplied by scale
     * @param scale defines the scaling factor to apply
     * @returns a new Color4 object
     */
    Color4.prototype.scale = function (scale) {
        return new Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale);
    };
    /**
     * Multiplies the current Color4 values by scale and stores the result in "result"
     * @param scale defines the scaling factor to apply
     * @param result defines the Color4 object where to store the result
     * @returns the current unmodified Color4
     */
    Color4.prototype.scaleToRef = function (scale, result) {
        result.r = this.r * scale;
        result.g = this.g * scale;
        result.b = this.b * scale;
        result.a = this.a * scale;
        return this;
    };
    /**
     * Scale the current Color4 values by a factor and add the result to a given Color4
     * @param scale defines the scale factor
     * @param result defines the Color4 object where to store the result
     * @returns the unmodified current Color4
     */
    Color4.prototype.scaleAndAddToRef = function (scale, result) {
        result.r += this.r * scale;
        result.g += this.g * scale;
        result.b += this.b * scale;
        result.a += this.a * scale;
        return this;
    };
    /**
     * Clamps the rgb values by the min and max values and stores the result into "result"
     * @param min defines minimum clamping value (default is 0)
     * @param max defines maximum clamping value (default is 1)
     * @param result defines color to store the result into.
     * @returns the cuurent Color4
     */
    Color4.prototype.clampToRef = function (min, max, result) {
        if (min === void 0) { min = 0; }
        if (max === void 0) { max = 1; }
        result.r = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.r, min, max);
        result.g = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.g, min, max);
        result.b = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.b, min, max);
        result.a = _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(this.a, min, max);
        return this;
    };
    /**
      * Multipy an Color4 value by another and return a new Color4 object
      * @param color defines the Color4 value to multiply by
      * @returns a new Color4 object
      */
    Color4.prototype.multiply = function (color) {
        return new Color4(this.r * color.r, this.g * color.g, this.b * color.b, this.a * color.a);
    };
    /**
     * Multipy a Color4 value by another and push the result in a reference value
     * @param color defines the Color4 value to multiply by
     * @param result defines the Color4 to fill the result in
     * @returns the result Color4
     */
    Color4.prototype.multiplyToRef = function (color, result) {
        result.r = this.r * color.r;
        result.g = this.g * color.g;
        result.b = this.b * color.b;
        result.a = this.a * color.a;
        return result;
    };
    /**
     * Creates a string with the Color4 current values
     * @returns the string representation of the Color4 object
     */
    Color4.prototype.toString = function () {
        return "{R: " + this.r + " G:" + this.g + " B:" + this.b + " A:" + this.a + "}";
    };
    /**
     * Returns the string "Color4"
     * @returns "Color4"
     */
    Color4.prototype.getClassName = function () {
        return "Color4";
    };
    /**
     * Compute the Color4 hash code
     * @returns an unique number that can be used to hash Color4 objects
     */
    Color4.prototype.getHashCode = function () {
        var hash = (this.r * 255) | 0;
        hash = (hash * 397) ^ ((this.g * 255) | 0);
        hash = (hash * 397) ^ ((this.b * 255) | 0);
        hash = (hash * 397) ^ ((this.a * 255) | 0);
        return hash;
    };
    /**
     * Creates a new Color4 copied from the current one
     * @returns a new Color4 object
     */
    Color4.prototype.clone = function () {
        return new Color4(this.r, this.g, this.b, this.a);
    };
    /**
     * Copies the given Color4 values into the current one
     * @param source defines the source Color4 object
     * @returns the current updated Color4 object
     */
    Color4.prototype.copyFrom = function (source) {
        this.r = source.r;
        this.g = source.g;
        this.b = source.b;
        this.a = source.a;
        return this;
    };
    /**
     * Copies the given float values into the current one
     * @param r defines the red component to read from
     * @param g defines the green component to read from
     * @param b defines the blue component to read from
     * @param a defines the alpha component to read from
     * @returns the current updated Color4 object
     */
    Color4.prototype.copyFromFloats = function (r, g, b, a) {
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
        return this;
    };
    /**
     * Copies the given float values into the current one
     * @param r defines the red component to read from
     * @param g defines the green component to read from
     * @param b defines the blue component to read from
     * @param a defines the alpha component to read from
     * @returns the current updated Color4 object
     */
    Color4.prototype.set = function (r, g, b, a) {
        return this.copyFromFloats(r, g, b, a);
    };
    /**
     * Compute the Color4 hexadecimal code as a string
     * @returns a string containing the hexadecimal representation of the Color4 object
     */
    Color4.prototype.toHexString = function () {
        var intR = (this.r * 255) | 0;
        var intG = (this.g * 255) | 0;
        var intB = (this.b * 255) | 0;
        var intA = (this.a * 255) | 0;
        return "#" + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intR) + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intG) + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intB) + _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].ToHex(intA);
    };
    /**
     * Computes a new Color4 converted from the current one to linear space
     * @returns a new Color4 object
     */
    Color4.prototype.toLinearSpace = function () {
        var convertedColor = new Color4();
        this.toLinearSpaceToRef(convertedColor);
        return convertedColor;
    };
    /**
     * Converts the Color4 values to linear space and stores the result in "convertedColor"
     * @param convertedColor defines the Color4 object where to store the linear space version
     * @returns the unmodified Color4
     */
    Color4.prototype.toLinearSpaceToRef = function (convertedColor) {
        convertedColor.r = Math.pow(this.r, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]);
        convertedColor.g = Math.pow(this.g, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]);
        convertedColor.b = Math.pow(this.b, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToLinearSpace"]);
        convertedColor.a = this.a;
        return this;
    };
    /**
     * Computes a new Color4 converted from the current one to gamma space
     * @returns a new Color4 object
     */
    Color4.prototype.toGammaSpace = function () {
        var convertedColor = new Color4();
        this.toGammaSpaceToRef(convertedColor);
        return convertedColor;
    };
    /**
     * Converts the Color4 values to gamma space and stores the result in "convertedColor"
     * @param convertedColor defines the Color4 object where to store the gamma space version
     * @returns the unmodified Color4
     */
    Color4.prototype.toGammaSpaceToRef = function (convertedColor) {
        convertedColor.r = Math.pow(this.r, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]);
        convertedColor.g = Math.pow(this.g, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]);
        convertedColor.b = Math.pow(this.b, _math_constants__WEBPACK_IMPORTED_MODULE_1__["ToGammaSpace"]);
        convertedColor.a = this.a;
        return this;
    };
    // Statics
    /**
     * Creates a new Color4 from the string containing valid hexadecimal values
     * @param hex defines a string containing valid hexadecimal values
     * @returns a new Color4 object
     */
    Color4.FromHexString = function (hex) {
        if (hex.substring(0, 1) !== "#" || hex.length !== 9) {
            return new Color4(0.0, 0.0, 0.0, 0.0);
        }
        var r = parseInt(hex.substring(1, 3), 16);
        var g = parseInt(hex.substring(3, 5), 16);
        var b = parseInt(hex.substring(5, 7), 16);
        var a = parseInt(hex.substring(7, 9), 16);
        return Color4.FromInts(r, g, b, a);
    };
    /**
     * Creates a new Color4 object set with the linearly interpolated values of "amount" between the left Color4 object and the right Color4 object
     * @param left defines the start value
     * @param right defines the end value
     * @param amount defines the gradient factor
     * @returns a new Color4 object
     */
    Color4.Lerp = function (left, right, amount) {
        var result = new Color4(0.0, 0.0, 0.0, 0.0);
        Color4.LerpToRef(left, right, amount, result);
        return result;
    };
    /**
     * Set the given "result" with the linearly interpolated values of "amount" between the left Color4 object and the right Color4 object
     * @param left defines the start value
     * @param right defines the end value
     * @param amount defines the gradient factor
     * @param result defines the Color4 object where to store data
     */
    Color4.LerpToRef = function (left, right, amount, result) {
        result.r = left.r + (right.r - left.r) * amount;
        result.g = left.g + (right.g - left.g) * amount;
        result.b = left.b + (right.b - left.b) * amount;
        result.a = left.a + (right.a - left.a) * amount;
    };
    /**
     * Creates a new Color4 from a Color3 and an alpha value
     * @param color3 defines the source Color3 to read from
     * @param alpha defines the alpha component (1.0 by default)
     * @returns a new Color4 object
     */
    Color4.FromColor3 = function (color3, alpha) {
        if (alpha === void 0) { alpha = 1.0; }
        return new Color4(color3.r, color3.g, color3.b, alpha);
    };
    /**
     * Creates a new Color4 from the starting index element of the given array
     * @param array defines the source array to read from
     * @param offset defines the offset in the source array
     * @returns a new Color4 object
     */
    Color4.FromArray = function (array, offset) {
        if (offset === void 0) { offset = 0; }
        return new Color4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);
    };
    /**
     * Creates a new Color3 from integer values (< 256)
     * @param r defines the red component to read from (value between 0 and 255)
     * @param g defines the green component to read from (value between 0 and 255)
     * @param b defines the blue component to read from (value between 0 and 255)
     * @param a defines the alpha component to read from (value between 0 and 255)
     * @returns a new Color3 object
     */
    Color4.FromInts = function (r, g, b, a) {
        return new Color4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
    };
    /**
     * Check the content of a given array and convert it to an array containing RGBA data
     * If the original array was already containing count * 4 values then it is returned directly
     * @param colors defines the array to check
     * @param count defines the number of RGBA data to expect
     * @returns an array containing count * 4 values (RGBA)
     */
    Color4.CheckColors4 = function (colors, count) {
        // Check if color3 was used
        if (colors.length === count * 3) {
            var colors4 = [];
            for (var index = 0; index < colors.length; index += 3) {
                var newIndex = (index / 3) * 4;
                colors4[newIndex] = colors[index];
                colors4[newIndex + 1] = colors[index + 1];
                colors4[newIndex + 2] = colors[index + 2];
                colors4[newIndex + 3] = 1.0;
            }
            return colors4;
        }
        return colors;
    };
    return Color4;
}());

/**
 * @hidden
 */
var TmpColors = /** @class */ (function () {
    function TmpColors() {
    }
    TmpColors.Color3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(3, Color3.Black);
    TmpColors.Color4 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(3, function () { return new Color4(0, 0, 0, 0); });
    return TmpColors;
}());

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Color3"] = Color3;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Color4"] = Color4;


/***/ }),

/***/ "./Maths/math.constants.ts":
/*!*********************************!*\
  !*** ./Maths/math.constants.ts ***!
  \*********************************/
/*! exports provided: ToGammaSpace, ToLinearSpace, Epsilon */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ToGammaSpace", function() { return ToGammaSpace; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ToLinearSpace", function() { return ToLinearSpace; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Epsilon", function() { return Epsilon; });
/**
 * Constant used to convert a value to gamma space
 * @ignorenaming
 */
var ToGammaSpace = 1 / 2.2;
/**
 * Constant used to convert a value to linear space
 * @ignorenaming
 */
var ToLinearSpace = 2.2;
/**
 * Constant used to define the minimal number value in Babylon.js
 * @ignorenaming
 */
var Epsilon = 0.001;



/***/ }),

/***/ "./Maths/math.frustum.ts":
/*!*******************************!*\
  !*** ./Maths/math.frustum.ts ***!
  \*******************************/
/*! exports provided: Frustum */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return Frustum; });
/* harmony import */ var _math_plane__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.plane */ "./Maths/math.plane.ts");

/**
 * Reprasents a camera frustum
 */
var Frustum = /** @class */ (function () {
    function Frustum() {
    }
    /**
     * Gets the planes representing the frustum
     * @param transform matrix to be applied to the returned planes
     * @returns a new array of 6 Frustum planes computed by the given transformation matrix.
     */
    Frustum.GetPlanes = function (transform) {
        var frustumPlanes = [];
        for (var index = 0; index < 6; index++) {
            frustumPlanes.push(new _math_plane__WEBPACK_IMPORTED_MODULE_0__["Plane"](0.0, 0.0, 0.0, 0.0));
        }
        Frustum.GetPlanesToRef(transform, frustumPlanes);
        return frustumPlanes;
    };
    /**
     * Gets the near frustum plane transformed by the transform matrix
     * @param transform transformation matrix to be applied to the resulting frustum plane
     * @param frustumPlane the resuling frustum plane
     */
    Frustum.GetNearPlaneToRef = function (transform, frustumPlane) {
        var m = transform.m;
        frustumPlane.normal.x = m[3] + m[2];
        frustumPlane.normal.y = m[7] + m[6];
        frustumPlane.normal.z = m[11] + m[10];
        frustumPlane.d = m[15] + m[14];
        frustumPlane.normalize();
    };
    /**
     * Gets the far frustum plane transformed by the transform matrix
     * @param transform transformation matrix to be applied to the resulting frustum plane
     * @param frustumPlane the resuling frustum plane
     */
    Frustum.GetFarPlaneToRef = function (transform, frustumPlane) {
        var m = transform.m;
        frustumPlane.normal.x = m[3] - m[2];
        frustumPlane.normal.y = m[7] - m[6];
        frustumPlane.normal.z = m[11] - m[10];
        frustumPlane.d = m[15] - m[14];
        frustumPlane.normalize();
    };
    /**
     * Gets the left frustum plane transformed by the transform matrix
     * @param transform transformation matrix to be applied to the resulting frustum plane
     * @param frustumPlane the resuling frustum plane
     */
    Frustum.GetLeftPlaneToRef = function (transform, frustumPlane) {
        var m = transform.m;
        frustumPlane.normal.x = m[3] + m[0];
        frustumPlane.normal.y = m[7] + m[4];
        frustumPlane.normal.z = m[11] + m[8];
        frustumPlane.d = m[15] + m[12];
        frustumPlane.normalize();
    };
    /**
     * Gets the right frustum plane transformed by the transform matrix
     * @param transform transformation matrix to be applied to the resulting frustum plane
     * @param frustumPlane the resuling frustum plane
     */
    Frustum.GetRightPlaneToRef = function (transform, frustumPlane) {
        var m = transform.m;
        frustumPlane.normal.x = m[3] - m[0];
        frustumPlane.normal.y = m[7] - m[4];
        frustumPlane.normal.z = m[11] - m[8];
        frustumPlane.d = m[15] - m[12];
        frustumPlane.normalize();
    };
    /**
     * Gets the top frustum plane transformed by the transform matrix
     * @param transform transformation matrix to be applied to the resulting frustum plane
     * @param frustumPlane the resuling frustum plane
     */
    Frustum.GetTopPlaneToRef = function (transform, frustumPlane) {
        var m = transform.m;
        frustumPlane.normal.x = m[3] - m[1];
        frustumPlane.normal.y = m[7] - m[5];
        frustumPlane.normal.z = m[11] - m[9];
        frustumPlane.d = m[15] - m[13];
        frustumPlane.normalize();
    };
    /**
     * Gets the bottom frustum plane transformed by the transform matrix
     * @param transform transformation matrix to be applied to the resulting frustum plane
     * @param frustumPlane the resuling frustum plane
     */
    Frustum.GetBottomPlaneToRef = function (transform, frustumPlane) {
        var m = transform.m;
        frustumPlane.normal.x = m[3] + m[1];
        frustumPlane.normal.y = m[7] + m[5];
        frustumPlane.normal.z = m[11] + m[9];
        frustumPlane.d = m[15] + m[13];
        frustumPlane.normalize();
    };
    /**
     * Sets the given array "frustumPlanes" with the 6 Frustum planes computed by the given transformation matrix.
     * @param transform transformation matrix to be applied to the resulting frustum planes
     * @param frustumPlanes the resuling frustum planes
     */
    Frustum.GetPlanesToRef = function (transform, frustumPlanes) {
        // Near
        Frustum.GetNearPlaneToRef(transform, frustumPlanes[0]);
        // Far
        Frustum.GetFarPlaneToRef(transform, frustumPlanes[1]);
        // Left
        Frustum.GetLeftPlaneToRef(transform, frustumPlanes[2]);
        // Right
        Frustum.GetRightPlaneToRef(transform, frustumPlanes[3]);
        // Top
        Frustum.GetTopPlaneToRef(transform, frustumPlanes[4]);
        // Bottom
        Frustum.GetBottomPlaneToRef(transform, frustumPlanes[5]);
    };
    return Frustum;
}());



/***/ }),

/***/ "./Maths/math.functions.ts":
/*!*********************************!*\
  !*** ./Maths/math.functions.ts ***!
  \*********************************/
/*! exports provided: extractMinAndMaxIndexed, extractMinAndMax */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "extractMinAndMaxIndexed", function() { return extractMinAndMaxIndexed; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "extractMinAndMax", function() { return extractMinAndMax; });
/* harmony import */ var _math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.vector */ "./Maths/math.vector.ts");

/**
 * Extracts minimum and maximum values from a list of indexed positions
 * @param positions defines the positions to use
 * @param indices defines the indices to the positions
 * @param indexStart defines the start index
 * @param indexCount defines the end index
 * @param bias defines bias value to add to the result
 * @return minimum and maximum values
 */
function extractMinAndMaxIndexed(positions, indices, indexStart, indexCount, bias) {
    if (bias === void 0) { bias = null; }
    var minimum = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
    var maximum = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
    for (var index = indexStart; index < indexStart + indexCount; index++) {
        var offset = indices[index] * 3;
        var x = positions[offset];
        var y = positions[offset + 1];
        var z = positions[offset + 2];
        minimum.minimizeInPlaceFromFloats(x, y, z);
        maximum.maximizeInPlaceFromFloats(x, y, z);
    }
    if (bias) {
        minimum.x -= minimum.x * bias.x + bias.y;
        minimum.y -= minimum.y * bias.x + bias.y;
        minimum.z -= minimum.z * bias.x + bias.y;
        maximum.x += maximum.x * bias.x + bias.y;
        maximum.y += maximum.y * bias.x + bias.y;
        maximum.z += maximum.z * bias.x + bias.y;
    }
    return {
        minimum: minimum,
        maximum: maximum
    };
}
/**
 * Extracts minimum and maximum values from a list of positions
 * @param positions defines the positions to use
 * @param start defines the start index in the positions array
 * @param count defines the number of positions to handle
 * @param bias defines bias value to add to the result
 * @param stride defines the stride size to use (distance between two positions in the positions array)
 * @return minimum and maximum values
 */
function extractMinAndMax(positions, start, count, bias, stride) {
    if (bias === void 0) { bias = null; }
    var minimum = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
    var maximum = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
    if (!stride) {
        stride = 3;
    }
    for (var index = start, offset = start * stride; index < start + count; index++, offset += stride) {
        var x = positions[offset];
        var y = positions[offset + 1];
        var z = positions[offset + 2];
        minimum.minimizeInPlaceFromFloats(x, y, z);
        maximum.maximizeInPlaceFromFloats(x, y, z);
    }
    if (bias) {
        minimum.x -= minimum.x * bias.x + bias.y;
        minimum.y -= minimum.y * bias.x + bias.y;
        minimum.z -= minimum.z * bias.x + bias.y;
        maximum.x += maximum.x * bias.x + bias.y;
        maximum.y += maximum.y * bias.x + bias.y;
        maximum.z += maximum.z * bias.x + bias.y;
    }
    return {
        minimum: minimum,
        maximum: maximum
    };
}


/***/ }),

/***/ "./Maths/math.path.ts":
/*!****************************!*\
  !*** ./Maths/math.path.ts ***!
  \****************************/
/*! exports provided: Orientation, BezierCurve, Angle, Arc2, Path2, Path3D, Curve3 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Orientation", function() { return Orientation; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BezierCurve", function() { return BezierCurve; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Angle", function() { return Angle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Arc2", function() { return Arc2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Path2", function() { return Path2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Path3D", function() { return Path3D; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Curve3", function() { return Curve3; });
/* harmony import */ var _math_scalar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _math_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./math.constants */ "./Maths/math.constants.ts");



/**
 * Defines potential orientation for back face culling
 */
var Orientation;
(function (Orientation) {
    /**
     * Clockwise
     */
    Orientation[Orientation["CW"] = 0] = "CW";
    /** Counter clockwise */
    Orientation[Orientation["CCW"] = 1] = "CCW";
})(Orientation || (Orientation = {}));
/** Class used to represent a Bezier curve */
var BezierCurve = /** @class */ (function () {
    function BezierCurve() {
    }
    /**
     * Returns the cubic Bezier interpolated value (float) at "t" (float) from the given x1, y1, x2, y2 floats
     * @param t defines the time
     * @param x1 defines the left coordinate on X axis
     * @param y1 defines the left coordinate on Y axis
     * @param x2 defines the right coordinate on X axis
     * @param y2 defines the right coordinate on Y axis
     * @returns the interpolated value
     */
    BezierCurve.Interpolate = function (t, x1, y1, x2, y2) {
        // Extract X (which is equal to time here)
        var f0 = 1 - 3 * x2 + 3 * x1;
        var f1 = 3 * x2 - 6 * x1;
        var f2 = 3 * x1;
        var refinedT = t;
        for (var i = 0; i < 5; i++) {
            var refinedT2 = refinedT * refinedT;
            var refinedT3 = refinedT2 * refinedT;
            var x = f0 * refinedT3 + f1 * refinedT2 + f2 * refinedT;
            var slope = 1.0 / (3.0 * f0 * refinedT2 + 2.0 * f1 * refinedT + f2);
            refinedT -= (x - t) * slope;
            refinedT = Math.min(1, Math.max(0, refinedT));
        }
        // Resolve cubic bezier for the given x
        return 3 * Math.pow(1 - refinedT, 2) * refinedT * y1 +
            3 * (1 - refinedT) * Math.pow(refinedT, 2) * y2 +
            Math.pow(refinedT, 3);
    };
    return BezierCurve;
}());

/**
 * Defines angle representation
 */
var Angle = /** @class */ (function () {
    /**
     * Creates an Angle object of "radians" radians (float).
     * @param radians the angle in radians
     */
    function Angle(radians) {
        this._radians = radians;
        if (this._radians < 0.0) {
            this._radians += (2.0 * Math.PI);
        }
    }
    /**
     * Get value in degrees
     * @returns the Angle value in degrees (float)
     */
    Angle.prototype.degrees = function () {
        return this._radians * 180.0 / Math.PI;
    };
    /**
     * Get value in radians
     * @returns the Angle value in radians (float)
     */
    Angle.prototype.radians = function () {
        return this._radians;
    };
    /**
     * Gets a new Angle object valued with the angle value in radians between the two given vectors
     * @param a defines first vector
     * @param b defines second vector
     * @returns a new Angle
     */
    Angle.BetweenTwoPoints = function (a, b) {
        var delta = b.subtract(a);
        var theta = Math.atan2(delta.y, delta.x);
        return new Angle(theta);
    };
    /**
     * Gets a new Angle object from the given float in radians
     * @param radians defines the angle value in radians
     * @returns a new Angle
     */
    Angle.FromRadians = function (radians) {
        return new Angle(radians);
    };
    /**
     * Gets a new Angle object from the given float in degrees
     * @param degrees defines the angle value in degrees
     * @returns a new Angle
     */
    Angle.FromDegrees = function (degrees) {
        return new Angle(degrees * Math.PI / 180.0);
    };
    return Angle;
}());

/**
 * This represents an arc in a 2d space.
 */
var Arc2 = /** @class */ (function () {
    /**
     * Creates an Arc object from the three given points : start, middle and end.
     * @param startPoint Defines the start point of the arc
     * @param midPoint Defines the midlle point of the arc
     * @param endPoint Defines the end point of the arc
     */
    function Arc2(
    /** Defines the start point of the arc */
    startPoint,
    /** Defines the mid point of the arc */
    midPoint,
    /** Defines the end point of the arc */
    endPoint) {
        this.startPoint = startPoint;
        this.midPoint = midPoint;
        this.endPoint = endPoint;
        var temp = Math.pow(midPoint.x, 2) + Math.pow(midPoint.y, 2);
        var startToMid = (Math.pow(startPoint.x, 2) + Math.pow(startPoint.y, 2) - temp) / 2.;
        var midToEnd = (temp - Math.pow(endPoint.x, 2) - Math.pow(endPoint.y, 2)) / 2.;
        var det = (startPoint.x - midPoint.x) * (midPoint.y - endPoint.y) - (midPoint.x - endPoint.x) * (startPoint.y - midPoint.y);
        this.centerPoint = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"]((startToMid * (midPoint.y - endPoint.y) - midToEnd * (startPoint.y - midPoint.y)) / det, ((startPoint.x - midPoint.x) * midToEnd - (midPoint.x - endPoint.x) * startToMid) / det);
        this.radius = this.centerPoint.subtract(this.startPoint).length();
        this.startAngle = Angle.BetweenTwoPoints(this.centerPoint, this.startPoint);
        var a1 = this.startAngle.degrees();
        var a2 = Angle.BetweenTwoPoints(this.centerPoint, this.midPoint).degrees();
        var a3 = Angle.BetweenTwoPoints(this.centerPoint, this.endPoint).degrees();
        // angles correction
        if (a2 - a1 > +180.0) {
            a2 -= 360.0;
        }
        if (a2 - a1 < -180.0) {
            a2 += 360.0;
        }
        if (a3 - a2 > +180.0) {
            a3 -= 360.0;
        }
        if (a3 - a2 < -180.0) {
            a3 += 360.0;
        }
        this.orientation = (a2 - a1) < 0 ? Orientation.CW : Orientation.CCW;
        this.angle = Angle.FromDegrees(this.orientation === Orientation.CW ? a1 - a3 : a3 - a1);
    }
    return Arc2;
}());

/**
 * Represents a 2D path made up of multiple 2D points
 */
var Path2 = /** @class */ (function () {
    /**
     * Creates a Path2 object from the starting 2D coordinates x and y.
     * @param x the starting points x value
     * @param y the starting points y value
     */
    function Path2(x, y) {
        this._points = new Array();
        this._length = 0.0;
        /**
         * If the path start and end point are the same
         */
        this.closed = false;
        this._points.push(new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](x, y));
    }
    /**
     * Adds a new segment until the given coordinates (x, y) to the current Path2.
     * @param x the added points x value
     * @param y the added points y value
     * @returns the updated Path2.
     */
    Path2.prototype.addLineTo = function (x, y) {
        if (this.closed) {
            return this;
        }
        var newPoint = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](x, y);
        var previousPoint = this._points[this._points.length - 1];
        this._points.push(newPoint);
        this._length += newPoint.subtract(previousPoint).length();
        return this;
    };
    /**
     * Adds _numberOfSegments_ segments according to the arc definition (middle point coordinates, end point coordinates, the arc start point being the current Path2 last point) to the current Path2.
     * @param midX middle point x value
     * @param midY middle point y value
     * @param endX end point x value
     * @param endY end point y value
     * @param numberOfSegments (default: 36)
     * @returns the updated Path2.
     */
    Path2.prototype.addArcTo = function (midX, midY, endX, endY, numberOfSegments) {
        if (numberOfSegments === void 0) { numberOfSegments = 36; }
        if (this.closed) {
            return this;
        }
        var startPoint = this._points[this._points.length - 1];
        var midPoint = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](midX, midY);
        var endPoint = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](endX, endY);
        var arc = new Arc2(startPoint, midPoint, endPoint);
        var increment = arc.angle.radians() / numberOfSegments;
        if (arc.orientation === Orientation.CW) {
            increment *= -1;
        }
        var currentAngle = arc.startAngle.radians() + increment;
        for (var i = 0; i < numberOfSegments; i++) {
            var x = Math.cos(currentAngle) * arc.radius + arc.centerPoint.x;
            var y = Math.sin(currentAngle) * arc.radius + arc.centerPoint.y;
            this.addLineTo(x, y);
            currentAngle += increment;
        }
        return this;
    };
    /**
     * Closes the Path2.
     * @returns the Path2.
     */
    Path2.prototype.close = function () {
        this.closed = true;
        return this;
    };
    /**
     * Gets the sum of the distance between each sequential point in the path
     * @returns the Path2 total length (float).
     */
    Path2.prototype.length = function () {
        var result = this._length;
        if (!this.closed) {
            var lastPoint = this._points[this._points.length - 1];
            var firstPoint = this._points[0];
            result += (firstPoint.subtract(lastPoint).length());
        }
        return result;
    };
    /**
     * Gets the points which construct the path
     * @returns the Path2 internal array of points.
     */
    Path2.prototype.getPoints = function () {
        return this._points;
    };
    /**
     * Retreives the point at the distance aways from the starting point
     * @param normalizedLengthPosition the length along the path to retreive the point from
     * @returns a new Vector2 located at a percentage of the Path2 total length on this path.
     */
    Path2.prototype.getPointAtLengthPosition = function (normalizedLengthPosition) {
        if (normalizedLengthPosition < 0 || normalizedLengthPosition > 1) {
            return _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"].Zero();
        }
        var lengthPosition = normalizedLengthPosition * this.length();
        var previousOffset = 0;
        for (var i = 0; i < this._points.length; i++) {
            var j = (i + 1) % this._points.length;
            var a = this._points[i];
            var b = this._points[j];
            var bToA = b.subtract(a);
            var nextOffset = (bToA.length() + previousOffset);
            if (lengthPosition >= previousOffset && lengthPosition <= nextOffset) {
                var dir = bToA.normalize();
                var localOffset = lengthPosition - previousOffset;
                return new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](a.x + (dir.x * localOffset), a.y + (dir.y * localOffset));
            }
            previousOffset = nextOffset;
        }
        return _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"].Zero();
    };
    /**
     * Creates a new path starting from an x and y position
     * @param x starting x value
     * @param y starting y value
     * @returns a new Path2 starting at the coordinates (x, y).
     */
    Path2.StartingAt = function (x, y) {
        return new Path2(x, y);
    };
    return Path2;
}());

/**
 * Represents a 3D path made up of multiple 3D points
 */
var Path3D = /** @class */ (function () {
    /**
    * new Path3D(path, normal, raw)
    * Creates a Path3D. A Path3D is a logical math object, so not a mesh.
    * please read the description in the tutorial : https://doc.babylonjs.com/how_to/how_to_use_path3d
    * @param path an array of Vector3, the curve axis of the Path3D
    * @param firstNormal (options) Vector3, the first wanted normal to the curve. Ex (0, 1, 0) for a vertical normal.
    * @param raw (optional, default false) : boolean, if true the returned Path3D isn't normalized. Useful to depict path acceleration or speed.
    */
    function Path3D(
    /**
     * an array of Vector3, the curve axis of the Path3D
     */
    path, firstNormal, raw) {
        if (firstNormal === void 0) { firstNormal = null; }
        this.path = path;
        this._curve = new Array();
        this._distances = new Array();
        this._tangents = new Array();
        this._normals = new Array();
        this._binormals = new Array();
        for (var p = 0; p < path.length; p++) {
            this._curve[p] = path[p].clone(); // hard copy
        }
        this._raw = raw || false;
        this._compute(firstNormal);
    }
    /**
     * Returns the Path3D array of successive Vector3 designing its curve.
     * @returns the Path3D array of successive Vector3 designing its curve.
     */
    Path3D.prototype.getCurve = function () {
        return this._curve;
    };
    /**
     * Returns an array populated with tangent vectors on each Path3D curve point.
     * @returns an array populated with tangent vectors on each Path3D curve point.
     */
    Path3D.prototype.getTangents = function () {
        return this._tangents;
    };
    /**
     * Returns an array populated with normal vectors on each Path3D curve point.
     * @returns an array populated with normal vectors on each Path3D curve point.
     */
    Path3D.prototype.getNormals = function () {
        return this._normals;
    };
    /**
     * Returns an array populated with binormal vectors on each Path3D curve point.
     * @returns an array populated with binormal vectors on each Path3D curve point.
     */
    Path3D.prototype.getBinormals = function () {
        return this._binormals;
    };
    /**
     * Returns an array populated with distances (float) of the i-th point from the first curve point.
     * @returns an array populated with distances (float) of the i-th point from the first curve point.
     */
    Path3D.prototype.getDistances = function () {
        return this._distances;
    };
    /**
     * Forces the Path3D tangent, normal, binormal and distance recomputation.
     * @param path path which all values are copied into the curves points
     * @param firstNormal which should be projected onto the curve
     * @returns the same object updated.
     */
    Path3D.prototype.update = function (path, firstNormal) {
        if (firstNormal === void 0) { firstNormal = null; }
        for (var p = 0; p < path.length; p++) {
            this._curve[p].x = path[p].x;
            this._curve[p].y = path[p].y;
            this._curve[p].z = path[p].z;
        }
        this._compute(firstNormal);
        return this;
    };
    // private function compute() : computes tangents, normals and binormals
    Path3D.prototype._compute = function (firstNormal) {
        var l = this._curve.length;
        // first and last tangents
        this._tangents[0] = this._getFirstNonNullVector(0);
        if (!this._raw) {
            this._tangents[0].normalize();
        }
        this._tangents[l - 1] = this._curve[l - 1].subtract(this._curve[l - 2]);
        if (!this._raw) {
            this._tangents[l - 1].normalize();
        }
        // normals and binormals at first point : arbitrary vector with _normalVector()
        var tg0 = this._tangents[0];
        var pp0 = this._normalVector(tg0, firstNormal);
        this._normals[0] = pp0;
        if (!this._raw) {
            this._normals[0].normalize();
        }
        this._binormals[0] = _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(tg0, this._normals[0]);
        if (!this._raw) {
            this._binormals[0].normalize();
        }
        this._distances[0] = 0.0;
        // normals and binormals : next points
        var prev; // previous vector (segment)
        var cur; // current vector (segment)
        var curTang; // current tangent
        // previous normal
        var prevBinor; // previous binormal
        for (var i = 1; i < l; i++) {
            // tangents
            prev = this._getLastNonNullVector(i);
            if (i < l - 1) {
                cur = this._getFirstNonNullVector(i);
                this._tangents[i] = prev.add(cur);
                this._tangents[i].normalize();
            }
            this._distances[i] = this._distances[i - 1] + prev.length();
            // normals and binormals
            // http://www.cs.cmu.edu/afs/andrew/scs/cs/15-462/web/old/asst2camera.html
            curTang = this._tangents[i];
            prevBinor = this._binormals[i - 1];
            this._normals[i] = _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(prevBinor, curTang);
            if (!this._raw) {
                this._normals[i].normalize();
            }
            this._binormals[i] = _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(curTang, this._normals[i]);
            if (!this._raw) {
                this._binormals[i].normalize();
            }
        }
    };
    // private function getFirstNonNullVector(index)
    // returns the first non null vector from index : curve[index + N].subtract(curve[index])
    Path3D.prototype._getFirstNonNullVector = function (index) {
        var i = 1;
        var nNVector = this._curve[index + i].subtract(this._curve[index]);
        while (nNVector.length() === 0 && index + i + 1 < this._curve.length) {
            i++;
            nNVector = this._curve[index + i].subtract(this._curve[index]);
        }
        return nNVector;
    };
    // private function getLastNonNullVector(index)
    // returns the last non null vector from index : curve[index].subtract(curve[index - N])
    Path3D.prototype._getLastNonNullVector = function (index) {
        var i = 1;
        var nLVector = this._curve[index].subtract(this._curve[index - i]);
        while (nLVector.length() === 0 && index > i + 1) {
            i++;
            nLVector = this._curve[index].subtract(this._curve[index - i]);
        }
        return nLVector;
    };
    // private function normalVector(v0, vt, va) :
    // returns an arbitrary point in the plane defined by the point v0 and the vector vt orthogonal to this plane
    // if va is passed, it returns the va projection on the plane orthogonal to vt at the point v0
    Path3D.prototype._normalVector = function (vt, va) {
        var normal0;
        var tgl = vt.length();
        if (tgl === 0.0) {
            tgl = 1.0;
        }
        if (va === undefined || va === null) {
            var point;
            if (!_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(Math.abs(vt.y) / tgl, 1.0, _math_constants__WEBPACK_IMPORTED_MODULE_2__["Epsilon"])) { // search for a point in the plane
                point = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0.0, -1.0, 0.0);
            }
            else if (!_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(Math.abs(vt.x) / tgl, 1.0, _math_constants__WEBPACK_IMPORTED_MODULE_2__["Epsilon"])) {
                point = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](1.0, 0.0, 0.0);
            }
            else if (!_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(Math.abs(vt.z) / tgl, 1.0, _math_constants__WEBPACK_IMPORTED_MODULE_2__["Epsilon"])) {
                point = new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0.0, 0.0, 1.0);
            }
            else {
                point = _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
            }
            normal0 = _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(vt, point);
        }
        else {
            normal0 = _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Cross(vt, va);
            _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(normal0, vt, normal0);
        }
        normal0.normalize();
        return normal0;
    };
    return Path3D;
}());

/**
 * A Curve3 object is a logical object, so not a mesh, to handle curves in the 3D geometric space.
 * A Curve3 is designed from a series of successive Vector3.
 * @see https://doc.babylonjs.com/how_to/how_to_use_curve3
 */
var Curve3 = /** @class */ (function () {
    /**
     * A Curve3 object is a logical object, so not a mesh, to handle curves in the 3D geometric space.
     * A Curve3 is designed from a series of successive Vector3.
     * Tuto : https://doc.babylonjs.com/how_to/how_to_use_curve3#curve3-object
     * @param points points which make up the curve
     */
    function Curve3(points) {
        this._length = 0.0;
        this._points = points;
        this._length = this._computeLength(points);
    }
    /**
     * Returns a Curve3 object along a Quadratic Bezier curve : https://doc.babylonjs.com/how_to/how_to_use_curve3#quadratic-bezier-curve
     * @param v0 (Vector3) the origin point of the Quadratic Bezier
     * @param v1 (Vector3) the control point
     * @param v2 (Vector3) the end point of the Quadratic Bezier
     * @param nbPoints (integer) the wanted number of points in the curve
     * @returns the created Curve3
     */
    Curve3.CreateQuadraticBezier = function (v0, v1, v2, nbPoints) {
        nbPoints = nbPoints > 2 ? nbPoints : 3;
        var bez = new Array();
        var equation = function (t, val0, val1, val2) {
            var res = (1.0 - t) * (1.0 - t) * val0 + 2.0 * t * (1.0 - t) * val1 + t * t * val2;
            return res;
        };
        for (var i = 0; i <= nbPoints; i++) {
            bez.push(new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](equation(i / nbPoints, v0.x, v1.x, v2.x), equation(i / nbPoints, v0.y, v1.y, v2.y), equation(i / nbPoints, v0.z, v1.z, v2.z)));
        }
        return new Curve3(bez);
    };
    /**
     * Returns a Curve3 object along a Cubic Bezier curve : https://doc.babylonjs.com/how_to/how_to_use_curve3#cubic-bezier-curve
     * @param v0 (Vector3) the origin point of the Cubic Bezier
     * @param v1 (Vector3) the first control point
     * @param v2 (Vector3) the second control point
     * @param v3 (Vector3) the end point of the Cubic Bezier
     * @param nbPoints (integer) the wanted number of points in the curve
     * @returns the created Curve3
     */
    Curve3.CreateCubicBezier = function (v0, v1, v2, v3, nbPoints) {
        nbPoints = nbPoints > 3 ? nbPoints : 4;
        var bez = new Array();
        var equation = function (t, val0, val1, val2, val3) {
            var res = (1.0 - t) * (1.0 - t) * (1.0 - t) * val0 + 3.0 * t * (1.0 - t) * (1.0 - t) * val1 + 3.0 * t * t * (1.0 - t) * val2 + t * t * t * val3;
            return res;
        };
        for (var i = 0; i <= nbPoints; i++) {
            bez.push(new _math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](equation(i / nbPoints, v0.x, v1.x, v2.x, v3.x), equation(i / nbPoints, v0.y, v1.y, v2.y, v3.y), equation(i / nbPoints, v0.z, v1.z, v2.z, v3.z)));
        }
        return new Curve3(bez);
    };
    /**
     * Returns a Curve3 object along a Hermite Spline curve : https://doc.babylonjs.com/how_to/how_to_use_curve3#hermite-spline
     * @param p1 (Vector3) the origin point of the Hermite Spline
     * @param t1 (Vector3) the tangent vector at the origin point
     * @param p2 (Vector3) the end point of the Hermite Spline
     * @param t2 (Vector3) the tangent vector at the end point
     * @param nbPoints (integer) the wanted number of points in the curve
     * @returns the created Curve3
     */
    Curve3.CreateHermiteSpline = function (p1, t1, p2, t2, nbPoints) {
        var hermite = new Array();
        var step = 1.0 / nbPoints;
        for (var i = 0; i <= nbPoints; i++) {
            hermite.push(_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Hermite(p1, t1, p2, t2, i * step));
        }
        return new Curve3(hermite);
    };
    /**
     * Returns a Curve3 object along a CatmullRom Spline curve :
     * @param points (array of Vector3) the points the spline must pass through. At least, four points required
     * @param nbPoints (integer) the wanted number of points between each curve control points
     * @param closed (boolean) optional with default false, when true forms a closed loop from the points
     * @returns the created Curve3
     */
    Curve3.CreateCatmullRomSpline = function (points, nbPoints, closed) {
        var catmullRom = new Array();
        var step = 1.0 / nbPoints;
        var amount = 0.0;
        if (closed) {
            var pointsCount = points.length;
            for (var i = 0; i < pointsCount; i++) {
                amount = 0;
                for (var c = 0; c < nbPoints; c++) {
                    catmullRom.push(_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CatmullRom(points[i % pointsCount], points[(i + 1) % pointsCount], points[(i + 2) % pointsCount], points[(i + 3) % pointsCount], amount));
                    amount += step;
                }
            }
            catmullRom.push(catmullRom[0]);
        }
        else {
            var totalPoints = new Array();
            totalPoints.push(points[0].clone());
            Array.prototype.push.apply(totalPoints, points);
            totalPoints.push(points[points.length - 1].clone());
            for (var i = 0; i < totalPoints.length - 3; i++) {
                amount = 0;
                for (var c = 0; c < nbPoints; c++) {
                    catmullRom.push(_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CatmullRom(totalPoints[i], totalPoints[i + 1], totalPoints[i + 2], totalPoints[i + 3], amount));
                    amount += step;
                }
            }
            i--;
            catmullRom.push(_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CatmullRom(totalPoints[i], totalPoints[i + 1], totalPoints[i + 2], totalPoints[i + 3], amount));
        }
        return new Curve3(catmullRom);
    };
    /**
     * @returns the Curve3 stored array of successive Vector3
     */
    Curve3.prototype.getPoints = function () {
        return this._points;
    };
    /**
     * @returns the computed length (float) of the curve.
     */
    Curve3.prototype.length = function () {
        return this._length;
    };
    /**
     * Returns a new instance of Curve3 object : var curve = curveA.continue(curveB);
     * This new Curve3 is built by translating and sticking the curveB at the end of the curveA.
     * curveA and curveB keep unchanged.
     * @param curve the curve to continue from this curve
     * @returns the newly constructed curve
     */
    Curve3.prototype.continue = function (curve) {
        var lastPoint = this._points[this._points.length - 1];
        var continuedPoints = this._points.slice();
        var curvePoints = curve.getPoints();
        for (var i = 1; i < curvePoints.length; i++) {
            continuedPoints.push(curvePoints[i].subtract(curvePoints[0]).add(lastPoint));
        }
        var continuedCurve = new Curve3(continuedPoints);
        return continuedCurve;
    };
    Curve3.prototype._computeLength = function (path) {
        var l = 0;
        for (var i = 1; i < path.length; i++) {
            l += (path[i].subtract(path[i - 1])).length();
        }
        return l;
    };
    return Curve3;
}());



/***/ }),

/***/ "./Maths/math.plane.ts":
/*!*****************************!*\
  !*** ./Maths/math.plane.ts ***!
  \*****************************/
/*! exports provided: Plane */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Plane", function() { return Plane; });
/* harmony import */ var _math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.vector */ "./Maths/math.vector.ts");

/**
 * Represens a plane by the equation ax + by + cz + d = 0
 */
var Plane = /** @class */ (function () {
    /**
     * Creates a Plane object according to the given floats a, b, c, d and the plane equation : ax + by + cz + d = 0
     * @param a a component of the plane
     * @param b b component of the plane
     * @param c c component of the plane
     * @param d d component of the plane
     */
    function Plane(a, b, c, d) {
        this.normal = new _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](a, b, c);
        this.d = d;
    }
    /**
     * @returns the plane coordinates as a new array of 4 elements [a, b, c, d].
     */
    Plane.prototype.asArray = function () {
        return [this.normal.x, this.normal.y, this.normal.z, this.d];
    };
    // Methods
    /**
     * @returns a new plane copied from the current Plane.
     */
    Plane.prototype.clone = function () {
        return new Plane(this.normal.x, this.normal.y, this.normal.z, this.d);
    };
    /**
     * @returns the string "Plane".
     */
    Plane.prototype.getClassName = function () {
        return "Plane";
    };
    /**
     * @returns the Plane hash code.
     */
    Plane.prototype.getHashCode = function () {
        var hash = this.normal.getHashCode();
        hash = (hash * 397) ^ (this.d | 0);
        return hash;
    };
    /**
     * Normalize the current Plane in place.
     * @returns the updated Plane.
     */
    Plane.prototype.normalize = function () {
        var norm = (Math.sqrt((this.normal.x * this.normal.x) + (this.normal.y * this.normal.y) + (this.normal.z * this.normal.z)));
        var magnitude = 0.0;
        if (norm !== 0) {
            magnitude = 1.0 / norm;
        }
        this.normal.x *= magnitude;
        this.normal.y *= magnitude;
        this.normal.z *= magnitude;
        this.d *= magnitude;
        return this;
    };
    /**
     * Applies a transformation the plane and returns the result
     * @param transformation the transformation matrix to be applied to the plane
     * @returns a new Plane as the result of the transformation of the current Plane by the given matrix.
     */
    Plane.prototype.transform = function (transformation) {
        var transposedMatrix = Plane._TmpMatrix;
        _math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].TransposeToRef(transformation, transposedMatrix);
        var m = transposedMatrix.m;
        var x = this.normal.x;
        var y = this.normal.y;
        var z = this.normal.z;
        var d = this.d;
        var normalX = x * m[0] + y * m[1] + z * m[2] + d * m[3];
        var normalY = x * m[4] + y * m[5] + z * m[6] + d * m[7];
        var normalZ = x * m[8] + y * m[9] + z * m[10] + d * m[11];
        var finalD = x * m[12] + y * m[13] + z * m[14] + d * m[15];
        return new Plane(normalX, normalY, normalZ, finalD);
    };
    /**
     * Calcualtte the dot product between the point and the plane normal
     * @param point point to calculate the dot product with
     * @returns the dot product (float) of the point coordinates and the plane normal.
     */
    Plane.prototype.dotCoordinate = function (point) {
        return ((((this.normal.x * point.x) + (this.normal.y * point.y)) + (this.normal.z * point.z)) + this.d);
    };
    /**
     * Updates the current Plane from the plane defined by the three given points.
     * @param point1 one of the points used to contruct the plane
     * @param point2 one of the points used to contruct the plane
     * @param point3 one of the points used to contruct the plane
     * @returns the updated Plane.
     */
    Plane.prototype.copyFromPoints = function (point1, point2, point3) {
        var x1 = point2.x - point1.x;
        var y1 = point2.y - point1.y;
        var z1 = point2.z - point1.z;
        var x2 = point3.x - point1.x;
        var y2 = point3.y - point1.y;
        var z2 = point3.z - point1.z;
        var yz = (y1 * z2) - (z1 * y2);
        var xz = (z1 * x2) - (x1 * z2);
        var xy = (x1 * y2) - (y1 * x2);
        var pyth = (Math.sqrt((yz * yz) + (xz * xz) + (xy * xy)));
        var invPyth;
        if (pyth !== 0) {
            invPyth = 1.0 / pyth;
        }
        else {
            invPyth = 0.0;
        }
        this.normal.x = yz * invPyth;
        this.normal.y = xz * invPyth;
        this.normal.z = xy * invPyth;
        this.d = -((this.normal.x * point1.x) + (this.normal.y * point1.y) + (this.normal.z * point1.z));
        return this;
    };
    /**
     * Checks if the plane is facing a given direction
     * @param direction the direction to check if the plane is facing
     * @param epsilon value the dot product is compared against (returns true if dot <= epsilon)
     * @returns True is the vector "direction"  is the same side than the plane normal.
     */
    Plane.prototype.isFrontFacingTo = function (direction, epsilon) {
        var dot = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this.normal, direction);
        return (dot <= epsilon);
    };
    /**
     * Calculates the distance to a point
     * @param point point to calculate distance to
     * @returns the signed distance (float) from the given point to the Plane.
     */
    Plane.prototype.signedDistanceTo = function (point) {
        return _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(point, this.normal) + this.d;
    };
    // Statics
    /**
     * Creates a plane from an  array
     * @param array the array to create a plane from
     * @returns a new Plane from the given array.
     */
    Plane.FromArray = function (array) {
        return new Plane(array[0], array[1], array[2], array[3]);
    };
    /**
     * Creates a plane from three points
     * @param point1 point used to create the plane
     * @param point2 point used to create the plane
     * @param point3 point used to create the plane
     * @returns a new Plane defined by the three given points.
     */
    Plane.FromPoints = function (point1, point2, point3) {
        var result = new Plane(0.0, 0.0, 0.0, 0.0);
        result.copyFromPoints(point1, point2, point3);
        return result;
    };
    /**
     * Creates a plane from an origin point and a normal
     * @param origin origin of the plane to be constructed
     * @param normal normal of the plane to be constructed
     * @returns a new Plane the normal vector to this plane at the given origin point.
     * Note : the vector "normal" is updated because normalized.
     */
    Plane.FromPositionAndNormal = function (origin, normal) {
        var result = new Plane(0.0, 0.0, 0.0, 0.0);
        normal.normalize();
        result.normal = normal;
        result.d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z);
        return result;
    };
    /**
     * Calculates the distance from a plane and a point
     * @param origin origin of the plane to be constructed
     * @param normal normal of the plane to be constructed
     * @param point point to calculate distance to
     * @returns the signed distance between the plane defined by the normal vector at the "origin"" point and the given other point.
     */
    Plane.SignedDistanceToPlaneFromPositionAndNormal = function (origin, normal, point) {
        var d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z);
        return _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(point, normal) + d;
    };
    Plane._TmpMatrix = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Identity();
    return Plane;
}());



/***/ }),

/***/ "./Maths/math.scalar.ts":
/*!******************************!*\
  !*** ./Maths/math.scalar.ts ***!
  \******************************/
/*! exports provided: Scalar */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scalar", function() { return Scalar; });
/**
 * Scalar computation library
 */
var Scalar = /** @class */ (function () {
    function Scalar() {
    }
    /**
     * Boolean : true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)
     * @param a number
     * @param b number
     * @param epsilon (default = 1.401298E-45)
     * @returns true if the absolute difference between a and b is lower than epsilon (default = 1.401298E-45)
     */
    Scalar.WithinEpsilon = function (a, b, epsilon) {
        if (epsilon === void 0) { epsilon = 1.401298E-45; }
        var num = a - b;
        return -epsilon <= num && num <= epsilon;
    };
    /**
     * Returns a string : the upper case translation of the number i to hexadecimal.
     * @param i number
     * @returns the upper case translation of the number i to hexadecimal.
     */
    Scalar.ToHex = function (i) {
        var str = i.toString(16);
        if (i <= 15) {
            return ("0" + str).toUpperCase();
        }
        return str.toUpperCase();
    };
    /**
     * Returns -1 if value is negative and +1 is value is positive.
     * @param value the value
     * @returns the value itself if it's equal to zero.
     */
    Scalar.Sign = function (value) {
        value = +value; // convert to a number
        if (value === 0 || isNaN(value)) {
            return value;
        }
        return value > 0 ? 1 : -1;
    };
    /**
     * Returns the value itself if it's between min and max.
     * Returns min if the value is lower than min.
     * Returns max if the value is greater than max.
     * @param value the value to clmap
     * @param min the min value to clamp to (default: 0)
     * @param max the max value to clamp to (default: 1)
     * @returns the clamped value
     */
    Scalar.Clamp = function (value, min, max) {
        if (min === void 0) { min = 0; }
        if (max === void 0) { max = 1; }
        return Math.min(max, Math.max(min, value));
    };
    /**
     * the log2 of value.
     * @param value the value to compute log2 of
     * @returns the log2 of value.
     */
    Scalar.Log2 = function (value) {
        return Math.log(value) * Math.LOG2E;
    };
    /**
    * Loops the value, so that it is never larger than length and never smaller than 0.
    *
    * This is similar to the modulo operator but it works with floating point numbers.
    * For example, using 3.0 for t and 2.5 for length, the result would be 0.5.
    * With t = 5 and length = 2.5, the result would be 0.0.
    * Note, however, that the behaviour is not defined for negative numbers as it is for the modulo operator
    * @param value the value
    * @param length the length
    * @returns the looped value
    */
    Scalar.Repeat = function (value, length) {
        return value - Math.floor(value / length) * length;
    };
    /**
     * Normalize the value between 0.0 and 1.0 using min and max values
     * @param value value to normalize
     * @param min max to normalize between
     * @param max min to normalize between
     * @returns the normalized value
     */
    Scalar.Normalize = function (value, min, max) {
        return (value - min) / (max - min);
    };
    /**
    * Denormalize the value from 0.0 and 1.0 using min and max values
    * @param normalized value to denormalize
    * @param min max to denormalize between
    * @param max min to denormalize between
    * @returns the denormalized value
    */
    Scalar.Denormalize = function (normalized, min, max) {
        return (normalized * (max - min) + min);
    };
    /**
    * Calculates the shortest difference between two given angles given in degrees.
    * @param current current angle in degrees
    * @param target target angle in degrees
    * @returns the delta
    */
    Scalar.DeltaAngle = function (current, target) {
        var num = Scalar.Repeat(target - current, 360.0);
        if (num > 180.0) {
            num -= 360.0;
        }
        return num;
    };
    /**
    * PingPongs the value t, so that it is never larger than length and never smaller than 0.
    * @param tx value
    * @param length length
    * @returns The returned value will move back and forth between 0 and length
    */
    Scalar.PingPong = function (tx, length) {
        var t = Scalar.Repeat(tx, length * 2.0);
        return length - Math.abs(t - length);
    };
    /**
    * Interpolates between min and max with smoothing at the limits.
    *
    * This function interpolates between min and max in a similar way to Lerp. However, the interpolation will gradually speed up
    * from the start and slow down toward the end. This is useful for creating natural-looking animation, fading and other transitions.
    * @param from from
    * @param to to
    * @param tx value
    * @returns the smooth stepped value
    */
    Scalar.SmoothStep = function (from, to, tx) {
        var t = Scalar.Clamp(tx);
        t = -2.0 * t * t * t + 3.0 * t * t;
        return to * t + from * (1.0 - t);
    };
    /**
    * Moves a value current towards target.
    *
    * This is essentially the same as Mathf.Lerp but instead the function will ensure that the speed never exceeds maxDelta.
    * Negative values of maxDelta pushes the value away from target.
    * @param current current value
    * @param target target value
    * @param maxDelta max distance to move
    * @returns resulting value
    */
    Scalar.MoveTowards = function (current, target, maxDelta) {
        var result = 0;
        if (Math.abs(target - current) <= maxDelta) {
            result = target;
        }
        else {
            result = current + Scalar.Sign(target - current) * maxDelta;
        }
        return result;
    };
    /**
    * Same as MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.
    *
    * Variables current and target are assumed to be in degrees. For optimization reasons, negative values of maxDelta
    *  are not supported and may cause oscillation. To push current away from a target angle, add 180 to that angle instead.
    * @param current current value
    * @param target target value
    * @param maxDelta max distance to move
    * @returns resulting angle
    */
    Scalar.MoveTowardsAngle = function (current, target, maxDelta) {
        var num = Scalar.DeltaAngle(current, target);
        var result = 0;
        if (-maxDelta < num && num < maxDelta) {
            result = target;
        }
        else {
            target = current + num;
            result = Scalar.MoveTowards(current, target, maxDelta);
        }
        return result;
    };
    /**
     * Creates a new scalar with values linearly interpolated of "amount" between the start scalar and the end scalar.
     * @param start start value
     * @param end target value
     * @param amount amount to lerp between
     * @returns the lerped value
     */
    Scalar.Lerp = function (start, end, amount) {
        return start + ((end - start) * amount);
    };
    /**
    * Same as Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.
    * The parameter t is clamped to the range [0, 1]. Variables a and b are assumed to be in degrees.
    * @param start start value
    * @param end target value
    * @param amount amount to lerp between
    * @returns the lerped value
    */
    Scalar.LerpAngle = function (start, end, amount) {
        var num = Scalar.Repeat(end - start, 360.0);
        if (num > 180.0) {
            num -= 360.0;
        }
        return start + num * Scalar.Clamp(amount);
    };
    /**
    * Calculates the linear parameter t that produces the interpolant value within the range [a, b].
    * @param a start value
    * @param b target value
    * @param value value between a and b
    * @returns the inverseLerp value
    */
    Scalar.InverseLerp = function (a, b, value) {
        var result = 0;
        if (a != b) {
            result = Scalar.Clamp((value - a) / (b - a));
        }
        else {
            result = 0.0;
        }
        return result;
    };
    /**
     * Returns a new scalar located for "amount" (float) on the Hermite spline defined by the scalars "value1", "value3", "tangent1", "tangent2".
     * @see http://mathworld.wolfram.com/HermitePolynomial.html
     * @param value1 spline value
     * @param tangent1 spline value
     * @param value2 spline value
     * @param tangent2 spline value
     * @param amount input value
     * @returns hermite result
     */
    Scalar.Hermite = function (value1, tangent1, value2, tangent2, amount) {
        var squared = amount * amount;
        var cubed = amount * squared;
        var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
        var part2 = (-2.0 * cubed) + (3.0 * squared);
        var part3 = (cubed - (2.0 * squared)) + amount;
        var part4 = cubed - squared;
        return (((value1 * part1) + (value2 * part2)) + (tangent1 * part3)) + (tangent2 * part4);
    };
    /**
    * Returns a random float number between and min and max values
    * @param min min value of random
    * @param max max value of random
    * @returns random value
    */
    Scalar.RandomRange = function (min, max) {
        if (min === max) {
            return min;
        }
        return ((Math.random() * (max - min)) + min);
    };
    /**
    * This function returns percentage of a number in a given range.
    *
    * RangeToPercent(40,20,60) will return 0.5 (50%)
    * RangeToPercent(34,0,100) will return 0.34 (34%)
    * @param number to convert to percentage
    * @param min min range
    * @param max max range
    * @returns the percentage
    */
    Scalar.RangeToPercent = function (number, min, max) {
        return ((number - min) / (max - min));
    };
    /**
    * This function returns number that corresponds to the percentage in a given range.
    *
    * PercentToRange(0.34,0,100) will return 34.
    * @param percent to convert to number
    * @param min min range
    * @param max max range
    * @returns the number
    */
    Scalar.PercentToRange = function (percent, min, max) {
        return ((max - min) * percent + min);
    };
    /**
     * Returns the angle converted to equivalent value between -Math.PI and Math.PI radians.
     * @param angle The angle to normalize in radian.
     * @return The converted angle.
     */
    Scalar.NormalizeRadians = function (angle) {
        // More precise but slower version kept for reference.
        // angle = angle % Tools.TwoPi;
        // angle = (angle + Tools.TwoPi) % Tools.TwoPi;
        //if (angle > Math.PI) {
        //  angle -= Tools.TwoPi;
        //}
        angle -= (Scalar.TwoPi * Math.floor((angle + Math.PI) / Scalar.TwoPi));
        return angle;
    };
    /**
     * Two pi constants convenient for computation.
     */
    Scalar.TwoPi = Math.PI * 2;
    return Scalar;
}());



/***/ }),

/***/ "./Maths/math.size.ts":
/*!****************************!*\
  !*** ./Maths/math.size.ts ***!
  \****************************/
/*! exports provided: Size */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Size", function() { return Size; });
/**
 * Size containing widht and height
 */
var Size = /** @class */ (function () {
    /**
     * Creates a Size object from the given width and height (floats).
     * @param width width of the new size
     * @param height height of the new size
     */
    function Size(width, height) {
        this.width = width;
        this.height = height;
    }
    /**
     * Returns a string with the Size width and height
     * @returns a string with the Size width and height
     */
    Size.prototype.toString = function () {
        return "{W: " + this.width + ", H: " + this.height + "}";
    };
    /**
     * "Size"
     * @returns the string "Size"
     */
    Size.prototype.getClassName = function () {
        return "Size";
    };
    /**
     * Returns the Size hash code.
     * @returns a hash code for a unique width and height
     */
    Size.prototype.getHashCode = function () {
        var hash = this.width | 0;
        hash = (hash * 397) ^ (this.height | 0);
        return hash;
    };
    /**
     * Updates the current size from the given one.
     * @param src the given size
     */
    Size.prototype.copyFrom = function (src) {
        this.width = src.width;
        this.height = src.height;
    };
    /**
     * Updates in place the current Size from the given floats.
     * @param width width of the new size
     * @param height height of the new size
     * @returns the updated Size.
     */
    Size.prototype.copyFromFloats = function (width, height) {
        this.width = width;
        this.height = height;
        return this;
    };
    /**
     * Updates in place the current Size from the given floats.
     * @param width width to set
     * @param height height to set
     * @returns the updated Size.
     */
    Size.prototype.set = function (width, height) {
        return this.copyFromFloats(width, height);
    };
    /**
     * Multiplies the width and height by numbers
     * @param w factor to multiple the width by
     * @param h factor to multiple the height by
     * @returns a new Size set with the multiplication result of the current Size and the given floats.
     */
    Size.prototype.multiplyByFloats = function (w, h) {
        return new Size(this.width * w, this.height * h);
    };
    /**
     * Clones the size
     * @returns a new Size copied from the given one.
     */
    Size.prototype.clone = function () {
        return new Size(this.width, this.height);
    };
    /**
     * True if the current Size and the given one width and height are strictly equal.
     * @param other the other size to compare against
     * @returns True if the current Size and the given one width and height are strictly equal.
     */
    Size.prototype.equals = function (other) {
        if (!other) {
            return false;
        }
        return (this.width === other.width) && (this.height === other.height);
    };
    Object.defineProperty(Size.prototype, "surface", {
        /**
         * The surface of the Size : width * height (float).
         */
        get: function () {
            return this.width * this.height;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Create a new size of zero
     * @returns a new Size set to (0.0, 0.0)
     */
    Size.Zero = function () {
        return new Size(0.0, 0.0);
    };
    /**
     * Sums the width and height of two sizes
     * @param otherSize size to add to this size
     * @returns a new Size set as the addition result of the current Size and the given one.
     */
    Size.prototype.add = function (otherSize) {
        var r = new Size(this.width + otherSize.width, this.height + otherSize.height);
        return r;
    };
    /**
     * Subtracts the width and height of two
     * @param otherSize size to subtract to this size
     * @returns a new Size set as the subtraction result of  the given one from the current Size.
     */
    Size.prototype.subtract = function (otherSize) {
        var r = new Size(this.width - otherSize.width, this.height - otherSize.height);
        return r;
    };
    /**
     * Creates a new Size set at the linear interpolation "amount" between "start" and "end"
     * @param start starting size to lerp between
     * @param end end size to lerp between
     * @param amount amount to lerp between the start and end values
     * @returns a new Size set at the linear interpolation "amount" between "start" and "end"
     */
    Size.Lerp = function (start, end, amount) {
        var w = start.width + ((end.width - start.width) * amount);
        var h = start.height + ((end.height - start.height) * amount);
        return new Size(w, h);
    };
    return Size;
}());



/***/ }),

/***/ "./Maths/math.ts":
/*!***********************!*\
  !*** ./Maths/math.ts ***!
  \***********************/
/*! exports provided: Space, Axis, Color3, Color4, TmpColors, ToGammaSpace, ToLinearSpace, Epsilon, Frustum, Plane, Size, Vector2, Vector3, Vector4, Quaternion, Matrix, TmpVectors, Viewport, Orientation, BezierCurve, Angle, Arc2, Path2, Path3D, Curve3, PositionNormalVertex, PositionNormalTextureVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _math_axis__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.axis */ "./Maths/math.axis.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Space", function() { return _math_axis__WEBPACK_IMPORTED_MODULE_0__["Space"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Axis", function() { return _math_axis__WEBPACK_IMPORTED_MODULE_0__["Axis"]; });

/* harmony import */ var _math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math.color */ "./Maths/math.color.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3", function() { return _math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color4", function() { return _math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpColors", function() { return _math_color__WEBPACK_IMPORTED_MODULE_1__["TmpColors"]; });

/* harmony import */ var _math_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./math.constants */ "./Maths/math.constants.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToGammaSpace", function() { return _math_constants__WEBPACK_IMPORTED_MODULE_2__["ToGammaSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToLinearSpace", function() { return _math_constants__WEBPACK_IMPORTED_MODULE_2__["ToLinearSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Epsilon", function() { return _math_constants__WEBPACK_IMPORTED_MODULE_2__["Epsilon"]; });

/* harmony import */ var _math_frustum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./math.frustum */ "./Maths/math.frustum.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return _math_frustum__WEBPACK_IMPORTED_MODULE_3__["Frustum"]; });

/* harmony import */ var _math_path__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./math.path */ "./Maths/math.path.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Orientation", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["Orientation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurve", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["BezierCurve"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Angle", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["Angle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Arc2", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["Arc2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path2", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["Path2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path3D", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["Path3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Curve3", function() { return _math_path__WEBPACK_IMPORTED_MODULE_4__["Curve3"]; });

/* harmony import */ var _math_plane__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./math.plane */ "./Maths/math.plane.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Plane", function() { return _math_plane__WEBPACK_IMPORTED_MODULE_5__["Plane"]; });

/* harmony import */ var _math_size__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./math.size */ "./Maths/math.size.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Size", function() { return _math_size__WEBPACK_IMPORTED_MODULE_6__["Size"]; });

/* harmony import */ var _math_vector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./math.vector */ "./Maths/math.vector.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector2", function() { return _math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector3", function() { return _math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector4", function() { return _math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quaternion", function() { return _math_vector__WEBPACK_IMPORTED_MODULE_7__["Quaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Matrix", function() { return _math_vector__WEBPACK_IMPORTED_MODULE_7__["Matrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpVectors", function() { return _math_vector__WEBPACK_IMPORTED_MODULE_7__["TmpVectors"]; });

/* harmony import */ var _math_vertexFormat__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./math.vertexFormat */ "./Maths/math.vertexFormat.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalVertex", function() { return _math_vertexFormat__WEBPACK_IMPORTED_MODULE_8__["PositionNormalVertex"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalTextureVertex", function() { return _math_vertexFormat__WEBPACK_IMPORTED_MODULE_8__["PositionNormalTextureVertex"]; });

/* harmony import */ var _math_viewport__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./math.viewport */ "./Maths/math.viewport.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Viewport", function() { return _math_viewport__WEBPACK_IMPORTED_MODULE_9__["Viewport"]; });













/***/ }),

/***/ "./Maths/math.vector.ts":
/*!******************************!*\
  !*** ./Maths/math.vector.ts ***!
  \******************************/
/*! exports provided: Vector2, Vector3, Vector4, Quaternion, Matrix, TmpVectors */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector2", function() { return Vector2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector3", function() { return Vector3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector4", function() { return Vector4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Quaternion", function() { return Quaternion; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix", function() { return Matrix; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TmpVectors", function() { return TmpVectors; });
/* harmony import */ var _math_scalar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _math_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./math.constants */ "./Maths/math.constants.ts");
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");




/**
 * Class representing a vector containing 2 coordinates
 */
var Vector2 = /** @class */ (function () {
    /**
     * Creates a new Vector2 from the given x and y coordinates
     * @param x defines the first coordinate
     * @param y defines the second coordinate
     */
    function Vector2(
    /** defines the first coordinate */
    x,
    /** defines the second coordinate */
    y) {
        if (x === void 0) { x = 0; }
        if (y === void 0) { y = 0; }
        this.x = x;
        this.y = y;
    }
    /**
     * Gets a string with the Vector2 coordinates
     * @returns a string with the Vector2 coordinates
     */
    Vector2.prototype.toString = function () {
        return "{X: " + this.x + " Y:" + this.y + "}";
    };
    /**
     * Gets class name
     * @returns the string "Vector2"
     */
    Vector2.prototype.getClassName = function () {
        return "Vector2";
    };
    /**
     * Gets current vector hash code
     * @returns the Vector2 hash code as a number
     */
    Vector2.prototype.getHashCode = function () {
        var hash = this.x | 0;
        hash = (hash * 397) ^ (this.y | 0);
        return hash;
    };
    // Operators
    /**
     * Sets the Vector2 coordinates in the given array or Float32Array from the given index.
     * @param array defines the source array
     * @param index defines the offset in source array
     * @returns the current Vector2
     */
    Vector2.prototype.toArray = function (array, index) {
        if (index === void 0) { index = 0; }
        array[index] = this.x;
        array[index + 1] = this.y;
        return this;
    };
    /**
     * Copy the current vector to an array
     * @returns a new array with 2 elements: the Vector2 coordinates.
     */
    Vector2.prototype.asArray = function () {
        var result = new Array();
        this.toArray(result, 0);
        return result;
    };
    /**
     * Sets the Vector2 coordinates with the given Vector2 coordinates
     * @param source defines the source Vector2
     * @returns the current updated Vector2
     */
    Vector2.prototype.copyFrom = function (source) {
        this.x = source.x;
        this.y = source.y;
        return this;
    };
    /**
     * Sets the Vector2 coordinates with the given floats
     * @param x defines the first coordinate
     * @param y defines the second coordinate
     * @returns the current updated Vector2
     */
    Vector2.prototype.copyFromFloats = function (x, y) {
        this.x = x;
        this.y = y;
        return this;
    };
    /**
     * Sets the Vector2 coordinates with the given floats
     * @param x defines the first coordinate
     * @param y defines the second coordinate
     * @returns the current updated Vector2
     */
    Vector2.prototype.set = function (x, y) {
        return this.copyFromFloats(x, y);
    };
    /**
     * Add another vector with the current one
     * @param otherVector defines the other vector
     * @returns a new Vector2 set with the addition of the current Vector2 and the given one coordinates
     */
    Vector2.prototype.add = function (otherVector) {
        return new Vector2(this.x + otherVector.x, this.y + otherVector.y);
    };
    /**
     * Sets the "result" coordinates with the addition of the current Vector2 and the given one coordinates
     * @param otherVector defines the other vector
     * @param result defines the target vector
     * @returns the unmodified current Vector2
     */
    Vector2.prototype.addToRef = function (otherVector, result) {
        result.x = this.x + otherVector.x;
        result.y = this.y + otherVector.y;
        return this;
    };
    /**
     * Set the Vector2 coordinates by adding the given Vector2 coordinates
     * @param otherVector defines the other vector
     * @returns the current updated Vector2
     */
    Vector2.prototype.addInPlace = function (otherVector) {
        this.x += otherVector.x;
        this.y += otherVector.y;
        return this;
    };
    /**
     * Gets a new Vector2 by adding the current Vector2 coordinates to the given Vector3 x, y coordinates
     * @param otherVector defines the other vector
     * @returns a new Vector2
     */
    Vector2.prototype.addVector3 = function (otherVector) {
        return new Vector2(this.x + otherVector.x, this.y + otherVector.y);
    };
    /**
     * Gets a new Vector2 set with the subtracted coordinates of the given one from the current Vector2
     * @param otherVector defines the other vector
     * @returns a new Vector2
     */
    Vector2.prototype.subtract = function (otherVector) {
        return new Vector2(this.x - otherVector.x, this.y - otherVector.y);
    };
    /**
     * Sets the "result" coordinates with the subtraction of the given one from the current Vector2 coordinates.
     * @param otherVector defines the other vector
     * @param result defines the target vector
     * @returns the unmodified current Vector2
     */
    Vector2.prototype.subtractToRef = function (otherVector, result) {
        result.x = this.x - otherVector.x;
        result.y = this.y - otherVector.y;
        return this;
    };
    /**
     * Sets the current Vector2 coordinates by subtracting from it the given one coordinates
     * @param otherVector defines the other vector
     * @returns the current updated Vector2
     */
    Vector2.prototype.subtractInPlace = function (otherVector) {
        this.x -= otherVector.x;
        this.y -= otherVector.y;
        return this;
    };
    /**
     * Multiplies in place the current Vector2 coordinates by the given ones
     * @param otherVector defines the other vector
     * @returns the current updated Vector2
     */
    Vector2.prototype.multiplyInPlace = function (otherVector) {
        this.x *= otherVector.x;
        this.y *= otherVector.y;
        return this;
    };
    /**
     * Returns a new Vector2 set with the multiplication of the current Vector2 and the given one coordinates
     * @param otherVector defines the other vector
     * @returns a new Vector2
     */
    Vector2.prototype.multiply = function (otherVector) {
        return new Vector2(this.x * otherVector.x, this.y * otherVector.y);
    };
    /**
     * Sets "result" coordinates with the multiplication of the current Vector2 and the given one coordinates
     * @param otherVector defines the other vector
     * @param result defines the target vector
     * @returns the unmodified current Vector2
     */
    Vector2.prototype.multiplyToRef = function (otherVector, result) {
        result.x = this.x * otherVector.x;
        result.y = this.y * otherVector.y;
        return this;
    };
    /**
     * Gets a new Vector2 set with the Vector2 coordinates multiplied by the given floats
     * @param x defines the first coordinate
     * @param y defines the second coordinate
     * @returns a new Vector2
     */
    Vector2.prototype.multiplyByFloats = function (x, y) {
        return new Vector2(this.x * x, this.y * y);
    };
    /**
     * Returns a new Vector2 set with the Vector2 coordinates divided by the given one coordinates
     * @param otherVector defines the other vector
     * @returns a new Vector2
     */
    Vector2.prototype.divide = function (otherVector) {
        return new Vector2(this.x / otherVector.x, this.y / otherVector.y);
    };
    /**
     * Sets the "result" coordinates with the Vector2 divided by the given one coordinates
     * @param otherVector defines the other vector
     * @param result defines the target vector
     * @returns the unmodified current Vector2
     */
    Vector2.prototype.divideToRef = function (otherVector, result) {
        result.x = this.x / otherVector.x;
        result.y = this.y / otherVector.y;
        return this;
    };
    /**
     * Divides the current Vector2 coordinates by the given ones
     * @param otherVector defines the other vector
     * @returns the current updated Vector2
     */
    Vector2.prototype.divideInPlace = function (otherVector) {
        return this.divideToRef(otherVector, this);
    };
    /**
     * Gets a new Vector2 with current Vector2 negated coordinates
     * @returns a new Vector2
     */
    Vector2.prototype.negate = function () {
        return new Vector2(-this.x, -this.y);
    };
    /**
     * Multiply the Vector2 coordinates by scale
     * @param scale defines the scaling factor
     * @returns the current updated Vector2
     */
    Vector2.prototype.scaleInPlace = function (scale) {
        this.x *= scale;
        this.y *= scale;
        return this;
    };
    /**
     * Returns a new Vector2 scaled by "scale" from the current Vector2
     * @param scale defines the scaling factor
     * @returns a new Vector2
     */
    Vector2.prototype.scale = function (scale) {
        var result = new Vector2(0, 0);
        this.scaleToRef(scale, result);
        return result;
    };
    /**
     * Scale the current Vector2 values by a factor to a given Vector2
     * @param scale defines the scale factor
     * @param result defines the Vector2 object where to store the result
     * @returns the unmodified current Vector2
     */
    Vector2.prototype.scaleToRef = function (scale, result) {
        result.x = this.x * scale;
        result.y = this.y * scale;
        return this;
    };
    /**
     * Scale the current Vector2 values by a factor and add the result to a given Vector2
     * @param scale defines the scale factor
     * @param result defines the Vector2 object where to store the result
     * @returns the unmodified current Vector2
     */
    Vector2.prototype.scaleAndAddToRef = function (scale, result) {
        result.x += this.x * scale;
        result.y += this.y * scale;
        return this;
    };
    /**
     * Gets a boolean if two vectors are equals
     * @param otherVector defines the other vector
     * @returns true if the given vector coordinates strictly equal the current Vector2 ones
     */
    Vector2.prototype.equals = function (otherVector) {
        return otherVector && this.x === otherVector.x && this.y === otherVector.y;
    };
    /**
     * Gets a boolean if two vectors are equals (using an epsilon value)
     * @param otherVector defines the other vector
     * @param epsilon defines the minimal distance to consider equality
     * @returns true if the given vector coordinates are close to the current ones by a distance of epsilon.
     */
    Vector2.prototype.equalsWithEpsilon = function (otherVector, epsilon) {
        if (epsilon === void 0) { epsilon = _math_constants__WEBPACK_IMPORTED_MODULE_1__["Epsilon"]; }
        return otherVector && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.x, otherVector.x, epsilon) && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.y, otherVector.y, epsilon);
    };
    /**
     * Gets a new Vector2 from current Vector2 floored values
     * @returns a new Vector2
     */
    Vector2.prototype.floor = function () {
        return new Vector2(Math.floor(this.x), Math.floor(this.y));
    };
    /**
     * Gets a new Vector2 from current Vector2 floored values
     * @returns a new Vector2
     */
    Vector2.prototype.fract = function () {
        return new Vector2(this.x - Math.floor(this.x), this.y - Math.floor(this.y));
    };
    // Properties
    /**
     * Gets the length of the vector
     * @returns the vector length (float)
     */
    Vector2.prototype.length = function () {
        return Math.sqrt(this.x * this.x + this.y * this.y);
    };
    /**
     * Gets the vector squared length
     * @returns the vector squared length (float)
     */
    Vector2.prototype.lengthSquared = function () {
        return (this.x * this.x + this.y * this.y);
    };
    // Methods
    /**
     * Normalize the vector
     * @returns the current updated Vector2
     */
    Vector2.prototype.normalize = function () {
        var len = this.length();
        if (len === 0) {
            return this;
        }
        var num = 1.0 / len;
        this.x *= num;
        this.y *= num;
        return this;
    };
    /**
     * Gets a new Vector2 copied from the Vector2
     * @returns a new Vector2
     */
    Vector2.prototype.clone = function () {
        return new Vector2(this.x, this.y);
    };
    // Statics
    /**
     * Gets a new Vector2(0, 0)
     * @returns a new Vector2
     */
    Vector2.Zero = function () {
        return new Vector2(0, 0);
    };
    /**
     * Gets a new Vector2(1, 1)
     * @returns a new Vector2
     */
    Vector2.One = function () {
        return new Vector2(1, 1);
    };
    /**
     * Gets a new Vector2 set from the given index element of the given array
     * @param array defines the data source
     * @param offset defines the offset in the data source
     * @returns a new Vector2
     */
    Vector2.FromArray = function (array, offset) {
        if (offset === void 0) { offset = 0; }
        return new Vector2(array[offset], array[offset + 1]);
    };
    /**
     * Sets "result" from the given index element of the given array
     * @param array defines the data source
     * @param offset defines the offset in the data source
     * @param result defines the target vector
     */
    Vector2.FromArrayToRef = function (array, offset, result) {
        result.x = array[offset];
        result.y = array[offset + 1];
    };
    /**
     * Gets a new Vector2 located for "amount" (float) on the CatmullRom spline defined by the given four Vector2
     * @param value1 defines 1st point of control
     * @param value2 defines 2nd point of control
     * @param value3 defines 3rd point of control
     * @param value4 defines 4th point of control
     * @param amount defines the interpolation factor
     * @returns a new Vector2
     */
    Vector2.CatmullRom = function (value1, value2, value3, value4, amount) {
        var squared = amount * amount;
        var cubed = amount * squared;
        var x = 0.5 * ((((2.0 * value2.x) + ((-value1.x + value3.x) * amount)) +
            (((((2.0 * value1.x) - (5.0 * value2.x)) + (4.0 * value3.x)) - value4.x) * squared)) +
            ((((-value1.x + (3.0 * value2.x)) - (3.0 * value3.x)) + value4.x) * cubed));
        var y = 0.5 * ((((2.0 * value2.y) + ((-value1.y + value3.y) * amount)) +
            (((((2.0 * value1.y) - (5.0 * value2.y)) + (4.0 * value3.y)) - value4.y) * squared)) +
            ((((-value1.y + (3.0 * value2.y)) - (3.0 * value3.y)) + value4.y) * cubed));
        return new Vector2(x, y);
    };
    /**
     * Returns a new Vector2 set with same the coordinates than "value" ones if the vector "value" is in the square defined by "min" and "max".
     * If a coordinate of "value" is lower than "min" coordinates, the returned Vector2 is given this "min" coordinate.
     * If a coordinate of "value" is greater than "max" coordinates, the returned Vector2 is given this "max" coordinate
     * @param value defines the value to clamp
     * @param min defines the lower limit
     * @param max defines the upper limit
     * @returns a new Vector2
     */
    Vector2.Clamp = function (value, min, max) {
        var x = value.x;
        x = (x > max.x) ? max.x : x;
        x = (x < min.x) ? min.x : x;
        var y = value.y;
        y = (y > max.y) ? max.y : y;
        y = (y < min.y) ? min.y : y;
        return new Vector2(x, y);
    };
    /**
     * Returns a new Vector2 located for "amount" (float) on the Hermite spline defined by the vectors "value1", "value3", "tangent1", "tangent2"
     * @param value1 defines the 1st control point
     * @param tangent1 defines the outgoing tangent
     * @param value2 defines the 2nd control point
     * @param tangent2 defines the incoming tangent
     * @param amount defines the interpolation factor
     * @returns a new Vector2
     */
    Vector2.Hermite = function (value1, tangent1, value2, tangent2, amount) {
        var squared = amount * amount;
        var cubed = amount * squared;
        var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
        var part2 = (-2.0 * cubed) + (3.0 * squared);
        var part3 = (cubed - (2.0 * squared)) + amount;
        var part4 = cubed - squared;
        var x = (((value1.x * part1) + (value2.x * part2)) + (tangent1.x * part3)) + (tangent2.x * part4);
        var y = (((value1.y * part1) + (value2.y * part2)) + (tangent1.y * part3)) + (tangent2.y * part4);
        return new Vector2(x, y);
    };
    /**
     * Returns a new Vector2 located for "amount" (float) on the linear interpolation between the vector "start" adn the vector "end".
     * @param start defines the start vector
     * @param end defines the end vector
     * @param amount defines the interpolation factor
     * @returns a new Vector2
     */
    Vector2.Lerp = function (start, end, amount) {
        var x = start.x + ((end.x - start.x) * amount);
        var y = start.y + ((end.y - start.y) * amount);
        return new Vector2(x, y);
    };
    /**
     * Gets the dot product of the vector "left" and the vector "right"
     * @param left defines first vector
     * @param right defines second vector
     * @returns the dot product (float)
     */
    Vector2.Dot = function (left, right) {
        return left.x * right.x + left.y * right.y;
    };
    /**
     * Returns a new Vector2 equal to the normalized given vector
     * @param vector defines the vector to normalize
     * @returns a new Vector2
     */
    Vector2.Normalize = function (vector) {
        var newVector = vector.clone();
        newVector.normalize();
        return newVector;
    };
    /**
     * Gets a new Vector2 set with the minimal coordinate values from the "left" and "right" vectors
     * @param left defines 1st vector
     * @param right defines 2nd vector
     * @returns a new Vector2
     */
    Vector2.Minimize = function (left, right) {
        var x = (left.x < right.x) ? left.x : right.x;
        var y = (left.y < right.y) ? left.y : right.y;
        return new Vector2(x, y);
    };
    /**
     * Gets a new Vecto2 set with the maximal coordinate values from the "left" and "right" vectors
     * @param left defines 1st vector
     * @param right defines 2nd vector
     * @returns a new Vector2
     */
    Vector2.Maximize = function (left, right) {
        var x = (left.x > right.x) ? left.x : right.x;
        var y = (left.y > right.y) ? left.y : right.y;
        return new Vector2(x, y);
    };
    /**
     * Gets a new Vector2 set with the transformed coordinates of the given vector by the given transformation matrix
     * @param vector defines the vector to transform
     * @param transformation defines the matrix to apply
     * @returns a new Vector2
     */
    Vector2.Transform = function (vector, transformation) {
        var r = Vector2.Zero();
        Vector2.TransformToRef(vector, transformation, r);
        return r;
    };
    /**
     * Transforms the given vector coordinates by the given transformation matrix and stores the result in the vector "result" coordinates
     * @param vector defines the vector to transform
     * @param transformation defines the matrix to apply
     * @param result defines the target vector
     */
    Vector2.TransformToRef = function (vector, transformation, result) {
        var m = transformation.m;
        var x = (vector.x * m[0]) + (vector.y * m[4]) + m[12];
        var y = (vector.x * m[1]) + (vector.y * m[5]) + m[13];
        result.x = x;
        result.y = y;
    };
    /**
     * Determines if a given vector is included in a triangle
     * @param p defines the vector to test
     * @param p0 defines 1st triangle point
     * @param p1 defines 2nd triangle point
     * @param p2 defines 3rd triangle point
     * @returns true if the point "p" is in the triangle defined by the vertors "p0", "p1", "p2"
     */
    Vector2.PointInTriangle = function (p, p0, p1, p2) {
        var a = 1 / 2 * (-p1.y * p2.x + p0.y * (-p1.x + p2.x) + p0.x * (p1.y - p2.y) + p1.x * p2.y);
        var sign = a < 0 ? -1 : 1;
        var s = (p0.y * p2.x - p0.x * p2.y + (p2.y - p0.y) * p.x + (p0.x - p2.x) * p.y) * sign;
        var t = (p0.x * p1.y - p0.y * p1.x + (p0.y - p1.y) * p.x + (p1.x - p0.x) * p.y) * sign;
        return s > 0 && t > 0 && (s + t) < 2 * a * sign;
    };
    /**
     * Gets the distance between the vectors "value1" and "value2"
     * @param value1 defines first vector
     * @param value2 defines second vector
     * @returns the distance between vectors
     */
    Vector2.Distance = function (value1, value2) {
        return Math.sqrt(Vector2.DistanceSquared(value1, value2));
    };
    /**
     * Returns the squared distance between the vectors "value1" and "value2"
     * @param value1 defines first vector
     * @param value2 defines second vector
     * @returns the squared distance between vectors
     */
    Vector2.DistanceSquared = function (value1, value2) {
        var x = value1.x - value2.x;
        var y = value1.y - value2.y;
        return (x * x) + (y * y);
    };
    /**
     * Gets a new Vector2 located at the center of the vectors "value1" and "value2"
     * @param value1 defines first vector
     * @param value2 defines second vector
     * @returns a new Vector2
     */
    Vector2.Center = function (value1, value2) {
        var center = value1.add(value2);
        center.scaleInPlace(0.5);
        return center;
    };
    /**
     * Gets the shortest distance (float) between the point "p" and the segment defined by the two points "segA" and "segB".
     * @param p defines the middle point
     * @param segA defines one point of the segment
     * @param segB defines the other point of the segment
     * @returns the shortest distance
     */
    Vector2.DistanceOfPointFromSegment = function (p, segA, segB) {
        var l2 = Vector2.DistanceSquared(segA, segB);
        if (l2 === 0.0) {
            return Vector2.Distance(p, segA);
        }
        var v = segB.subtract(segA);
        var t = Math.max(0, Math.min(1, Vector2.Dot(p.subtract(segA), v) / l2));
        var proj = segA.add(v.multiplyByFloats(t, t));
        return Vector2.Distance(p, proj);
    };
    return Vector2;
}());

/**
 * Classed used to store (x,y,z) vector representation
 * A Vector3 is the main object used in 3D geometry
 * It can represent etiher the coordinates of a point the space, either a direction
 * Reminder: js uses a left handed forward facing system
 */
var Vector3 = /** @class */ (function () {
    /**
     * Creates a new Vector3 object from the given x, y, z (floats) coordinates.
     * @param x defines the first coordinates (on X axis)
     * @param y defines the second coordinates (on Y axis)
     * @param z defines the third coordinates (on Z axis)
     */
    function Vector3(
    /**
     * Defines the first coordinates (on X axis)
     */
    x,
    /**
     * Defines the second coordinates (on Y axis)
     */
    y,
    /**
     * Defines the third coordinates (on Z axis)
     */
    z) {
        if (x === void 0) { x = 0; }
        if (y === void 0) { y = 0; }
        if (z === void 0) { z = 0; }
        this.x = x;
        this.y = y;
        this.z = z;
    }
    /**
     * Creates a string representation of the Vector3
     * @returns a string with the Vector3 coordinates.
     */
    Vector3.prototype.toString = function () {
        return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + "}";
    };
    /**
     * Gets the class name
     * @returns the string "Vector3"
     */
    Vector3.prototype.getClassName = function () {
        return "Vector3";
    };
    /**
     * Creates the Vector3 hash code
     * @returns a number which tends to be unique between Vector3 instances
     */
    Vector3.prototype.getHashCode = function () {
        var hash = this.x | 0;
        hash = (hash * 397) ^ (this.y | 0);
        hash = (hash * 397) ^ (this.z | 0);
        return hash;
    };
    // Operators
    /**
     * Creates an array containing three elements : the coordinates of the Vector3
     * @returns a new array of numbers
     */
    Vector3.prototype.asArray = function () {
        var result = [];
        this.toArray(result, 0);
        return result;
    };
    /**
     * Populates the given array or Float32Array from the given index with the successive coordinates of the Vector3
     * @param array defines the destination array
     * @param index defines the offset in the destination array
     * @returns the current Vector3
     */
    Vector3.prototype.toArray = function (array, index) {
        if (index === void 0) { index = 0; }
        array[index] = this.x;
        array[index + 1] = this.y;
        array[index + 2] = this.z;
        return this;
    };
    /**
     * Converts the current Vector3 into a quaternion (considering that the Vector3 contains Euler angles representation of a rotation)
     * @returns a new Quaternion object, computed from the Vector3 coordinates
     */
    Vector3.prototype.toQuaternion = function () {
        return Quaternion.RotationYawPitchRoll(this.y, this.x, this.z);
    };
    /**
     * Adds the given vector to the current Vector3
     * @param otherVector defines the second operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.addInPlace = function (otherVector) {
        return this.addInPlaceFromFloats(otherVector.x, otherVector.y, otherVector.z);
    };
    /**
     * Adds the given coordinates to the current Vector3
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.addInPlaceFromFloats = function (x, y, z) {
        this.x += x;
        this.y += y;
        this.z += z;
        return this;
    };
    /**
     * Gets a new Vector3, result of the addition the current Vector3 and the given vector
     * @param otherVector defines the second operand
     * @returns the resulting Vector3
     */
    Vector3.prototype.add = function (otherVector) {
        return new Vector3(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z);
    };
    /**
     * Adds the current Vector3 to the given one and stores the result in the vector "result"
     * @param otherVector defines the second operand
     * @param result defines the Vector3 object where to store the result
     * @returns the current Vector3
     */
    Vector3.prototype.addToRef = function (otherVector, result) {
        return result.copyFromFloats(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z);
    };
    /**
     * Subtract the given vector from the current Vector3
     * @param otherVector defines the second operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.subtractInPlace = function (otherVector) {
        this.x -= otherVector.x;
        this.y -= otherVector.y;
        this.z -= otherVector.z;
        return this;
    };
    /**
     * Returns a new Vector3, result of the subtraction of the given vector from the current Vector3
     * @param otherVector defines the second operand
     * @returns the resulting Vector3
     */
    Vector3.prototype.subtract = function (otherVector) {
        return new Vector3(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z);
    };
    /**
     * Subtracts the given vector from the current Vector3 and stores the result in the vector "result".
     * @param otherVector defines the second operand
     * @param result defines the Vector3 object where to store the result
     * @returns the current Vector3
     */
    Vector3.prototype.subtractToRef = function (otherVector, result) {
        return this.subtractFromFloatsToRef(otherVector.x, otherVector.y, otherVector.z, result);
    };
    /**
     * Returns a new Vector3 set with the subtraction of the given floats from the current Vector3 coordinates
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the resulting Vector3
     */
    Vector3.prototype.subtractFromFloats = function (x, y, z) {
        return new Vector3(this.x - x, this.y - y, this.z - z);
    };
    /**
     * Subtracts the given floats from the current Vector3 coordinates and set the given vector "result" with this result
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @param result defines the Vector3 object where to store the result
     * @returns the current Vector3
     */
    Vector3.prototype.subtractFromFloatsToRef = function (x, y, z, result) {
        return result.copyFromFloats(this.x - x, this.y - y, this.z - z);
    };
    /**
     * Gets a new Vector3 set with the current Vector3 negated coordinates
     * @returns a new Vector3
     */
    Vector3.prototype.negate = function () {
        return new Vector3(-this.x, -this.y, -this.z);
    };
    /**
     * Multiplies the Vector3 coordinates by the float "scale"
     * @param scale defines the multiplier factor
     * @returns the current updated Vector3
     */
    Vector3.prototype.scaleInPlace = function (scale) {
        this.x *= scale;
        this.y *= scale;
        this.z *= scale;
        return this;
    };
    /**
     * Returns a new Vector3 set with the current Vector3 coordinates multiplied by the float "scale"
     * @param scale defines the multiplier factor
     * @returns a new Vector3
     */
    Vector3.prototype.scale = function (scale) {
        return new Vector3(this.x * scale, this.y * scale, this.z * scale);
    };
    /**
     * Multiplies the current Vector3 coordinates by the float "scale" and stores the result in the given vector "result" coordinates
     * @param scale defines the multiplier factor
     * @param result defines the Vector3 object where to store the result
     * @returns the current Vector3
     */
    Vector3.prototype.scaleToRef = function (scale, result) {
        return result.copyFromFloats(this.x * scale, this.y * scale, this.z * scale);
    };
    /**
     * Scale the current Vector3 values by a factor and add the result to a given Vector3
     * @param scale defines the scale factor
     * @param result defines the Vector3 object where to store the result
     * @returns the unmodified current Vector3
     */
    Vector3.prototype.scaleAndAddToRef = function (scale, result) {
        return result.addInPlaceFromFloats(this.x * scale, this.y * scale, this.z * scale);
    };
    /**
     * Returns true if the current Vector3 and the given vector coordinates are strictly equal
     * @param otherVector defines the second operand
     * @returns true if both vectors are equals
     */
    Vector3.prototype.equals = function (otherVector) {
        return otherVector && this.x === otherVector.x && this.y === otherVector.y && this.z === otherVector.z;
    };
    /**
     * Returns true if the current Vector3 and the given vector coordinates are distant less than epsilon
     * @param otherVector defines the second operand
     * @param epsilon defines the minimal distance to define values as equals
     * @returns true if both vectors are distant less than epsilon
     */
    Vector3.prototype.equalsWithEpsilon = function (otherVector, epsilon) {
        if (epsilon === void 0) { epsilon = _math_constants__WEBPACK_IMPORTED_MODULE_1__["Epsilon"]; }
        return otherVector && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.x, otherVector.x, epsilon) && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.y, otherVector.y, epsilon) && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.z, otherVector.z, epsilon);
    };
    /**
     * Returns true if the current Vector3 coordinates equals the given floats
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns true if both vectors are equals
     */
    Vector3.prototype.equalsToFloats = function (x, y, z) {
        return this.x === x && this.y === y && this.z === z;
    };
    /**
     * Multiplies the current Vector3 coordinates by the given ones
     * @param otherVector defines the second operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.multiplyInPlace = function (otherVector) {
        this.x *= otherVector.x;
        this.y *= otherVector.y;
        this.z *= otherVector.z;
        return this;
    };
    /**
     * Returns a new Vector3, result of the multiplication of the current Vector3 by the given vector
     * @param otherVector defines the second operand
     * @returns the new Vector3
     */
    Vector3.prototype.multiply = function (otherVector) {
        return this.multiplyByFloats(otherVector.x, otherVector.y, otherVector.z);
    };
    /**
     * Multiplies the current Vector3 by the given one and stores the result in the given vector "result"
     * @param otherVector defines the second operand
     * @param result defines the Vector3 object where to store the result
     * @returns the current Vector3
     */
    Vector3.prototype.multiplyToRef = function (otherVector, result) {
        return result.copyFromFloats(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z);
    };
    /**
     * Returns a new Vector3 set with the result of the mulliplication of the current Vector3 coordinates by the given floats
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the new Vector3
     */
    Vector3.prototype.multiplyByFloats = function (x, y, z) {
        return new Vector3(this.x * x, this.y * y, this.z * z);
    };
    /**
     * Returns a new Vector3 set with the result of the division of the current Vector3 coordinates by the given ones
     * @param otherVector defines the second operand
     * @returns the new Vector3
     */
    Vector3.prototype.divide = function (otherVector) {
        return new Vector3(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z);
    };
    /**
     * Divides the current Vector3 coordinates by the given ones and stores the result in the given vector "result"
     * @param otherVector defines the second operand
     * @param result defines the Vector3 object where to store the result
     * @returns the current Vector3
     */
    Vector3.prototype.divideToRef = function (otherVector, result) {
        return result.copyFromFloats(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z);
    };
    /**
     * Divides the current Vector3 coordinates by the given ones.
     * @param otherVector defines the second operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.divideInPlace = function (otherVector) {
        return this.divideToRef(otherVector, this);
    };
    /**
     * Updates the current Vector3 with the minimal coordinate values between its and the given vector ones
     * @param other defines the second operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.minimizeInPlace = function (other) {
        return this.minimizeInPlaceFromFloats(other.x, other.y, other.z);
    };
    /**
     * Updates the current Vector3 with the maximal coordinate values between its and the given vector ones.
     * @param other defines the second operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.maximizeInPlace = function (other) {
        return this.maximizeInPlaceFromFloats(other.x, other.y, other.z);
    };
    /**
     * Updates the current Vector3 with the minimal coordinate values between its and the given coordinates
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.minimizeInPlaceFromFloats = function (x, y, z) {
        if (x < this.x) {
            this.x = x;
        }
        if (y < this.y) {
            this.y = y;
        }
        if (z < this.z) {
            this.z = z;
        }
        return this;
    };
    /**
     * Updates the current Vector3 with the maximal coordinate values between its and the given coordinates.
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.maximizeInPlaceFromFloats = function (x, y, z) {
        if (x > this.x) {
            this.x = x;
        }
        if (y > this.y) {
            this.y = y;
        }
        if (z > this.z) {
            this.z = z;
        }
        return this;
    };
    /**
     * Due to float precision, scale of a mesh could be uniform but float values are off by a small fraction
     * Check if is non uniform within a certain amount of decimal places to account for this
     * @param epsilon the amount the values can differ
     * @returns if the the vector is non uniform to a certain number of decimal places
     */
    Vector3.prototype.isNonUniformWithinEpsilon = function (epsilon) {
        var absX = Math.abs(this.x);
        var absY = Math.abs(this.y);
        if (!_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(absX, absY, epsilon)) {
            return true;
        }
        var absZ = Math.abs(this.z);
        if (!_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(absX, absZ, epsilon)) {
            return true;
        }
        if (!_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(absY, absZ, epsilon)) {
            return true;
        }
        return false;
    };
    Object.defineProperty(Vector3.prototype, "isNonUniform", {
        /**
         * Gets a boolean indicating that the vector is non uniform meaning x, y or z are not all the same
         */
        get: function () {
            var absX = Math.abs(this.x);
            var absY = Math.abs(this.y);
            if (absX !== absY) {
                return true;
            }
            var absZ = Math.abs(this.z);
            if (absX !== absZ) {
                return true;
            }
            if (absY !== absZ) {
                return true;
            }
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets a new Vector3 from current Vector3 floored values
     * @returns a new Vector3
     */
    Vector3.prototype.floor = function () {
        return new Vector3(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z));
    };
    /**
     * Gets a new Vector3 from current Vector3 floored values
     * @returns a new Vector3
     */
    Vector3.prototype.fract = function () {
        return new Vector3(this.x - Math.floor(this.x), this.y - Math.floor(this.y), this.z - Math.floor(this.z));
    };
    // Properties
    /**
     * Gets the length of the Vector3
     * @returns the length of the Vector3
     */
    Vector3.prototype.length = function () {
        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
    };
    /**
     * Gets the squared length of the Vector3
     * @returns squared length of the Vector3
     */
    Vector3.prototype.lengthSquared = function () {
        return (this.x * this.x + this.y * this.y + this.z * this.z);
    };
    /**
     * Normalize the current Vector3.
     * Please note that this is an in place operation.
     * @returns the current updated Vector3
     */
    Vector3.prototype.normalize = function () {
        return this.normalizeFromLength(this.length());
    };
    /**
     * Reorders the x y z properties of the vector in place
     * @param order new ordering of the properties (eg. for vector 1,2,3 with "ZYX" will produce 3,2,1)
     * @returns the current updated vector
     */
    Vector3.prototype.reorderInPlace = function (order) {
        var _this = this;
        order = order.toLowerCase();
        if (order === "xyz") {
            return this;
        }
        MathTmp.Vector3[0].copyFrom(this);
        ["x", "y", "z"].forEach(function (val, i) {
            _this[val] = MathTmp.Vector3[0][order[i]];
        });
        return this;
    };
    /**
     * Rotates the vector around 0,0,0 by a quaternion
     * @param quaternion the rotation quaternion
     * @param result vector to store the result
     * @returns the resulting vector
     */
    Vector3.prototype.rotateByQuaternionToRef = function (quaternion, result) {
        quaternion.toRotationMatrix(MathTmp.Matrix[0]);
        Vector3.TransformCoordinatesToRef(this, MathTmp.Matrix[0], result);
        return result;
    };
    /**
     * Rotates a vector around a given point
     * @param quaternion the rotation quaternion
     * @param point the point to rotate around
     * @param result vector to store the result
     * @returns the resulting vector
     */
    Vector3.prototype.rotateByQuaternionAroundPointToRef = function (quaternion, point, result) {
        this.subtractToRef(point, MathTmp.Vector3[0]);
        MathTmp.Vector3[0].rotateByQuaternionToRef(quaternion, MathTmp.Vector3[0]);
        point.addToRef(MathTmp.Vector3[0], result);
        return result;
    };
    /**
     * Normalize the current Vector3 with the given input length.
     * Please note that this is an in place operation.
     * @param len the length of the vector
     * @returns the current updated Vector3
     */
    Vector3.prototype.normalizeFromLength = function (len) {
        if (len === 0 || len === 1.0) {
            return this;
        }
        return this.scaleInPlace(1.0 / len);
    };
    /**
     * Normalize the current Vector3 to a new vector
     * @returns the new Vector3
     */
    Vector3.prototype.normalizeToNew = function () {
        var normalized = new Vector3(0, 0, 0);
        this.normalizeToRef(normalized);
        return normalized;
    };
    /**
     * Normalize the current Vector3 to the reference
     * @param reference define the Vector3 to update
     * @returns the updated Vector3
     */
    Vector3.prototype.normalizeToRef = function (reference) {
        var len = this.length();
        if (len === 0 || len === 1.0) {
            return reference.copyFromFloats(this.x, this.y, this.z);
        }
        return this.scaleToRef(1.0 / len, reference);
    };
    /**
     * Creates a new Vector3 copied from the current Vector3
     * @returns the new Vector3
     */
    Vector3.prototype.clone = function () {
        return new Vector3(this.x, this.y, this.z);
    };
    /**
     * Copies the given vector coordinates to the current Vector3 ones
     * @param source defines the source Vector3
     * @returns the current updated Vector3
     */
    Vector3.prototype.copyFrom = function (source) {
        return this.copyFromFloats(source.x, source.y, source.z);
    };
    /**
     * Copies the given floats to the current Vector3 coordinates
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.copyFromFloats = function (x, y, z) {
        this.x = x;
        this.y = y;
        this.z = z;
        return this;
    };
    /**
     * Copies the given floats to the current Vector3 coordinates
     * @param x defines the x coordinate of the operand
     * @param y defines the y coordinate of the operand
     * @param z defines the z coordinate of the operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.set = function (x, y, z) {
        return this.copyFromFloats(x, y, z);
    };
    /**
     * Copies the given float to the current Vector3 coordinates
     * @param v defines the x, y and z coordinates of the operand
     * @returns the current updated Vector3
     */
    Vector3.prototype.setAll = function (v) {
        this.x = this.y = this.z = v;
        return this;
    };
    // Statics
    /**
     * Get the clip factor between two vectors
     * @param vector0 defines the first operand
     * @param vector1 defines the second operand
     * @param axis defines the axis to use
     * @param size defines the size along the axis
     * @returns the clip factor
     */
    Vector3.GetClipFactor = function (vector0, vector1, axis, size) {
        var d0 = Vector3.Dot(vector0, axis) - size;
        var d1 = Vector3.Dot(vector1, axis) - size;
        var s = d0 / (d0 - d1);
        return s;
    };
    /**
     * Get angle between two vectors
     * @param vector0 angle between vector0 and vector1
     * @param vector1 angle between vector0 and vector1
     * @param normal direction of the normal
     * @return the angle between vector0 and vector1
     */
    Vector3.GetAngleBetweenVectors = function (vector0, vector1, normal) {
        var v0 = vector0.normalizeToRef(MathTmp.Vector3[1]);
        var v1 = vector1.normalizeToRef(MathTmp.Vector3[2]);
        var dot = Vector3.Dot(v0, v1);
        var n = MathTmp.Vector3[3];
        Vector3.CrossToRef(v0, v1, n);
        if (Vector3.Dot(n, normal) > 0) {
            return Math.acos(dot);
        }
        return -Math.acos(dot);
    };
    /**
     * Returns a new Vector3 set from the index "offset" of the given array
     * @param array defines the source array
     * @param offset defines the offset in the source array
     * @returns the new Vector3
     */
    Vector3.FromArray = function (array, offset) {
        if (offset === void 0) { offset = 0; }
        return new Vector3(array[offset], array[offset + 1], array[offset + 2]);
    };
    /**
     * Returns a new Vector3 set from the index "offset" of the given Float32Array
     * This function is deprecated. Use FromArray instead
     * @param array defines the source array
     * @param offset defines the offset in the source array
     * @returns the new Vector3
     */
    Vector3.FromFloatArray = function (array, offset) {
        return Vector3.FromArray(array, offset);
    };
    /**
     * Sets the given vector "result" with the element values from the index "offset" of the given array
     * @param array defines the source array
     * @param offset defines the offset in the source array
     * @param result defines the Vector3 where to store the result
     */
    Vector3.FromArrayToRef = function (array, offset, result) {
        result.x = array[offset];
        result.y = array[offset + 1];
        result.z = array[offset + 2];
    };
    /**
     * Sets the given vector "result" with the element values from the index "offset" of the given Float32Array
     * This function is deprecated.  Use FromArrayToRef instead.
     * @param array defines the source array
     * @param offset defines the offset in the source array
     * @param result defines the Vector3 where to store the result
     */
    Vector3.FromFloatArrayToRef = function (array, offset, result) {
        return Vector3.FromArrayToRef(array, offset, result);
    };
    /**
     * Sets the given vector "result" with the given floats.
     * @param x defines the x coordinate of the source
     * @param y defines the y coordinate of the source
     * @param z defines the z coordinate of the source
     * @param result defines the Vector3 where to store the result
     */
    Vector3.FromFloatsToRef = function (x, y, z, result) {
        result.copyFromFloats(x, y, z);
    };
    /**
     * Returns a new Vector3 set to (0.0, 0.0, 0.0)
     * @returns a new empty Vector3
     */
    Vector3.Zero = function () {
        return new Vector3(0.0, 0.0, 0.0);
    };
    /**
     * Returns a new Vector3 set to (1.0, 1.0, 1.0)
     * @returns a new unit Vector3
     */
    Vector3.One = function () {
        return new Vector3(1.0, 1.0, 1.0);
    };
    /**
     * Returns a new Vector3 set to (0.0, 1.0, 0.0)
     * @returns a new up Vector3
     */
    Vector3.Up = function () {
        return new Vector3(0.0, 1.0, 0.0);
    };
    Object.defineProperty(Vector3, "UpReadOnly", {
        /**
         * Gets a up Vector3 that must not be updated
         */
        get: function () {
            return Vector3._UpReadOnly;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Vector3, "ZeroReadOnly", {
        /**
         * Gets a zero Vector3 that must not be updated
         */
        get: function () {
            return Vector3._ZeroReadOnly;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns a new Vector3 set to (0.0, -1.0, 0.0)
     * @returns a new down Vector3
     */
    Vector3.Down = function () {
        return new Vector3(0.0, -1.0, 0.0);
    };
    /**
     * Returns a new Vector3 set to (0.0, 0.0, 1.0)
     * @returns a new forward Vector3
     */
    Vector3.Forward = function () {
        return new Vector3(0.0, 0.0, 1.0);
    };
    /**
     * Returns a new Vector3 set to (0.0, 0.0, -1.0)
     * @returns a new forward Vector3
     */
    Vector3.Backward = function () {
        return new Vector3(0.0, 0.0, -1.0);
    };
    /**
     * Returns a new Vector3 set to (1.0, 0.0, 0.0)
     * @returns a new right Vector3
     */
    Vector3.Right = function () {
        return new Vector3(1.0, 0.0, 0.0);
    };
    /**
     * Returns a new Vector3 set to (-1.0, 0.0, 0.0)
     * @returns a new left Vector3
     */
    Vector3.Left = function () {
        return new Vector3(-1.0, 0.0, 0.0);
    };
    /**
     * Returns a new Vector3 set with the result of the transformation by the given matrix of the given vector.
     * This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)
     * @param vector defines the Vector3 to transform
     * @param transformation defines the transformation matrix
     * @returns the transformed Vector3
     */
    Vector3.TransformCoordinates = function (vector, transformation) {
        var result = Vector3.Zero();
        Vector3.TransformCoordinatesToRef(vector, transformation, result);
        return result;
    };
    /**
     * Sets the given vector "result" coordinates with the result of the transformation by the given matrix of the given vector
     * This method computes tranformed coordinates only, not transformed direction vectors (ie. it takes translation in account)
     * @param vector defines the Vector3 to transform
     * @param transformation defines the transformation matrix
     * @param result defines the Vector3 where to store the result
     */
    Vector3.TransformCoordinatesToRef = function (vector, transformation, result) {
        Vector3.TransformCoordinatesFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
    };
    /**
     * Sets the given vector "result" coordinates with the result of the transformation by the given matrix of the given floats (x, y, z)
     * This method computes tranformed coordinates only, not transformed direction vectors
     * @param x define the x coordinate of the source vector
     * @param y define the y coordinate of the source vector
     * @param z define the z coordinate of the source vector
     * @param transformation defines the transformation matrix
     * @param result defines the Vector3 where to store the result
     */
    Vector3.TransformCoordinatesFromFloatsToRef = function (x, y, z, transformation, result) {
        var m = transformation.m;
        var rx = x * m[0] + y * m[4] + z * m[8] + m[12];
        var ry = x * m[1] + y * m[5] + z * m[9] + m[13];
        var rz = x * m[2] + y * m[6] + z * m[10] + m[14];
        var rw = 1 / (x * m[3] + y * m[7] + z * m[11] + m[15]);
        result.x = rx * rw;
        result.y = ry * rw;
        result.z = rz * rw;
    };
    /**
     * Returns a new Vector3 set with the result of the normal transformation by the given matrix of the given vector
     * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)
     * @param vector defines the Vector3 to transform
     * @param transformation defines the transformation matrix
     * @returns the new Vector3
     */
    Vector3.TransformNormal = function (vector, transformation) {
        var result = Vector3.Zero();
        Vector3.TransformNormalToRef(vector, transformation, result);
        return result;
    };
    /**
     * Sets the given vector "result" with the result of the normal transformation by the given matrix of the given vector
     * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)
     * @param vector defines the Vector3 to transform
     * @param transformation defines the transformation matrix
     * @param result defines the Vector3 where to store the result
     */
    Vector3.TransformNormalToRef = function (vector, transformation, result) {
        this.TransformNormalFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
    };
    /**
     * Sets the given vector "result" with the result of the normal transformation by the given matrix of the given floats (x, y, z)
     * This methods computes transformed normalized direction vectors only (ie. it does not apply translation)
     * @param x define the x coordinate of the source vector
     * @param y define the y coordinate of the source vector
     * @param z define the z coordinate of the source vector
     * @param transformation defines the transformation matrix
     * @param result defines the Vector3 where to store the result
     */
    Vector3.TransformNormalFromFloatsToRef = function (x, y, z, transformation, result) {
        var m = transformation.m;
        result.x = x * m[0] + y * m[4] + z * m[8];
        result.y = x * m[1] + y * m[5] + z * m[9];
        result.z = x * m[2] + y * m[6] + z * m[10];
    };
    /**
     * Returns a new Vector3 located for "amount" on the CatmullRom interpolation spline defined by the vectors "value1", "value2", "value3", "value4"
     * @param value1 defines the first control point
     * @param value2 defines the second control point
     * @param value3 defines the third control point
     * @param value4 defines the fourth control point
     * @param amount defines the amount on the spline to use
     * @returns the new Vector3
     */
    Vector3.CatmullRom = function (value1, value2, value3, value4, amount) {
        var squared = amount * amount;
        var cubed = amount * squared;
        var x = 0.5 * ((((2.0 * value2.x) + ((-value1.x + value3.x) * amount)) +
            (((((2.0 * value1.x) - (5.0 * value2.x)) + (4.0 * value3.x)) - value4.x) * squared)) +
            ((((-value1.x + (3.0 * value2.x)) - (3.0 * value3.x)) + value4.x) * cubed));
        var y = 0.5 * ((((2.0 * value2.y) + ((-value1.y + value3.y) * amount)) +
            (((((2.0 * value1.y) - (5.0 * value2.y)) + (4.0 * value3.y)) - value4.y) * squared)) +
            ((((-value1.y + (3.0 * value2.y)) - (3.0 * value3.y)) + value4.y) * cubed));
        var z = 0.5 * ((((2.0 * value2.z) + ((-value1.z + value3.z) * amount)) +
            (((((2.0 * value1.z) - (5.0 * value2.z)) + (4.0 * value3.z)) - value4.z) * squared)) +
            ((((-value1.z + (3.0 * value2.z)) - (3.0 * value3.z)) + value4.z) * cubed));
        return new Vector3(x, y, z);
    };
    /**
     * Returns a new Vector3 set with the coordinates of "value", if the vector "value" is in the cube defined by the vectors "min" and "max"
     * If a coordinate value of "value" is lower than one of the "min" coordinate, then this "value" coordinate is set with the "min" one
     * If a coordinate value of "value" is greater than one of the "max" coordinate, then this "value" coordinate is set with the "max" one
     * @param value defines the current value
     * @param min defines the lower range value
     * @param max defines the upper range value
     * @returns the new Vector3
     */
    Vector3.Clamp = function (value, min, max) {
        var v = new Vector3();
        Vector3.ClampToRef(value, min, max, v);
        return v;
    };
    /**
     * Sets the given vector "result" with the coordinates of "value", if the vector "value" is in the cube defined by the vectors "min" and "max"
     * If a coordinate value of "value" is lower than one of the "min" coordinate, then this "value" coordinate is set with the "min" one
     * If a coordinate value of "value" is greater than one of the "max" coordinate, then this "value" coordinate is set with the "max" one
     * @param value defines the current value
     * @param min defines the lower range value
     * @param max defines the upper range value
     * @param result defines the Vector3 where to store the result
     */
    Vector3.ClampToRef = function (value, min, max, result) {
        var x = value.x;
        x = (x > max.x) ? max.x : x;
        x = (x < min.x) ? min.x : x;
        var y = value.y;
        y = (y > max.y) ? max.y : y;
        y = (y < min.y) ? min.y : y;
        var z = value.z;
        z = (z > max.z) ? max.z : z;
        z = (z < min.z) ? min.z : z;
        result.copyFromFloats(x, y, z);
    };
    /**
     * Checks if a given vector is inside a specific range
     * @param v defines the vector to test
     * @param min defines the minimum range
     * @param max defines the maximum range
     */
    Vector3.CheckExtends = function (v, min, max) {
        min.minimizeInPlace(v);
        max.maximizeInPlace(v);
    };
    /**
     * Returns a new Vector3 located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2"
     * @param value1 defines the first control point
     * @param tangent1 defines the first tangent vector
     * @param value2 defines the second control point
     * @param tangent2 defines the second tangent vector
     * @param amount defines the amount on the interpolation spline (between 0 and 1)
     * @returns the new Vector3
     */
    Vector3.Hermite = function (value1, tangent1, value2, tangent2, amount) {
        var squared = amount * amount;
        var cubed = amount * squared;
        var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
        var part2 = (-2.0 * cubed) + (3.0 * squared);
        var part3 = (cubed - (2.0 * squared)) + amount;
        var part4 = cubed - squared;
        var x = (((value1.x * part1) + (value2.x * part2)) + (tangent1.x * part3)) + (tangent2.x * part4);
        var y = (((value1.y * part1) + (value2.y * part2)) + (tangent1.y * part3)) + (tangent2.y * part4);
        var z = (((value1.z * part1) + (value2.z * part2)) + (tangent1.z * part3)) + (tangent2.z * part4);
        return new Vector3(x, y, z);
    };
    /**
     * Returns a new Vector3 located for "amount" (float) on the linear interpolation between the vectors "start" and "end"
     * @param start defines the start value
     * @param end defines the end value
     * @param amount max defines amount between both (between 0 and 1)
     * @returns the new Vector3
     */
    Vector3.Lerp = function (start, end, amount) {
        var result = new Vector3(0, 0, 0);
        Vector3.LerpToRef(start, end, amount, result);
        return result;
    };
    /**
     * Sets the given vector "result" with the result of the linear interpolation from the vector "start" for "amount" to the vector "end"
     * @param start defines the start value
     * @param end defines the end value
     * @param amount max defines amount between both (between 0 and 1)
     * @param result defines the Vector3 where to store the result
     */
    Vector3.LerpToRef = function (start, end, amount, result) {
        result.x = start.x + ((end.x - start.x) * amount);
        result.y = start.y + ((end.y - start.y) * amount);
        result.z = start.z + ((end.z - start.z) * amount);
    };
    /**
     * Returns the dot product (float) between the vectors "left" and "right"
     * @param left defines the left operand
     * @param right defines the right operand
     * @returns the dot product
     */
    Vector3.Dot = function (left, right) {
        return (left.x * right.x + left.y * right.y + left.z * right.z);
    };
    /**
     * Returns a new Vector3 as the cross product of the vectors "left" and "right"
     * The cross product is then orthogonal to both "left" and "right"
     * @param left defines the left operand
     * @param right defines the right operand
     * @returns the cross product
     */
    Vector3.Cross = function (left, right) {
        var result = Vector3.Zero();
        Vector3.CrossToRef(left, right, result);
        return result;
    };
    /**
     * Sets the given vector "result" with the cross product of "left" and "right"
     * The cross product is then orthogonal to both "left" and "right"
     * @param left defines the left operand
     * @param right defines the right operand
     * @param result defines the Vector3 where to store the result
     */
    Vector3.CrossToRef = function (left, right, result) {
        var x = left.y * right.z - left.z * right.y;
        var y = left.z * right.x - left.x * right.z;
        var z = left.x * right.y - left.y * right.x;
        result.copyFromFloats(x, y, z);
    };
    /**
     * Returns a new Vector3 as the normalization of the given vector
     * @param vector defines the Vector3 to normalize
     * @returns the new Vector3
     */
    Vector3.Normalize = function (vector) {
        var result = Vector3.Zero();
        Vector3.NormalizeToRef(vector, result);
        return result;
    };
    /**
     * Sets the given vector "result" with the normalization of the given first vector
     * @param vector defines the Vector3 to normalize
     * @param result defines the Vector3 where to store the result
     */
    Vector3.NormalizeToRef = function (vector, result) {
        vector.normalizeToRef(result);
    };
    /**
     * Project a Vector3 onto screen space
     * @param vector defines the Vector3 to project
     * @param world defines the world matrix to use
     * @param transform defines the transform (view x projection) matrix to use
     * @param viewport defines the screen viewport to use
     * @returns the new Vector3
     */
    Vector3.Project = function (vector, world, transform, viewport) {
        var cw = viewport.width;
        var ch = viewport.height;
        var cx = viewport.x;
        var cy = viewport.y;
        var viewportMatrix = MathTmp.Matrix[1];
        Matrix.FromValuesToRef(cw / 2.0, 0, 0, 0, 0, -ch / 2.0, 0, 0, 0, 0, 0.5, 0, cx + cw / 2.0, ch / 2.0 + cy, 0.5, 1, viewportMatrix);
        var matrix = MathTmp.Matrix[0];
        world.multiplyToRef(transform, matrix);
        matrix.multiplyToRef(viewportMatrix, matrix);
        return Vector3.TransformCoordinates(vector, matrix);
    };
    /** @hidden */
    Vector3._UnprojectFromInvertedMatrixToRef = function (source, matrix, result) {
        Vector3.TransformCoordinatesToRef(source, matrix, result);
        var m = matrix.m;
        var num = source.x * m[3] + source.y * m[7] + source.z * m[11] + m[15];
        if (_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(num, 1.0)) {
            result.scaleInPlace(1.0 / num);
        }
    };
    /**
     * Unproject from screen space to object space
     * @param source defines the screen space Vector3 to use
     * @param viewportWidth defines the current width of the viewport
     * @param viewportHeight defines the current height of the viewport
     * @param world defines the world matrix to use (can be set to Identity to go to world space)
     * @param transform defines the transform (view x projection) matrix to use
     * @returns the new Vector3
     */
    Vector3.UnprojectFromTransform = function (source, viewportWidth, viewportHeight, world, transform) {
        var matrix = MathTmp.Matrix[0];
        world.multiplyToRef(transform, matrix);
        matrix.invert();
        source.x = source.x / viewportWidth * 2 - 1;
        source.y = -(source.y / viewportHeight * 2 - 1);
        var vector = new Vector3();
        Vector3._UnprojectFromInvertedMatrixToRef(source, matrix, vector);
        return vector;
    };
    /**
     * Unproject from screen space to object space
     * @param source defines the screen space Vector3 to use
     * @param viewportWidth defines the current width of the viewport
     * @param viewportHeight defines the current height of the viewport
     * @param world defines the world matrix to use (can be set to Identity to go to world space)
     * @param view defines the view matrix to use
     * @param projection defines the projection matrix to use
     * @returns the new Vector3
     */
    Vector3.Unproject = function (source, viewportWidth, viewportHeight, world, view, projection) {
        var result = Vector3.Zero();
        Vector3.UnprojectToRef(source, viewportWidth, viewportHeight, world, view, projection, result);
        return result;
    };
    /**
     * Unproject from screen space to object space
     * @param source defines the screen space Vector3 to use
     * @param viewportWidth defines the current width of the viewport
     * @param viewportHeight defines the current height of the viewport
     * @param world defines the world matrix to use (can be set to Identity to go to world space)
     * @param view defines the view matrix to use
     * @param projection defines the projection matrix to use
     * @param result defines the Vector3 where to store the result
     */
    Vector3.UnprojectToRef = function (source, viewportWidth, viewportHeight, world, view, projection, result) {
        Vector3.UnprojectFloatsToRef(source.x, source.y, source.z, viewportWidth, viewportHeight, world, view, projection, result);
    };
    /**
     * Unproject from screen space to object space
     * @param sourceX defines the screen space x coordinate to use
     * @param sourceY defines the screen space y coordinate to use
     * @param sourceZ defines the screen space z coordinate to use
     * @param viewportWidth defines the current width of the viewport
     * @param viewportHeight defines the current height of the viewport
     * @param world defines the world matrix to use (can be set to Identity to go to world space)
     * @param view defines the view matrix to use
     * @param projection defines the projection matrix to use
     * @param result defines the Vector3 where to store the result
     */
    Vector3.UnprojectFloatsToRef = function (sourceX, sourceY, sourceZ, viewportWidth, viewportHeight, world, view, projection, result) {
        var matrix = MathTmp.Matrix[0];
        world.multiplyToRef(view, matrix);
        matrix.multiplyToRef(projection, matrix);
        matrix.invert();
        var screenSource = MathTmp.Vector3[0];
        screenSource.x = sourceX / viewportWidth * 2 - 1;
        screenSource.y = -(sourceY / viewportHeight * 2 - 1);
        screenSource.z = 2 * sourceZ - 1.0;
        Vector3._UnprojectFromInvertedMatrixToRef(screenSource, matrix, result);
    };
    /**
     * Gets the minimal coordinate values between two Vector3
     * @param left defines the first operand
     * @param right defines the second operand
     * @returns the new Vector3
     */
    Vector3.Minimize = function (left, right) {
        var min = left.clone();
        min.minimizeInPlace(right);
        return min;
    };
    /**
     * Gets the maximal coordinate values between two Vector3
     * @param left defines the first operand
     * @param right defines the second operand
     * @returns the new Vector3
     */
    Vector3.Maximize = function (left, right) {
        var max = left.clone();
        max.maximizeInPlace(right);
        return max;
    };
    /**
     * Returns the distance between the vectors "value1" and "value2"
     * @param value1 defines the first operand
     * @param value2 defines the second operand
     * @returns the distance
     */
    Vector3.Distance = function (value1, value2) {
        return Math.sqrt(Vector3.DistanceSquared(value1, value2));
    };
    /**
     * Returns the squared distance between the vectors "value1" and "value2"
     * @param value1 defines the first operand
     * @param value2 defines the second operand
     * @returns the squared distance
     */
    Vector3.DistanceSquared = function (value1, value2) {
        var x = value1.x - value2.x;
        var y = value1.y - value2.y;
        var z = value1.z - value2.z;
        return (x * x) + (y * y) + (z * z);
    };
    /**
     * Returns a new Vector3 located at the center between "value1" and "value2"
     * @param value1 defines the first operand
     * @param value2 defines the second operand
     * @returns the new Vector3
     */
    Vector3.Center = function (value1, value2) {
        var center = value1.add(value2);
        center.scaleInPlace(0.5);
        return center;
    };
    /**
     * Given three orthogonal normalized left-handed oriented Vector3 axis in space (target system),
     * RotationFromAxis() returns the rotation Euler angles (ex : rotation.x, rotation.y, rotation.z) to apply
     * to something in order to rotate it from its local system to the given target system
     * Note: axis1, axis2 and axis3 are normalized during this operation
     * @param axis1 defines the first axis
     * @param axis2 defines the second axis
     * @param axis3 defines the third axis
     * @returns a new Vector3
     */
    Vector3.RotationFromAxis = function (axis1, axis2, axis3) {
        var rotation = Vector3.Zero();
        Vector3.RotationFromAxisToRef(axis1, axis2, axis3, rotation);
        return rotation;
    };
    /**
     * The same than RotationFromAxis but updates the given ref Vector3 parameter instead of returning a new Vector3
     * @param axis1 defines the first axis
     * @param axis2 defines the second axis
     * @param axis3 defines the third axis
     * @param ref defines the Vector3 where to store the result
     */
    Vector3.RotationFromAxisToRef = function (axis1, axis2, axis3, ref) {
        var quat = MathTmp.Quaternion[0];
        Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);
        quat.toEulerAnglesToRef(ref);
    };
    Vector3._UpReadOnly = Vector3.Up();
    Vector3._ZeroReadOnly = Vector3.Zero();
    return Vector3;
}());

/**
 * Vector4 class created for EulerAngle class conversion to Quaternion
 */
var Vector4 = /** @class */ (function () {
    /**
     * Creates a Vector4 object from the given floats.
     * @param x x value of the vector
     * @param y y value of the vector
     * @param z z value of the vector
     * @param w w value of the vector
     */
    function Vector4(
    /** x value of the vector */
    x,
    /** y value of the vector */
    y,
    /** z value of the vector */
    z,
    /** w value of the vector */
    w) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
    }
    /**
     * Returns the string with the Vector4 coordinates.
     * @returns a string containing all the vector values
     */
    Vector4.prototype.toString = function () {
        return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + " W:" + this.w + "}";
    };
    /**
     * Returns the string "Vector4".
     * @returns "Vector4"
     */
    Vector4.prototype.getClassName = function () {
        return "Vector4";
    };
    /**
     * Returns the Vector4 hash code.
     * @returns a unique hash code
     */
    Vector4.prototype.getHashCode = function () {
        var hash = this.x | 0;
        hash = (hash * 397) ^ (this.y | 0);
        hash = (hash * 397) ^ (this.z | 0);
        hash = (hash * 397) ^ (this.w | 0);
        return hash;
    };
    // Operators
    /**
     * Returns a new array populated with 4 elements : the Vector4 coordinates.
     * @returns the resulting array
     */
    Vector4.prototype.asArray = function () {
        var result = new Array();
        this.toArray(result, 0);
        return result;
    };
    /**
     * Populates the given array from the given index with the Vector4 coordinates.
     * @param array array to populate
     * @param index index of the array to start at (default: 0)
     * @returns the Vector4.
     */
    Vector4.prototype.toArray = function (array, index) {
        if (index === undefined) {
            index = 0;
        }
        array[index] = this.x;
        array[index + 1] = this.y;
        array[index + 2] = this.z;
        array[index + 3] = this.w;
        return this;
    };
    /**
     * Adds the given vector to the current Vector4.
     * @param otherVector the vector to add
     * @returns the updated Vector4.
     */
    Vector4.prototype.addInPlace = function (otherVector) {
        this.x += otherVector.x;
        this.y += otherVector.y;
        this.z += otherVector.z;
        this.w += otherVector.w;
        return this;
    };
    /**
     * Returns a new Vector4 as the result of the addition of the current Vector4 and the given one.
     * @param otherVector the vector to add
     * @returns the resulting vector
     */
    Vector4.prototype.add = function (otherVector) {
        return new Vector4(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z, this.w + otherVector.w);
    };
    /**
     * Updates the given vector "result" with the result of the addition of the current Vector4 and the given one.
     * @param otherVector the vector to add
     * @param result the vector to store the result
     * @returns the current Vector4.
     */
    Vector4.prototype.addToRef = function (otherVector, result) {
        result.x = this.x + otherVector.x;
        result.y = this.y + otherVector.y;
        result.z = this.z + otherVector.z;
        result.w = this.w + otherVector.w;
        return this;
    };
    /**
     * Subtract in place the given vector from the current Vector4.
     * @param otherVector the vector to subtract
     * @returns the updated Vector4.
     */
    Vector4.prototype.subtractInPlace = function (otherVector) {
        this.x -= otherVector.x;
        this.y -= otherVector.y;
        this.z -= otherVector.z;
        this.w -= otherVector.w;
        return this;
    };
    /**
     * Returns a new Vector4 with the result of the subtraction of the given vector from the current Vector4.
     * @param otherVector the vector to add
     * @returns the new vector with the result
     */
    Vector4.prototype.subtract = function (otherVector) {
        return new Vector4(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z, this.w - otherVector.w);
    };
    /**
     * Sets the given vector "result" with the result of the subtraction of the given vector from the current Vector4.
     * @param otherVector the vector to subtract
     * @param result the vector to store the result
     * @returns the current Vector4.
     */
    Vector4.prototype.subtractToRef = function (otherVector, result) {
        result.x = this.x - otherVector.x;
        result.y = this.y - otherVector.y;
        result.z = this.z - otherVector.z;
        result.w = this.w - otherVector.w;
        return this;
    };
    /**
     * Returns a new Vector4 set with the result of the subtraction of the given floats from the current Vector4 coordinates.
     */
    /**
     * Returns a new Vector4 set with the result of the subtraction of the given floats from the current Vector4 coordinates.
     * @param x value to subtract
     * @param y value to subtract
     * @param z value to subtract
     * @param w value to subtract
     * @returns new vector containing the result
     */
    Vector4.prototype.subtractFromFloats = function (x, y, z, w) {
        return new Vector4(this.x - x, this.y - y, this.z - z, this.w - w);
    };
    /**
     * Sets the given vector "result" set with the result of the subtraction of the given floats from the current Vector4 coordinates.
     * @param x value to subtract
     * @param y value to subtract
     * @param z value to subtract
     * @param w value to subtract
     * @param result the vector to store the result in
     * @returns the current Vector4.
     */
    Vector4.prototype.subtractFromFloatsToRef = function (x, y, z, w, result) {
        result.x = this.x - x;
        result.y = this.y - y;
        result.z = this.z - z;
        result.w = this.w - w;
        return this;
    };
    /**
     * Returns a new Vector4 set with the current Vector4 negated coordinates.
     * @returns a new vector with the negated values
     */
    Vector4.prototype.negate = function () {
        return new Vector4(-this.x, -this.y, -this.z, -this.w);
    };
    /**
     * Multiplies the current Vector4 coordinates by scale (float).
     * @param scale the number to scale with
     * @returns the updated Vector4.
     */
    Vector4.prototype.scaleInPlace = function (scale) {
        this.x *= scale;
        this.y *= scale;
        this.z *= scale;
        this.w *= scale;
        return this;
    };
    /**
     * Returns a new Vector4 set with the current Vector4 coordinates multiplied by scale (float).
     * @param scale the number to scale with
     * @returns a new vector with the result
     */
    Vector4.prototype.scale = function (scale) {
        return new Vector4(this.x * scale, this.y * scale, this.z * scale, this.w * scale);
    };
    /**
     * Sets the given vector "result" with the current Vector4 coordinates multiplied by scale (float).
     * @param scale the number to scale with
     * @param result a vector to store the result in
     * @returns the current Vector4.
     */
    Vector4.prototype.scaleToRef = function (scale, result) {
        result.x = this.x * scale;
        result.y = this.y * scale;
        result.z = this.z * scale;
        result.w = this.w * scale;
        return this;
    };
    /**
     * Scale the current Vector4 values by a factor and add the result to a given Vector4
     * @param scale defines the scale factor
     * @param result defines the Vector4 object where to store the result
     * @returns the unmodified current Vector4
     */
    Vector4.prototype.scaleAndAddToRef = function (scale, result) {
        result.x += this.x * scale;
        result.y += this.y * scale;
        result.z += this.z * scale;
        result.w += this.w * scale;
        return this;
    };
    /**
     * Boolean : True if the current Vector4 coordinates are stricly equal to the given ones.
     * @param otherVector the vector to compare against
     * @returns true if they are equal
     */
    Vector4.prototype.equals = function (otherVector) {
        return otherVector && this.x === otherVector.x && this.y === otherVector.y && this.z === otherVector.z && this.w === otherVector.w;
    };
    /**
     * Boolean : True if the current Vector4 coordinates are each beneath the distance "epsilon" from the given vector ones.
     * @param otherVector vector to compare against
     * @param epsilon (Default: very small number)
     * @returns true if they are equal
     */
    Vector4.prototype.equalsWithEpsilon = function (otherVector, epsilon) {
        if (epsilon === void 0) { epsilon = _math_constants__WEBPACK_IMPORTED_MODULE_1__["Epsilon"]; }
        return otherVector
            && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.x, otherVector.x, epsilon)
            && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.y, otherVector.y, epsilon)
            && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.z, otherVector.z, epsilon)
            && _math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].WithinEpsilon(this.w, otherVector.w, epsilon);
    };
    /**
     * Boolean : True if the given floats are strictly equal to the current Vector4 coordinates.
     * @param x x value to compare against
     * @param y y value to compare against
     * @param z z value to compare against
     * @param w w value to compare against
     * @returns true if equal
     */
    Vector4.prototype.equalsToFloats = function (x, y, z, w) {
        return this.x === x && this.y === y && this.z === z && this.w === w;
    };
    /**
     * Multiplies in place the current Vector4 by the given one.
     * @param otherVector vector to multiple with
     * @returns the updated Vector4.
     */
    Vector4.prototype.multiplyInPlace = function (otherVector) {
        this.x *= otherVector.x;
        this.y *= otherVector.y;
        this.z *= otherVector.z;
        this.w *= otherVector.w;
        return this;
    };
    /**
     * Returns a new Vector4 set with the multiplication result of the current Vector4 and the given one.
     * @param otherVector vector to multiple with
     * @returns resulting new vector
     */
    Vector4.prototype.multiply = function (otherVector) {
        return new Vector4(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z, this.w * otherVector.w);
    };
    /**
     * Updates the given vector "result" with the multiplication result of the current Vector4 and the given one.
     * @param otherVector vector to multiple with
     * @param result vector to store the result
     * @returns the current Vector4.
     */
    Vector4.prototype.multiplyToRef = function (otherVector, result) {
        result.x = this.x * otherVector.x;
        result.y = this.y * otherVector.y;
        result.z = this.z * otherVector.z;
        result.w = this.w * otherVector.w;
        return this;
    };
    /**
     * Returns a new Vector4 set with the multiplication result of the given floats and the current Vector4 coordinates.
     * @param x x value multiply with
     * @param y y value multiply with
     * @param z z value multiply with
     * @param w w value multiply with
     * @returns resulting new vector
     */
    Vector4.prototype.multiplyByFloats = function (x, y, z, w) {
        return new Vector4(this.x * x, this.y * y, this.z * z, this.w * w);
    };
    /**
     * Returns a new Vector4 set with the division result of the current Vector4 by the given one.
     * @param otherVector vector to devide with
     * @returns resulting new vector
     */
    Vector4.prototype.divide = function (otherVector) {
        return new Vector4(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z, this.w / otherVector.w);
    };
    /**
     * Updates the given vector "result" with the division result of the current Vector4 by the given one.
     * @param otherVector vector to devide with
     * @param result vector to store the result
     * @returns the current Vector4.
     */
    Vector4.prototype.divideToRef = function (otherVector, result) {
        result.x = this.x / otherVector.x;
        result.y = this.y / otherVector.y;
        result.z = this.z / otherVector.z;
        result.w = this.w / otherVector.w;
        return this;
    };
    /**
     * Divides the current Vector3 coordinates by the given ones.
     * @param otherVector vector to devide with
     * @returns the updated Vector3.
     */
    Vector4.prototype.divideInPlace = function (otherVector) {
        return this.divideToRef(otherVector, this);
    };
    /**
     * Updates the Vector4 coordinates with the minimum values between its own and the given vector ones
     * @param other defines the second operand
     * @returns the current updated Vector4
     */
    Vector4.prototype.minimizeInPlace = function (other) {
        if (other.x < this.x) {
            this.x = other.x;
        }
        if (other.y < this.y) {
            this.y = other.y;
        }
        if (other.z < this.z) {
            this.z = other.z;
        }
        if (other.w < this.w) {
            this.w = other.w;
        }
        return this;
    };
    /**
     * Updates the Vector4 coordinates with the maximum values between its own and the given vector ones
     * @param other defines the second operand
     * @returns the current updated Vector4
     */
    Vector4.prototype.maximizeInPlace = function (other) {
        if (other.x > this.x) {
            this.x = other.x;
        }
        if (other.y > this.y) {
            this.y = other.y;
        }
        if (other.z > this.z) {
            this.z = other.z;
        }
        if (other.w > this.w) {
            this.w = other.w;
        }
        return this;
    };
    /**
     * Gets a new Vector4 from current Vector4 floored values
     * @returns a new Vector4
     */
    Vector4.prototype.floor = function () {
        return new Vector4(Math.floor(this.x), Math.floor(this.y), Math.floor(this.z), Math.floor(this.w));
    };
    /**
     * Gets a new Vector4 from current Vector3 floored values
     * @returns a new Vector4
     */
    Vector4.prototype.fract = function () {
        return new Vector4(this.x - Math.floor(this.x), this.y - Math.floor(this.y), this.z - Math.floor(this.z), this.w - Math.floor(this.w));
    };
    // Properties
    /**
     * Returns the Vector4 length (float).
     * @returns the length
     */
    Vector4.prototype.length = function () {
        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
    };
    /**
     * Returns the Vector4 squared length (float).
     * @returns the length squared
     */
    Vector4.prototype.lengthSquared = function () {
        return (this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
    };
    // Methods
    /**
     * Normalizes in place the Vector4.
     * @returns the updated Vector4.
     */
    Vector4.prototype.normalize = function () {
        var len = this.length();
        if (len === 0) {
            return this;
        }
        return this.scaleInPlace(1.0 / len);
    };
    /**
     * Returns a new Vector3 from the Vector4 (x, y, z) coordinates.
     * @returns this converted to a new vector3
     */
    Vector4.prototype.toVector3 = function () {
        return new Vector3(this.x, this.y, this.z);
    };
    /**
     * Returns a new Vector4 copied from the current one.
     * @returns the new cloned vector
     */
    Vector4.prototype.clone = function () {
        return new Vector4(this.x, this.y, this.z, this.w);
    };
    /**
     * Updates the current Vector4 with the given one coordinates.
     * @param source the source vector to copy from
     * @returns the updated Vector4.
     */
    Vector4.prototype.copyFrom = function (source) {
        this.x = source.x;
        this.y = source.y;
        this.z = source.z;
        this.w = source.w;
        return this;
    };
    /**
     * Updates the current Vector4 coordinates with the given floats.
     * @param x float to copy from
     * @param y float to copy from
     * @param z float to copy from
     * @param w float to copy from
     * @returns the updated Vector4.
     */
    Vector4.prototype.copyFromFloats = function (x, y, z, w) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
        return this;
    };
    /**
     * Updates the current Vector4 coordinates with the given floats.
     * @param x float to set from
     * @param y float to set from
     * @param z float to set from
     * @param w float to set from
     * @returns the updated Vector4.
     */
    Vector4.prototype.set = function (x, y, z, w) {
        return this.copyFromFloats(x, y, z, w);
    };
    /**
     * Copies the given float to the current Vector3 coordinates
     * @param v defines the x, y, z and w coordinates of the operand
     * @returns the current updated Vector3
     */
    Vector4.prototype.setAll = function (v) {
        this.x = this.y = this.z = this.w = v;
        return this;
    };
    // Statics
    /**
     * Returns a new Vector4 set from the starting index of the given array.
     * @param array the array to pull values from
     * @param offset the offset into the array to start at
     * @returns the new vector
     */
    Vector4.FromArray = function (array, offset) {
        if (!offset) {
            offset = 0;
        }
        return new Vector4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);
    };
    /**
     * Updates the given vector "result" from the starting index of the given array.
     * @param array the array to pull values from
     * @param offset the offset into the array to start at
     * @param result the vector to store the result in
     */
    Vector4.FromArrayToRef = function (array, offset, result) {
        result.x = array[offset];
        result.y = array[offset + 1];
        result.z = array[offset + 2];
        result.w = array[offset + 3];
    };
    /**
     * Updates the given vector "result" from the starting index of the given Float32Array.
     * @param array the array to pull values from
     * @param offset the offset into the array to start at
     * @param result the vector to store the result in
     */
    Vector4.FromFloatArrayToRef = function (array, offset, result) {
        Vector4.FromArrayToRef(array, offset, result);
    };
    /**
     * Updates the given vector "result" coordinates from the given floats.
     * @param x float to set from
     * @param y float to set from
     * @param z float to set from
     * @param w float to set from
     * @param result the vector to the floats in
     */
    Vector4.FromFloatsToRef = function (x, y, z, w, result) {
        result.x = x;
        result.y = y;
        result.z = z;
        result.w = w;
    };
    /**
     * Returns a new Vector4 set to (0.0, 0.0, 0.0, 0.0)
     * @returns the new vector
     */
    Vector4.Zero = function () {
        return new Vector4(0.0, 0.0, 0.0, 0.0);
    };
    /**
     * Returns a new Vector4 set to (1.0, 1.0, 1.0, 1.0)
     * @returns the new vector
     */
    Vector4.One = function () {
        return new Vector4(1.0, 1.0, 1.0, 1.0);
    };
    /**
     * Returns a new normalized Vector4 from the given one.
     * @param vector the vector to normalize
     * @returns the vector
     */
    Vector4.Normalize = function (vector) {
        var result = Vector4.Zero();
        Vector4.NormalizeToRef(vector, result);
        return result;
    };
    /**
     * Updates the given vector "result" from the normalization of the given one.
     * @param vector the vector to normalize
     * @param result the vector to store the result in
     */
    Vector4.NormalizeToRef = function (vector, result) {
        result.copyFrom(vector);
        result.normalize();
    };
    /**
     * Returns a vector with the minimum values from the left and right vectors
     * @param left left vector to minimize
     * @param right right vector to minimize
     * @returns a new vector with the minimum of the left and right vector values
     */
    Vector4.Minimize = function (left, right) {
        var min = left.clone();
        min.minimizeInPlace(right);
        return min;
    };
    /**
     * Returns a vector with the maximum values from the left and right vectors
     * @param left left vector to maximize
     * @param right right vector to maximize
     * @returns a new vector with the maximum of the left and right vector values
     */
    Vector4.Maximize = function (left, right) {
        var max = left.clone();
        max.maximizeInPlace(right);
        return max;
    };
    /**
     * Returns the distance (float) between the vectors "value1" and "value2".
     * @param value1 value to calulate the distance between
     * @param value2 value to calulate the distance between
     * @return the distance between the two vectors
     */
    Vector4.Distance = function (value1, value2) {
        return Math.sqrt(Vector4.DistanceSquared(value1, value2));
    };
    /**
     * Returns the squared distance (float) between the vectors "value1" and "value2".
     * @param value1 value to calulate the distance between
     * @param value2 value to calulate the distance between
     * @return the distance between the two vectors squared
     */
    Vector4.DistanceSquared = function (value1, value2) {
        var x = value1.x - value2.x;
        var y = value1.y - value2.y;
        var z = value1.z - value2.z;
        var w = value1.w - value2.w;
        return (x * x) + (y * y) + (z * z) + (w * w);
    };
    /**
     * Returns a new Vector4 located at the center between the vectors "value1" and "value2".
     * @param value1 value to calulate the center between
     * @param value2 value to calulate the center between
     * @return the center between the two vectors
     */
    Vector4.Center = function (value1, value2) {
        var center = value1.add(value2);
        center.scaleInPlace(0.5);
        return center;
    };
    /**
     * Returns a new Vector4 set with the result of the normal transformation by the given matrix of the given vector.
     * This methods computes transformed normalized direction vectors only.
     * @param vector the vector to transform
     * @param transformation the transformation matrix to apply
     * @returns the new vector
     */
    Vector4.TransformNormal = function (vector, transformation) {
        var result = Vector4.Zero();
        Vector4.TransformNormalToRef(vector, transformation, result);
        return result;
    };
    /**
     * Sets the given vector "result" with the result of the normal transformation by the given matrix of the given vector.
     * This methods computes transformed normalized direction vectors only.
     * @param vector the vector to transform
     * @param transformation the transformation matrix to apply
     * @param result the vector to store the result in
     */
    Vector4.TransformNormalToRef = function (vector, transformation, result) {
        var m = transformation.m;
        var x = (vector.x * m[0]) + (vector.y * m[4]) + (vector.z * m[8]);
        var y = (vector.x * m[1]) + (vector.y * m[5]) + (vector.z * m[9]);
        var z = (vector.x * m[2]) + (vector.y * m[6]) + (vector.z * m[10]);
        result.x = x;
        result.y = y;
        result.z = z;
        result.w = vector.w;
    };
    /**
     * Sets the given vector "result" with the result of the normal transformation by the given matrix of the given floats (x, y, z, w).
     * This methods computes transformed normalized direction vectors only.
     * @param x value to transform
     * @param y value to transform
     * @param z value to transform
     * @param w value to transform
     * @param transformation the transformation matrix to apply
     * @param result the vector to store the results in
     */
    Vector4.TransformNormalFromFloatsToRef = function (x, y, z, w, transformation, result) {
        var m = transformation.m;
        result.x = (x * m[0]) + (y * m[4]) + (z * m[8]);
        result.y = (x * m[1]) + (y * m[5]) + (z * m[9]);
        result.z = (x * m[2]) + (y * m[6]) + (z * m[10]);
        result.w = w;
    };
    /**
     * Creates a new Vector4 from a Vector3
     * @param source defines the source data
     * @param w defines the 4th component (default is 0)
     * @returns a new Vector4
     */
    Vector4.FromVector3 = function (source, w) {
        if (w === void 0) { w = 0; }
        return new Vector4(source.x, source.y, source.z, w);
    };
    return Vector4;
}());

/**
 * Class used to store quaternion data
 * @see https://en.wikipedia.org/wiki/Quaternion
 * @see http://doc.babylonjs.com/features/position,_rotation,_scaling
 */
var Quaternion = /** @class */ (function () {
    /**
     * Creates a new Quaternion from the given floats
     * @param x defines the first component (0 by default)
     * @param y defines the second component (0 by default)
     * @param z defines the third component (0 by default)
     * @param w defines the fourth component (1.0 by default)
     */
    function Quaternion(
    /** defines the first component (0 by default) */
    x,
    /** defines the second component (0 by default) */
    y,
    /** defines the third component (0 by default) */
    z,
    /** defines the fourth component (1.0 by default) */
    w) {
        if (x === void 0) { x = 0.0; }
        if (y === void 0) { y = 0.0; }
        if (z === void 0) { z = 0.0; }
        if (w === void 0) { w = 1.0; }
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
    }
    /**
     * Gets a string representation for the current quaternion
     * @returns a string with the Quaternion coordinates
     */
    Quaternion.prototype.toString = function () {
        return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + " W:" + this.w + "}";
    };
    /**
     * Gets the class name of the quaternion
     * @returns the string "Quaternion"
     */
    Quaternion.prototype.getClassName = function () {
        return "Quaternion";
    };
    /**
     * Gets a hash code for this quaternion
     * @returns the quaternion hash code
     */
    Quaternion.prototype.getHashCode = function () {
        var hash = this.x | 0;
        hash = (hash * 397) ^ (this.y | 0);
        hash = (hash * 397) ^ (this.z | 0);
        hash = (hash * 397) ^ (this.w | 0);
        return hash;
    };
    /**
     * Copy the quaternion to an array
     * @returns a new array populated with 4 elements from the quaternion coordinates
     */
    Quaternion.prototype.asArray = function () {
        return [this.x, this.y, this.z, this.w];
    };
    /**
     * Check if two quaternions are equals
     * @param otherQuaternion defines the second operand
     * @return true if the current quaternion and the given one coordinates are strictly equals
     */
    Quaternion.prototype.equals = function (otherQuaternion) {
        return otherQuaternion && this.x === otherQuaternion.x && this.y === otherQuaternion.y && this.z === otherQuaternion.z && this.w === otherQuaternion.w;
    };
    /**
     * Clone the current quaternion
     * @returns a new quaternion copied from the current one
     */
    Quaternion.prototype.clone = function () {
        return new Quaternion(this.x, this.y, this.z, this.w);
    };
    /**
     * Copy a quaternion to the current one
     * @param other defines the other quaternion
     * @returns the updated current quaternion
     */
    Quaternion.prototype.copyFrom = function (other) {
        this.x = other.x;
        this.y = other.y;
        this.z = other.z;
        this.w = other.w;
        return this;
    };
    /**
     * Updates the current quaternion with the given float coordinates
     * @param x defines the x coordinate
     * @param y defines the y coordinate
     * @param z defines the z coordinate
     * @param w defines the w coordinate
     * @returns the updated current quaternion
     */
    Quaternion.prototype.copyFromFloats = function (x, y, z, w) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
        return this;
    };
    /**
     * Updates the current quaternion from the given float coordinates
     * @param x defines the x coordinate
     * @param y defines the y coordinate
     * @param z defines the z coordinate
     * @param w defines the w coordinate
     * @returns the updated current quaternion
     */
    Quaternion.prototype.set = function (x, y, z, w) {
        return this.copyFromFloats(x, y, z, w);
    };
    /**
     * Adds two quaternions
     * @param other defines the second operand
     * @returns a new quaternion as the addition result of the given one and the current quaternion
     */
    Quaternion.prototype.add = function (other) {
        return new Quaternion(this.x + other.x, this.y + other.y, this.z + other.z, this.w + other.w);
    };
    /**
     * Add a quaternion to the current one
     * @param other defines the quaternion to add
     * @returns the current quaternion
     */
    Quaternion.prototype.addInPlace = function (other) {
        this.x += other.x;
        this.y += other.y;
        this.z += other.z;
        this.w += other.w;
        return this;
    };
    /**
     * Subtract two quaternions
     * @param other defines the second operand
     * @returns a new quaternion as the subtraction result of the given one from the current one
     */
    Quaternion.prototype.subtract = function (other) {
        return new Quaternion(this.x - other.x, this.y - other.y, this.z - other.z, this.w - other.w);
    };
    /**
     * Multiplies the current quaternion by a scale factor
     * @param value defines the scale factor
     * @returns a new quaternion set by multiplying the current quaternion coordinates by the float "scale"
     */
    Quaternion.prototype.scale = function (value) {
        return new Quaternion(this.x * value, this.y * value, this.z * value, this.w * value);
    };
    /**
     * Scale the current quaternion values by a factor and stores the result to a given quaternion
     * @param scale defines the scale factor
     * @param result defines the Quaternion object where to store the result
     * @returns the unmodified current quaternion
     */
    Quaternion.prototype.scaleToRef = function (scale, result) {
        result.x = this.x * scale;
        result.y = this.y * scale;
        result.z = this.z * scale;
        result.w = this.w * scale;
        return this;
    };
    /**
     * Multiplies in place the current quaternion by a scale factor
     * @param value defines the scale factor
     * @returns the current modified quaternion
     */
    Quaternion.prototype.scaleInPlace = function (value) {
        this.x *= value;
        this.y *= value;
        this.z *= value;
        this.w *= value;
        return this;
    };
    /**
     * Scale the current quaternion values by a factor and add the result to a given quaternion
     * @param scale defines the scale factor
     * @param result defines the Quaternion object where to store the result
     * @returns the unmodified current quaternion
     */
    Quaternion.prototype.scaleAndAddToRef = function (scale, result) {
        result.x += this.x * scale;
        result.y += this.y * scale;
        result.z += this.z * scale;
        result.w += this.w * scale;
        return this;
    };
    /**
     * Multiplies two quaternions
     * @param q1 defines the second operand
     * @returns a new quaternion set as the multiplication result of the current one with the given one "q1"
     */
    Quaternion.prototype.multiply = function (q1) {
        var result = new Quaternion(0, 0, 0, 1.0);
        this.multiplyToRef(q1, result);
        return result;
    };
    /**
     * Sets the given "result" as the the multiplication result of the current one with the given one "q1"
     * @param q1 defines the second operand
     * @param result defines the target quaternion
     * @returns the current quaternion
     */
    Quaternion.prototype.multiplyToRef = function (q1, result) {
        var x = this.x * q1.w + this.y * q1.z - this.z * q1.y + this.w * q1.x;
        var y = -this.x * q1.z + this.y * q1.w + this.z * q1.x + this.w * q1.y;
        var z = this.x * q1.y - this.y * q1.x + this.z * q1.w + this.w * q1.z;
        var w = -this.x * q1.x - this.y * q1.y - this.z * q1.z + this.w * q1.w;
        result.copyFromFloats(x, y, z, w);
        return this;
    };
    /**
     * Updates the current quaternion with the multiplication of itself with the given one "q1"
     * @param q1 defines the second operand
     * @returns the currentupdated quaternion
     */
    Quaternion.prototype.multiplyInPlace = function (q1) {
        this.multiplyToRef(q1, this);
        return this;
    };
    /**
     * Conjugates (1-q) the current quaternion and stores the result in the given quaternion
     * @param ref defines the target quaternion
     * @returns the current quaternion
     */
    Quaternion.prototype.conjugateToRef = function (ref) {
        ref.copyFromFloats(-this.x, -this.y, -this.z, this.w);
        return this;
    };
    /**
     * Conjugates in place (1-q) the current quaternion
     * @returns the current updated quaternion
     */
    Quaternion.prototype.conjugateInPlace = function () {
        this.x *= -1;
        this.y *= -1;
        this.z *= -1;
        return this;
    };
    /**
     * Conjugates in place (1-q) the current quaternion
     * @returns a new quaternion
     */
    Quaternion.prototype.conjugate = function () {
        var result = new Quaternion(-this.x, -this.y, -this.z, this.w);
        return result;
    };
    /**
     * Gets length of current quaternion
     * @returns the quaternion length (float)
     */
    Quaternion.prototype.length = function () {
        return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w));
    };
    /**
     * Normalize in place the current quaternion
     * @returns the current updated quaternion
     */
    Quaternion.prototype.normalize = function () {
        var len = this.length();
        if (len === 0) {
            return this;
        }
        var inv = 1.0 / len;
        this.x *= inv;
        this.y *= inv;
        this.z *= inv;
        this.w *= inv;
        return this;
    };
    /**
     * Returns a new Vector3 set with the Euler angles translated from the current quaternion
     * @param order is a reserved parameter and is ignore for now
     * @returns a new Vector3 containing the Euler angles
     */
    Quaternion.prototype.toEulerAngles = function (order) {
        if (order === void 0) { order = "YZX"; }
        var result = Vector3.Zero();
        this.toEulerAnglesToRef(result);
        return result;
    };
    /**
     * Sets the given vector3 "result" with the Euler angles translated from the current quaternion
     * @param result defines the vector which will be filled with the Euler angles
     * @param order is a reserved parameter and is ignore for now
     * @returns the current unchanged quaternion
     */
    Quaternion.prototype.toEulerAnglesToRef = function (result) {
        var qz = this.z;
        var qx = this.x;
        var qy = this.y;
        var qw = this.w;
        var sqw = qw * qw;
        var sqz = qz * qz;
        var sqx = qx * qx;
        var sqy = qy * qy;
        var zAxisY = qy * qz - qx * qw;
        var limit = .4999999;
        if (zAxisY < -limit) {
            result.y = 2 * Math.atan2(qy, qw);
            result.x = Math.PI / 2;
            result.z = 0;
        }
        else if (zAxisY > limit) {
            result.y = 2 * Math.atan2(qy, qw);
            result.x = -Math.PI / 2;
            result.z = 0;
        }
        else {
            result.z = Math.atan2(2.0 * (qx * qy + qz * qw), (-sqz - sqx + sqy + sqw));
            result.x = Math.asin(-2.0 * (qz * qy - qx * qw));
            result.y = Math.atan2(2.0 * (qz * qx + qy * qw), (sqz - sqx - sqy + sqw));
        }
        return this;
    };
    /**
     * Updates the given rotation matrix with the current quaternion values
     * @param result defines the target matrix
     * @returns the current unchanged quaternion
     */
    Quaternion.prototype.toRotationMatrix = function (result) {
        Matrix.FromQuaternionToRef(this, result);
        return this;
    };
    /**
     * Updates the current quaternion from the given rotation matrix values
     * @param matrix defines the source matrix
     * @returns the current updated quaternion
     */
    Quaternion.prototype.fromRotationMatrix = function (matrix) {
        Quaternion.FromRotationMatrixToRef(matrix, this);
        return this;
    };
    // Statics
    /**
     * Creates a new quaternion from a rotation matrix
     * @param matrix defines the source matrix
     * @returns a new quaternion created from the given rotation matrix values
     */
    Quaternion.FromRotationMatrix = function (matrix) {
        var result = new Quaternion();
        Quaternion.FromRotationMatrixToRef(matrix, result);
        return result;
    };
    /**
     * Updates the given quaternion with the given rotation matrix values
     * @param matrix defines the source matrix
     * @param result defines the target quaternion
     */
    Quaternion.FromRotationMatrixToRef = function (matrix, result) {
        var data = matrix.m;
        var m11 = data[0], m12 = data[4], m13 = data[8];
        var m21 = data[1], m22 = data[5], m23 = data[9];
        var m31 = data[2], m32 = data[6], m33 = data[10];
        var trace = m11 + m22 + m33;
        var s;
        if (trace > 0) {
            s = 0.5 / Math.sqrt(trace + 1.0);
            result.w = 0.25 / s;
            result.x = (m32 - m23) * s;
            result.y = (m13 - m31) * s;
            result.z = (m21 - m12) * s;
        }
        else if (m11 > m22 && m11 > m33) {
            s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
            result.w = (m32 - m23) / s;
            result.x = 0.25 * s;
            result.y = (m12 + m21) / s;
            result.z = (m13 + m31) / s;
        }
        else if (m22 > m33) {
            s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
            result.w = (m13 - m31) / s;
            result.x = (m12 + m21) / s;
            result.y = 0.25 * s;
            result.z = (m23 + m32) / s;
        }
        else {
            s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
            result.w = (m21 - m12) / s;
            result.x = (m13 + m31) / s;
            result.y = (m23 + m32) / s;
            result.z = 0.25 * s;
        }
    };
    /**
     * Returns the dot product (float) between the quaternions "left" and "right"
     * @param left defines the left operand
     * @param right defines the right operand
     * @returns the dot product
     */
    Quaternion.Dot = function (left, right) {
        return (left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w);
    };
    /**
     * Checks if the two quaternions are close to each other
     * @param quat0 defines the first quaternion to check
     * @param quat1 defines the second quaternion to check
     * @returns true if the two quaternions are close to each other
     */
    Quaternion.AreClose = function (quat0, quat1) {
        var dot = Quaternion.Dot(quat0, quat1);
        return dot >= 0;
    };
    /**
     * Creates an empty quaternion
     * @returns a new quaternion set to (0.0, 0.0, 0.0)
     */
    Quaternion.Zero = function () {
        return new Quaternion(0.0, 0.0, 0.0, 0.0);
    };
    /**
     * Inverse a given quaternion
     * @param q defines the source quaternion
     * @returns a new quaternion as the inverted current quaternion
     */
    Quaternion.Inverse = function (q) {
        return new Quaternion(-q.x, -q.y, -q.z, q.w);
    };
    /**
     * Inverse a given quaternion
     * @param q defines the source quaternion
     * @param result the quaternion the result will be stored in
     * @returns the result quaternion
     */
    Quaternion.InverseToRef = function (q, result) {
        result.set(-q.x, -q.y, -q.z, q.w);
        return result;
    };
    /**
     * Creates an identity quaternion
     * @returns the identity quaternion
     */
    Quaternion.Identity = function () {
        return new Quaternion(0.0, 0.0, 0.0, 1.0);
    };
    /**
     * Gets a boolean indicating if the given quaternion is identity
     * @param quaternion defines the quaternion to check
     * @returns true if the quaternion is identity
     */
    Quaternion.IsIdentity = function (quaternion) {
        return quaternion && quaternion.x === 0 && quaternion.y === 0 && quaternion.z === 0 && quaternion.w === 1;
    };
    /**
     * Creates a quaternion from a rotation around an axis
     * @param axis defines the axis to use
     * @param angle defines the angle to use
     * @returns a new quaternion created from the given axis (Vector3) and angle in radians (float)
     */
    Quaternion.RotationAxis = function (axis, angle) {
        return Quaternion.RotationAxisToRef(axis, angle, new Quaternion());
    };
    /**
     * Creates a rotation around an axis and stores it into the given quaternion
     * @param axis defines the axis to use
     * @param angle defines the angle to use
     * @param result defines the target quaternion
     * @returns the target quaternion
     */
    Quaternion.RotationAxisToRef = function (axis, angle, result) {
        var sin = Math.sin(angle / 2);
        axis.normalize();
        result.w = Math.cos(angle / 2);
        result.x = axis.x * sin;
        result.y = axis.y * sin;
        result.z = axis.z * sin;
        return result;
    };
    /**
     * Creates a new quaternion from data stored into an array
     * @param array defines the data source
     * @param offset defines the offset in the source array where the data starts
     * @returns a new quaternion
     */
    Quaternion.FromArray = function (array, offset) {
        if (!offset) {
            offset = 0;
        }
        return new Quaternion(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);
    };
    /**
     * Create a quaternion from Euler rotation angles
     * @param x Pitch
     * @param y Yaw
     * @param z Roll
     * @returns the new Quaternion
     */
    Quaternion.FromEulerAngles = function (x, y, z) {
        var q = new Quaternion();
        Quaternion.RotationYawPitchRollToRef(y, x, z, q);
        return q;
    };
    /**
     * Updates a quaternion from Euler rotation angles
     * @param x Pitch
     * @param y Yaw
     * @param z Roll
     * @param result the quaternion to store the result
     * @returns the updated quaternion
     */
    Quaternion.FromEulerAnglesToRef = function (x, y, z, result) {
        Quaternion.RotationYawPitchRollToRef(y, x, z, result);
        return result;
    };
    /**
     * Create a quaternion from Euler rotation vector
     * @param vec the Euler vector (x Pitch, y Yaw, z Roll)
     * @returns the new Quaternion
     */
    Quaternion.FromEulerVector = function (vec) {
        var q = new Quaternion();
        Quaternion.RotationYawPitchRollToRef(vec.y, vec.x, vec.z, q);
        return q;
    };
    /**
     * Updates a quaternion from Euler rotation vector
     * @param vec the Euler vector (x Pitch, y Yaw, z Roll)
     * @param result the quaternion to store the result
     * @returns the updated quaternion
     */
    Quaternion.FromEulerVectorToRef = function (vec, result) {
        Quaternion.RotationYawPitchRollToRef(vec.y, vec.x, vec.z, result);
        return result;
    };
    /**
     * Creates a new quaternion from the given Euler float angles (y, x, z)
     * @param yaw defines the rotation around Y axis
     * @param pitch defines the rotation around X axis
     * @param roll defines the rotation around Z axis
     * @returns the new quaternion
     */
    Quaternion.RotationYawPitchRoll = function (yaw, pitch, roll) {
        var q = new Quaternion();
        Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, q);
        return q;
    };
    /**
     * Creates a new rotation from the given Euler float angles (y, x, z) and stores it in the target quaternion
     * @param yaw defines the rotation around Y axis
     * @param pitch defines the rotation around X axis
     * @param roll defines the rotation around Z axis
     * @param result defines the target quaternion
     */
    Quaternion.RotationYawPitchRollToRef = function (yaw, pitch, roll, result) {
        // Produces a quaternion from Euler angles in the z-y-x orientation (Tait-Bryan angles)
        var halfRoll = roll * 0.5;
        var halfPitch = pitch * 0.5;
        var halfYaw = yaw * 0.5;
        var sinRoll = Math.sin(halfRoll);
        var cosRoll = Math.cos(halfRoll);
        var sinPitch = Math.sin(halfPitch);
        var cosPitch = Math.cos(halfPitch);
        var sinYaw = Math.sin(halfYaw);
        var cosYaw = Math.cos(halfYaw);
        result.x = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
        result.y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
        result.z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
        result.w = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
    };
    /**
     * Creates a new quaternion from the given Euler float angles expressed in z-x-z orientation
     * @param alpha defines the rotation around first axis
     * @param beta defines the rotation around second axis
     * @param gamma defines the rotation around third axis
     * @returns the new quaternion
     */
    Quaternion.RotationAlphaBetaGamma = function (alpha, beta, gamma) {
        var result = new Quaternion();
        Quaternion.RotationAlphaBetaGammaToRef(alpha, beta, gamma, result);
        return result;
    };
    /**
     * Creates a new quaternion from the given Euler float angles expressed in z-x-z orientation and stores it in the target quaternion
     * @param alpha defines the rotation around first axis
     * @param beta defines the rotation around second axis
     * @param gamma defines the rotation around third axis
     * @param result defines the target quaternion
     */
    Quaternion.RotationAlphaBetaGammaToRef = function (alpha, beta, gamma, result) {
        // Produces a quaternion from Euler angles in the z-x-z orientation
        var halfGammaPlusAlpha = (gamma + alpha) * 0.5;
        var halfGammaMinusAlpha = (gamma - alpha) * 0.5;
        var halfBeta = beta * 0.5;
        result.x = Math.cos(halfGammaMinusAlpha) * Math.sin(halfBeta);
        result.y = Math.sin(halfGammaMinusAlpha) * Math.sin(halfBeta);
        result.z = Math.sin(halfGammaPlusAlpha) * Math.cos(halfBeta);
        result.w = Math.cos(halfGammaPlusAlpha) * Math.cos(halfBeta);
    };
    /**
     * Creates a new quaternion containing the rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system (axis1, axis2 and axis3 are normalized during this operation)
     * @param axis1 defines the first axis
     * @param axis2 defines the second axis
     * @param axis3 defines the third axis
     * @returns the new quaternion
     */
    Quaternion.RotationQuaternionFromAxis = function (axis1, axis2, axis3) {
        var quat = new Quaternion(0.0, 0.0, 0.0, 0.0);
        Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);
        return quat;
    };
    /**
     * Creates a rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system (axis1, axis2 and axis3 are normalized during this operation) and stores it in the target quaternion
     * @param axis1 defines the first axis
     * @param axis2 defines the second axis
     * @param axis3 defines the third axis
     * @param ref defines the target quaternion
     */
    Quaternion.RotationQuaternionFromAxisToRef = function (axis1, axis2, axis3, ref) {
        var rotMat = MathTmp.Matrix[0];
        Matrix.FromXYZAxesToRef(axis1.normalize(), axis2.normalize(), axis3.normalize(), rotMat);
        Quaternion.FromRotationMatrixToRef(rotMat, ref);
    };
    /**
     * Interpolates between two quaternions
     * @param left defines first quaternion
     * @param right defines second quaternion
     * @param amount defines the gradient to use
     * @returns the new interpolated quaternion
     */
    Quaternion.Slerp = function (left, right, amount) {
        var result = Quaternion.Identity();
        Quaternion.SlerpToRef(left, right, amount, result);
        return result;
    };
    /**
     * Interpolates between two quaternions and stores it into a target quaternion
     * @param left defines first quaternion
     * @param right defines second quaternion
     * @param amount defines the gradient to use
     * @param result defines the target quaternion
     */
    Quaternion.SlerpToRef = function (left, right, amount, result) {
        var num2;
        var num3;
        var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
        var flag = false;
        if (num4 < 0) {
            flag = true;
            num4 = -num4;
        }
        if (num4 > 0.999999) {
            num3 = 1 - amount;
            num2 = flag ? -amount : amount;
        }
        else {
            var num5 = Math.acos(num4);
            var num6 = (1.0 / Math.sin(num5));
            num3 = (Math.sin((1.0 - amount) * num5)) * num6;
            num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
        }
        result.x = (num3 * left.x) + (num2 * right.x);
        result.y = (num3 * left.y) + (num2 * right.y);
        result.z = (num3 * left.z) + (num2 * right.z);
        result.w = (num3 * left.w) + (num2 * right.w);
    };
    /**
     * Interpolate between two quaternions using Hermite interpolation
     * @param value1 defines first quaternion
     * @param tangent1 defines the incoming tangent
     * @param value2 defines second quaternion
     * @param tangent2 defines the outgoing tangent
     * @param amount defines the target quaternion
     * @returns the new interpolated quaternion
     */
    Quaternion.Hermite = function (value1, tangent1, value2, tangent2, amount) {
        var squared = amount * amount;
        var cubed = amount * squared;
        var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
        var part2 = (-2.0 * cubed) + (3.0 * squared);
        var part3 = (cubed - (2.0 * squared)) + amount;
        var part4 = cubed - squared;
        var x = (((value1.x * part1) + (value2.x * part2)) + (tangent1.x * part3)) + (tangent2.x * part4);
        var y = (((value1.y * part1) + (value2.y * part2)) + (tangent1.y * part3)) + (tangent2.y * part4);
        var z = (((value1.z * part1) + (value2.z * part2)) + (tangent1.z * part3)) + (tangent2.z * part4);
        var w = (((value1.w * part1) + (value2.w * part2)) + (tangent1.w * part3)) + (tangent2.w * part4);
        return new Quaternion(x, y, z, w);
    };
    return Quaternion;
}());

/**
 * Class used to store matrix data (4x4)
 */
var Matrix = /** @class */ (function () {
    /**
     * Creates an empty matrix (filled with zeros)
     */
    function Matrix() {
        this._isIdentity = false;
        this._isIdentityDirty = true;
        this._isIdentity3x2 = true;
        this._isIdentity3x2Dirty = true;
        /**
         * Gets the update flag of the matrix which is an unique number for the matrix.
         * It will be incremented every time the matrix data change.
         * You can use it to speed the comparison between two versions of the same matrix.
         */
        this.updateFlag = -1;
        this._m = new Float32Array(16);
        this._updateIdentityStatus(false);
    }
    Object.defineProperty(Matrix.prototype, "m", {
        /**
         * Gets the internal data of the matrix
         */
        get: function () { return this._m; },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    Matrix.prototype._markAsUpdated = function () {
        this.updateFlag = Matrix._updateFlagSeed++;
        this._isIdentity = false;
        this._isIdentity3x2 = false;
        this._isIdentityDirty = true;
        this._isIdentity3x2Dirty = true;
    };
    /** @hidden */
    Matrix.prototype._updateIdentityStatus = function (isIdentity, isIdentityDirty, isIdentity3x2, isIdentity3x2Dirty) {
        if (isIdentityDirty === void 0) { isIdentityDirty = false; }
        if (isIdentity3x2 === void 0) { isIdentity3x2 = false; }
        if (isIdentity3x2Dirty === void 0) { isIdentity3x2Dirty = true; }
        this.updateFlag = Matrix._updateFlagSeed++;
        this._isIdentity = isIdentity;
        this._isIdentity3x2 = isIdentity || isIdentity3x2;
        this._isIdentityDirty = this._isIdentity ? false : isIdentityDirty;
        this._isIdentity3x2Dirty = this._isIdentity3x2 ? false : isIdentity3x2Dirty;
    };
    // Properties
    /**
     * Check if the current matrix is identity
     * @returns true is the matrix is the identity matrix
     */
    Matrix.prototype.isIdentity = function () {
        if (this._isIdentityDirty) {
            this._isIdentityDirty = false;
            var m = this._m;
            this._isIdentity = (m[0] === 1.0 && m[1] === 0.0 && m[2] === 0.0 && m[3] === 0.0 &&
                m[4] === 0.0 && m[5] === 1.0 && m[6] === 0.0 && m[7] === 0.0 &&
                m[8] === 0.0 && m[9] === 0.0 && m[10] === 1.0 && m[11] === 0.0 &&
                m[12] === 0.0 && m[13] === 0.0 && m[14] === 0.0 && m[15] === 1.0);
        }
        return this._isIdentity;
    };
    /**
     * Check if the current matrix is identity as a texture matrix (3x2 store in 4x4)
     * @returns true is the matrix is the identity matrix
     */
    Matrix.prototype.isIdentityAs3x2 = function () {
        if (this._isIdentity3x2Dirty) {
            this._isIdentity3x2Dirty = false;
            if (this._m[0] !== 1.0 || this._m[5] !== 1.0 || this._m[15] !== 1.0) {
                this._isIdentity3x2 = false;
            }
            else if (this._m[1] !== 0.0 || this._m[2] !== 0.0 || this._m[3] !== 0.0 ||
                this._m[4] !== 0.0 || this._m[6] !== 0.0 || this._m[7] !== 0.0 ||
                this._m[8] !== 0.0 || this._m[9] !== 0.0 || this._m[10] !== 0.0 || this._m[11] !== 0.0 ||
                this._m[12] !== 0.0 || this._m[13] !== 0.0 || this._m[14] !== 0.0) {
                this._isIdentity3x2 = false;
            }
            else {
                this._isIdentity3x2 = true;
            }
        }
        return this._isIdentity3x2;
    };
    /**
     * Gets the determinant of the matrix
     * @returns the matrix determinant
     */
    Matrix.prototype.determinant = function () {
        if (this._isIdentity === true) {
            return 1;
        }
        var m = this._m;
        var m00 = m[0], m01 = m[1], m02 = m[2], m03 = m[3];
        var m10 = m[4], m11 = m[5], m12 = m[6], m13 = m[7];
        var m20 = m[8], m21 = m[9], m22 = m[10], m23 = m[11];
        var m30 = m[12], m31 = m[13], m32 = m[14], m33 = m[15];
        // https://en.wikipedia.org/wiki/Laplace_expansion
        // to compute the deterrminant of a 4x4 Matrix we compute the cofactors of any row or column,
        // then we multiply each Cofactor by its corresponding matrix value and sum them all to get the determinant
        // Cofactor(i, j) = sign(i,j) * det(Minor(i, j))
        // where
        //  - sign(i,j) = (i+j) % 2 === 0 ? 1 : -1
        //  - Minor(i, j) is the 3x3 matrix we get by removing row i and column j from current Matrix
        //
        // Here we do that for the 1st row.
        var det_22_33 = m22 * m33 - m32 * m23;
        var det_21_33 = m21 * m33 - m31 * m23;
        var det_21_32 = m21 * m32 - m31 * m22;
        var det_20_33 = m20 * m33 - m30 * m23;
        var det_20_32 = m20 * m32 - m22 * m30;
        var det_20_31 = m20 * m31 - m30 * m21;
        var cofact_00 = +(m11 * det_22_33 - m12 * det_21_33 + m13 * det_21_32);
        var cofact_01 = -(m10 * det_22_33 - m12 * det_20_33 + m13 * det_20_32);
        var cofact_02 = +(m10 * det_21_33 - m11 * det_20_33 + m13 * det_20_31);
        var cofact_03 = -(m10 * det_21_32 - m11 * det_20_32 + m12 * det_20_31);
        return m00 * cofact_00 + m01 * cofact_01 + m02 * cofact_02 + m03 * cofact_03;
    };
    // Methods
    /**
     * Returns the matrix as a Float32Array
     * @returns the matrix underlying array
     */
    Matrix.prototype.toArray = function () {
        return this._m;
    };
    /**
     * Returns the matrix as a Float32Array
    * @returns the matrix underlying array.
    */
    Matrix.prototype.asArray = function () {
        return this._m;
    };
    /**
     * Inverts the current matrix in place
     * @returns the current inverted matrix
     */
    Matrix.prototype.invert = function () {
        this.invertToRef(this);
        return this;
    };
    /**
     * Sets all the matrix elements to zero
     * @returns the current matrix
     */
    Matrix.prototype.reset = function () {
        Matrix.FromValuesToRef(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, this);
        this._updateIdentityStatus(false);
        return this;
    };
    /**
     * Adds the current matrix with a second one
     * @param other defines the matrix to add
     * @returns a new matrix as the addition of the current matrix and the given one
     */
    Matrix.prototype.add = function (other) {
        var result = new Matrix();
        this.addToRef(other, result);
        return result;
    };
    /**
     * Sets the given matrix "result" to the addition of the current matrix and the given one
     * @param other defines the matrix to add
     * @param result defines the target matrix
     * @returns the current matrix
     */
    Matrix.prototype.addToRef = function (other, result) {
        var m = this._m;
        var resultM = result._m;
        var otherM = other.m;
        for (var index = 0; index < 16; index++) {
            resultM[index] = m[index] + otherM[index];
        }
        result._markAsUpdated();
        return this;
    };
    /**
     * Adds in place the given matrix to the current matrix
     * @param other defines the second operand
     * @returns the current updated matrix
     */
    Matrix.prototype.addToSelf = function (other) {
        var m = this._m;
        var otherM = other.m;
        for (var index = 0; index < 16; index++) {
            m[index] += otherM[index];
        }
        this._markAsUpdated();
        return this;
    };
    /**
     * Sets the given matrix to the current inverted Matrix
     * @param other defines the target matrix
     * @returns the unmodified current matrix
     */
    Matrix.prototype.invertToRef = function (other) {
        if (this._isIdentity === true) {
            Matrix.IdentityToRef(other);
            return this;
        }
        // the inverse of a Matrix is the transpose of cofactor matrix divided by the determinant
        var m = this._m;
        var m00 = m[0], m01 = m[1], m02 = m[2], m03 = m[3];
        var m10 = m[4], m11 = m[5], m12 = m[6], m13 = m[7];
        var m20 = m[8], m21 = m[9], m22 = m[10], m23 = m[11];
        var m30 = m[12], m31 = m[13], m32 = m[14], m33 = m[15];
        var det_22_33 = m22 * m33 - m32 * m23;
        var det_21_33 = m21 * m33 - m31 * m23;
        var det_21_32 = m21 * m32 - m31 * m22;
        var det_20_33 = m20 * m33 - m30 * m23;
        var det_20_32 = m20 * m32 - m22 * m30;
        var det_20_31 = m20 * m31 - m30 * m21;
        var cofact_00 = +(m11 * det_22_33 - m12 * det_21_33 + m13 * det_21_32);
        var cofact_01 = -(m10 * det_22_33 - m12 * det_20_33 + m13 * det_20_32);
        var cofact_02 = +(m10 * det_21_33 - m11 * det_20_33 + m13 * det_20_31);
        var cofact_03 = -(m10 * det_21_32 - m11 * det_20_32 + m12 * det_20_31);
        var det = m00 * cofact_00 + m01 * cofact_01 + m02 * cofact_02 + m03 * cofact_03;
        if (det === 0) {
            // not invertible
            other.copyFrom(this);
            return this;
        }
        var detInv = 1 / det;
        var det_12_33 = m12 * m33 - m32 * m13;
        var det_11_33 = m11 * m33 - m31 * m13;
        var det_11_32 = m11 * m32 - m31 * m12;
        var det_10_33 = m10 * m33 - m30 * m13;
        var det_10_32 = m10 * m32 - m30 * m12;
        var det_10_31 = m10 * m31 - m30 * m11;
        var det_12_23 = m12 * m23 - m22 * m13;
        var det_11_23 = m11 * m23 - m21 * m13;
        var det_11_22 = m11 * m22 - m21 * m12;
        var det_10_23 = m10 * m23 - m20 * m13;
        var det_10_22 = m10 * m22 - m20 * m12;
        var det_10_21 = m10 * m21 - m20 * m11;
        var cofact_10 = -(m01 * det_22_33 - m02 * det_21_33 + m03 * det_21_32);
        var cofact_11 = +(m00 * det_22_33 - m02 * det_20_33 + m03 * det_20_32);
        var cofact_12 = -(m00 * det_21_33 - m01 * det_20_33 + m03 * det_20_31);
        var cofact_13 = +(m00 * det_21_32 - m01 * det_20_32 + m02 * det_20_31);
        var cofact_20 = +(m01 * det_12_33 - m02 * det_11_33 + m03 * det_11_32);
        var cofact_21 = -(m00 * det_12_33 - m02 * det_10_33 + m03 * det_10_32);
        var cofact_22 = +(m00 * det_11_33 - m01 * det_10_33 + m03 * det_10_31);
        var cofact_23 = -(m00 * det_11_32 - m01 * det_10_32 + m02 * det_10_31);
        var cofact_30 = -(m01 * det_12_23 - m02 * det_11_23 + m03 * det_11_22);
        var cofact_31 = +(m00 * det_12_23 - m02 * det_10_23 + m03 * det_10_22);
        var cofact_32 = -(m00 * det_11_23 - m01 * det_10_23 + m03 * det_10_21);
        var cofact_33 = +(m00 * det_11_22 - m01 * det_10_22 + m02 * det_10_21);
        Matrix.FromValuesToRef(cofact_00 * detInv, cofact_10 * detInv, cofact_20 * detInv, cofact_30 * detInv, cofact_01 * detInv, cofact_11 * detInv, cofact_21 * detInv, cofact_31 * detInv, cofact_02 * detInv, cofact_12 * detInv, cofact_22 * detInv, cofact_32 * detInv, cofact_03 * detInv, cofact_13 * detInv, cofact_23 * detInv, cofact_33 * detInv, other);
        return this;
    };
    /**
     * add a value at the specified position in the current Matrix
     * @param index the index of the value within the matrix. between 0 and 15.
     * @param value the value to be added
     * @returns the current updated matrix
     */
    Matrix.prototype.addAtIndex = function (index, value) {
        this._m[index] += value;
        this._markAsUpdated();
        return this;
    };
    /**
     * mutiply the specified position in the current Matrix by a value
     * @param index the index of the value within the matrix. between 0 and 15.
     * @param value the value to be added
     * @returns the current updated matrix
     */
    Matrix.prototype.multiplyAtIndex = function (index, value) {
        this._m[index] *= value;
        this._markAsUpdated();
        return this;
    };
    /**
     * Inserts the translation vector (using 3 floats) in the current matrix
     * @param x defines the 1st component of the translation
     * @param y defines the 2nd component of the translation
     * @param z defines the 3rd component of the translation
     * @returns the current updated matrix
     */
    Matrix.prototype.setTranslationFromFloats = function (x, y, z) {
        this._m[12] = x;
        this._m[13] = y;
        this._m[14] = z;
        this._markAsUpdated();
        return this;
    };
    /**
     * Adds the translation vector (using 3 floats) in the current matrix
     * @param x defines the 1st component of the translation
     * @param y defines the 2nd component of the translation
     * @param z defines the 3rd component of the translation
     * @returns the current updated matrix
     */
    Matrix.prototype.addTranslationFromFloats = function (x, y, z) {
        this._m[12] += x;
        this._m[13] += y;
        this._m[14] += z;
        this._markAsUpdated();
        return this;
    };
    /**
     * Inserts the translation vector in the current matrix
     * @param vector3 defines the translation to insert
     * @returns the current updated matrix
     */
    Matrix.prototype.setTranslation = function (vector3) {
        return this.setTranslationFromFloats(vector3.x, vector3.y, vector3.z);
    };
    /**
     * Gets the translation value of the current matrix
     * @returns a new Vector3 as the extracted translation from the matrix
     */
    Matrix.prototype.getTranslation = function () {
        return new Vector3(this._m[12], this._m[13], this._m[14]);
    };
    /**
     * Fill a Vector3 with the extracted translation from the matrix
     * @param result defines the Vector3 where to store the translation
     * @returns the current matrix
     */
    Matrix.prototype.getTranslationToRef = function (result) {
        result.x = this._m[12];
        result.y = this._m[13];
        result.z = this._m[14];
        return this;
    };
    /**
     * Remove rotation and scaling part from the matrix
     * @returns the updated matrix
     */
    Matrix.prototype.removeRotationAndScaling = function () {
        var m = this.m;
        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, m[12], m[13], m[14], m[15], this);
        this._updateIdentityStatus(m[12] === 0 && m[13] === 0 && m[14] === 0 && m[15] === 1);
        return this;
    };
    /**
     * Multiply two matrices
     * @param other defines the second operand
     * @returns a new matrix set with the multiplication result of the current Matrix and the given one
     */
    Matrix.prototype.multiply = function (other) {
        var result = new Matrix();
        this.multiplyToRef(other, result);
        return result;
    };
    /**
     * Copy the current matrix from the given one
     * @param other defines the source matrix
     * @returns the current updated matrix
     */
    Matrix.prototype.copyFrom = function (other) {
        other.copyToArray(this._m);
        var o = other;
        this._updateIdentityStatus(o._isIdentity, o._isIdentityDirty, o._isIdentity3x2, o._isIdentity3x2Dirty);
        return this;
    };
    /**
     * Populates the given array from the starting index with the current matrix values
     * @param array defines the target array
     * @param offset defines the offset in the target array where to start storing values
     * @returns the current matrix
     */
    Matrix.prototype.copyToArray = function (array, offset) {
        if (offset === void 0) { offset = 0; }
        for (var index = 0; index < 16; index++) {
            array[offset + index] = this._m[index];
        }
        return this;
    };
    /**
     * Sets the given matrix "result" with the multiplication result of the current Matrix and the given one
     * @param other defines the second operand
     * @param result defines the matrix where to store the multiplication
     * @returns the current matrix
     */
    Matrix.prototype.multiplyToRef = function (other, result) {
        if (this._isIdentity) {
            result.copyFrom(other);
            return this;
        }
        if (other._isIdentity) {
            result.copyFrom(this);
            return this;
        }
        this.multiplyToArray(other, result._m, 0);
        result._markAsUpdated();
        return this;
    };
    /**
     * Sets the Float32Array "result" from the given index "offset" with the multiplication of the current matrix and the given one
     * @param other defines the second operand
     * @param result defines the array where to store the multiplication
     * @param offset defines the offset in the target array where to start storing values
     * @returns the current matrix
     */
    Matrix.prototype.multiplyToArray = function (other, result, offset) {
        var m = this._m;
        var otherM = other.m;
        var tm0 = m[0], tm1 = m[1], tm2 = m[2], tm3 = m[3];
        var tm4 = m[4], tm5 = m[5], tm6 = m[6], tm7 = m[7];
        var tm8 = m[8], tm9 = m[9], tm10 = m[10], tm11 = m[11];
        var tm12 = m[12], tm13 = m[13], tm14 = m[14], tm15 = m[15];
        var om0 = otherM[0], om1 = otherM[1], om2 = otherM[2], om3 = otherM[3];
        var om4 = otherM[4], om5 = otherM[5], om6 = otherM[6], om7 = otherM[7];
        var om8 = otherM[8], om9 = otherM[9], om10 = otherM[10], om11 = otherM[11];
        var om12 = otherM[12], om13 = otherM[13], om14 = otherM[14], om15 = otherM[15];
        result[offset] = tm0 * om0 + tm1 * om4 + tm2 * om8 + tm3 * om12;
        result[offset + 1] = tm0 * om1 + tm1 * om5 + tm2 * om9 + tm3 * om13;
        result[offset + 2] = tm0 * om2 + tm1 * om6 + tm2 * om10 + tm3 * om14;
        result[offset + 3] = tm0 * om3 + tm1 * om7 + tm2 * om11 + tm3 * om15;
        result[offset + 4] = tm4 * om0 + tm5 * om4 + tm6 * om8 + tm7 * om12;
        result[offset + 5] = tm4 * om1 + tm5 * om5 + tm6 * om9 + tm7 * om13;
        result[offset + 6] = tm4 * om2 + tm5 * om6 + tm6 * om10 + tm7 * om14;
        result[offset + 7] = tm4 * om3 + tm5 * om7 + tm6 * om11 + tm7 * om15;
        result[offset + 8] = tm8 * om0 + tm9 * om4 + tm10 * om8 + tm11 * om12;
        result[offset + 9] = tm8 * om1 + tm9 * om5 + tm10 * om9 + tm11 * om13;
        result[offset + 10] = tm8 * om2 + tm9 * om6 + tm10 * om10 + tm11 * om14;
        result[offset + 11] = tm8 * om3 + tm9 * om7 + tm10 * om11 + tm11 * om15;
        result[offset + 12] = tm12 * om0 + tm13 * om4 + tm14 * om8 + tm15 * om12;
        result[offset + 13] = tm12 * om1 + tm13 * om5 + tm14 * om9 + tm15 * om13;
        result[offset + 14] = tm12 * om2 + tm13 * om6 + tm14 * om10 + tm15 * om14;
        result[offset + 15] = tm12 * om3 + tm13 * om7 + tm14 * om11 + tm15 * om15;
        return this;
    };
    /**
     * Check equality between this matrix and a second one
     * @param value defines the second matrix to compare
     * @returns true is the current matrix and the given one values are strictly equal
     */
    Matrix.prototype.equals = function (value) {
        var other = value;
        if (!other) {
            return false;
        }
        if (this._isIdentity || other._isIdentity) {
            if (!this._isIdentityDirty && !other._isIdentityDirty) {
                return this._isIdentity && other._isIdentity;
            }
        }
        var m = this.m;
        var om = other.m;
        return (m[0] === om[0] && m[1] === om[1] && m[2] === om[2] && m[3] === om[3] &&
            m[4] === om[4] && m[5] === om[5] && m[6] === om[6] && m[7] === om[7] &&
            m[8] === om[8] && m[9] === om[9] && m[10] === om[10] && m[11] === om[11] &&
            m[12] === om[12] && m[13] === om[13] && m[14] === om[14] && m[15] === om[15]);
    };
    /**
     * Clone the current matrix
     * @returns a new matrix from the current matrix
     */
    Matrix.prototype.clone = function () {
        var matrix = new Matrix();
        matrix.copyFrom(this);
        return matrix;
    };
    /**
     * Returns the name of the current matrix class
     * @returns the string "Matrix"
     */
    Matrix.prototype.getClassName = function () {
        return "Matrix";
    };
    /**
     * Gets the hash code of the current matrix
     * @returns the hash code
     */
    Matrix.prototype.getHashCode = function () {
        var hash = this._m[0] | 0;
        for (var i = 1; i < 16; i++) {
            hash = (hash * 397) ^ (this._m[i] | 0);
        }
        return hash;
    };
    /**
     * Decomposes the current Matrix into a translation, rotation and scaling components
     * @param scale defines the scale vector3 given as a reference to update
     * @param rotation defines the rotation quaternion given as a reference to update
     * @param translation defines the translation vector3 given as a reference to update
     * @returns true if operation was successful
     */
    Matrix.prototype.decompose = function (scale, rotation, translation) {
        if (this._isIdentity) {
            if (translation) {
                translation.setAll(0);
            }
            if (scale) {
                scale.setAll(1);
            }
            if (rotation) {
                rotation.copyFromFloats(0, 0, 0, 1);
            }
            return true;
        }
        var m = this._m;
        if (translation) {
            translation.copyFromFloats(m[12], m[13], m[14]);
        }
        scale = scale || MathTmp.Vector3[0];
        scale.x = Math.sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
        scale.y = Math.sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
        scale.z = Math.sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
        if (this.determinant() <= 0) {
            scale.y *= -1;
        }
        if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
            if (rotation) {
                rotation.copyFromFloats(0.0, 0.0, 0.0, 1.0);
            }
            return false;
        }
        if (rotation) {
            var sx = 1 / scale.x, sy = 1 / scale.y, sz = 1 / scale.z;
            Matrix.FromValuesToRef(m[0] * sx, m[1] * sx, m[2] * sx, 0.0, m[4] * sy, m[5] * sy, m[6] * sy, 0.0, m[8] * sz, m[9] * sz, m[10] * sz, 0.0, 0.0, 0.0, 0.0, 1.0, MathTmp.Matrix[0]);
            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
        }
        return true;
    };
    /**
     * Gets specific row of the matrix
     * @param index defines the number of the row to get
     * @returns the index-th row of the current matrix as a new Vector4
     */
    Matrix.prototype.getRow = function (index) {
        if (index < 0 || index > 3) {
            return null;
        }
        var i = index * 4;
        return new Vector4(this._m[i + 0], this._m[i + 1], this._m[i + 2], this._m[i + 3]);
    };
    /**
     * Sets the index-th row of the current matrix to the vector4 values
     * @param index defines the number of the row to set
     * @param row defines the target vector4
     * @returns the updated current matrix
     */
    Matrix.prototype.setRow = function (index, row) {
        return this.setRowFromFloats(index, row.x, row.y, row.z, row.w);
    };
    /**
     * Compute the transpose of the matrix
     * @returns the new transposed matrix
     */
    Matrix.prototype.transpose = function () {
        return Matrix.Transpose(this);
    };
    /**
     * Compute the transpose of the matrix and store it in a given matrix
     * @param result defines the target matrix
     * @returns the current matrix
     */
    Matrix.prototype.transposeToRef = function (result) {
        Matrix.TransposeToRef(this, result);
        return this;
    };
    /**
     * Sets the index-th row of the current matrix with the given 4 x float values
     * @param index defines the row index
     * @param x defines the x component to set
     * @param y defines the y component to set
     * @param z defines the z component to set
     * @param w defines the w component to set
     * @returns the updated current matrix
     */
    Matrix.prototype.setRowFromFloats = function (index, x, y, z, w) {
        if (index < 0 || index > 3) {
            return this;
        }
        var i = index * 4;
        this._m[i + 0] = x;
        this._m[i + 1] = y;
        this._m[i + 2] = z;
        this._m[i + 3] = w;
        this._markAsUpdated();
        return this;
    };
    /**
     * Compute a new matrix set with the current matrix values multiplied by scale (float)
     * @param scale defines the scale factor
     * @returns a new matrix
     */
    Matrix.prototype.scale = function (scale) {
        var result = new Matrix();
        this.scaleToRef(scale, result);
        return result;
    };
    /**
     * Scale the current matrix values by a factor to a given result matrix
     * @param scale defines the scale factor
     * @param result defines the matrix to store the result
     * @returns the current matrix
     */
    Matrix.prototype.scaleToRef = function (scale, result) {
        for (var index = 0; index < 16; index++) {
            result._m[index] = this._m[index] * scale;
        }
        result._markAsUpdated();
        return this;
    };
    /**
     * Scale the current matrix values by a factor and add the result to a given matrix
     * @param scale defines the scale factor
     * @param result defines the Matrix to store the result
     * @returns the current matrix
     */
    Matrix.prototype.scaleAndAddToRef = function (scale, result) {
        for (var index = 0; index < 16; index++) {
            result._m[index] += this._m[index] * scale;
        }
        result._markAsUpdated();
        return this;
    };
    /**
     * Writes to the given matrix a normal matrix, computed from this one (using values from identity matrix for fourth row and column).
     * @param ref matrix to store the result
     */
    Matrix.prototype.toNormalMatrix = function (ref) {
        var tmp = MathTmp.Matrix[0];
        this.invertToRef(tmp);
        tmp.transposeToRef(ref);
        var m = ref._m;
        Matrix.FromValuesToRef(m[0], m[1], m[2], 0.0, m[4], m[5], m[6], 0.0, m[8], m[9], m[10], 0.0, 0.0, 0.0, 0.0, 1.0, ref);
    };
    /**
     * Gets only rotation part of the current matrix
     * @returns a new matrix sets to the extracted rotation matrix from the current one
     */
    Matrix.prototype.getRotationMatrix = function () {
        var result = new Matrix();
        this.getRotationMatrixToRef(result);
        return result;
    };
    /**
     * Extracts the rotation matrix from the current one and sets it as the given "result"
     * @param result defines the target matrix to store data to
     * @returns the current matrix
     */
    Matrix.prototype.getRotationMatrixToRef = function (result) {
        var scale = MathTmp.Vector3[0];
        if (!this.decompose(scale)) {
            Matrix.IdentityToRef(result);
            return this;
        }
        var m = this._m;
        var sx = 1 / scale.x, sy = 1 / scale.y, sz = 1 / scale.z;
        Matrix.FromValuesToRef(m[0] * sx, m[1] * sx, m[2] * sx, 0.0, m[4] * sy, m[5] * sy, m[6] * sy, 0.0, m[8] * sz, m[9] * sz, m[10] * sz, 0.0, 0.0, 0.0, 0.0, 1.0, result);
        return this;
    };
    /**
     * Toggles model matrix from being right handed to left handed in place and vice versa
     */
    Matrix.prototype.toggleModelMatrixHandInPlace = function () {
        var m = this._m;
        m[2] *= -1;
        m[6] *= -1;
        m[8] *= -1;
        m[9] *= -1;
        m[14] *= -1;
        this._markAsUpdated();
    };
    /**
     * Toggles projection matrix from being right handed to left handed in place and vice versa
     */
    Matrix.prototype.toggleProjectionMatrixHandInPlace = function () {
        var m = this._m;
        m[8] *= -1;
        m[9] *= -1;
        m[10] *= -1;
        m[11] *= -1;
        this._markAsUpdated();
    };
    // Statics
    /**
     * Creates a matrix from an array
     * @param array defines the source array
     * @param offset defines an offset in the source array
     * @returns a new Matrix set from the starting index of the given array
     */
    Matrix.FromArray = function (array, offset) {
        if (offset === void 0) { offset = 0; }
        var result = new Matrix();
        Matrix.FromArrayToRef(array, offset, result);
        return result;
    };
    /**
     * Copy the content of an array into a given matrix
     * @param array defines the source array
     * @param offset defines an offset in the source array
     * @param result defines the target matrix
     */
    Matrix.FromArrayToRef = function (array, offset, result) {
        for (var index = 0; index < 16; index++) {
            result._m[index] = array[index + offset];
        }
        result._markAsUpdated();
    };
    /**
     * Stores an array into a matrix after having multiplied each component by a given factor
     * @param array defines the source array
     * @param offset defines the offset in the source array
     * @param scale defines the scaling factor
     * @param result defines the target matrix
     */
    Matrix.FromFloat32ArrayToRefScaled = function (array, offset, scale, result) {
        for (var index = 0; index < 16; index++) {
            result._m[index] = array[index + offset] * scale;
        }
        result._markAsUpdated();
    };
    Object.defineProperty(Matrix, "IdentityReadOnly", {
        /**
         * Gets an identity matrix that must not be updated
         */
        get: function () {
            return Matrix._identityReadOnly;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Stores a list of values (16) inside a given matrix
     * @param initialM11 defines 1st value of 1st row
     * @param initialM12 defines 2nd value of 1st row
     * @param initialM13 defines 3rd value of 1st row
     * @param initialM14 defines 4th value of 1st row
     * @param initialM21 defines 1st value of 2nd row
     * @param initialM22 defines 2nd value of 2nd row
     * @param initialM23 defines 3rd value of 2nd row
     * @param initialM24 defines 4th value of 2nd row
     * @param initialM31 defines 1st value of 3rd row
     * @param initialM32 defines 2nd value of 3rd row
     * @param initialM33 defines 3rd value of 3rd row
     * @param initialM34 defines 4th value of 3rd row
     * @param initialM41 defines 1st value of 4th row
     * @param initialM42 defines 2nd value of 4th row
     * @param initialM43 defines 3rd value of 4th row
     * @param initialM44 defines 4th value of 4th row
     * @param result defines the target matrix
     */
    Matrix.FromValuesToRef = function (initialM11, initialM12, initialM13, initialM14, initialM21, initialM22, initialM23, initialM24, initialM31, initialM32, initialM33, initialM34, initialM41, initialM42, initialM43, initialM44, result) {
        var m = result._m;
        m[0] = initialM11;
        m[1] = initialM12;
        m[2] = initialM13;
        m[3] = initialM14;
        m[4] = initialM21;
        m[5] = initialM22;
        m[6] = initialM23;
        m[7] = initialM24;
        m[8] = initialM31;
        m[9] = initialM32;
        m[10] = initialM33;
        m[11] = initialM34;
        m[12] = initialM41;
        m[13] = initialM42;
        m[14] = initialM43;
        m[15] = initialM44;
        result._markAsUpdated();
    };
    /**
     * Creates new matrix from a list of values (16)
     * @param initialM11 defines 1st value of 1st row
     * @param initialM12 defines 2nd value of 1st row
     * @param initialM13 defines 3rd value of 1st row
     * @param initialM14 defines 4th value of 1st row
     * @param initialM21 defines 1st value of 2nd row
     * @param initialM22 defines 2nd value of 2nd row
     * @param initialM23 defines 3rd value of 2nd row
     * @param initialM24 defines 4th value of 2nd row
     * @param initialM31 defines 1st value of 3rd row
     * @param initialM32 defines 2nd value of 3rd row
     * @param initialM33 defines 3rd value of 3rd row
     * @param initialM34 defines 4th value of 3rd row
     * @param initialM41 defines 1st value of 4th row
     * @param initialM42 defines 2nd value of 4th row
     * @param initialM43 defines 3rd value of 4th row
     * @param initialM44 defines 4th value of 4th row
     * @returns the new matrix
     */
    Matrix.FromValues = function (initialM11, initialM12, initialM13, initialM14, initialM21, initialM22, initialM23, initialM24, initialM31, initialM32, initialM33, initialM34, initialM41, initialM42, initialM43, initialM44) {
        var result = new Matrix();
        var m = result._m;
        m[0] = initialM11;
        m[1] = initialM12;
        m[2] = initialM13;
        m[3] = initialM14;
        m[4] = initialM21;
        m[5] = initialM22;
        m[6] = initialM23;
        m[7] = initialM24;
        m[8] = initialM31;
        m[9] = initialM32;
        m[10] = initialM33;
        m[11] = initialM34;
        m[12] = initialM41;
        m[13] = initialM42;
        m[14] = initialM43;
        m[15] = initialM44;
        result._markAsUpdated();
        return result;
    };
    /**
     * Creates a new matrix composed by merging scale (vector3), rotation (quaternion) and translation (vector3)
     * @param scale defines the scale vector3
     * @param rotation defines the rotation quaternion
     * @param translation defines the translation vector3
     * @returns a new matrix
     */
    Matrix.Compose = function (scale, rotation, translation) {
        var result = new Matrix();
        Matrix.ComposeToRef(scale, rotation, translation, result);
        return result;
    };
    /**
     * Sets a matrix to a value composed by merging scale (vector3), rotation (quaternion) and translation (vector3)
     * @param scale defines the scale vector3
     * @param rotation defines the rotation quaternion
     * @param translation defines the translation vector3
     * @param result defines the target matrix
     */
    Matrix.ComposeToRef = function (scale, rotation, translation, result) {
        var m = result._m;
        var x = rotation.x, y = rotation.y, z = rotation.z, w = rotation.w;
        var x2 = x + x, y2 = y + y, z2 = z + z;
        var xx = x * x2, xy = x * y2, xz = x * z2;
        var yy = y * y2, yz = y * z2, zz = z * z2;
        var wx = w * x2, wy = w * y2, wz = w * z2;
        var sx = scale.x, sy = scale.y, sz = scale.z;
        m[0] = (1 - (yy + zz)) * sx;
        m[1] = (xy + wz) * sx;
        m[2] = (xz - wy) * sx;
        m[3] = 0;
        m[4] = (xy - wz) * sy;
        m[5] = (1 - (xx + zz)) * sy;
        m[6] = (yz + wx) * sy;
        m[7] = 0;
        m[8] = (xz + wy) * sz;
        m[9] = (yz - wx) * sz;
        m[10] = (1 - (xx + yy)) * sz;
        m[11] = 0;
        m[12] = translation.x;
        m[13] = translation.y;
        m[14] = translation.z;
        m[15] = 1;
        result._markAsUpdated();
    };
    /**
     * Creates a new identity matrix
     * @returns a new identity matrix
     */
    Matrix.Identity = function () {
        var identity = Matrix.FromValues(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
        identity._updateIdentityStatus(true);
        return identity;
    };
    /**
     * Creates a new identity matrix and stores the result in a given matrix
     * @param result defines the target matrix
     */
    Matrix.IdentityToRef = function (result) {
        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, result);
        result._updateIdentityStatus(true);
    };
    /**
     * Creates a new zero matrix
     * @returns a new zero matrix
     */
    Matrix.Zero = function () {
        var zero = Matrix.FromValues(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
        zero._updateIdentityStatus(false);
        return zero;
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the X axis
     * @param angle defines the angle (in radians) to use
     * @return the new matrix
     */
    Matrix.RotationX = function (angle) {
        var result = new Matrix();
        Matrix.RotationXToRef(angle, result);
        return result;
    };
    /**
     * Creates a new matrix as the invert of a given matrix
     * @param source defines the source matrix
     * @returns the new matrix
     */
    Matrix.Invert = function (source) {
        var result = new Matrix();
        source.invertToRef(result);
        return result;
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the X axis and stores it in a given matrix
     * @param angle defines the angle (in radians) to use
     * @param result defines the target matrix
     */
    Matrix.RotationXToRef = function (angle, result) {
        var s = Math.sin(angle);
        var c = Math.cos(angle);
        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, c, s, 0.0, 0.0, -s, c, 0.0, 0.0, 0.0, 0.0, 1.0, result);
        result._updateIdentityStatus(c === 1 && s === 0);
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the Y axis
     * @param angle defines the angle (in radians) to use
     * @return the new matrix
     */
    Matrix.RotationY = function (angle) {
        var result = new Matrix();
        Matrix.RotationYToRef(angle, result);
        return result;
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the Y axis and stores it in a given matrix
     * @param angle defines the angle (in radians) to use
     * @param result defines the target matrix
     */
    Matrix.RotationYToRef = function (angle, result) {
        var s = Math.sin(angle);
        var c = Math.cos(angle);
        Matrix.FromValuesToRef(c, 0.0, -s, 0.0, 0.0, 1.0, 0.0, 0.0, s, 0.0, c, 0.0, 0.0, 0.0, 0.0, 1.0, result);
        result._updateIdentityStatus(c === 1 && s === 0);
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the Z axis
     * @param angle defines the angle (in radians) to use
     * @return the new matrix
     */
    Matrix.RotationZ = function (angle) {
        var result = new Matrix();
        Matrix.RotationZToRef(angle, result);
        return result;
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the Z axis and stores it in a given matrix
     * @param angle defines the angle (in radians) to use
     * @param result defines the target matrix
     */
    Matrix.RotationZToRef = function (angle, result) {
        var s = Math.sin(angle);
        var c = Math.cos(angle);
        Matrix.FromValuesToRef(c, s, 0.0, 0.0, -s, c, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, result);
        result._updateIdentityStatus(c === 1 && s === 0);
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the given axis
     * @param axis defines the axis to use
     * @param angle defines the angle (in radians) to use
     * @return the new matrix
     */
    Matrix.RotationAxis = function (axis, angle) {
        var result = new Matrix();
        Matrix.RotationAxisToRef(axis, angle, result);
        return result;
    };
    /**
     * Creates a new rotation matrix for "angle" radians around the given axis and stores it in a given matrix
     * @param axis defines the axis to use
     * @param angle defines the angle (in radians) to use
     * @param result defines the target matrix
     */
    Matrix.RotationAxisToRef = function (axis, angle, result) {
        var s = Math.sin(-angle);
        var c = Math.cos(-angle);
        var c1 = 1 - c;
        axis.normalize();
        var m = result._m;
        m[0] = (axis.x * axis.x) * c1 + c;
        m[1] = (axis.x * axis.y) * c1 - (axis.z * s);
        m[2] = (axis.x * axis.z) * c1 + (axis.y * s);
        m[3] = 0.0;
        m[4] = (axis.y * axis.x) * c1 + (axis.z * s);
        m[5] = (axis.y * axis.y) * c1 + c;
        m[6] = (axis.y * axis.z) * c1 - (axis.x * s);
        m[7] = 0.0;
        m[8] = (axis.z * axis.x) * c1 - (axis.y * s);
        m[9] = (axis.z * axis.y) * c1 + (axis.x * s);
        m[10] = (axis.z * axis.z) * c1 + c;
        m[11] = 0.0;
        m[12] = 0.0;
        m[13] = 0.0;
        m[14] = 0.0;
        m[15] = 1.0;
        result._markAsUpdated();
    };
    /**
     * Takes normalised vectors and returns a rotation matrix to align "from" with "to".
     * Taken from http://www.iquilezles.org/www/articles/noacos/noacos.htm
     * @param from defines the vector to align
     * @param to defines the vector to align to
     * @param result defines the target matrix
     */
    Matrix.RotationAlignToRef = function (from, to, result) {
        var v = Vector3.Cross(to, from);
        var c = Vector3.Dot(to, from);
        var k = 1 / (1 + c);
        var m = result._m;
        m[0] = v.x * v.x * k + c;
        m[1] = v.y * v.x * k - v.z;
        m[2] = v.z * v.x * k + v.y;
        m[3] = 0;
        m[4] = v.x * v.y * k + v.z;
        m[5] = v.y * v.y * k + c;
        m[6] = v.z * v.y * k - v.x;
        m[7] = 0;
        m[8] = v.x * v.z * k - v.y;
        m[9] = v.y * v.z * k + v.x;
        m[10] = v.z * v.z * k + c;
        m[11] = 0;
        m[12] = 0;
        m[13] = 0;
        m[14] = 0;
        m[15] = 1;
        result._markAsUpdated();
    };
    /**
     * Creates a rotation matrix
     * @param yaw defines the yaw angle in radians (Y axis)
     * @param pitch defines the pitch angle in radians (X axis)
     * @param roll defines the roll angle in radians (X axis)
     * @returns the new rotation matrix
     */
    Matrix.RotationYawPitchRoll = function (yaw, pitch, roll) {
        var result = new Matrix();
        Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, result);
        return result;
    };
    /**
     * Creates a rotation matrix and stores it in a given matrix
     * @param yaw defines the yaw angle in radians (Y axis)
     * @param pitch defines the pitch angle in radians (X axis)
     * @param roll defines the roll angle in radians (X axis)
     * @param result defines the target matrix
     */
    Matrix.RotationYawPitchRollToRef = function (yaw, pitch, roll, result) {
        Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, MathTmp.Quaternion[0]);
        MathTmp.Quaternion[0].toRotationMatrix(result);
    };
    /**
     * Creates a scaling matrix
     * @param x defines the scale factor on X axis
     * @param y defines the scale factor on Y axis
     * @param z defines the scale factor on Z axis
     * @returns the new matrix
     */
    Matrix.Scaling = function (x, y, z) {
        var result = new Matrix();
        Matrix.ScalingToRef(x, y, z, result);
        return result;
    };
    /**
     * Creates a scaling matrix and stores it in a given matrix
     * @param x defines the scale factor on X axis
     * @param y defines the scale factor on Y axis
     * @param z defines the scale factor on Z axis
     * @param result defines the target matrix
     */
    Matrix.ScalingToRef = function (x, y, z, result) {
        Matrix.FromValuesToRef(x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, 1.0, result);
        result._updateIdentityStatus(x === 1 && y === 1 && z === 1);
    };
    /**
     * Creates a translation matrix
     * @param x defines the translation on X axis
     * @param y defines the translation on Y axis
     * @param z defines the translationon Z axis
     * @returns the new matrix
     */
    Matrix.Translation = function (x, y, z) {
        var result = new Matrix();
        Matrix.TranslationToRef(x, y, z, result);
        return result;
    };
    /**
     * Creates a translation matrix and stores it in a given matrix
     * @param x defines the translation on X axis
     * @param y defines the translation on Y axis
     * @param z defines the translationon Z axis
     * @param result defines the target matrix
     */
    Matrix.TranslationToRef = function (x, y, z, result) {
        Matrix.FromValuesToRef(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, x, y, z, 1.0, result);
        result._updateIdentityStatus(x === 0 && y === 0 && z === 0);
    };
    /**
     * Returns a new Matrix whose values are the interpolated values for "gradient" (float) between the ones of the matrices "startValue" and "endValue".
     * @param startValue defines the start value
     * @param endValue defines the end value
     * @param gradient defines the gradient factor
     * @returns the new matrix
     */
    Matrix.Lerp = function (startValue, endValue, gradient) {
        var result = new Matrix();
        Matrix.LerpToRef(startValue, endValue, gradient, result);
        return result;
    };
    /**
     * Set the given matrix "result" as the interpolated values for "gradient" (float) between the ones of the matrices "startValue" and "endValue".
     * @param startValue defines the start value
     * @param endValue defines the end value
     * @param gradient defines the gradient factor
     * @param result defines the Matrix object where to store data
     */
    Matrix.LerpToRef = function (startValue, endValue, gradient, result) {
        var resultM = result._m;
        var startM = startValue.m;
        var endM = endValue.m;
        for (var index = 0; index < 16; index++) {
            resultM[index] = startM[index] * (1.0 - gradient) + endM[index] * gradient;
        }
        result._markAsUpdated();
    };
    /**
     * Builds a new matrix whose values are computed by:
     * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
     * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
     * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
     * @param startValue defines the first matrix
     * @param endValue defines the second matrix
     * @param gradient defines the gradient between the two matrices
     * @returns the new matrix
     */
    Matrix.DecomposeLerp = function (startValue, endValue, gradient) {
        var result = new Matrix();
        Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
        return result;
    };
    /**
     * Update a matrix to values which are computed by:
     * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
     * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
     * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
     * @param startValue defines the first matrix
     * @param endValue defines the second matrix
     * @param gradient defines the gradient between the two matrices
     * @param result defines the target matrix
     */
    Matrix.DecomposeLerpToRef = function (startValue, endValue, gradient, result) {
        var startScale = MathTmp.Vector3[0];
        var startRotation = MathTmp.Quaternion[0];
        var startTranslation = MathTmp.Vector3[1];
        startValue.decompose(startScale, startRotation, startTranslation);
        var endScale = MathTmp.Vector3[2];
        var endRotation = MathTmp.Quaternion[1];
        var endTranslation = MathTmp.Vector3[3];
        endValue.decompose(endScale, endRotation, endTranslation);
        var resultScale = MathTmp.Vector3[4];
        Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
        var resultRotation = MathTmp.Quaternion[2];
        Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
        var resultTranslation = MathTmp.Vector3[5];
        Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
        Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
    };
    /**
     * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
     * This function works in left handed mode
     * @param eye defines the final position of the entity
     * @param target defines where the entity should look at
     * @param up defines the up vector for the entity
     * @returns the new matrix
     */
    Matrix.LookAtLH = function (eye, target, up) {
        var result = new Matrix();
        Matrix.LookAtLHToRef(eye, target, up, result);
        return result;
    };
    /**
     * Sets the given "result" Matrix to a rotation matrix used to rotate an entity so that it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up".
     * This function works in left handed mode
     * @param eye defines the final position of the entity
     * @param target defines where the entity should look at
     * @param up defines the up vector for the entity
     * @param result defines the target matrix
     */
    Matrix.LookAtLHToRef = function (eye, target, up, result) {
        var xAxis = MathTmp.Vector3[0];
        var yAxis = MathTmp.Vector3[1];
        var zAxis = MathTmp.Vector3[2];
        // Z axis
        target.subtractToRef(eye, zAxis);
        zAxis.normalize();
        // X axis
        Vector3.CrossToRef(up, zAxis, xAxis);
        var xSquareLength = xAxis.lengthSquared();
        if (xSquareLength === 0) {
            xAxis.x = 1.0;
        }
        else {
            xAxis.normalizeFromLength(Math.sqrt(xSquareLength));
        }
        // Y axis
        Vector3.CrossToRef(zAxis, xAxis, yAxis);
        yAxis.normalize();
        // Eye angles
        var ex = -Vector3.Dot(xAxis, eye);
        var ey = -Vector3.Dot(yAxis, eye);
        var ez = -Vector3.Dot(zAxis, eye);
        Matrix.FromValuesToRef(xAxis.x, yAxis.x, zAxis.x, 0.0, xAxis.y, yAxis.y, zAxis.y, 0.0, xAxis.z, yAxis.z, zAxis.z, 0.0, ex, ey, ez, 1.0, result);
    };
    /**
     * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
     * This function works in right handed mode
     * @param eye defines the final position of the entity
     * @param target defines where the entity should look at
     * @param up defines the up vector for the entity
     * @returns the new matrix
     */
    Matrix.LookAtRH = function (eye, target, up) {
        var result = new Matrix();
        Matrix.LookAtRHToRef(eye, target, up, result);
        return result;
    };
    /**
     * Sets the given "result" Matrix to a rotation matrix used to rotate an entity so that it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up".
     * This function works in right handed mode
     * @param eye defines the final position of the entity
     * @param target defines where the entity should look at
     * @param up defines the up vector for the entity
     * @param result defines the target matrix
     */
    Matrix.LookAtRHToRef = function (eye, target, up, result) {
        var xAxis = MathTmp.Vector3[0];
        var yAxis = MathTmp.Vector3[1];
        var zAxis = MathTmp.Vector3[2];
        // Z axis
        eye.subtractToRef(target, zAxis);
        zAxis.normalize();
        // X axis
        Vector3.CrossToRef(up, zAxis, xAxis);
        var xSquareLength = xAxis.lengthSquared();
        if (xSquareLength === 0) {
            xAxis.x = 1.0;
        }
        else {
            xAxis.normalizeFromLength(Math.sqrt(xSquareLength));
        }
        // Y axis
        Vector3.CrossToRef(zAxis, xAxis, yAxis);
        yAxis.normalize();
        // Eye angles
        var ex = -Vector3.Dot(xAxis, eye);
        var ey = -Vector3.Dot(yAxis, eye);
        var ez = -Vector3.Dot(zAxis, eye);
        Matrix.FromValuesToRef(xAxis.x, yAxis.x, zAxis.x, 0.0, xAxis.y, yAxis.y, zAxis.y, 0.0, xAxis.z, yAxis.z, zAxis.z, 0.0, ex, ey, ez, 1.0, result);
    };
    /**
     * Create a left-handed orthographic projection matrix
     * @param width defines the viewport width
     * @param height defines the viewport height
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @returns a new matrix as a left-handed orthographic projection matrix
     */
    Matrix.OrthoLH = function (width, height, znear, zfar) {
        var matrix = new Matrix();
        Matrix.OrthoLHToRef(width, height, znear, zfar, matrix);
        return matrix;
    };
    /**
     * Store a left-handed orthographic projection to a given matrix
     * @param width defines the viewport width
     * @param height defines the viewport height
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @param result defines the target matrix
     */
    Matrix.OrthoLHToRef = function (width, height, znear, zfar, result) {
        var n = znear;
        var f = zfar;
        var a = 2.0 / width;
        var b = 2.0 / height;
        var c = 2.0 / (f - n);
        var d = -(f + n) / (f - n);
        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 0.0, 0.0, 0.0, d, 1.0, result);
        result._updateIdentityStatus(a === 1 && b === 1 && c === 1 && d === 0);
    };
    /**
     * Create a left-handed orthographic projection matrix
     * @param left defines the viewport left coordinate
     * @param right defines the viewport right coordinate
     * @param bottom defines the viewport bottom coordinate
     * @param top defines the viewport top coordinate
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @returns a new matrix as a left-handed orthographic projection matrix
     */
    Matrix.OrthoOffCenterLH = function (left, right, bottom, top, znear, zfar) {
        var matrix = new Matrix();
        Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, matrix);
        return matrix;
    };
    /**
     * Stores a left-handed orthographic projection into a given matrix
     * @param left defines the viewport left coordinate
     * @param right defines the viewport right coordinate
     * @param bottom defines the viewport bottom coordinate
     * @param top defines the viewport top coordinate
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @param result defines the target matrix
     */
    Matrix.OrthoOffCenterLHToRef = function (left, right, bottom, top, znear, zfar, result) {
        var n = znear;
        var f = zfar;
        var a = 2.0 / (right - left);
        var b = 2.0 / (top - bottom);
        var c = 2.0 / (f - n);
        var d = -(f + n) / (f - n);
        var i0 = (left + right) / (left - right);
        var i1 = (top + bottom) / (bottom - top);
        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 0.0, i0, i1, d, 1.0, result);
        result._markAsUpdated();
    };
    /**
     * Creates a right-handed orthographic projection matrix
     * @param left defines the viewport left coordinate
     * @param right defines the viewport right coordinate
     * @param bottom defines the viewport bottom coordinate
     * @param top defines the viewport top coordinate
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @returns a new matrix as a right-handed orthographic projection matrix
     */
    Matrix.OrthoOffCenterRH = function (left, right, bottom, top, znear, zfar) {
        var matrix = new Matrix();
        Matrix.OrthoOffCenterRHToRef(left, right, bottom, top, znear, zfar, matrix);
        return matrix;
    };
    /**
     * Stores a right-handed orthographic projection into a given matrix
     * @param left defines the viewport left coordinate
     * @param right defines the viewport right coordinate
     * @param bottom defines the viewport bottom coordinate
     * @param top defines the viewport top coordinate
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @param result defines the target matrix
     */
    Matrix.OrthoOffCenterRHToRef = function (left, right, bottom, top, znear, zfar, result) {
        Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, result);
        result._m[10] *= -1; // No need to call _markAsUpdated as previous function already called it and let _isIdentityDirty to true
    };
    /**
     * Creates a left-handed perspective projection matrix
     * @param width defines the viewport width
     * @param height defines the viewport height
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @returns a new matrix as a left-handed perspective projection matrix
     */
    Matrix.PerspectiveLH = function (width, height, znear, zfar) {
        var matrix = new Matrix();
        var n = znear;
        var f = zfar;
        var a = 2.0 * n / width;
        var b = 2.0 * n / height;
        var c = (f + n) / (f - n);
        var d = -2.0 * f * n / (f - n);
        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 1.0, 0.0, 0.0, d, 0.0, matrix);
        matrix._updateIdentityStatus(false);
        return matrix;
    };
    /**
     * Creates a left-handed perspective projection matrix
     * @param fov defines the horizontal field of view
     * @param aspect defines the aspect ratio
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @returns a new matrix as a left-handed perspective projection matrix
     */
    Matrix.PerspectiveFovLH = function (fov, aspect, znear, zfar) {
        var matrix = new Matrix();
        Matrix.PerspectiveFovLHToRef(fov, aspect, znear, zfar, matrix);
        return matrix;
    };
    /**
     * Stores a left-handed perspective projection into a given matrix
     * @param fov defines the horizontal field of view
     * @param aspect defines the aspect ratio
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @param result defines the target matrix
     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally
     */
    Matrix.PerspectiveFovLHToRef = function (fov, aspect, znear, zfar, result, isVerticalFovFixed) {
        if (isVerticalFovFixed === void 0) { isVerticalFovFixed = true; }
        var n = znear;
        var f = zfar;
        var t = 1.0 / (Math.tan(fov * 0.5));
        var a = isVerticalFovFixed ? (t / aspect) : t;
        var b = isVerticalFovFixed ? t : (t * aspect);
        var c = (f + n) / (f - n);
        var d = -2.0 * f * n / (f - n);
        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, 1.0, 0.0, 0.0, d, 0.0, result);
        result._updateIdentityStatus(false);
    };
    /**
     * Creates a right-handed perspective projection matrix
     * @param fov defines the horizontal field of view
     * @param aspect defines the aspect ratio
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @returns a new matrix as a right-handed perspective projection matrix
     */
    Matrix.PerspectiveFovRH = function (fov, aspect, znear, zfar) {
        var matrix = new Matrix();
        Matrix.PerspectiveFovRHToRef(fov, aspect, znear, zfar, matrix);
        return matrix;
    };
    /**
     * Stores a right-handed perspective projection into a given matrix
     * @param fov defines the horizontal field of view
     * @param aspect defines the aspect ratio
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @param result defines the target matrix
     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally
     */
    Matrix.PerspectiveFovRHToRef = function (fov, aspect, znear, zfar, result, isVerticalFovFixed) {
        //alternatively this could be expressed as:
        //    m = PerspectiveFovLHToRef
        //    m[10] *= -1.0;
        //    m[11] *= -1.0;
        if (isVerticalFovFixed === void 0) { isVerticalFovFixed = true; }
        var n = znear;
        var f = zfar;
        var t = 1.0 / (Math.tan(fov * 0.5));
        var a = isVerticalFovFixed ? (t / aspect) : t;
        var b = isVerticalFovFixed ? t : (t * aspect);
        var c = -(f + n) / (f - n);
        var d = -2 * f * n / (f - n);
        Matrix.FromValuesToRef(a, 0.0, 0.0, 0.0, 0.0, b, 0.0, 0.0, 0.0, 0.0, c, -1.0, 0.0, 0.0, d, 0.0, result);
        result._updateIdentityStatus(false);
    };
    /**
     * Stores a perspective projection for WebVR info a given matrix
     * @param fov defines the field of view
     * @param znear defines the near clip plane
     * @param zfar defines the far clip plane
     * @param result defines the target matrix
     * @param rightHanded defines if the matrix must be in right-handed mode (false by default)
     */
    Matrix.PerspectiveFovWebVRToRef = function (fov, znear, zfar, result, rightHanded) {
        if (rightHanded === void 0) { rightHanded = false; }
        var rightHandedFactor = rightHanded ? -1 : 1;
        var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);
        var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);
        var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);
        var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);
        var xScale = 2.0 / (leftTan + rightTan);
        var yScale = 2.0 / (upTan + downTan);
        var m = result._m;
        m[0] = xScale;
        m[1] = m[2] = m[3] = m[4] = 0.0;
        m[5] = yScale;
        m[6] = m[7] = 0.0;
        m[8] = ((leftTan - rightTan) * xScale * 0.5);
        m[9] = -((upTan - downTan) * yScale * 0.5);
        m[10] = -zfar / (znear - zfar);
        m[11] = 1.0 * rightHandedFactor;
        m[12] = m[13] = m[15] = 0.0;
        m[14] = -(2.0 * zfar * znear) / (zfar - znear);
        result._markAsUpdated();
    };
    /**
     * Computes a complete transformation matrix
     * @param viewport defines the viewport to use
     * @param world defines the world matrix
     * @param view defines the view matrix
     * @param projection defines the projection matrix
     * @param zmin defines the near clip plane
     * @param zmax defines the far clip plane
     * @returns the transformation matrix
     */
    Matrix.GetFinalMatrix = function (viewport, world, view, projection, zmin, zmax) {
        var cw = viewport.width;
        var ch = viewport.height;
        var cx = viewport.x;
        var cy = viewport.y;
        var viewportMatrix = Matrix.FromValues(cw / 2.0, 0.0, 0.0, 0.0, 0.0, -ch / 2.0, 0.0, 0.0, 0.0, 0.0, zmax - zmin, 0.0, cx + cw / 2.0, ch / 2.0 + cy, zmin, 1.0);
        var matrix = MathTmp.Matrix[0];
        world.multiplyToRef(view, matrix);
        matrix.multiplyToRef(projection, matrix);
        return matrix.multiply(viewportMatrix);
    };
    /**
     * Extracts a 2x2 matrix from a given matrix and store the result in a Float32Array
     * @param matrix defines the matrix to use
     * @returns a new Float32Array array with 4 elements : the 2x2 matrix extracted from the given matrix
     */
    Matrix.GetAsMatrix2x2 = function (matrix) {
        var m = matrix.m;
        return new Float32Array([m[0], m[1], m[4], m[5]]);
    };
    /**
     * Extracts a 3x3 matrix from a given matrix and store the result in a Float32Array
     * @param matrix defines the matrix to use
     * @returns a new Float32Array array with 9 elements : the 3x3 matrix extracted from the given matrix
     */
    Matrix.GetAsMatrix3x3 = function (matrix) {
        var m = matrix.m;
        return new Float32Array([
            m[0], m[1], m[2],
            m[4], m[5], m[6],
            m[8], m[9], m[10]
        ]);
    };
    /**
     * Compute the transpose of a given matrix
     * @param matrix defines the matrix to transpose
     * @returns the new matrix
     */
    Matrix.Transpose = function (matrix) {
        var result = new Matrix();
        Matrix.TransposeToRef(matrix, result);
        return result;
    };
    /**
     * Compute the transpose of a matrix and store it in a target matrix
     * @param matrix defines the matrix to transpose
     * @param result defines the target matrix
     */
    Matrix.TransposeToRef = function (matrix, result) {
        var rm = result._m;
        var mm = matrix.m;
        rm[0] = mm[0];
        rm[1] = mm[4];
        rm[2] = mm[8];
        rm[3] = mm[12];
        rm[4] = mm[1];
        rm[5] = mm[5];
        rm[6] = mm[9];
        rm[7] = mm[13];
        rm[8] = mm[2];
        rm[9] = mm[6];
        rm[10] = mm[10];
        rm[11] = mm[14];
        rm[12] = mm[3];
        rm[13] = mm[7];
        rm[14] = mm[11];
        rm[15] = mm[15];
        // identity-ness does not change when transposing
        result._updateIdentityStatus(matrix._isIdentity, matrix._isIdentityDirty);
    };
    /**
     * Computes a reflection matrix from a plane
     * @param plane defines the reflection plane
     * @returns a new matrix
     */
    Matrix.Reflection = function (plane) {
        var matrix = new Matrix();
        Matrix.ReflectionToRef(plane, matrix);
        return matrix;
    };
    /**
     * Computes a reflection matrix from a plane
     * @param plane defines the reflection plane
     * @param result defines the target matrix
     */
    Matrix.ReflectionToRef = function (plane, result) {
        plane.normalize();
        var x = plane.normal.x;
        var y = plane.normal.y;
        var z = plane.normal.z;
        var temp = -2 * x;
        var temp2 = -2 * y;
        var temp3 = -2 * z;
        Matrix.FromValuesToRef(temp * x + 1, temp2 * x, temp3 * x, 0.0, temp * y, temp2 * y + 1, temp3 * y, 0.0, temp * z, temp2 * z, temp3 * z + 1, 0.0, temp * plane.d, temp2 * plane.d, temp3 * plane.d, 1.0, result);
    };
    /**
     * Sets the given matrix as a rotation matrix composed from the 3 left handed axes
     * @param xaxis defines the value of the 1st axis
     * @param yaxis defines the value of the 2nd axis
     * @param zaxis defines the value of the 3rd axis
     * @param result defines the target matrix
     */
    Matrix.FromXYZAxesToRef = function (xaxis, yaxis, zaxis, result) {
        Matrix.FromValuesToRef(xaxis.x, xaxis.y, xaxis.z, 0.0, yaxis.x, yaxis.y, yaxis.z, 0.0, zaxis.x, zaxis.y, zaxis.z, 0.0, 0.0, 0.0, 0.0, 1.0, result);
    };
    /**
     * Creates a rotation matrix from a quaternion and stores it in a target matrix
     * @param quat defines the quaternion to use
     * @param result defines the target matrix
     */
    Matrix.FromQuaternionToRef = function (quat, result) {
        var xx = quat.x * quat.x;
        var yy = quat.y * quat.y;
        var zz = quat.z * quat.z;
        var xy = quat.x * quat.y;
        var zw = quat.z * quat.w;
        var zx = quat.z * quat.x;
        var yw = quat.y * quat.w;
        var yz = quat.y * quat.z;
        var xw = quat.x * quat.w;
        result._m[0] = 1.0 - (2.0 * (yy + zz));
        result._m[1] = 2.0 * (xy + zw);
        result._m[2] = 2.0 * (zx - yw);
        result._m[3] = 0.0;
        result._m[4] = 2.0 * (xy - zw);
        result._m[5] = 1.0 - (2.0 * (zz + xx));
        result._m[6] = 2.0 * (yz + xw);
        result._m[7] = 0.0;
        result._m[8] = 2.0 * (zx + yw);
        result._m[9] = 2.0 * (yz - xw);
        result._m[10] = 1.0 - (2.0 * (yy + xx));
        result._m[11] = 0.0;
        result._m[12] = 0.0;
        result._m[13] = 0.0;
        result._m[14] = 0.0;
        result._m[15] = 1.0;
        result._markAsUpdated();
    };
    Matrix._updateFlagSeed = 0;
    Matrix._identityReadOnly = Matrix.Identity();
    return Matrix;
}());

/**
 * @hidden
 * Same as Tmp but not exported to keep it only for math functions to avoid conflicts
 */
var MathTmp = /** @class */ (function () {
    function MathTmp() {
    }
    MathTmp.Vector3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(6, Vector3.Zero);
    MathTmp.Matrix = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(2, Matrix.Identity);
    MathTmp.Quaternion = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(3, Quaternion.Zero);
    return MathTmp;
}());
/**
 * @hidden
 */
var TmpVectors = /** @class */ (function () {
    function TmpVectors() {
    }
    TmpVectors.Vector2 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(3, Vector2.Zero); // 3 temp Vector2 at once should be enough
    TmpVectors.Vector3 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(13, Vector3.Zero); // 13 temp Vector3 at once should be enough
    TmpVectors.Vector4 = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(3, Vector4.Zero); // 3 temp Vector4 at once should be enough
    TmpVectors.Quaternion = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(2, Quaternion.Zero); // 2 temp Quaternion at once should be enough
    TmpVectors.Matrix = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_2__["ArrayTools"].BuildArray(8, Matrix.Identity); // 8 temp Matrices at once should be enough
    return TmpVectors;
}());

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Vector2"] = Vector2;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Vector3"] = Vector3;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Vector4"] = Vector4;
_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__["_TypeStore"].RegisteredTypes["BABYLON.Matrix"] = Matrix;


/***/ }),

/***/ "./Maths/math.vertexFormat.ts":
/*!************************************!*\
  !*** ./Maths/math.vertexFormat.ts ***!
  \************************************/
/*! exports provided: PositionNormalVertex, PositionNormalTextureVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PositionNormalVertex", function() { return PositionNormalVertex; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PositionNormalTextureVertex", function() { return PositionNormalTextureVertex; });
/* harmony import */ var _math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.vector */ "./Maths/math.vector.ts");

/**
 * Contains position and normal vectors for a vertex
 */
var PositionNormalVertex = /** @class */ (function () {
    /**
     * Creates a PositionNormalVertex
     * @param position the position of the vertex (defaut: 0,0,0)
     * @param normal the normal of the vertex (defaut: 0,1,0)
     */
    function PositionNormalVertex(
    /** the position of the vertex (defaut: 0,0,0) */
    position,
    /** the normal of the vertex (defaut: 0,1,0) */
    normal) {
        if (position === void 0) { position = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(); }
        if (normal === void 0) { normal = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up(); }
        this.position = position;
        this.normal = normal;
    }
    /**
     * Clones the PositionNormalVertex
     * @returns the cloned PositionNormalVertex
     */
    PositionNormalVertex.prototype.clone = function () {
        return new PositionNormalVertex(this.position.clone(), this.normal.clone());
    };
    return PositionNormalVertex;
}());

/**
 * Contains position, normal and uv vectors for a vertex
 */
var PositionNormalTextureVertex = /** @class */ (function () {
    /**
     * Creates a PositionNormalTextureVertex
     * @param position the position of the vertex (defaut: 0,0,0)
     * @param normal the normal of the vertex (defaut: 0,1,0)
     * @param uv the uv of the vertex (default: 0,0)
     */
    function PositionNormalTextureVertex(
    /** the position of the vertex (defaut: 0,0,0) */
    position,
    /** the normal of the vertex (defaut: 0,1,0) */
    normal,
    /** the uv of the vertex (default: 0,0) */
    uv) {
        if (position === void 0) { position = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(); }
        if (normal === void 0) { normal = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up(); }
        if (uv === void 0) { uv = _math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Zero(); }
        this.position = position;
        this.normal = normal;
        this.uv = uv;
    }
    /**
     * Clones the PositionNormalTextureVertex
     * @returns the cloned PositionNormalTextureVertex
     */
    PositionNormalTextureVertex.prototype.clone = function () {
        return new PositionNormalTextureVertex(this.position.clone(), this.normal.clone(), this.uv.clone());
    };
    return PositionNormalTextureVertex;
}());



/***/ }),

/***/ "./Maths/math.viewport.ts":
/*!********************************!*\
  !*** ./Maths/math.viewport.ts ***!
  \********************************/
/*! exports provided: Viewport */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Viewport", function() { return Viewport; });
/**
 * Class used to represent a viewport on screen
 */
var Viewport = /** @class */ (function () {
    /**
     * Creates a Viewport object located at (x, y) and sized (width, height)
     * @param x defines viewport left coordinate
     * @param y defines viewport top coordinate
     * @param width defines the viewport width
     * @param height defines the viewport height
     */
    function Viewport(
    /** viewport left coordinate */
    x,
    /** viewport top coordinate */
    y,
    /**viewport width */
    width,
    /** viewport height */
    height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }
    /**
     * Creates a new viewport using absolute sizing (from 0-> width, 0-> height instead of 0->1)
     * @param renderWidth defines the rendering width
     * @param renderHeight defines the rendering height
     * @returns a new Viewport
     */
    Viewport.prototype.toGlobal = function (renderWidth, renderHeight) {
        return new Viewport(this.x * renderWidth, this.y * renderHeight, this.width * renderWidth, this.height * renderHeight);
    };
    /**
     * Stores absolute viewport value into a target viewport (from 0-> width, 0-> height instead of 0->1)
     * @param renderWidth defines the rendering width
     * @param renderHeight defines the rendering height
     * @param ref defines the target viewport
     * @returns the current viewport
     */
    Viewport.prototype.toGlobalToRef = function (renderWidth, renderHeight, ref) {
        ref.x = this.x * renderWidth;
        ref.y = this.y * renderHeight;
        ref.width = this.width * renderWidth;
        ref.height = this.height * renderHeight;
        return this;
    };
    /**
     * Returns a new Viewport copied from the current one
     * @returns a new Viewport
     */
    Viewport.prototype.clone = function () {
        return new Viewport(this.x, this.y, this.width, this.height);
    };
    return Viewport;
}());



/***/ }),

/***/ "./Maths/sphericalPolynomial.ts":
/*!**************************************!*\
  !*** ./Maths/sphericalPolynomial.ts ***!
  \**************************************/
/*! exports provided: SphericalHarmonics, SphericalPolynomial */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphericalHarmonics", function() { return SphericalHarmonics; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphericalPolynomial", function() { return SphericalPolynomial; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");

// https://dickyjim.wordpress.com/2013/09/04/spherical-harmonics-for-beginners/
// http://silviojemma.com/public/papers/lighting/spherical-harmonic-lighting.pdf
// https://www.ppsloan.org/publications/StupidSH36.pdf
// http://cseweb.ucsd.edu/~ravir/papers/envmap/envmap.pdf
// https://www.ppsloan.org/publications/SHJCGT.pdf
// https://www.ppsloan.org/publications/shdering.pdf
// https://google.github.io/filament/Filament.md.html#annex/sphericalharmonics
// https://patapom.com/blog/SHPortal/
// https://imdoingitwrong.wordpress.com/2011/04/14/spherical-harmonics-wtf/
// Using real SH basis:
//  m>0             m   m
// y   = sqrt(2) * K * P * cos(m*phi) * cos(theta)
//  l               l   l
//
//  m<0             m   |m|
// y   = sqrt(2) * K * P * sin(m*phi) * cos(theta)
//  l               l   l
//
//  m=0   0   0
// y   = K * P * trigono terms
//  l     l   l
//
//  m       (2l + 1)(l - |m|)!
// K = sqrt(------------------)
//  l           4pi(l + |m|)!
//
// and P by recursion:
//
// P00(x) = 1
// P01(x) = x
// Pll(x) = (-1^l)(2l - 1)!!(1-x*x)^(1/2)
//          ((2l - 1)x[Pl-1/m]-(l + m - 1)[Pl-2/m])
// Plm(x) = ---------------------------------------
//                         l - m
// Leaving the trigonometric terms aside we can precompute the constants to :
var SH3ylmBasisConstants = [
    Math.sqrt(1 / (4 * Math.PI)),
    -Math.sqrt(3 / (4 * Math.PI)),
    Math.sqrt(3 / (4 * Math.PI)),
    -Math.sqrt(3 / (4 * Math.PI)),
    Math.sqrt(15 / (4 * Math.PI)),
    -Math.sqrt(15 / (4 * Math.PI)),
    Math.sqrt(5 / (16 * Math.PI)),
    -Math.sqrt(15 / (4 * Math.PI)),
    Math.sqrt(15 / (16 * Math.PI)),
];
// cm = cos(m * phi)
// sm = sin(m * phi)
// {x,y,z} = {cos(phi)sin(theta), sin(phi)sin(theta), cos(theta)}
// By recursion on using trigo identities:
var SH3ylmBasisTrigonometricTerms = [
    function (direction) { return 1; },
    function (direction) { return direction.y; },
    function (direction) { return direction.z; },
    function (direction) { return direction.x; },
    function (direction) { return direction.x * direction.y; },
    function (direction) { return direction.y * direction.z; },
    function (direction) { return 3 * direction.z * direction.z - 1; },
    function (direction) { return direction.x * direction.z; },
    function (direction) { return direction.x * direction.x - direction.y * direction.y; },
];
// Wrap the full compute
var applySH3 = function (lm, direction) {
    return SH3ylmBasisConstants[lm] * SH3ylmBasisTrigonometricTerms[lm](direction);
};
// Derived from the integration of the a kernel convolution to SH.
// Great explanation here: https://patapom.com/blog/SHPortal/#about-distant-radiance-and-irradiance-environments
var SHCosKernelConvolution = [
    Math.PI,
    2 * Math.PI / 3,
    2 * Math.PI / 3,
    2 * Math.PI / 3,
    Math.PI / 4,
    Math.PI / 4,
    Math.PI / 4,
    Math.PI / 4,
    Math.PI / 4,
];
/**
 * Class representing spherical harmonics coefficients to the 3rd degree
 */
var SphericalHarmonics = /** @class */ (function () {
    function SphericalHarmonics() {
        /**
         * Defines whether or not the harmonics have been prescaled for rendering.
         */
        this.preScaled = false;
        /**
         * The l0,0 coefficients of the spherical harmonics
         */
        this.l00 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l1,-1 coefficients of the spherical harmonics
         */
        this.l1_1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l1,0 coefficients of the spherical harmonics
         */
        this.l10 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l1,1 coefficients of the spherical harmonics
         */
        this.l11 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l2,-2 coefficients of the spherical harmonics
         */
        this.l2_2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l2,-1 coefficients of the spherical harmonics
         */
        this.l2_1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l2,0 coefficients of the spherical harmonics
         */
        this.l20 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l2,1 coefficients of the spherical harmonics
         */
        this.l21 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The l2,2 coefficients of the spherical harmonics
         */
        this.l22 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    }
    /**
     * Adds a light to the spherical harmonics
     * @param direction the direction of the light
     * @param color the color of the light
     * @param deltaSolidAngle the delta solid angle of the light
     */
    SphericalHarmonics.prototype.addLight = function (direction, color, deltaSolidAngle) {
        var colorVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](color.r, color.g, color.b);
        var c = colorVector.scale(deltaSolidAngle);
        this.l00 = this.l00.add(c.scale(applySH3(0, direction)));
        this.l1_1 = this.l1_1.add(c.scale(applySH3(1, direction)));
        this.l10 = this.l10.add(c.scale(applySH3(2, direction)));
        this.l11 = this.l11.add(c.scale(applySH3(3, direction)));
        this.l2_2 = this.l2_2.add(c.scale(applySH3(4, direction)));
        this.l2_1 = this.l2_1.add(c.scale(applySH3(5, direction)));
        this.l20 = this.l20.add(c.scale(applySH3(6, direction)));
        this.l21 = this.l21.add(c.scale(applySH3(7, direction)));
        this.l22 = this.l22.add(c.scale(applySH3(8, direction)));
    };
    /**
     * Scales the spherical harmonics by the given amount
     * @param scale the amount to scale
     */
    SphericalHarmonics.prototype.scaleInPlace = function (scale) {
        this.l00.scaleInPlace(scale);
        this.l1_1.scaleInPlace(scale);
        this.l10.scaleInPlace(scale);
        this.l11.scaleInPlace(scale);
        this.l2_2.scaleInPlace(scale);
        this.l2_1.scaleInPlace(scale);
        this.l20.scaleInPlace(scale);
        this.l21.scaleInPlace(scale);
        this.l22.scaleInPlace(scale);
    };
    /**
     * Convert from incident radiance (Li) to irradiance (E) by applying convolution with the cosine-weighted hemisphere.
     *
     * ```
     * E_lm = A_l * L_lm
     * ```
     *
     * In spherical harmonics this convolution amounts to scaling factors for each frequency band.
     * This corresponds to equation 5 in "An Efficient Representation for Irradiance Environment Maps", where
     * the scaling factors are given in equation 9.
     */
    SphericalHarmonics.prototype.convertIncidentRadianceToIrradiance = function () {
        // Constant (Band 0)
        this.l00.scaleInPlace(SHCosKernelConvolution[0]);
        // Linear (Band 1)
        this.l1_1.scaleInPlace(SHCosKernelConvolution[1]);
        this.l10.scaleInPlace(SHCosKernelConvolution[2]);
        this.l11.scaleInPlace(SHCosKernelConvolution[3]);
        // Quadratic (Band 2)
        this.l2_2.scaleInPlace(SHCosKernelConvolution[4]);
        this.l2_1.scaleInPlace(SHCosKernelConvolution[5]);
        this.l20.scaleInPlace(SHCosKernelConvolution[6]);
        this.l21.scaleInPlace(SHCosKernelConvolution[7]);
        this.l22.scaleInPlace(SHCosKernelConvolution[8]);
    };
    /**
     * Convert from irradiance to outgoing radiance for Lambertian BDRF, suitable for efficient shader evaluation.
     *
     * ```
     * L = (1/pi) * E * rho
     * ```
     *
     * This is done by an additional scale by 1/pi, so is a fairly trivial operation but important conceptually.
     */
    SphericalHarmonics.prototype.convertIrradianceToLambertianRadiance = function () {
        this.scaleInPlace(1.0 / Math.PI);
        // The resultant SH now represents outgoing radiance, so includes the Lambert 1/pi normalisation factor but without albedo (rho) applied
        // (The pixel shader must apply albedo after texture fetches, etc).
    };
    /**
     * Integrates the reconstruction coefficients directly in to the SH preventing further
     * required operations at run time.
     *
     * This is simply done by scaling back the SH with Ylm constants parameter.
     * The trigonometric part being applied by the shader at run time.
     */
    SphericalHarmonics.prototype.preScaleForRendering = function () {
        this.preScaled = true;
        this.l00.scaleInPlace(SH3ylmBasisConstants[0]);
        this.l1_1.scaleInPlace(SH3ylmBasisConstants[1]);
        this.l10.scaleInPlace(SH3ylmBasisConstants[2]);
        this.l11.scaleInPlace(SH3ylmBasisConstants[3]);
        this.l2_2.scaleInPlace(SH3ylmBasisConstants[4]);
        this.l2_1.scaleInPlace(SH3ylmBasisConstants[5]);
        this.l20.scaleInPlace(SH3ylmBasisConstants[6]);
        this.l21.scaleInPlace(SH3ylmBasisConstants[7]);
        this.l22.scaleInPlace(SH3ylmBasisConstants[8]);
    };
    /**
     * Constructs a spherical harmonics from an array.
     * @param data defines the 9x3 coefficients (l00, l1-1, l10, l11, l2-2, l2-1, l20, l21, l22)
     * @returns the spherical harmonics
     */
    SphericalHarmonics.FromArray = function (data) {
        var sh = new SphericalHarmonics();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[0], 0, sh.l00);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[1], 0, sh.l1_1);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[2], 0, sh.l10);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[3], 0, sh.l11);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[4], 0, sh.l2_2);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[5], 0, sh.l2_1);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[6], 0, sh.l20);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[7], 0, sh.l21);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[8], 0, sh.l22);
        return sh;
    };
    // Keep for references.
    /**
     * Gets the spherical harmonics from polynomial
     * @param polynomial the spherical polynomial
     * @returns the spherical harmonics
     */
    SphericalHarmonics.FromPolynomial = function (polynomial) {
        var result = new SphericalHarmonics();
        result.l00 = polynomial.xx.scale(0.376127).add(polynomial.yy.scale(0.376127)).add(polynomial.zz.scale(0.376126));
        result.l1_1 = polynomial.y.scale(0.977204);
        result.l10 = polynomial.z.scale(0.977204);
        result.l11 = polynomial.x.scale(0.977204);
        result.l2_2 = polynomial.xy.scale(1.16538);
        result.l2_1 = polynomial.yz.scale(1.16538);
        result.l20 = polynomial.zz.scale(1.34567).subtract(polynomial.xx.scale(0.672834)).subtract(polynomial.yy.scale(0.672834));
        result.l21 = polynomial.zx.scale(1.16538);
        result.l22 = polynomial.xx.scale(1.16538).subtract(polynomial.yy.scale(1.16538));
        result.l1_1.scaleInPlace(-1);
        result.l11.scaleInPlace(-1);
        result.l2_1.scaleInPlace(-1);
        result.l21.scaleInPlace(-1);
        result.scaleInPlace(Math.PI);
        return result;
    };
    return SphericalHarmonics;
}());

/**
 * Class representing spherical polynomial coefficients to the 3rd degree
 */
var SphericalPolynomial = /** @class */ (function () {
    function SphericalPolynomial() {
        /**
         * The x coefficients of the spherical polynomial
         */
        this.x = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The y coefficients of the spherical polynomial
         */
        this.y = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The z coefficients of the spherical polynomial
         */
        this.z = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The xx coefficients of the spherical polynomial
         */
        this.xx = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The yy coefficients of the spherical polynomial
         */
        this.yy = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The zz coefficients of the spherical polynomial
         */
        this.zz = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The xy coefficients of the spherical polynomial
         */
        this.xy = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The yz coefficients of the spherical polynomial
         */
        this.yz = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The zx coefficients of the spherical polynomial
         */
        this.zx = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    }
    Object.defineProperty(SphericalPolynomial.prototype, "preScaledHarmonics", {
        /**
         * The spherical harmonics used to create the polynomials.
         */
        get: function () {
            if (!this._harmonics) {
                this._harmonics = SphericalHarmonics.FromPolynomial(this);
            }
            if (!this._harmonics.preScaled) {
                this._harmonics.preScaleForRendering();
            }
            return this._harmonics;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Adds an ambient color to the spherical polynomial
     * @param color the color to add
     */
    SphericalPolynomial.prototype.addAmbient = function (color) {
        var colorVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](color.r, color.g, color.b);
        this.xx = this.xx.add(colorVector);
        this.yy = this.yy.add(colorVector);
        this.zz = this.zz.add(colorVector);
    };
    /**
     * Scales the spherical polynomial by the given amount
     * @param scale the amount to scale
     */
    SphericalPolynomial.prototype.scaleInPlace = function (scale) {
        this.x.scaleInPlace(scale);
        this.y.scaleInPlace(scale);
        this.z.scaleInPlace(scale);
        this.xx.scaleInPlace(scale);
        this.yy.scaleInPlace(scale);
        this.zz.scaleInPlace(scale);
        this.yz.scaleInPlace(scale);
        this.zx.scaleInPlace(scale);
        this.xy.scaleInPlace(scale);
    };
    /**
     * Gets the spherical polynomial from harmonics
     * @param harmonics the spherical harmonics
     * @returns the spherical polynomial
     */
    SphericalPolynomial.FromHarmonics = function (harmonics) {
        var result = new SphericalPolynomial();
        result._harmonics = harmonics;
        result.x = harmonics.l11.scale(1.02333).scale(-1);
        result.y = harmonics.l1_1.scale(1.02333).scale(-1);
        result.z = harmonics.l10.scale(1.02333);
        result.xx = harmonics.l00.scale(0.886277).subtract(harmonics.l20.scale(0.247708)).add(harmonics.l22.scale(0.429043));
        result.yy = harmonics.l00.scale(0.886277).subtract(harmonics.l20.scale(0.247708)).subtract(harmonics.l22.scale(0.429043));
        result.zz = harmonics.l00.scale(0.886277).add(harmonics.l20.scale(0.495417));
        result.yz = harmonics.l2_1.scale(0.858086).scale(-1);
        result.zx = harmonics.l21.scale(0.858086).scale(-1);
        result.xy = harmonics.l2_2.scale(0.858086);
        result.scaleInPlace(1.0 / Math.PI);
        return result;
    };
    /**
     * Constructs a spherical polynomial from an array.
     * @param data defines the 9x3 coefficients (x, y, z, xx, yy, zz, yz, zx, xy)
     * @returns the spherical polynomial
     */
    SphericalPolynomial.FromArray = function (data) {
        var sp = new SphericalPolynomial();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[0], 0, sp.x);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[1], 0, sp.y);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[2], 0, sp.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[3], 0, sp.xx);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[4], 0, sp.yy);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[5], 0, sp.zz);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[6], 0, sp.yz);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[7], 0, sp.zx);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(data[8], 0, sp.xy);
        return sp;
    };
    return SphericalPolynomial;
}());



/***/ }),

/***/ "./Meshes/Builders/boxBuilder.ts":
/*!***************************************!*\
  !*** ./Meshes/Builders/boxBuilder.ts ***!
  \***************************************/
/*! exports provided: BoxBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoxBuilder", function() { return BoxBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");




_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateBox = function (options) {
    var nbFaces = 6;
    var indices = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23];
    var normals = [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0];
    var uvs = [];
    var positions = [];
    var width = options.width || options.size || 1;
    var height = options.height || options.size || 1;
    var depth = options.depth || options.size || 1;
    var wrap = options.wrap || false;
    var topBaseAt = (options.topBaseAt === void 0) ? 1 : options.topBaseAt;
    var bottomBaseAt = (options.bottomBaseAt === void 0) ? 0 : options.bottomBaseAt;
    topBaseAt = (topBaseAt + 4) % 4; // places values as 0 to 3
    bottomBaseAt = (bottomBaseAt + 4) % 4; // places values as 0 to 3
    var topOrder = [2, 0, 3, 1];
    var bottomOrder = [2, 0, 1, 3];
    var topIndex = topOrder[topBaseAt];
    var bottomIndex = bottomOrder[bottomBaseAt];
    var basePositions = [1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1];
    if (wrap) {
        indices = [2, 3, 0, 2, 0, 1, 4, 5, 6, 4, 6, 7, 9, 10, 11, 9, 11, 8, 12, 14, 15, 12, 13, 14];
        basePositions = [-1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1];
        var topFaceBase = [[1, 1, 1], [-1, 1, 1], [-1, 1, -1], [1, 1, -1]];
        var bottomFaceBase = [[-1, -1, 1], [1, -1, 1], [1, -1, -1], [-1, -1, -1]];
        var topFaceOrder = [17, 18, 19, 16];
        var bottomFaceOrder = [22, 23, 20, 21];
        while (topIndex > 0) {
            topFaceBase.unshift(topFaceBase.pop());
            topFaceOrder.unshift(topFaceOrder.pop());
            topIndex--;
        }
        while (bottomIndex > 0) {
            bottomFaceBase.unshift(bottomFaceBase.pop());
            bottomFaceOrder.unshift(bottomFaceOrder.pop());
            bottomIndex--;
        }
        topFaceBase = topFaceBase.flat();
        bottomFaceBase = bottomFaceBase.flat();
        basePositions = basePositions.concat(topFaceBase).concat(bottomFaceBase);
        indices.push(topFaceOrder[0], topFaceOrder[2], topFaceOrder[3], topFaceOrder[0], topFaceOrder[1], topFaceOrder[2]);
        indices.push(bottomFaceOrder[0], bottomFaceOrder[2], bottomFaceOrder[3], bottomFaceOrder[0], bottomFaceOrder[1], bottomFaceOrder[2]);
    }
    var scaleArray = [width / 2, height / 2, depth / 2];
    positions = basePositions.reduce(function (accumulator, currentValue, currentIndex) { return accumulator.concat(currentValue * scaleArray[currentIndex % 3]); }, []);
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DEFAULTSIDE;
    var faceUV = options.faceUV || new Array(6);
    var faceColors = options.faceColors;
    var colors = [];
    // default face colors and UV if undefined
    for (var f = 0; f < 6; f++) {
        if (faceUV[f] === undefined) {
            faceUV[f] = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0, 0, 1, 1);
        }
        if (faceColors && faceColors[f] === undefined) {
            faceColors[f] = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1, 1, 1, 1);
        }
    }
    // Create each face in turn.
    for (var index = 0; index < nbFaces; index++) {
        uvs.push(faceUV[index].z, faceUV[index].w);
        uvs.push(faceUV[index].x, faceUV[index].w);
        uvs.push(faceUV[index].x, faceUV[index].y);
        uvs.push(faceUV[index].z, faceUV[index].y);
        if (faceColors) {
            for (var c = 0; c < 4; c++) {
                colors.push(faceColors[index].r, faceColors[index].g, faceColors[index].b, faceColors[index].a);
            }
        }
    }
    // sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    if (faceColors) {
        var totalColors = (sideOrientation === _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DOUBLESIDE) ? colors.concat(colors) : colors;
        vertexData.colors = totalColors;
    }
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreateBox = function (name, size, scene, updatable, sideOrientation) {
    if (scene === void 0) { scene = null; }
    var options = {
        size: size,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return BoxBuilder.CreateBox(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var BoxBuilder = /** @class */ (function () {
    function BoxBuilder() {
    }
    /**
     * Creates a box mesh
     * * The parameter `size` sets the size (float) of each box side (default 1)
     * * You can set some different box dimensions by using the parameters `width`, `height` and `depth` (all by default have the same value of `size`)
     * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of 6 Color3 elements) and `faceUV` (an array of 6 Vector4 elements)
     * * Please read this tutorial : https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @see https://doc.babylonjs.com/how_to/set_shapes#box
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the box mesh
     */
    BoxBuilder.CreateBox = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var box = new _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        box._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateBox(options);
        vertexData.applyToMesh(box, options.updatable);
        return box;
    };
    return BoxBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/cylinderBuilder.ts":
/*!********************************************!*\
  !*** ./Meshes/Builders/cylinderBuilder.ts ***!
  \********************************************/
/*! exports provided: CylinderBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderBuilder", function() { return CylinderBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../scene */ "./scene.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Maths/math.axis */ "./Maths/math.axis.ts");






_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateCylinder = function (options) {
    var height = options.height || 2;
    var diameterTop = (options.diameterTop === 0) ? 0 : options.diameterTop || options.diameter || 1;
    var diameterBottom = (options.diameterBottom === 0) ? 0 : options.diameterBottom || options.diameter || 1;
    diameterTop = diameterTop || 0.00001; // Prevent broken normals
    diameterBottom = diameterBottom || 0.00001; // Prevent broken normals
    var tessellation = options.tessellation || 24;
    var subdivisions = options.subdivisions || 1;
    var hasRings = options.hasRings ? true : false;
    var enclose = options.enclose ? true : false;
    var cap = (options.cap === 0) ? 0 : options.cap || _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CAP_ALL;
    var arc = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DEFAULTSIDE;
    var faceUV = options.faceUV || new Array(3);
    var faceColors = options.faceColors;
    // default face colors and UV if undefined
    var quadNb = (arc !== 1 && enclose) ? 2 : 0;
    var ringNb = (hasRings) ? subdivisions : 1;
    var surfaceNb = 2 + (1 + quadNb) * ringNb;
    var f;
    for (f = 0; f < surfaceNb; f++) {
        if (faceColors && faceColors[f] === undefined) {
            faceColors[f] = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1, 1, 1, 1);
        }
    }
    for (f = 0; f < surfaceNb; f++) {
        if (faceUV && faceUV[f] === undefined) {
            faceUV[f] = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0, 0, 1, 1);
        }
    }
    var indices = new Array();
    var positions = new Array();
    var normals = new Array();
    var uvs = new Array();
    var colors = new Array();
    var angle_step = Math.PI * 2 * arc / tessellation;
    var angle;
    var h;
    var radius;
    var tan = (diameterBottom - diameterTop) / 2 / height;
    var ringVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    var ringNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    var ringFirstVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    var ringFirstNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    var quadNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    var Y = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Axis"].Y;
    // positions, normals, uvs
    var i;
    var j;
    var r;
    var ringIdx = 1;
    var s = 1; // surface index
    var cs = 0;
    var v = 0;
    for (i = 0; i <= subdivisions; i++) {
        h = i / subdivisions;
        radius = (h * (diameterTop - diameterBottom) + diameterBottom) / 2;
        ringIdx = (hasRings && i !== 0 && i !== subdivisions) ? 2 : 1;
        for (r = 0; r < ringIdx; r++) {
            if (hasRings) {
                s += r;
            }
            if (enclose) {
                s += 2 * r;
            }
            for (j = 0; j <= tessellation; j++) {
                angle = j * angle_step;
                // position
                ringVertex.x = Math.cos(-angle) * radius;
                ringVertex.y = -height / 2 + h * height;
                ringVertex.z = Math.sin(-angle) * radius;
                // normal
                if (diameterTop === 0 && i === subdivisions) {
                    // if no top cap, reuse former normals
                    ringNormal.x = normals[normals.length - (tessellation + 1) * 3];
                    ringNormal.y = normals[normals.length - (tessellation + 1) * 3 + 1];
                    ringNormal.z = normals[normals.length - (tessellation + 1) * 3 + 2];
                }
                else {
                    ringNormal.x = ringVertex.x;
                    ringNormal.z = ringVertex.z;
                    ringNormal.y = Math.sqrt(ringNormal.x * ringNormal.x + ringNormal.z * ringNormal.z) * tan;
                    ringNormal.normalize();
                }
                // keep first ring vertex values for enclose
                if (j === 0) {
                    ringFirstVertex.copyFrom(ringVertex);
                    ringFirstNormal.copyFrom(ringNormal);
                }
                positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
                normals.push(ringNormal.x, ringNormal.y, ringNormal.z);
                if (hasRings) {
                    v = (cs !== s) ? faceUV[s].y : faceUV[s].w;
                }
                else {
                    v = faceUV[s].y + (faceUV[s].w - faceUV[s].y) * h;
                }
                uvs.push(faceUV[s].x + (faceUV[s].z - faceUV[s].x) * j / tessellation, v);
                if (faceColors) {
                    colors.push(faceColors[s].r, faceColors[s].g, faceColors[s].b, faceColors[s].a);
                }
            }
            // if enclose, add four vertices and their dedicated normals
            if (arc !== 1 && enclose) {
                positions.push(ringVertex.x, ringVertex.y, ringVertex.z);
                positions.push(0, ringVertex.y, 0);
                positions.push(0, ringVertex.y, 0);
                positions.push(ringFirstVertex.x, ringFirstVertex.y, ringFirstVertex.z);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(Y, ringNormal, quadNormal);
                quadNormal.normalize();
                normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(ringFirstNormal, Y, quadNormal);
                quadNormal.normalize();
                normals.push(quadNormal.x, quadNormal.y, quadNormal.z, quadNormal.x, quadNormal.y, quadNormal.z);
                if (hasRings) {
                    v = (cs !== s) ? faceUV[s + 1].y : faceUV[s + 1].w;
                }
                else {
                    v = faceUV[s + 1].y + (faceUV[s + 1].w - faceUV[s + 1].y) * h;
                }
                uvs.push(faceUV[s + 1].x, v);
                uvs.push(faceUV[s + 1].z, v);
                if (hasRings) {
                    v = (cs !== s) ? faceUV[s + 2].y : faceUV[s + 2].w;
                }
                else {
                    v = faceUV[s + 2].y + (faceUV[s + 2].w - faceUV[s + 2].y) * h;
                }
                uvs.push(faceUV[s + 2].x, v);
                uvs.push(faceUV[s + 2].z, v);
                if (faceColors) {
                    colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);
                    colors.push(faceColors[s + 1].r, faceColors[s + 1].g, faceColors[s + 1].b, faceColors[s + 1].a);
                    colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);
                    colors.push(faceColors[s + 2].r, faceColors[s + 2].g, faceColors[s + 2].b, faceColors[s + 2].a);
                }
            }
            if (cs !== s) {
                cs = s;
            }
        }
    }
    // indices
    var e = (arc !== 1 && enclose) ? tessellation + 4 : tessellation; // correction of number of iteration if enclose
    var s;
    i = 0;
    for (s = 0; s < subdivisions; s++) {
        var i0 = 0;
        var i1 = 0;
        var i2 = 0;
        var i3 = 0;
        for (j = 0; j < tessellation; j++) {
            i0 = i * (e + 1) + j;
            i1 = (i + 1) * (e + 1) + j;
            i2 = i * (e + 1) + (j + 1);
            i3 = (i + 1) * (e + 1) + (j + 1);
            indices.push(i0, i1, i2);
            indices.push(i3, i2, i1);
        }
        if (arc !== 1 && enclose) { // if enclose, add two quads
            indices.push(i0 + 2, i1 + 2, i2 + 2);
            indices.push(i3 + 2, i2 + 2, i1 + 2);
            indices.push(i0 + 4, i1 + 4, i2 + 4);
            indices.push(i3 + 4, i2 + 4, i1 + 4);
        }
        i = (hasRings) ? (i + 2) : (i + 1);
    }
    // Caps
    var createCylinderCap = function (isTop) {
        var radius = isTop ? diameterTop / 2 : diameterBottom / 2;
        if (radius === 0) {
            return;
        }
        // Cap positions, normals & uvs
        var angle;
        var circleVector;
        var i;
        var u = (isTop) ? faceUV[surfaceNb - 1] : faceUV[0];
        var c = null;
        if (faceColors) {
            c = (isTop) ? faceColors[surfaceNb - 1] : faceColors[0];
        }
        // cap center
        var vbase = positions.length / 3;
        var offset = isTop ? height / 2 : -height / 2;
        var center = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, offset, 0);
        positions.push(center.x, center.y, center.z);
        normals.push(0, isTop ? 1 : -1, 0);
        uvs.push(u.x + (u.z - u.x) * 0.5, u.y + (u.w - u.y) * 0.5);
        if (c) {
            colors.push(c.r, c.g, c.b, c.a);
        }
        var textureScale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0.5, 0.5);
        for (i = 0; i <= tessellation; i++) {
            angle = Math.PI * 2 * i * arc / tessellation;
            var cos = Math.cos(-angle);
            var sin = Math.sin(-angle);
            circleVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](cos * radius, offset, sin * radius);
            var textureCoordinate = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](cos * textureScale.x + 0.5, sin * textureScale.y + 0.5);
            positions.push(circleVector.x, circleVector.y, circleVector.z);
            normals.push(0, isTop ? 1 : -1, 0);
            uvs.push(u.x + (u.z - u.x) * textureCoordinate.x, u.y + (u.w - u.y) * textureCoordinate.y);
            if (c) {
                colors.push(c.r, c.g, c.b, c.a);
            }
        }
        // Cap indices
        for (i = 0; i < tessellation; i++) {
            if (!isTop) {
                indices.push(vbase);
                indices.push(vbase + (i + 1));
                indices.push(vbase + (i + 2));
            }
            else {
                indices.push(vbase);
                indices.push(vbase + (i + 2));
                indices.push(vbase + (i + 1));
            }
        }
    };
    // add caps to geometry based on cap parameter
    if ((cap === _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CAP_START)
        || (cap === _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CAP_ALL)) {
        createCylinderCap(false);
    }
    if ((cap === _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CAP_END)
        || (cap === _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CAP_ALL)) {
        createCylinderCap(true);
    }
    // Sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    if (faceColors) {
        vertexData.colors = colors;
    }
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable, sideOrientation) {
    if (scene === undefined || !(scene instanceof _scene__WEBPACK_IMPORTED_MODULE_4__["Scene"])) {
        if (scene !== undefined) {
            sideOrientation = updatable || _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].DEFAULTSIDE;
            updatable = scene;
        }
        scene = subdivisions;
        subdivisions = 1;
    }
    var options = {
        height: height,
        diameterTop: diameterTop,
        diameterBottom: diameterBottom,
        tessellation: tessellation,
        subdivisions: subdivisions,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return CylinderBuilder.CreateCylinder(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var CylinderBuilder = /** @class */ (function () {
    function CylinderBuilder() {
    }
    /**
     * Creates a cylinder or a cone mesh
     * * The parameter `height` sets the height size (float) of the cylinder/cone (float, default 2).
     * * The parameter `diameter` sets the diameter of the top and bottom cap at once (float, default 1).
     * * The parameters `diameterTop` and `diameterBottom` overwrite the parameter `diameter` and set respectively the top cap and bottom cap diameter (floats, default 1). The parameter "diameterBottom" can't be zero.
     * * The parameter `tessellation` sets the number of cylinder sides (positive integer, default 24). Set it to 3 to get a prism for instance.
     * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
     * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
     * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
     * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
     * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
     * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
     * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
     * * Now, if the cylinder has 5 independent subdivisions (hasRings = true), n equals : top face + 5 stripe surfaces + bottom face = 2 + 5 = 7
     * * Finally, if the cylinder has 5 independent subdivisions and is enclose, n equals : top face + 5 x (stripe surface + 2 closing faces) + bottom face = 2 + 5 * 3 = 17
     * * Each array (color or UVs) is always ordered the same way : the first element is the bottom cap, the last element is the top cap. The other elements are each a ring surface.
     * * If `enclose` is false, a ring surface is one element.
     * * If `enclose` is true, a ring surface is 3 successive elements in the array : the tubular surface, then the two closing faces.
     * * Example how to set colors and textures on a sliced cylinder : https://www.html5gamedevs.com/topic/17945-creating-a-closed-slice-of-a-cylinder/#comment-106379
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the cylinder mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#cylinder-or-cone
     */
    CylinderBuilder.CreateCylinder = function (name, options, scene) {
        var cylinder = new _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        cylinder._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateCylinder(options);
        vertexData.applyToMesh(cylinder, options.updatable);
        return cylinder;
    };
    return CylinderBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/decalBuilder.ts":
/*!*****************************************!*\
  !*** ./Meshes/Builders/decalBuilder.ts ***!
  \*****************************************/
/*! exports provided: DecalBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DecalBuilder", function() { return DecalBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Maths_math_vertexFormat__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.vertexFormat */ "./Maths/math.vertexFormat.ts");





_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateDecal = function (name, sourceMesh, position, normal, size, angle) {
    var options = {
        position: position,
        normal: normal,
        size: size,
        angle: angle
    };
    return DecalBuilder.CreateDecal(name, sourceMesh, options);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var DecalBuilder = /** @class */ (function () {
    function DecalBuilder() {
    }
    /**
     * Creates a decal mesh.
     * A decal is a mesh usually applied as a model onto the surface of another mesh. So don't forget the parameter `sourceMesh` depicting the decal
     * * The parameter `position` (Vector3, default `(0, 0, 0)`) sets the position of the decal in World coordinates
     * * The parameter `normal` (Vector3, default `Vector3.Up`) sets the normal of the mesh where the decal is applied onto in World coordinates
     * * The parameter `size` (Vector3, default `(1, 1, 1)`) sets the decal scaling
     * * The parameter `angle` (float in radian, default 0) sets the angle to rotate the decal
     * @param name defines the name of the mesh
     * @param sourceMesh defines the mesh where the decal must be applied
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the decal mesh
     * @see https://doc.babylonjs.com/how_to/decals
     */
    DecalBuilder.CreateDecal = function (name, sourceMesh, options) {
        var indices = sourceMesh.getIndices();
        var positions = sourceMesh.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind);
        var normals = sourceMesh.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind);
        var position = options.position || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        var normal = options.normal || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up();
        var size = options.size || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].One();
        var angle = options.angle || 0;
        // Getting correct rotation
        if (!normal) {
            var target = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 1);
            var camera = sourceMesh.getScene().activeCamera;
            var cameraWorldTarget = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(target, camera.getWorldMatrix());
            normal = camera.globalPosition.subtract(cameraWorldTarget);
        }
        var yaw = -Math.atan2(normal.z, normal.x) - Math.PI / 2;
        var len = Math.sqrt(normal.x * normal.x + normal.z * normal.z);
        var pitch = Math.atan2(normal.y, len);
        // Matrix
        var decalWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationYawPitchRoll(yaw, pitch, angle).multiply(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Translation(position.x, position.y, position.z));
        var inverseDecalWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Invert(decalWorldMatrix);
        var meshWorldMatrix = sourceMesh.getWorldMatrix();
        var transformMatrix = meshWorldMatrix.multiply(inverseDecalWorldMatrix);
        var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
        vertexData.indices = [];
        vertexData.positions = [];
        vertexData.normals = [];
        vertexData.uvs = [];
        var currentVertexDataIndex = 0;
        var extractDecalVector3 = function (indexId) {
            var result = new _Maths_math_vertexFormat__WEBPACK_IMPORTED_MODULE_4__["PositionNormalVertex"]();
            if (!indices || !positions || !normals) {
                return result;
            }
            var vertexId = indices[indexId];
            result.position = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](positions[vertexId * 3], positions[vertexId * 3 + 1], positions[vertexId * 3 + 2]);
            // Send vector to decal local world
            result.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(result.position, transformMatrix);
            // Get normal
            result.normal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](normals[vertexId * 3], normals[vertexId * 3 + 1], normals[vertexId * 3 + 2]);
            result.normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(result.normal, transformMatrix);
            return result;
        }; // Inspired by https://github.com/mrdoob/three.js/blob/eee231960882f6f3b6113405f524956145148146/examples/js/geometries/DecalGeometry.js
        var clip = function (vertices, axis) {
            if (vertices.length === 0) {
                return vertices;
            }
            var clipSize = 0.5 * Math.abs(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(size, axis));
            var clipVertices = function (v0, v1) {
                var clipFactor = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].GetClipFactor(v0.position, v1.position, axis, clipSize);
                return new _Maths_math_vertexFormat__WEBPACK_IMPORTED_MODULE_4__["PositionNormalVertex"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(v0.position, v1.position, clipFactor), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(v0.normal, v1.normal, clipFactor));
            };
            var result = new Array();
            for (var index = 0; index < vertices.length; index += 3) {
                var v1Out;
                var v2Out;
                var v3Out;
                var total = 0;
                var nV1 = null;
                var nV2 = null;
                var nV3 = null;
                var nV4 = null;
                var d1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(vertices[index].position, axis) - clipSize;
                var d2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(vertices[index + 1].position, axis) - clipSize;
                var d3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(vertices[index + 2].position, axis) - clipSize;
                v1Out = d1 > 0;
                v2Out = d2 > 0;
                v3Out = d3 > 0;
                total = (v1Out ? 1 : 0) + (v2Out ? 1 : 0) + (v3Out ? 1 : 0);
                switch (total) {
                    case 0:
                        result.push(vertices[index]);
                        result.push(vertices[index + 1]);
                        result.push(vertices[index + 2]);
                        break;
                    case 1:
                        if (v1Out) {
                            nV1 = vertices[index + 1];
                            nV2 = vertices[index + 2];
                            nV3 = clipVertices(vertices[index], nV1);
                            nV4 = clipVertices(vertices[index], nV2);
                        }
                        if (v2Out) {
                            nV1 = vertices[index];
                            nV2 = vertices[index + 2];
                            nV3 = clipVertices(vertices[index + 1], nV1);
                            nV4 = clipVertices(vertices[index + 1], nV2);
                            result.push(nV3);
                            result.push(nV2.clone());
                            result.push(nV1.clone());
                            result.push(nV2.clone());
                            result.push(nV3.clone());
                            result.push(nV4);
                            break;
                        }
                        if (v3Out) {
                            nV1 = vertices[index];
                            nV2 = vertices[index + 1];
                            nV3 = clipVertices(vertices[index + 2], nV1);
                            nV4 = clipVertices(vertices[index + 2], nV2);
                        }
                        if (nV1 && nV2 && nV3 && nV4) {
                            result.push(nV1.clone());
                            result.push(nV2.clone());
                            result.push(nV3);
                            result.push(nV4);
                            result.push(nV3.clone());
                            result.push(nV2.clone());
                        }
                        break;
                    case 2:
                        if (!v1Out) {
                            nV1 = vertices[index].clone();
                            nV2 = clipVertices(nV1, vertices[index + 1]);
                            nV3 = clipVertices(nV1, vertices[index + 2]);
                            result.push(nV1);
                            result.push(nV2);
                            result.push(nV3);
                        }
                        if (!v2Out) {
                            nV1 = vertices[index + 1].clone();
                            nV2 = clipVertices(nV1, vertices[index + 2]);
                            nV3 = clipVertices(nV1, vertices[index]);
                            result.push(nV1);
                            result.push(nV2);
                            result.push(nV3);
                        }
                        if (!v3Out) {
                            nV1 = vertices[index + 2].clone();
                            nV2 = clipVertices(nV1, vertices[index]);
                            nV3 = clipVertices(nV1, vertices[index + 1]);
                            result.push(nV1);
                            result.push(nV2);
                            result.push(nV3);
                        }
                        break;
                    case 3:
                        break;
                }
            }
            return result;
        };
        for (var index = 0; index < indices.length; index += 3) {
            var faceVertices = new Array();
            faceVertices.push(extractDecalVector3(index));
            faceVertices.push(extractDecalVector3(index + 1));
            faceVertices.push(extractDecalVector3(index + 2));
            // Clip
            faceVertices = clip(faceVertices, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1, 0, 0));
            faceVertices = clip(faceVertices, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1, 0, 0));
            faceVertices = clip(faceVertices, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1, 0));
            faceVertices = clip(faceVertices, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0));
            faceVertices = clip(faceVertices, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 1));
            faceVertices = clip(faceVertices, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, -1));
            if (faceVertices.length === 0) {
                continue;
            }
            // Add UVs and get back to world
            for (var vIndex = 0; vIndex < faceVertices.length; vIndex++) {
                var vertex = faceVertices[vIndex];
                //TODO check for Int32Array | Uint32Array | Uint16Array
                vertexData.indices.push(currentVertexDataIndex);
                vertex.position.toArray(vertexData.positions, currentVertexDataIndex * 3);
                vertex.normal.toArray(vertexData.normals, currentVertexDataIndex * 3);
                vertexData.uvs.push(0.5 + vertex.position.x / size.x);
                vertexData.uvs.push(0.5 + vertex.position.y / size.y);
                currentVertexDataIndex++;
            }
        }
        // Return mesh
        var decal = new _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"](name, sourceMesh.getScene());
        vertexData.applyToMesh(decal);
        decal.position = position.clone();
        decal.rotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](pitch, yaw, angle);
        return decal;
    };
    return DecalBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/discBuilder.ts":
/*!****************************************!*\
  !*** ./Meshes/Builders/discBuilder.ts ***!
  \****************************************/
/*! exports provided: DiscBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiscBuilder", function() { return DiscBuilder; });
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");


_mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].CreateDisc = function (options) {
    var positions = new Array();
    var indices = new Array();
    var normals = new Array();
    var uvs = new Array();
    var radius = options.radius || 0.5;
    var tessellation = options.tessellation || 64;
    var arc = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].DEFAULTSIDE;
    // positions and uvs
    positions.push(0, 0, 0); // disc center first
    uvs.push(0.5, 0.5);
    var theta = Math.PI * 2 * arc;
    var step = theta / tessellation;
    for (var a = 0; a < theta; a += step) {
        var x = Math.cos(a);
        var y = Math.sin(a);
        var u = (x + 1) / 2;
        var v = (1 - y) / 2;
        positions.push(radius * x, radius * y, 0);
        uvs.push(u, v);
    }
    if (arc === 1) {
        positions.push(positions[3], positions[4], positions[5]); // close the circle
        uvs.push(uvs[2], uvs[3]);
    }
    //indices
    var vertexNb = positions.length / 3;
    for (var i = 1; i < vertexNb - 1; i++) {
        indices.push(i + 1, 0, i);
    }
    // result
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].ComputeNormals(positions, indices, normals);
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateDisc = function (name, radius, tessellation, scene, updatable, sideOrientation) {
    if (scene === void 0) { scene = null; }
    var options = {
        radius: radius,
        tessellation: tessellation,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return DiscBuilder.CreateDisc(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var DiscBuilder = /** @class */ (function () {
    function DiscBuilder() {
    }
    /**
     * Creates a plane polygonal mesh.  By default, this is a disc
     * * The parameter `radius` sets the radius size (float) of the polygon (default 0.5)
     * * The parameter `tessellation` sets the number of polygon sides (positive integer, default 64). So a tessellation valued to 3 will build a triangle, to 4 a square, etc
     * * You can create an unclosed polygon with the parameter `arc` (positive float, default 1), valued between 0 and 1, what is the ratio of the circumference : 2 x PI x ratio
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the plane polygonal mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#disc-or-regular-polygon
     */
    DiscBuilder.CreateDisc = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var disc = new _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        disc._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].CreateDisc(options);
        vertexData.applyToMesh(disc, options.updatable);
        return disc;
    };
    return DiscBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/groundBuilder.ts":
/*!******************************************!*\
  !*** ./Meshes/Builders/groundBuilder.ts ***!
  \******************************************/
/*! exports provided: GroundBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GroundBuilder", function() { return GroundBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _groundMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../groundMesh */ "./Meshes/groundMesh.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Maths/math.constants */ "./Maths/math.constants.ts");








_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateGround = function (options) {
    var indices = [];
    var positions = [];
    var normals = [];
    var uvs = [];
    var row, col;
    var width = options.width || 1;
    var height = options.height || 1;
    var subdivisionsX = options.subdivisionsX || options.subdivisions || 1;
    var subdivisionsY = options.subdivisionsY || options.subdivisions || 1;
    for (row = 0; row <= subdivisionsY; row++) {
        for (col = 0; col <= subdivisionsX; col++) {
            var position = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]((col * width) / subdivisionsX - (width / 2.0), 0, ((subdivisionsY - row) * height) / subdivisionsY - (height / 2.0));
            var normal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1.0, 0);
            positions.push(position.x, position.y, position.z);
            normals.push(normal.x, normal.y, normal.z);
            uvs.push(col / subdivisionsX, 1.0 - row / subdivisionsY);
        }
    }
    for (row = 0; row < subdivisionsY; row++) {
        for (col = 0; col < subdivisionsX; col++) {
            indices.push(col + 1 + (row + 1) * (subdivisionsX + 1));
            indices.push(col + 1 + row * (subdivisionsX + 1));
            indices.push(col + row * (subdivisionsX + 1));
            indices.push(col + (row + 1) * (subdivisionsX + 1));
            indices.push(col + 1 + (row + 1) * (subdivisionsX + 1));
            indices.push(col + row * (subdivisionsX + 1));
        }
    }
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledGround = function (options) {
    var xmin = (options.xmin !== undefined && options.xmin !== null) ? options.xmin : -1.0;
    var zmin = (options.zmin !== undefined && options.zmin !== null) ? options.zmin : -1.0;
    var xmax = (options.xmax !== undefined && options.xmax !== null) ? options.xmax : 1.0;
    var zmax = (options.zmax !== undefined && options.zmax !== null) ? options.zmax : 1.0;
    var subdivisions = options.subdivisions || { w: 1, h: 1 };
    var precision = options.precision || { w: 1, h: 1 };
    var indices = new Array();
    var positions = new Array();
    var normals = new Array();
    var uvs = new Array();
    var row, col, tileRow, tileCol;
    subdivisions.h = (subdivisions.h < 1) ? 1 : subdivisions.h;
    subdivisions.w = (subdivisions.w < 1) ? 1 : subdivisions.w;
    precision.w = (precision.w < 1) ? 1 : precision.w;
    precision.h = (precision.h < 1) ? 1 : precision.h;
    var tileSize = {
        'w': (xmax - xmin) / subdivisions.w,
        'h': (zmax - zmin) / subdivisions.h
    };
    function applyTile(xTileMin, zTileMin, xTileMax, zTileMax) {
        // Indices
        var base = positions.length / 3;
        var rowLength = precision.w + 1;
        for (row = 0; row < precision.h; row++) {
            for (col = 0; col < precision.w; col++) {
                var square = [
                    base + col + row * rowLength,
                    base + (col + 1) + row * rowLength,
                    base + (col + 1) + (row + 1) * rowLength,
                    base + col + (row + 1) * rowLength
                ];
                indices.push(square[1]);
                indices.push(square[2]);
                indices.push(square[3]);
                indices.push(square[0]);
                indices.push(square[1]);
                indices.push(square[3]);
            }
        }
        // Position, normals and uvs
        var position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        var normal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1.0, 0);
        for (row = 0; row <= precision.h; row++) {
            position.z = (row * (zTileMax - zTileMin)) / precision.h + zTileMin;
            for (col = 0; col <= precision.w; col++) {
                position.x = (col * (xTileMax - xTileMin)) / precision.w + xTileMin;
                position.y = 0;
                positions.push(position.x, position.y, position.z);
                normals.push(normal.x, normal.y, normal.z);
                uvs.push(col / precision.w, row / precision.h);
            }
        }
    }
    for (tileRow = 0; tileRow < subdivisions.h; tileRow++) {
        for (tileCol = 0; tileCol < subdivisions.w; tileCol++) {
            applyTile(xmin + tileCol * tileSize.w, zmin + tileRow * tileSize.h, xmin + (tileCol + 1) * tileSize.w, zmin + (tileRow + 1) * tileSize.h);
        }
    }
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateGroundFromHeightMap = function (options) {
    var indices = [];
    var positions = [];
    var normals = [];
    var uvs = [];
    var row, col;
    var filter = options.colorFilter || new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"](0.3, 0.59, 0.11);
    var alphaFilter = options.alphaFilter || 0.0;
    var invert = false;
    if (options.minHeight > options.maxHeight) {
        invert = true;
        var temp = options.maxHeight;
        options.maxHeight = options.minHeight;
        options.minHeight = temp;
    }
    // Vertices
    for (row = 0; row <= options.subdivisions; row++) {
        for (col = 0; col <= options.subdivisions; col++) {
            var position = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]((col * options.width) / options.subdivisions - (options.width / 2.0), 0, ((options.subdivisions - row) * options.height) / options.subdivisions - (options.height / 2.0));
            // Compute height
            var heightMapX = (((position.x + options.width / 2) / options.width) * (options.bufferWidth - 1)) | 0;
            var heightMapY = ((1.0 - (position.z + options.height / 2) / options.height) * (options.bufferHeight - 1)) | 0;
            var pos = (heightMapX + heightMapY * options.bufferWidth) * 4;
            var r = options.buffer[pos] / 255.0;
            var g = options.buffer[pos + 1] / 255.0;
            var b = options.buffer[pos + 2] / 255.0;
            var a = options.buffer[pos + 3] / 255.0;
            if (invert) {
                r = 1.0 - r;
                g = 1.0 - g;
                b = 1.0 - b;
            }
            var gradient = r * filter.r + g * filter.g + b * filter.b;
            // If our alpha channel is not within our filter then we will assign a 'special' height
            // Then when building the indices, we will ignore any vertex that is using the special height
            if (a >= alphaFilter) {
                position.y = options.minHeight + (options.maxHeight - options.minHeight) * gradient;
            }
            else {
                position.y = options.minHeight - _Maths_math_constants__WEBPACK_IMPORTED_MODULE_7__["Epsilon"]; // We can't have a height below minHeight, normally.
            }
            // Add  vertex
            positions.push(position.x, position.y, position.z);
            normals.push(0, 0, 0);
            uvs.push(col / options.subdivisions, 1.0 - row / options.subdivisions);
        }
    }
    // Indices
    for (row = 0; row < options.subdivisions; row++) {
        for (col = 0; col < options.subdivisions; col++) {
            // Calculate Indices
            var idx1 = (col + 1 + (row + 1) * (options.subdivisions + 1));
            var idx2 = (col + 1 + row * (options.subdivisions + 1));
            var idx3 = (col + row * (options.subdivisions + 1));
            var idx4 = (col + (row + 1) * (options.subdivisions + 1));
            // Check that all indices are visible (based on our special height)
            // Only display the vertex if all Indices are visible
            // Positions are stored x,y,z for each vertex, hence the * 3 and + 1 for height
            var isVisibleIdx1 = positions[idx1 * 3 + 1] >= options.minHeight;
            var isVisibleIdx2 = positions[idx2 * 3 + 1] >= options.minHeight;
            var isVisibleIdx3 = positions[idx3 * 3 + 1] >= options.minHeight;
            if (isVisibleIdx1 && isVisibleIdx2 && isVisibleIdx3) {
                indices.push(idx1);
                indices.push(idx2);
                indices.push(idx3);
            }
            var isVisibleIdx4 = positions[idx4 * 3 + 1] >= options.minHeight;
            if (isVisibleIdx4 && isVisibleIdx1 && isVisibleIdx3) {
                indices.push(idx4);
                indices.push(idx1);
                indices.push(idx3);
            }
        }
    }
    // Normals
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].ComputeNormals(positions, indices, normals);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreateGround = function (name, width, height, subdivisions, scene, updatable) {
    var options = {
        width: width,
        height: height,
        subdivisions: subdivisions,
        updatable: updatable
    };
    return GroundBuilder.CreateGround(name, options, scene);
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreateTiledGround = function (name, xmin, zmin, xmax, zmax, subdivisions, precision, scene, updatable) {
    var options = {
        xmin: xmin,
        zmin: zmin,
        xmax: xmax,
        zmax: zmax,
        subdivisions: subdivisions,
        precision: precision,
        updatable: updatable
    };
    return GroundBuilder.CreateTiledGround(name, options, scene);
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreateGroundFromHeightMap = function (name, url, width, height, subdivisions, minHeight, maxHeight, scene, updatable, onReady, alphaFilter) {
    var options = {
        width: width,
        height: height,
        subdivisions: subdivisions,
        minHeight: minHeight,
        maxHeight: maxHeight,
        updatable: updatable,
        onReady: onReady,
        alphaFilter: alphaFilter
    };
    return GroundBuilder.CreateGroundFromHeightMap(name, url, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var GroundBuilder = /** @class */ (function () {
    function GroundBuilder() {
    }
    /**
     * Creates a ground mesh
     * * The parameters `width` and `height` (floats, default 1) set the width and height sizes of the ground
     * * The parameter `subdivisions` (positive integer) sets the number of subdivisions per side
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the ground mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#ground
     */
    GroundBuilder.CreateGround = function (name, options, scene) {
        var ground = new _groundMesh__WEBPACK_IMPORTED_MODULE_4__["GroundMesh"](name, scene);
        ground._setReady(false);
        ground._subdivisionsX = options.subdivisionsX || options.subdivisions || 1;
        ground._subdivisionsY = options.subdivisionsY || options.subdivisions || 1;
        ground._width = options.width || 1;
        ground._height = options.height || 1;
        ground._maxX = ground._width / 2;
        ground._maxZ = ground._height / 2;
        ground._minX = -ground._maxX;
        ground._minZ = -ground._maxZ;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateGround(options);
        vertexData.applyToMesh(ground, options.updatable);
        ground._setReady(true);
        return ground;
    };
    /**
     * Creates a tiled ground mesh
     * * The parameters `xmin` and `xmax` (floats, default -1 and 1) set the ground minimum and maximum X coordinates
     * * The parameters `zmin` and `zmax` (floats, default -1 and 1) set the ground minimum and maximum Z coordinates
     * * The parameter `subdivisions` is a javascript object `{w: positive integer, h: positive integer}` (default `{w: 6, h: 6}`). `w` and `h` are the numbers of subdivisions on the ground width and height. Each subdivision is called a tile
     * * The parameter `precision` is a javascript object `{w: positive integer, h: positive integer}` (default `{w: 2, h: 2}`). `w` and `h` are the numbers of subdivisions on the ground width and height of each tile
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the tiled ground mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#tiled-ground
     */
    GroundBuilder.CreateTiledGround = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var tiledGround = new _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"](name, scene);
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledGround(options);
        vertexData.applyToMesh(tiledGround, options.updatable);
        return tiledGround;
    };
    /**
     * Creates a ground mesh from a height map
     * * The parameter `url` sets the URL of the height map image resource.
     * * The parameters `width` and `height` (positive floats, default 10) set the ground width and height sizes.
     * * The parameter `subdivisions` (positive integer, default 1) sets the number of subdivision per side.
     * * The parameter `minHeight` (float, default 0) is the minimum altitude on the ground.
     * * The parameter `maxHeight` (float, default 1) is the maximum altitude on the ground.
     * * The parameter `colorFilter` (optional Color3, default (0.3, 0.59, 0.11) ) is the filter to apply to the image pixel colors to compute the height.
     * * The parameter `onReady` is a javascript callback function that will be called  once the mesh is just built (the height map download can last some time).
     * * The parameter `alphaFilter` will filter any data where the alpha channel is below this value, defaults 0 (all data visible)
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param url defines the url to the height map
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the ground mesh
     * @see https://doc.babylonjs.com/babylon101/height_map
     * @see https://doc.babylonjs.com/how_to/set_shapes#ground-from-a-height-map
     */
    GroundBuilder.CreateGroundFromHeightMap = function (name, url, options, scene) {
        if (scene === void 0) { scene = null; }
        var width = options.width || 10.0;
        var height = options.height || 10.0;
        var subdivisions = options.subdivisions || 1 | 0;
        var minHeight = options.minHeight || 0.0;
        var maxHeight = options.maxHeight || 1.0;
        var filter = options.colorFilter || new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"](0.3, 0.59, 0.11);
        var alphaFilter = options.alphaFilter || 0.0;
        var updatable = options.updatable;
        var onReady = options.onReady;
        scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__["EngineStore"].LastCreatedScene;
        var ground = new _groundMesh__WEBPACK_IMPORTED_MODULE_4__["GroundMesh"](name, scene);
        ground._subdivisionsX = subdivisions;
        ground._subdivisionsY = subdivisions;
        ground._width = width;
        ground._height = height;
        ground._maxX = ground._width / 2.0;
        ground._maxZ = ground._height / 2.0;
        ground._minX = -ground._maxX;
        ground._minZ = -ground._maxZ;
        ground._setReady(false);
        var onload = function (img) {
            // Getting height map data
            var canvas = document.createElement("canvas");
            var context = canvas.getContext("2d");
            if (!context) {
                throw new Error("Unable to get 2d context for CreateGroundFromHeightMap");
            }
            if (scene.isDisposed) {
                return;
            }
            var bufferWidth = img.width;
            var bufferHeight = img.height;
            canvas.width = bufferWidth;
            canvas.height = bufferHeight;
            context.drawImage(img, 0, 0);
            // Create VertexData from map data
            // Cast is due to wrong definition in lib.d.ts from ts 1.3 - https://github.com/Microsoft/TypeScript/issues/949
            var buffer = context.getImageData(0, 0, bufferWidth, bufferHeight).data;
            var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateGroundFromHeightMap({
                width: width, height: height,
                subdivisions: subdivisions,
                minHeight: minHeight, maxHeight: maxHeight, colorFilter: filter,
                buffer: buffer, bufferWidth: bufferWidth, bufferHeight: bufferHeight,
                alphaFilter: alphaFilter
            });
            vertexData.applyToMesh(ground, updatable);
            //execute ready callback, if set
            if (onReady) {
                onReady(ground);
            }
            ground._setReady(true);
        };
        _Misc_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].LoadImage(url, onload, function () { }, scene.offlineProvider);
        return ground;
    };
    return GroundBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/hemisphereBuilder.ts":
/*!**********************************************!*\
  !*** ./Meshes/Builders/hemisphereBuilder.ts ***!
  \**********************************************/
/*! exports provided: HemisphereBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HemisphereBuilder", function() { return HemisphereBuilder; });
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");


/**
 * Creates a hemispheric light
 */
_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateHemisphere = function (name, segments, diameter, scene) {
    var options = {
        segments: segments,
        diameter: diameter
    };
    return HemisphereBuilder.CreateHemisphere(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var HemisphereBuilder = /** @class */ (function () {
    function HemisphereBuilder() {
    }
    /**
     * Creates a hemisphere mesh
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the hemisphere mesh
     */
    HemisphereBuilder.CreateHemisphere = function (name, options, scene) {
        if (!options.diameter) {
            options.diameter = 1;
        }
        if (!options.segments) {
            options.segments = 16;
        }
        var halfSphere = _Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_1__["SphereBuilder"].CreateSphere("", { slice: 0.5, diameter: options.diameter, segments: options.segments }, scene);
        var disc = _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateDisc("", options.diameter / 2, (options.segments * 3) + (4 - options.segments), scene);
        disc.rotation.x = -Math.PI / 2;
        disc.parent = halfSphere;
        var merged = _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].MergeMeshes([disc, halfSphere], true);
        merged.name = name;
        return merged;
    };
    return HemisphereBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/icoSphereBuilder.ts":
/*!*********************************************!*\
  !*** ./Meshes/Builders/icoSphereBuilder.ts ***!
  \*********************************************/
/*! exports provided: IcoSphereBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IcoSphereBuilder", function() { return IcoSphereBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");



_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateIcoSphere = function (options) {
    var sideOrientation = options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].DEFAULTSIDE;
    var radius = options.radius || 1;
    var flat = (options.flat === undefined) ? true : options.flat;
    var subdivisions = options.subdivisions || 4;
    var radiusX = options.radiusX || radius;
    var radiusY = options.radiusY || radius;
    var radiusZ = options.radiusZ || radius;
    var t = (1 + Math.sqrt(5)) / 2;
    // 12 vertex x,y,z
    var ico_vertices = [
        -1, t, -0, 1, t, 0, -1, -t, 0, 1, -t, 0,
        0, -1, -t, 0, 1, -t, 0, -1, t, 0, 1, t,
        t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, -1 // v8-11
    ];
    // index of 3 vertex makes a face of icopshere
    var ico_indices = [
        0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 12, 22, 23,
        1, 5, 20, 5, 11, 4, 23, 22, 13, 22, 18, 6, 7, 1, 8,
        14, 21, 4, 14, 4, 2, 16, 13, 6, 15, 6, 19, 3, 8, 9,
        4, 21, 5, 13, 17, 23, 6, 13, 22, 19, 6, 18, 9, 8, 1
    ];
    // vertex for uv have aliased position, not for UV
    var vertices_unalias_id = [
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
        // vertex alias
        0,
        2,
        3,
        3,
        3,
        4,
        7,
        8,
        9,
        9,
        10,
        11 // 23: B + 12
    ];
    // uv as integer step (not pixels !)
    var ico_vertexuv = [
        5, 1, 3, 1, 6, 4, 0, 0,
        5, 3, 4, 2, 2, 2, 4, 0,
        2, 0, 1, 1, 6, 0, 6, 2,
        // vertex alias (for same vertex on different faces)
        0, 4,
        3, 3,
        4, 4,
        3, 1,
        4, 2,
        4, 4,
        0, 2,
        1, 1,
        2, 2,
        3, 3,
        1, 3,
        2, 4 // 23: B + 12
    ];
    // Vertices[0, 1, ...9, A, B] : position on UV plane
    // '+' indicate duplicate position to be fixed (3,9:0,2,3,4,7,8,A,B)
    // First island of uv mapping
    // v = 4h          3+  2
    // v = 3h        9+  4
    // v = 2h      9+  5   B
    // v = 1h    9   1   0
    // v = 0h  3   8   7   A
    //     u = 0 1 2 3 4 5 6  *a
    // Second island of uv mapping
    // v = 4h  0+  B+  4+
    // v = 3h    A+  2+
    // v = 2h  7+  6   3+
    // v = 1h    8+  3+
    // v = 0h
    //     u = 0 1 2 3 4 5 6  *a
    // Face layout on texture UV mapping
    // ============
    // \ 4  /\ 16 /   ======
    //  \  /  \  /   /\ 11 /
    //   \/ 7  \/   /  \  /
    //    =======  / 10 \/
    //   /\ 17 /\  =======
    //  /  \  /  \ \ 15 /\
    // / 8  \/ 12 \ \  /  \
    // ============  \/ 6  \
    // \ 18 /\  ============
    //  \  /  \ \ 5  /\ 0  /
    //   \/ 13 \ \  /  \  /
    //   =======  \/ 1  \/
    //       =============
    //      /\ 19 /\  2 /\
    //     /  \  /  \  /  \
    //    / 14 \/ 9  \/  3 \
    //   ===================
    // uv step is u:1 or 0.5, v:cos(30)=sqrt(3)/2, ratio approx is 84/97
    var ustep = 138 / 1024;
    var vstep = 239 / 1024;
    var uoffset = 60 / 1024;
    var voffset = 26 / 1024;
    // Second island should have margin, not to touch the first island
    // avoid any borderline artefact in pixel rounding
    var island_u_offset = -40 / 1024;
    var island_v_offset = +20 / 1024;
    // face is either island 0 or 1 :
    // second island is for faces : [4, 7, 8, 12, 13, 16, 17, 18]
    var island = [
        0, 0, 0, 0, 1,
        0, 0, 1, 1, 0,
        0, 0, 1, 1, 0,
        0, 1, 1, 1, 0 //  15 - 19
    ];
    var indices = new Array();
    var positions = new Array();
    var normals = new Array();
    var uvs = new Array();
    var current_indice = 0;
    // prepare array of 3 vector (empty) (to be worked in place, shared for each face)
    var face_vertex_pos = new Array(3);
    var face_vertex_uv = new Array(3);
    var v012;
    for (v012 = 0; v012 < 3; v012++) {
        face_vertex_pos[v012] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        face_vertex_uv[v012] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Zero();
    }
    // create all with normals
    for (var face = 0; face < 20; face++) {
        // 3 vertex per face
        for (v012 = 0; v012 < 3; v012++) {
            // look up vertex 0,1,2 to its index in 0 to 11 (or 23 including alias)
            var v_id = ico_indices[3 * face + v012];
            // vertex have 3D position (x,y,z)
            face_vertex_pos[v012].copyFromFloats(ico_vertices[3 * vertices_unalias_id[v_id]], ico_vertices[3 * vertices_unalias_id[v_id] + 1], ico_vertices[3 * vertices_unalias_id[v_id] + 2]);
            // Normalize to get normal, then scale to radius
            face_vertex_pos[v012].normalize().scaleInPlace(radius);
            // uv Coordinates from vertex ID
            face_vertex_uv[v012].copyFromFloats(ico_vertexuv[2 * v_id] * ustep + uoffset + island[face] * island_u_offset, ico_vertexuv[2 * v_id + 1] * vstep + voffset + island[face] * island_v_offset);
        }
        // Subdivide the face (interpolate pos, norm, uv)
        // - pos is linear interpolation, then projected to sphere (converge polyhedron to sphere)
        // - norm is linear interpolation of vertex corner normal
        //   (to be checked if better to re-calc from face vertex, or if approximation is OK ??? )
        // - uv is linear interpolation
        //
        // Topology is as below for sub-divide by 2
        // vertex shown as v0,v1,v2
        // interp index is i1 to progress in range [v0,v1[
        // interp index is i2 to progress in range [v0,v2[
        // face index as  (i1,i2)  for /\  : (i1,i2),(i1+1,i2),(i1,i2+1)
        //            and (i1,i2)' for \/  : (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
        //
        //
        //                    i2    v2
        //                    ^    ^
        //                   /    / \
        //                  /    /   \
        //                 /    /     \
        //                /    / (0,1) \
        //               /    #---------\
        //              /    / \ (0,0)'/ \
        //             /    /   \     /   \
        //            /    /     \   /     \
        //           /    / (0,0) \ / (1,0) \
        //          /    #---------#---------\
        //              v0                    v1
        //
        //              --------------------> i1
        //
        // interp of (i1,i2):
        //  along i2 :  x0=lerp(v0,v2, i2/S) <---> x1=lerp(v1,v2, i2/S)
        //  along i1 :  lerp(x0,x1, i1/(S-i2))
        //
        // centroid of triangle is needed to get help normal computation
        //  (c1,c2) are used for centroid location
        var interp_vertex = function (i1, i2, c1, c2) {
            // vertex is interpolated from
            //   - face_vertex_pos[0..2]
            //   - face_vertex_uv[0..2]
            var pos_x0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(face_vertex_pos[0], face_vertex_pos[2], i2 / subdivisions);
            var pos_x1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(face_vertex_pos[1], face_vertex_pos[2], i2 / subdivisions);
            var pos_interp = (subdivisions === i2) ? face_vertex_pos[2] : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(pos_x0, pos_x1, i1 / (subdivisions - i2));
            pos_interp.normalize();
            var vertex_normal;
            if (flat) {
                // in flat mode, recalculate normal as face centroid normal
                var centroid_x0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(face_vertex_pos[0], face_vertex_pos[2], c2 / subdivisions);
                var centroid_x1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(face_vertex_pos[1], face_vertex_pos[2], c2 / subdivisions);
                vertex_normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(centroid_x0, centroid_x1, c1 / (subdivisions - c2));
            }
            else {
                // in smooth mode, recalculate normal from each single vertex position
                vertex_normal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](pos_interp.x, pos_interp.y, pos_interp.z);
            }
            // Vertex normal need correction due to X,Y,Z radius scaling
            vertex_normal.x /= radiusX;
            vertex_normal.y /= radiusY;
            vertex_normal.z /= radiusZ;
            vertex_normal.normalize();
            var uv_x0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Lerp(face_vertex_uv[0], face_vertex_uv[2], i2 / subdivisions);
            var uv_x1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Lerp(face_vertex_uv[1], face_vertex_uv[2], i2 / subdivisions);
            var uv_interp = (subdivisions === i2) ? face_vertex_uv[2] : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Lerp(uv_x0, uv_x1, i1 / (subdivisions - i2));
            positions.push(pos_interp.x * radiusX, pos_interp.y * radiusY, pos_interp.z * radiusZ);
            normals.push(vertex_normal.x, vertex_normal.y, vertex_normal.z);
            uvs.push(uv_interp.x, uv_interp.y);
            // push each vertex has member of a face
            // Same vertex can bleong to multiple face, it is pushed multiple time (duplicate vertex are present)
            indices.push(current_indice);
            current_indice++;
        };
        for (var i2 = 0; i2 < subdivisions; i2++) {
            for (var i1 = 0; i1 + i2 < subdivisions; i1++) {
                // face : (i1,i2)  for /\  :
                // interp for : (i1,i2),(i1+1,i2),(i1,i2+1)
                interp_vertex(i1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
                interp_vertex(i1 + 1, i2, i1 + 1.0 / 3, i2 + 1.0 / 3);
                interp_vertex(i1, i2 + 1, i1 + 1.0 / 3, i2 + 1.0 / 3);
                if (i1 + i2 + 1 < subdivisions) {
                    // face : (i1,i2)' for \/  :
                    // interp for (i1+1,i2),(i1+1,i2+1),(i1,i2+1)
                    interp_vertex(i1 + 1, i2, i1 + 2.0 / 3, i2 + 2.0 / 3);
                    interp_vertex(i1 + 1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
                    interp_vertex(i1, i2 + 1, i1 + 2.0 / 3, i2 + 2.0 / 3);
                }
            }
        }
    }
    // Sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateIcoSphere = function (name, options, scene) {
    return IcoSphereBuilder.CreateIcoSphere(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var IcoSphereBuilder = /** @class */ (function () {
    function IcoSphereBuilder() {
    }
    /**
     * Creates a sphere based upon an icosahedron with 20 triangular faces which can be subdivided
     * * The parameter `radius` sets the radius size (float) of the icosphere (default 1)
     * * You can set some different icosphere dimensions, for instance to build an ellipsoid, by using the parameters `radiusX`, `radiusY` and `radiusZ` (all by default have the same value of `radius`)
     * * The parameter `subdivisions` sets the number of subdivisions (postive integer, default 4). The more subdivisions, the more faces on the icosphere whatever its size
     * * The parameter `flat` (boolean, default true) gives each side its own normals. Set it to false to get a smooth continuous light reflection on the surface
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the icosahedron mesh
     * @see https://doc.babylonjs.com/how_to/polyhedra_shapes#icosphere
     */
    IcoSphereBuilder.CreateIcoSphere = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var sphere = new _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        sphere._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateIcoSphere(options);
        vertexData.applyToMesh(sphere, options.updatable);
        return sphere;
    };
    return IcoSphereBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/index.ts":
/*!**********************************!*\
  !*** ./Meshes/Builders/index.ts ***!
  \**********************************/
/*! exports provided: BoxBuilder, SphereBuilder, CylinderBuilder, TorusBuilder, LinesBuilder, PlaneBuilder, GroundBuilder, TiledBoxBuilder, DiscBuilder, RibbonBuilder, HemisphereBuilder, TorusKnotBuilder, PolygonBuilder, ShapeBuilder, LatheBuilder, TiledPlaneBuilder, TubeBuilder, PolyhedronBuilder, IcoSphereBuilder, DecalBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _boxBuilder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxBuilder", function() { return _boxBuilder__WEBPACK_IMPORTED_MODULE_0__["BoxBuilder"]; });

/* harmony import */ var _tiledBoxBuilder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tiledBoxBuilder */ "./Meshes/Builders/tiledBoxBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledBoxBuilder", function() { return _tiledBoxBuilder__WEBPACK_IMPORTED_MODULE_1__["TiledBoxBuilder"]; });

/* harmony import */ var _discBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./discBuilder */ "./Meshes/Builders/discBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DiscBuilder", function() { return _discBuilder__WEBPACK_IMPORTED_MODULE_2__["DiscBuilder"]; });

/* harmony import */ var _ribbonBuilder__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ribbonBuilder */ "./Meshes/Builders/ribbonBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RibbonBuilder", function() { return _ribbonBuilder__WEBPACK_IMPORTED_MODULE_3__["RibbonBuilder"]; });

/* harmony import */ var _sphereBuilder__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereBuilder", function() { return _sphereBuilder__WEBPACK_IMPORTED_MODULE_4__["SphereBuilder"]; });

/* harmony import */ var _hemisphereBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./hemisphereBuilder */ "./Meshes/Builders/hemisphereBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphereBuilder", function() { return _hemisphereBuilder__WEBPACK_IMPORTED_MODULE_5__["HemisphereBuilder"]; });

/* harmony import */ var _cylinderBuilder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderBuilder", function() { return _cylinderBuilder__WEBPACK_IMPORTED_MODULE_6__["CylinderBuilder"]; });

/* harmony import */ var _torusBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./torusBuilder */ "./Meshes/Builders/torusBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusBuilder", function() { return _torusBuilder__WEBPACK_IMPORTED_MODULE_7__["TorusBuilder"]; });

/* harmony import */ var _torusKnotBuilder__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./torusKnotBuilder */ "./Meshes/Builders/torusKnotBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusKnotBuilder", function() { return _torusKnotBuilder__WEBPACK_IMPORTED_MODULE_8__["TorusKnotBuilder"]; });

/* harmony import */ var _linesBuilder__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./linesBuilder */ "./Meshes/Builders/linesBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesBuilder", function() { return _linesBuilder__WEBPACK_IMPORTED_MODULE_9__["LinesBuilder"]; });

/* harmony import */ var _polygonBuilder__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./polygonBuilder */ "./Meshes/Builders/polygonBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonBuilder", function() { return _polygonBuilder__WEBPACK_IMPORTED_MODULE_10__["PolygonBuilder"]; });

/* harmony import */ var _shapeBuilder__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./shapeBuilder */ "./Meshes/Builders/shapeBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShapeBuilder", function() { return _shapeBuilder__WEBPACK_IMPORTED_MODULE_11__["ShapeBuilder"]; });

/* harmony import */ var _latheBuilder__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./latheBuilder */ "./Meshes/Builders/latheBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LatheBuilder", function() { return _latheBuilder__WEBPACK_IMPORTED_MODULE_12__["LatheBuilder"]; });

/* harmony import */ var _planeBuilder__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./planeBuilder */ "./Meshes/Builders/planeBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneBuilder", function() { return _planeBuilder__WEBPACK_IMPORTED_MODULE_13__["PlaneBuilder"]; });

/* harmony import */ var _tiledPlaneBuilder__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./tiledPlaneBuilder */ "./Meshes/Builders/tiledPlaneBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledPlaneBuilder", function() { return _tiledPlaneBuilder__WEBPACK_IMPORTED_MODULE_14__["TiledPlaneBuilder"]; });

/* harmony import */ var _groundBuilder__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./groundBuilder */ "./Meshes/Builders/groundBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundBuilder", function() { return _groundBuilder__WEBPACK_IMPORTED_MODULE_15__["GroundBuilder"]; });

/* harmony import */ var _tubeBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./tubeBuilder */ "./Meshes/Builders/tubeBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TubeBuilder", function() { return _tubeBuilder__WEBPACK_IMPORTED_MODULE_16__["TubeBuilder"]; });

/* harmony import */ var _polyhedronBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./polyhedronBuilder */ "./Meshes/Builders/polyhedronBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolyhedronBuilder", function() { return _polyhedronBuilder__WEBPACK_IMPORTED_MODULE_17__["PolyhedronBuilder"]; });

/* harmony import */ var _icoSphereBuilder__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./icoSphereBuilder */ "./Meshes/Builders/icoSphereBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IcoSphereBuilder", function() { return _icoSphereBuilder__WEBPACK_IMPORTED_MODULE_18__["IcoSphereBuilder"]; });

/* harmony import */ var _decalBuilder__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./decalBuilder */ "./Meshes/Builders/decalBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DecalBuilder", function() { return _decalBuilder__WEBPACK_IMPORTED_MODULE_19__["DecalBuilder"]; });























/***/ }),

/***/ "./Meshes/Builders/latheBuilder.ts":
/*!*****************************************!*\
  !*** ./Meshes/Builders/latheBuilder.ts ***!
  \*****************************************/
/*! exports provided: LatheBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LatheBuilder", function() { return LatheBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ribbonBuilder */ "./Meshes/Builders/ribbonBuilder.ts");



_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateLathe = function (name, shape, radius, tessellation, scene, updatable, sideOrientation) {
    var options = {
        shape: shape,
        radius: radius,
        tessellation: tessellation,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return LatheBuilder.CreateLathe(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var LatheBuilder = /** @class */ (function () {
    function LatheBuilder() {
    }
    /**
     * Creates lathe mesh.
     * The lathe is a shape with a symetry axis : a 2D model shape is rotated around this axis to design the lathe
     * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be rotated in its local space : the shape must be designed in the xOy plane and will be rotated around the Y axis. It's usually a 2D shape, so the Vector3 z coordinates are often set to zero
     * * The parameter `radius` (positive float, default 1) is the radius value of the lathe
     * * The parameter `tessellation` (positive integer, default 64) is the side number of the lathe
     * * The parameter `clip` (positive integer, default 0) is the number of sides to not create without effecting the general shape of the sides
     * * The parameter `arc` (positive float, default 1) is the ratio of the lathe. 0.5 builds for instance half a lathe, so an opened shape
     * * The parameter `closed` (boolean, default true) opens/closes the lathe circumference. This should be set to false when used with the parameter "arc"
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the lathe mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#lathe
     */
    LatheBuilder.CreateLathe = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var arc = options.arc ? ((options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc) : 1.0;
        var closed = (options.closed === undefined) ? true : options.closed;
        var shape = options.shape;
        var radius = options.radius || 1;
        var tessellation = options.tessellation || 64;
        var clip = options.clip || 0;
        var updatable = options.updatable;
        var sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        var cap = options.cap || _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP;
        var pi2 = Math.PI * 2;
        var paths = new Array();
        var invertUV = options.invertUV || false;
        var i = 0;
        var p = 0;
        var step = pi2 / tessellation * arc;
        var rotated;
        var path = new Array();
        for (i = 0; i <= tessellation - clip; i++) {
            var path = [];
            if (cap == _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_START || cap == _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_ALL) {
                path.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, shape[0].y, 0));
                path.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](Math.cos(i * step) * shape[0].x * radius, shape[0].y, Math.sin(i * step) * shape[0].x * radius));
            }
            for (p = 0; p < shape.length; p++) {
                rotated = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](Math.cos(i * step) * shape[p].x * radius, shape[p].y, Math.sin(i * step) * shape[p].x * radius);
                path.push(rotated);
            }
            if (cap == _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_END || cap == _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_ALL) {
                path.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](Math.cos(i * step) * shape[shape.length - 1].x * radius, shape[shape.length - 1].y, Math.sin(i * step) * shape[shape.length - 1].x * radius));
                path.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, shape[shape.length - 1].y, 0));
            }
            paths.push(path);
        }
        // lathe ribbon
        var lathe = _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__["RibbonBuilder"].CreateRibbon(name, { pathArray: paths, closeArray: closed, sideOrientation: sideOrientation, updatable: updatable, invertUV: invertUV, frontUVs: options.frontUVs, backUVs: options.backUVs }, scene);
        return lathe;
    };
    return LatheBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/linesBuilder.ts":
/*!*****************************************!*\
  !*** ./Meshes/Builders/linesBuilder.ts ***!
  \*****************************************/
/*! exports provided: LinesBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinesBuilder", function() { return LinesBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Meshes/linesMesh */ "./Meshes/linesMesh.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");





_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateLineSystem = function (options) {
    var indices = [];
    var positions = [];
    var lines = options.lines;
    var colors = options.colors;
    var vertexColors = [];
    var idx = 0;
    for (var l = 0; l < lines.length; l++) {
        var points = lines[l];
        for (var index = 0; index < points.length; index++) {
            positions.push(points[index].x, points[index].y, points[index].z);
            if (colors) {
                var color = colors[l];
                vertexColors.push(color[index].r, color[index].g, color[index].b, color[index].a);
            }
            if (index > 0) {
                indices.push(idx - 1);
                indices.push(idx);
            }
            idx++;
        }
    }
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    if (colors) {
        vertexData.colors = vertexColors;
    }
    return vertexData;
};
_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateDashedLines = function (options) {
    var dashSize = options.dashSize || 3;
    var gapSize = options.gapSize || 1;
    var dashNb = options.dashNb || 200;
    var points = options.points;
    var positions = new Array();
    var indices = new Array();
    var curvect = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    var lg = 0;
    var nb = 0;
    var shft = 0;
    var dashshft = 0;
    var curshft = 0;
    var idx = 0;
    var i = 0;
    for (i = 0; i < points.length - 1; i++) {
        points[i + 1].subtractToRef(points[i], curvect);
        lg += curvect.length();
    }
    shft = lg / dashNb;
    dashshft = dashSize * shft / (dashSize + gapSize);
    for (i = 0; i < points.length - 1; i++) {
        points[i + 1].subtractToRef(points[i], curvect);
        nb = Math.floor(curvect.length() / shft);
        curvect.normalize();
        for (var j = 0; j < nb; j++) {
            curshft = shft * j;
            positions.push(points[i].x + curshft * curvect.x, points[i].y + curshft * curvect.y, points[i].z + curshft * curvect.z);
            positions.push(points[i].x + (curshft + dashshft) * curvect.x, points[i].y + (curshft + dashshft) * curvect.y, points[i].z + (curshft + dashshft) * curvect.z);
            indices.push(idx, idx + 1);
            idx += 2;
        }
    }
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
    vertexData.positions = positions;
    vertexData.indices = indices;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateLines = function (name, points, scene, updatable, instance) {
    if (scene === void 0) { scene = null; }
    if (updatable === void 0) { updatable = false; }
    if (instance === void 0) { instance = null; }
    var options = {
        points: points,
        updatable: updatable,
        instance: instance
    };
    return LinesBuilder.CreateLines(name, options, scene);
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateDashedLines = function (name, points, dashSize, gapSize, dashNb, scene, updatable, instance) {
    if (scene === void 0) { scene = null; }
    var options = {
        points: points,
        dashSize: dashSize,
        gapSize: gapSize,
        dashNb: dashNb,
        updatable: updatable,
        instance: instance
    };
    return LinesBuilder.CreateDashedLines(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var LinesBuilder = /** @class */ (function () {
    function LinesBuilder() {
    }
    /**
     * Creates a line system mesh. A line system is a pool of many lines gathered in a single mesh
     * * A line system mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of lines as an input parameter
     * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineSystem to this static function
     * * The parameter `lines` is an array of lines, each line being an array of successive Vector3
     * * The optional parameter `instance` is an instance of an existing LineSystem object to be updated with the passed `lines` parameter
     * * The optional parameter `colors` is an array of line colors, each line colors being an array of successive Color4, one per line point
     * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need the alpha blending (faster)
     * * Updating a simple Line mesh, you just need to update every line in the `lines` array : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#lines-and-dashedlines
     * * When updating an instance, remember that only line point positions can change, not the number of points, neither the number of lines
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#line-system
     * @param name defines the name of the new line system
     * @param options defines the options used to create the line system
     * @param scene defines the hosting scene
     * @returns a new line system mesh
     */
    LinesBuilder.CreateLineSystem = function (name, options, scene) {
        var instance = options.instance;
        var lines = options.lines;
        var colors = options.colors;
        if (instance) { // lines update
            var positions = instance.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind);
            var vertexColor;
            var lineColors;
            if (colors) {
                vertexColor = instance.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].ColorKind);
            }
            var i = 0;
            var c = 0;
            for (var l = 0; l < lines.length; l++) {
                var points = lines[l];
                for (var p = 0; p < points.length; p++) {
                    positions[i] = points[p].x;
                    positions[i + 1] = points[p].y;
                    positions[i + 2] = points[p].z;
                    if (colors && vertexColor) {
                        lineColors = colors[l];
                        vertexColor[c] = lineColors[p].r;
                        vertexColor[c + 1] = lineColors[p].g;
                        vertexColor[c + 2] = lineColors[p].b;
                        vertexColor[c + 3] = lineColors[p].a;
                        c += 4;
                    }
                    i += 3;
                }
            }
            instance.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind, positions, false, false);
            if (colors && vertexColor) {
                instance.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].ColorKind, vertexColor, false, false);
            }
            return instance;
        }
        // line system creation
        var useVertexColor = (colors) ? true : false;
        var lineSystem = new _Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__["LinesMesh"](name, scene, null, undefined, undefined, useVertexColor, options.useVertexAlpha);
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateLineSystem(options);
        vertexData.applyToMesh(lineSystem, options.updatable);
        return lineSystem;
    };
    /**
     * Creates a line mesh
     * A line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter
     * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function
     * * The parameter `points` is an array successive Vector3
     * * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#lines-and-dashedlines
     * * The optional parameter `colors` is an array of successive Color4, one per line point
     * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need alpha blending (faster)
     * * When updating an instance, remember that only point positions can change, not the number of points
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#lines
     * @param name defines the name of the new line system
     * @param options defines the options used to create the line system
     * @param scene defines the hosting scene
     * @returns a new line mesh
     */
    LinesBuilder.CreateLines = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var colors = (options.colors) ? [options.colors] : null;
        var lines = LinesBuilder.CreateLineSystem(name, { lines: [options.points], updatable: options.updatable, instance: options.instance, colors: colors, useVertexAlpha: options.useVertexAlpha }, scene);
        return lines;
    };
    /**
     * Creates a dashed line mesh
     * * A dashed line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter
     * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function
     * * The parameter `points` is an array successive Vector3
     * * The parameter `dashNb` is the intended total number of dashes (positive integer, default 200)
     * * The parameter `dashSize` is the size of the dashes relatively the dash number (positive float, default 3)
     * * The parameter `gapSize` is the size of the gap between two successive dashes relatively the dash number (positive float, default 1)
     * * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#lines-and-dashedlines
     * * When updating an instance, remember that only point positions can change, not the number of points
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the dashed line mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#dashed-lines
     */
    LinesBuilder.CreateDashedLines = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var points = options.points;
        var instance = options.instance;
        var gapSize = options.gapSize || 1;
        var dashSize = options.dashSize || 3;
        if (instance) { //  dashed lines update
            var positionFunction = function (positions) {
                var curvect = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                var nbSeg = positions.length / 6;
                var lg = 0;
                var nb = 0;
                var shft = 0;
                var dashshft = 0;
                var curshft = 0;
                var p = 0;
                var i = 0;
                var j = 0;
                for (i = 0; i < points.length - 1; i++) {
                    points[i + 1].subtractToRef(points[i], curvect);
                    lg += curvect.length();
                }
                shft = lg / nbSeg;
                var dashSize = instance._creationDataStorage.dashSize;
                var gapSize = instance._creationDataStorage.gapSize;
                dashshft = dashSize * shft / (dashSize + gapSize);
                for (i = 0; i < points.length - 1; i++) {
                    points[i + 1].subtractToRef(points[i], curvect);
                    nb = Math.floor(curvect.length() / shft);
                    curvect.normalize();
                    j = 0;
                    while (j < nb && p < positions.length) {
                        curshft = shft * j;
                        positions[p] = points[i].x + curshft * curvect.x;
                        positions[p + 1] = points[i].y + curshft * curvect.y;
                        positions[p + 2] = points[i].z + curshft * curvect.z;
                        positions[p + 3] = points[i].x + (curshft + dashshft) * curvect.x;
                        positions[p + 4] = points[i].y + (curshft + dashshft) * curvect.y;
                        positions[p + 5] = points[i].z + (curshft + dashshft) * curvect.z;
                        p += 6;
                        j++;
                    }
                }
                while (p < positions.length) {
                    positions[p] = points[i].x;
                    positions[p + 1] = points[i].y;
                    positions[p + 2] = points[i].z;
                    p += 3;
                }
            };
            instance.updateMeshPositions(positionFunction, false);
            return instance;
        }
        // dashed lines creation
        var dashedLines = new _Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__["LinesMesh"](name, scene);
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateDashedLines(options);
        vertexData.applyToMesh(dashedLines, options.updatable);
        dashedLines._creationDataStorage = new _mesh__WEBPACK_IMPORTED_MODULE_1__["_CreationDataStorage"]();
        dashedLines._creationDataStorage.dashSize = dashSize;
        dashedLines._creationDataStorage.gapSize = gapSize;
        return dashedLines;
    };
    return LinesBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/planeBuilder.ts":
/*!*****************************************!*\
  !*** ./Meshes/Builders/planeBuilder.ts ***!
  \*****************************************/
/*! exports provided: PlaneBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlaneBuilder", function() { return PlaneBuilder; });
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");


_mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].CreatePlane = function (options) {
    var indices = [];
    var positions = [];
    var normals = [];
    var uvs = [];
    var width = options.width || options.size || 1;
    var height = options.height || options.size || 1;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].DEFAULTSIDE;
    // Vertices
    var halfWidth = width / 2.0;
    var halfHeight = height / 2.0;
    positions.push(-halfWidth, -halfHeight, 0);
    normals.push(0, 0, -1.0);
    uvs.push(0.0, 0.0);
    positions.push(halfWidth, -halfHeight, 0);
    normals.push(0, 0, -1.0);
    uvs.push(1.0, 0.0);
    positions.push(halfWidth, halfHeight, 0);
    normals.push(0, 0, -1.0);
    uvs.push(1.0, 1.0);
    positions.push(-halfWidth, halfHeight, 0);
    normals.push(0, 0, -1.0);
    uvs.push(0.0, 1.0);
    // Indices
    indices.push(0);
    indices.push(1);
    indices.push(2);
    indices.push(0);
    indices.push(2);
    indices.push(3);
    // Sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreatePlane = function (name, size, scene, updatable, sideOrientation) {
    var options = {
        size: size,
        width: size,
        height: size,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return PlaneBuilder.CreatePlane(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var PlaneBuilder = /** @class */ (function () {
    function PlaneBuilder() {
    }
    /**
     * Creates a plane mesh
     * * The parameter `size` sets the size (float) of both sides of the plane at once (default 1)
     * * You can set some different plane dimensions by using the parameters `width` and `height` (both by default have the same value of `size`)
     * * The parameter `sourcePlane` is a Plane instance. It builds a mesh plane from a Math plane
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the plane mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#plane
     */
    PlaneBuilder.CreatePlane = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var plane = new _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        plane._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].CreatePlane(options);
        vertexData.applyToMesh(plane, options.updatable);
        if (options.sourcePlane) {
            plane.translate(options.sourcePlane.normal, -options.sourcePlane.d);
            plane.setDirection(options.sourcePlane.normal.scale(-1));
        }
        return plane;
    };
    return PlaneBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/polygonBuilder.ts":
/*!*******************************************!*\
  !*** ./Meshes/Builders/polygonBuilder.ts ***!
  \*******************************************/
/*! exports provided: PolygonBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PolygonBuilder", function() { return PolygonBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _polygonMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../polygonMesh */ "./Meshes/polygonMesh.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Engines/engineStore */ "./Engines/engineStore.ts");







_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreatePolygon = function (polygon, sideOrientation, fUV, fColors, frontUVs, backUVs) {
    var faceUV = fUV || new Array(3);
    var faceColors = fColors;
    var colors = [];
    // default face colors and UV if undefined
    for (var f = 0; f < 3; f++) {
        if (faceUV[f] === undefined) {
            faceUV[f] = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0, 0, 1, 1);
        }
        if (faceColors && faceColors[f] === undefined) {
            faceColors[f] = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1, 1, 1, 1);
        }
    }
    var positions = polygon.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind);
    var normals = polygon.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind);
    var uvs = polygon.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].UVKind);
    var indices = polygon.getIndices();
    // set face colours and textures
    var idx = 0;
    var face = 0;
    for (var index = 0; index < normals.length; index += 3) {
        //Edge Face  no. 1
        if (Math.abs(normals[index + 1]) < 0.001) {
            face = 1;
        }
        //Top Face  no. 0
        if (Math.abs(normals[index + 1] - 1) < 0.001) {
            face = 0;
        }
        //Bottom Face  no. 2
        if (Math.abs(normals[index + 1] + 1) < 0.001) {
            face = 2;
        }
        idx = index / 3;
        uvs[2 * idx] = (1 - uvs[2 * idx]) * faceUV[face].x + uvs[2 * idx] * faceUV[face].z;
        uvs[2 * idx + 1] = (1 - uvs[2 * idx + 1]) * faceUV[face].y + uvs[2 * idx + 1] * faceUV[face].w;
        if (faceColors) {
            colors.push(faceColors[face].r, faceColors[face].g, faceColors[face].b, faceColors[face].a);
        }
    }
    // sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, frontUVs, backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    if (faceColors) {
        var totalColors = (sideOrientation === _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DOUBLESIDE) ? colors.concat(colors) : colors;
        vertexData.colors = totalColors;
    }
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreatePolygon = function (name, shape, scene, holes, updatable, sideOrientation, earcutInjection) {
    if (earcutInjection === void 0) { earcutInjection = earcut; }
    var options = {
        shape: shape,
        holes: holes,
        updatable: updatable,
        sideOrientation: sideOrientation
    };
    return PolygonBuilder.CreatePolygon(name, options, scene, earcutInjection);
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].ExtrudePolygon = function (name, shape, depth, scene, holes, updatable, sideOrientation, earcutInjection) {
    if (earcutInjection === void 0) { earcutInjection = earcut; }
    var options = {
        shape: shape,
        holes: holes,
        depth: depth,
        updatable: updatable,
        sideOrientation: sideOrientation
    };
    return PolygonBuilder.ExtrudePolygon(name, options, scene, earcutInjection);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var PolygonBuilder = /** @class */ (function () {
    function PolygonBuilder() {
    }
    /**
     * Creates a polygon mesh
     * The polygon's shape will depend on the input parameters and is constructed parallel to a ground mesh
     * * The parameter `shape` is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors
     * * You can set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4)
     * * Remember you can only change the shape positions, not their number when updating a polygon
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @param earcutInjection can be used to inject your own earcut reference
     * @returns the polygon mesh
     */
    PolygonBuilder.CreatePolygon = function (name, options, scene, earcutInjection) {
        if (scene === void 0) { scene = null; }
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        var shape = options.shape;
        var holes = options.holes || [];
        var depth = options.depth || 0;
        var contours = [];
        var hole = [];
        for (var i = 0; i < shape.length; i++) {
            contours[i] = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](shape[i].x, shape[i].z);
        }
        var epsilon = 0.00000001;
        if (contours[0].equalsWithEpsilon(contours[contours.length - 1], epsilon)) {
            contours.pop();
        }
        var polygonTriangulation = new _polygonMesh__WEBPACK_IMPORTED_MODULE_4__["PolygonMeshBuilder"](name, contours, scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__["EngineStore"].LastCreatedScene, earcutInjection);
        for (var hNb = 0; hNb < holes.length; hNb++) {
            hole = [];
            for (var hPoint = 0; hPoint < holes[hNb].length; hPoint++) {
                hole.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](holes[hNb][hPoint].x, holes[hNb][hPoint].z));
            }
            polygonTriangulation.addHole(hole);
        }
        var polygon = polygonTriangulation.build(options.updatable, depth);
        polygon._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreatePolygon(polygon, options.sideOrientation, options.faceUV, options.faceColors, options.frontUVs, options.backUVs);
        vertexData.applyToMesh(polygon, options.updatable);
        return polygon;
    };
    /**
     * Creates an extruded polygon mesh, with depth in the Y direction.
     * * You can set different colors and different images to the top, bottom and extruded side by using the parameters `faceColors` (an array of 3 Color3 elements) and `faceUV` (an array of 3 Vector4 elements)
     * @see https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @param earcutInjection can be used to inject your own earcut reference
     * @returns the polygon mesh
     */
    PolygonBuilder.ExtrudePolygon = function (name, options, scene, earcutInjection) {
        if (scene === void 0) { scene = null; }
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        return PolygonBuilder.CreatePolygon(name, options, scene, earcutInjection);
    };
    return PolygonBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/polyhedronBuilder.ts":
/*!**********************************************!*\
  !*** ./Meshes/Builders/polyhedronBuilder.ts ***!
  \**********************************************/
/*! exports provided: PolyhedronBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PolyhedronBuilder", function() { return PolyhedronBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");




_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreatePolyhedron = function (options) {
    // provided polyhedron types :
    // 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
    // 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)
    var polyhedra = [];
    polyhedra[0] = { vertex: [[0, 0, 1.732051], [1.632993, 0, -0.5773503], [-0.8164966, 1.414214, -0.5773503], [-0.8164966, -1.414214, -0.5773503]], face: [[0, 1, 2], [0, 2, 3], [0, 3, 1], [1, 3, 2]] };
    polyhedra[1] = { vertex: [[0, 0, 1.414214], [1.414214, 0, 0], [0, 1.414214, 0], [-1.414214, 0, 0], [0, -1.414214, 0], [0, 0, -1.414214]], face: [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1], [1, 4, 5], [1, 5, 2], [2, 5, 3], [3, 5, 4]] };
    polyhedra[2] = {
        vertex: [[0, 0, 1.070466], [0.7136442, 0, 0.7978784], [-0.3568221, 0.618034, 0.7978784], [-0.3568221, -0.618034, 0.7978784], [0.7978784, 0.618034, 0.3568221], [0.7978784, -0.618034, 0.3568221], [-0.9341724, 0.381966, 0.3568221], [0.1362939, 1, 0.3568221], [0.1362939, -1, 0.3568221], [-0.9341724, -0.381966, 0.3568221], [0.9341724, 0.381966, -0.3568221], [0.9341724, -0.381966, -0.3568221], [-0.7978784, 0.618034, -0.3568221], [-0.1362939, 1, -0.3568221], [-0.1362939, -1, -0.3568221], [-0.7978784, -0.618034, -0.3568221], [0.3568221, 0.618034, -0.7978784], [0.3568221, -0.618034, -0.7978784], [-0.7136442, 0, -0.7978784], [0, 0, -1.070466]],
        face: [[0, 1, 4, 7, 2], [0, 2, 6, 9, 3], [0, 3, 8, 5, 1], [1, 5, 11, 10, 4], [2, 7, 13, 12, 6], [3, 9, 15, 14, 8], [4, 10, 16, 13, 7], [5, 8, 14, 17, 11], [6, 12, 18, 15, 9], [10, 11, 17, 19, 16], [12, 13, 16, 19, 18], [14, 15, 18, 19, 17]]
    };
    polyhedra[3] = {
        vertex: [[0, 0, 1.175571], [1.051462, 0, 0.5257311], [0.3249197, 1, 0.5257311], [-0.8506508, 0.618034, 0.5257311], [-0.8506508, -0.618034, 0.5257311], [0.3249197, -1, 0.5257311], [0.8506508, 0.618034, -0.5257311], [0.8506508, -0.618034, -0.5257311], [-0.3249197, 1, -0.5257311], [-1.051462, 0, -0.5257311], [-0.3249197, -1, -0.5257311], [0, 0, -1.175571]],
        face: [[0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 1], [1, 5, 7], [1, 7, 6], [1, 6, 2], [2, 6, 8], [2, 8, 3], [3, 8, 9], [3, 9, 4], [4, 9, 10], [4, 10, 5], [5, 10, 7], [6, 7, 11], [6, 11, 8], [7, 10, 11], [8, 11, 9], [9, 11, 10]]
    };
    polyhedra[4] = {
        vertex: [[0, 0, 1.070722], [0.7148135, 0, 0.7971752], [-0.104682, 0.7071068, 0.7971752], [-0.6841528, 0.2071068, 0.7971752], [-0.104682, -0.7071068, 0.7971752], [0.6101315, 0.7071068, 0.5236279], [1.04156, 0.2071068, 0.1367736], [0.6101315, -0.7071068, 0.5236279], [-0.3574067, 1, 0.1367736], [-0.7888348, -0.5, 0.5236279], [-0.9368776, 0.5, 0.1367736], [-0.3574067, -1, 0.1367736], [0.3574067, 1, -0.1367736], [0.9368776, -0.5, -0.1367736], [0.7888348, 0.5, -0.5236279], [0.3574067, -1, -0.1367736], [-0.6101315, 0.7071068, -0.5236279], [-1.04156, -0.2071068, -0.1367736], [-0.6101315, -0.7071068, -0.5236279], [0.104682, 0.7071068, -0.7971752], [0.6841528, -0.2071068, -0.7971752], [0.104682, -0.7071068, -0.7971752], [-0.7148135, 0, -0.7971752], [0, 0, -1.070722]],
        face: [[0, 2, 3], [1, 6, 5], [4, 9, 11], [7, 15, 13], [8, 16, 10], [12, 14, 19], [17, 22, 18], [20, 21, 23], [0, 1, 5, 2], [0, 3, 9, 4], [0, 4, 7, 1], [1, 7, 13, 6], [2, 5, 12, 8], [2, 8, 10, 3], [3, 10, 17, 9], [4, 11, 15, 7], [5, 6, 14, 12], [6, 13, 20, 14], [8, 12, 19, 16], [9, 17, 18, 11], [10, 16, 22, 17], [11, 18, 21, 15], [13, 15, 21, 20], [14, 20, 23, 19], [16, 19, 23, 22], [18, 22, 23, 21]]
    };
    polyhedra[5] = { vertex: [[0, 0, 1.322876], [1.309307, 0, 0.1889822], [-0.9819805, 0.8660254, 0.1889822], [0.1636634, -1.299038, 0.1889822], [0.3273268, 0.8660254, -0.9449112], [-0.8183171, -0.4330127, -0.9449112]], face: [[0, 3, 1], [2, 4, 5], [0, 1, 4, 2], [0, 2, 5, 3], [1, 3, 5, 4]] };
    polyhedra[6] = { vertex: [[0, 0, 1.159953], [1.013464, 0, 0.5642542], [-0.3501431, 0.9510565, 0.5642542], [-0.7715208, -0.6571639, 0.5642542], [0.6633206, 0.9510565, -0.03144481], [0.8682979, -0.6571639, -0.3996071], [-1.121664, 0.2938926, -0.03144481], [-0.2348831, -1.063314, -0.3996071], [0.5181548, 0.2938926, -0.9953061], [-0.5850262, -0.112257, -0.9953061]], face: [[0, 1, 4, 2], [0, 2, 6, 3], [1, 5, 8, 4], [3, 6, 9, 7], [5, 7, 9, 8], [0, 3, 7, 5, 1], [2, 4, 8, 9, 6]] };
    polyhedra[7] = { vertex: [[0, 0, 1.118034], [0.8944272, 0, 0.6708204], [-0.2236068, 0.8660254, 0.6708204], [-0.7826238, -0.4330127, 0.6708204], [0.6708204, 0.8660254, 0.2236068], [1.006231, -0.4330127, -0.2236068], [-1.006231, 0.4330127, 0.2236068], [-0.6708204, -0.8660254, -0.2236068], [0.7826238, 0.4330127, -0.6708204], [0.2236068, -0.8660254, -0.6708204], [-0.8944272, 0, -0.6708204], [0, 0, -1.118034]], face: [[0, 1, 4, 2], [0, 2, 6, 3], [1, 5, 8, 4], [3, 6, 10, 7], [5, 9, 11, 8], [7, 10, 11, 9], [0, 3, 7, 9, 5, 1], [2, 4, 8, 11, 10, 6]] };
    polyhedra[8] = { vertex: [[-0.729665, 0.670121, 0.319155], [-0.655235, -0.29213, -0.754096], [-0.093922, -0.607123, 0.537818], [0.702196, 0.595691, 0.485187], [0.776626, -0.36656, -0.588064]], face: [[1, 4, 2], [0, 1, 2], [3, 0, 2], [4, 3, 2], [4, 1, 0, 3]] };
    polyhedra[9] = { vertex: [[-0.868849, -0.100041, 0.61257], [-0.329458, 0.976099, 0.28078], [-0.26629, -0.013796, -0.477654], [-0.13392, -1.034115, 0.229829], [0.738834, 0.707117, -0.307018], [0.859683, -0.535264, -0.338508]], face: [[3, 0, 2], [5, 3, 2], [4, 5, 2], [1, 4, 2], [0, 1, 2], [0, 3, 5, 4, 1]] };
    polyhedra[10] = { vertex: [[-0.610389, 0.243975, 0.531213], [-0.187812, -0.48795, -0.664016], [-0.187812, 0.9759, -0.664016], [0.187812, -0.9759, 0.664016], [0.798201, 0.243975, 0.132803]], face: [[1, 3, 0], [3, 4, 0], [3, 1, 4], [0, 2, 1], [0, 4, 2], [2, 4, 1]] };
    polyhedra[11] = { vertex: [[-1.028778, 0.392027, -0.048786], [-0.640503, -0.646161, 0.621837], [-0.125162, -0.395663, -0.540059], [0.004683, 0.888447, -0.651988], [0.125161, 0.395663, 0.540059], [0.632925, -0.791376, 0.433102], [1.031672, 0.157063, -0.354165]], face: [[3, 2, 0], [2, 1, 0], [2, 5, 1], [0, 4, 3], [0, 1, 4], [4, 1, 5], [2, 3, 6], [3, 4, 6], [5, 2, 6], [4, 5, 6]] };
    polyhedra[12] = { vertex: [[-0.669867, 0.334933, -0.529576], [-0.669867, 0.334933, 0.529577], [-0.4043, 1.212901, 0], [-0.334933, -0.669867, -0.529576], [-0.334933, -0.669867, 0.529577], [0.334933, 0.669867, -0.529576], [0.334933, 0.669867, 0.529577], [0.4043, -1.212901, 0], [0.669867, -0.334933, -0.529576], [0.669867, -0.334933, 0.529577]], face: [[8, 9, 7], [6, 5, 2], [3, 8, 7], [5, 0, 2], [4, 3, 7], [0, 1, 2], [9, 4, 7], [1, 6, 2], [9, 8, 5, 6], [8, 3, 0, 5], [3, 4, 1, 0], [4, 9, 6, 1]] };
    polyhedra[13] = { vertex: [[-0.931836, 0.219976, -0.264632], [-0.636706, 0.318353, 0.692816], [-0.613483, -0.735083, -0.264632], [-0.326545, 0.979634, 0], [-0.318353, -0.636706, 0.692816], [-0.159176, 0.477529, -0.856368], [0.159176, -0.477529, -0.856368], [0.318353, 0.636706, 0.692816], [0.326545, -0.979634, 0], [0.613482, 0.735082, -0.264632], [0.636706, -0.318353, 0.692816], [0.931835, -0.219977, -0.264632]], face: [[11, 10, 8], [7, 9, 3], [6, 11, 8], [9, 5, 3], [2, 6, 8], [5, 0, 3], [4, 2, 8], [0, 1, 3], [10, 4, 8], [1, 7, 3], [10, 11, 9, 7], [11, 6, 5, 9], [6, 2, 0, 5], [2, 4, 1, 0], [4, 10, 7, 1]] };
    polyhedra[14] = {
        vertex: [[-0.93465, 0.300459, -0.271185], [-0.838689, -0.260219, -0.516017], [-0.711319, 0.717591, 0.128359], [-0.710334, -0.156922, 0.080946], [-0.599799, 0.556003, -0.725148], [-0.503838, -0.004675, -0.969981], [-0.487004, 0.26021, 0.48049], [-0.460089, -0.750282, -0.512622], [-0.376468, 0.973135, -0.325605], [-0.331735, -0.646985, 0.084342], [-0.254001, 0.831847, 0.530001], [-0.125239, -0.494738, -0.966586], [0.029622, 0.027949, 0.730817], [0.056536, -0.982543, -0.262295], [0.08085, 1.087391, 0.076037], [0.125583, -0.532729, 0.485984], [0.262625, 0.599586, 0.780328], [0.391387, -0.726999, -0.716259], [0.513854, -0.868287, 0.139347], [0.597475, 0.85513, 0.326364], [0.641224, 0.109523, 0.783723], [0.737185, -0.451155, 0.538891], [0.848705, -0.612742, -0.314616], [0.976075, 0.365067, 0.32976], [1.072036, -0.19561, 0.084927]],
        face: [[15, 18, 21], [12, 20, 16], [6, 10, 2], [3, 0, 1], [9, 7, 13], [2, 8, 4, 0], [0, 4, 5, 1], [1, 5, 11, 7], [7, 11, 17, 13], [13, 17, 22, 18], [18, 22, 24, 21], [21, 24, 23, 20], [20, 23, 19, 16], [16, 19, 14, 10], [10, 14, 8, 2], [15, 9, 13, 18], [12, 15, 21, 20], [6, 12, 16, 10], [3, 6, 2, 0], [9, 3, 1, 7], [9, 15, 12, 6, 3], [22, 17, 11, 5, 4, 8, 14, 19, 23, 24]]
    };
    var type = options.type && (options.type < 0 || options.type >= polyhedra.length) ? 0 : options.type || 0;
    var size = options.size;
    var sizeX = options.sizeX || size || 1;
    var sizeY = options.sizeY || size || 1;
    var sizeZ = options.sizeZ || size || 1;
    var data = options.custom || polyhedra[type];
    var nbfaces = data.face.length;
    var faceUV = options.faceUV || new Array(nbfaces);
    var faceColors = options.faceColors;
    var flat = (options.flat === undefined) ? true : options.flat;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DEFAULTSIDE;
    var positions = new Array();
    var indices = new Array();
    var normals = new Array();
    var uvs = new Array();
    var colors = new Array();
    var index = 0;
    var faceIdx = 0; // face cursor in the array "indexes"
    var indexes = new Array();
    var i = 0;
    var f = 0;
    var u, v, ang, x, y, tmp;
    // default face colors and UV if undefined
    if (flat) {
        for (f = 0; f < nbfaces; f++) {
            if (faceColors && faceColors[f] === undefined) {
                faceColors[f] = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1, 1, 1, 1);
            }
            if (faceUV && faceUV[f] === undefined) {
                faceUV[f] = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0, 0, 1, 1);
            }
        }
    }
    if (!flat) {
        for (i = 0; i < data.vertex.length; i++) {
            positions.push(data.vertex[i][0] * sizeX, data.vertex[i][1] * sizeY, data.vertex[i][2] * sizeZ);
            uvs.push(0, 0);
        }
        for (f = 0; f < nbfaces; f++) {
            for (i = 0; i < data.face[f].length - 2; i++) {
                indices.push(data.face[f][0], data.face[f][i + 2], data.face[f][i + 1]);
            }
        }
    }
    else {
        for (f = 0; f < nbfaces; f++) {
            var fl = data.face[f].length; // number of vertices of the current face
            ang = 2 * Math.PI / fl;
            x = 0.5 * Math.tan(ang / 2);
            y = 0.5;
            // positions, uvs, colors
            for (i = 0; i < fl; i++) {
                // positions
                positions.push(data.vertex[data.face[f][i]][0] * sizeX, data.vertex[data.face[f][i]][1] * sizeY, data.vertex[data.face[f][i]][2] * sizeZ);
                indexes.push(index);
                index++;
                // uvs
                u = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * (0.5 + x);
                v = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * (y - 0.5);
                uvs.push(u, v);
                tmp = x * Math.cos(ang) - y * Math.sin(ang);
                y = x * Math.sin(ang) + y * Math.cos(ang);
                x = tmp;
                // colors
                if (faceColors) {
                    colors.push(faceColors[f].r, faceColors[f].g, faceColors[f].b, faceColors[f].a);
                }
            }
            // indices from indexes
            for (i = 0; i < fl - 2; i++) {
                indices.push(indexes[0 + faceIdx], indexes[i + 2 + faceIdx], indexes[i + 1 + faceIdx]);
            }
            faceIdx += fl;
        }
    }
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].ComputeNormals(positions, indices, normals);
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.positions = positions;
    vertexData.indices = indices;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    if (faceColors && flat) {
        vertexData.colors = colors;
    }
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].CreatePolyhedron = function (name, options, scene) {
    return PolyhedronBuilder.CreatePolyhedron(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var PolyhedronBuilder = /** @class */ (function () {
    function PolyhedronBuilder() {
    }
    /**
     * Creates a polyhedron mesh
     * * The parameter `type` (positive integer, max 14, default 0) sets the polyhedron type to build among the 15 embbeded types. Please refer to the type sheet in the tutorial to choose the wanted type
     * * The parameter `size` (positive float, default 1) sets the polygon size
     * * You can overwrite the `size` on each dimension bu using the parameters `sizeX`, `sizeY` or `sizeZ` (positive floats, default to `size` value)
     * * You can build other polyhedron types than the 15 embbeded ones by setting the parameter `custom` (`polyhedronObject`, default null). If you set the parameter `custom`, this overwrittes the parameter `type`
     * * A `polyhedronObject` is a formatted javascript object. You'll find a full file with pre-set polyhedra here : https://github.com/BabylonJS/Extensions/tree/master/Polyhedron
     * * You can set the color and the UV of each side of the polyhedron with the parameters `faceColors` (Color4, default `(1, 1, 1, 1)`) and faceUV (Vector4, default `(0, 0, 1, 1)`)
     * * To understand how to set `faceUV` or `faceColors`, please read this by considering the right number of faces of your polyhedron, instead of only 6 for the box : https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * * The parameter `flat` (boolean, default true). If set to false, it gives the polyhedron a single global face, so less vertices and shared normals. In this case, `faceColors` and `faceUV` are ignored
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the polyhedron mesh
     * @see https://doc.babylonjs.com/how_to/polyhedra_shapes
     */
    PolyhedronBuilder.CreatePolyhedron = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var polyhedron = new _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        polyhedron._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreatePolyhedron(options);
        vertexData.applyToMesh(polyhedron, options.updatable);
        return polyhedron;
    };
    return PolyhedronBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/ribbonBuilder.ts":
/*!******************************************!*\
  !*** ./Meshes/Builders/ribbonBuilder.ts ***!
  \******************************************/
/*! exports provided: RibbonBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RibbonBuilder", function() { return RibbonBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Culling/boundingInfo */ "./Culling/boundingInfo.ts");





_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateRibbon = function (options) {
    var pathArray = options.pathArray;
    var closeArray = options.closeArray || false;
    var closePath = options.closePath || false;
    var invertUV = options.invertUV || false;
    var defaultOffset = Math.floor(pathArray[0].length / 2);
    var offset = options.offset || defaultOffset;
    offset = offset > defaultOffset ? defaultOffset : Math.floor(offset); // offset max allowed : defaultOffset
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DEFAULTSIDE;
    var customUV = options.uvs;
    var customColors = options.colors;
    var positions = [];
    var indices = [];
    var normals = [];
    var uvs = [];
    var us = []; // us[path_id] = [uDist1, uDist2, uDist3 ... ] distances between points on path path_id
    var vs = []; // vs[i] = [vDist1, vDist2, vDist3, ... ] distances between points i of consecutives paths from pathArray
    var uTotalDistance = []; // uTotalDistance[p] : total distance of path p
    var vTotalDistance = []; //  vTotalDistance[i] : total distance between points i of first and last path from pathArray
    var minlg; // minimal length among all paths from pathArray
    var lg = []; // array of path lengths : nb of vertex per path
    var idx = []; // array of path indexes : index of each path (first vertex) in the total vertex number
    var p; // path iterator
    var i; // point iterator
    var j; // point iterator
    // if single path in pathArray
    if (pathArray.length < 2) {
        var ar1 = [];
        var ar2 = [];
        for (i = 0; i < pathArray[0].length - offset; i++) {
            ar1.push(pathArray[0][i]);
            ar2.push(pathArray[0][i + offset]);
        }
        pathArray = [ar1, ar2];
    }
    // positions and horizontal distances (u)
    var idc = 0;
    var closePathCorr = (closePath) ? 1 : 0; // the final index will be +1 if closePath
    var path;
    var l;
    minlg = pathArray[0].length;
    var vectlg;
    var dist;
    for (p = 0; p < pathArray.length; p++) {
        uTotalDistance[p] = 0;
        us[p] = [0];
        path = pathArray[p];
        l = path.length;
        minlg = (minlg < l) ? minlg : l;
        j = 0;
        while (j < l) {
            positions.push(path[j].x, path[j].y, path[j].z);
            if (j > 0) {
                vectlg = path[j].subtract(path[j - 1]).length();
                dist = vectlg + uTotalDistance[p];
                us[p].push(dist);
                uTotalDistance[p] = dist;
            }
            j++;
        }
        if (closePath) { // an extra hidden vertex is added in the "positions" array
            j--;
            positions.push(path[0].x, path[0].y, path[0].z);
            vectlg = path[j].subtract(path[0]).length();
            dist = vectlg + uTotalDistance[p];
            us[p].push(dist);
            uTotalDistance[p] = dist;
        }
        lg[p] = l + closePathCorr;
        idx[p] = idc;
        idc += (l + closePathCorr);
    }
    // vertical distances (v)
    var path1;
    var path2;
    var vertex1 = null;
    var vertex2 = null;
    for (i = 0; i < minlg + closePathCorr; i++) {
        vTotalDistance[i] = 0;
        vs[i] = [0];
        for (p = 0; p < pathArray.length - 1; p++) {
            path1 = pathArray[p];
            path2 = pathArray[p + 1];
            if (i === minlg) { // closePath
                vertex1 = path1[0];
                vertex2 = path2[0];
            }
            else {
                vertex1 = path1[i];
                vertex2 = path2[i];
            }
            vectlg = vertex2.subtract(vertex1).length();
            dist = vectlg + vTotalDistance[i];
            vs[i].push(dist);
            vTotalDistance[i] = dist;
        }
        if (closeArray && vertex2 && vertex1) {
            path1 = pathArray[p];
            path2 = pathArray[0];
            if (i === minlg) { // closePath
                vertex2 = path2[0];
            }
            vectlg = vertex2.subtract(vertex1).length();
            dist = vectlg + vTotalDistance[i];
            vTotalDistance[i] = dist;
        }
    }
    // uvs
    var u;
    var v;
    if (customUV) {
        for (p = 0; p < customUV.length; p++) {
            uvs.push(customUV[p].x, customUV[p].y);
        }
    }
    else {
        for (p = 0; p < pathArray.length; p++) {
            for (i = 0; i < minlg + closePathCorr; i++) {
                u = (uTotalDistance[p] != 0.0) ? us[p][i] / uTotalDistance[p] : 0.0;
                v = (vTotalDistance[i] != 0.0) ? vs[i][p] / vTotalDistance[i] : 0.0;
                if (invertUV) {
                    uvs.push(v, u);
                }
                else {
                    uvs.push(u, v);
                }
            }
        }
    }
    // indices
    p = 0; // path index
    var pi = 0; // positions array index
    var l1 = lg[p] - 1; // path1 length
    var l2 = lg[p + 1] - 1; // path2 length
    var min = (l1 < l2) ? l1 : l2; // current path stop index
    var shft = idx[1] - idx[0]; // shift
    var path1nb = closeArray ? lg.length : lg.length - 1; // number of path1 to iterate on
    while (pi <= min && p < path1nb) { //  stay under min and don't go over next to last path
        // draw two triangles between path1 (p1) and path2 (p2) : (p1.pi, p2.pi, p1.pi+1) and (p2.pi+1, p1.pi+1, p2.pi) clockwise
        indices.push(pi, pi + shft, pi + 1);
        indices.push(pi + shft + 1, pi + 1, pi + shft);
        pi += 1;
        if (pi === min) { // if end of one of two consecutive paths reached, go to next existing path
            p++;
            if (p === lg.length - 1) { // last path of pathArray reached <=> closeArray == true
                shft = idx[0] - idx[p];
                l1 = lg[p] - 1;
                l2 = lg[0] - 1;
            }
            else {
                shft = idx[p + 1] - idx[p];
                l1 = lg[p] - 1;
                l2 = lg[p + 1] - 1;
            }
            pi = idx[p];
            min = (l1 < l2) ? l1 + pi : l2 + pi;
        }
    }
    // normals
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].ComputeNormals(positions, indices, normals);
    if (closePath) { // update both the first and last vertex normals to their average value
        var indexFirst = 0;
        var indexLast = 0;
        for (p = 0; p < pathArray.length; p++) {
            indexFirst = idx[p] * 3;
            if (p + 1 < pathArray.length) {
                indexLast = (idx[p + 1] - 1) * 3;
            }
            else {
                indexLast = normals.length - 3;
            }
            normals[indexFirst] = (normals[indexFirst] + normals[indexLast]) * 0.5;
            normals[indexFirst + 1] = (normals[indexFirst + 1] + normals[indexLast + 1]) * 0.5;
            normals[indexFirst + 2] = (normals[indexFirst + 2] + normals[indexLast + 2]) * 0.5;
            normals[indexLast] = normals[indexFirst];
            normals[indexLast + 1] = normals[indexFirst + 1];
            normals[indexLast + 2] = normals[indexFirst + 2];
        }
    }
    // sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Colors
    var colors = null;
    if (customColors) {
        colors = new Float32Array(customColors.length * 4);
        for (var c = 0; c < customColors.length; c++) {
            colors[c * 4] = customColors[c].r;
            colors[c * 4 + 1] = customColors[c].g;
            colors[c * 4 + 2] = customColors[c].b;
            colors[c * 4 + 3] = customColors[c].a;
        }
    }
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    var positions32 = new Float32Array(positions);
    var normals32 = new Float32Array(normals);
    var uvs32 = new Float32Array(uvs);
    vertexData.indices = indices;
    vertexData.positions = positions32;
    vertexData.normals = normals32;
    vertexData.uvs = uvs32;
    if (colors) {
        vertexData.set(colors, _buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind);
    }
    if (closePath) {
        vertexData._idx = idx;
    }
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation, instance) {
    if (closeArray === void 0) { closeArray = false; }
    if (updatable === void 0) { updatable = false; }
    return RibbonBuilder.CreateRibbon(name, {
        pathArray: pathArray,
        closeArray: closeArray,
        closePath: closePath,
        offset: offset,
        updatable: updatable,
        sideOrientation: sideOrientation,
        instance: instance
    }, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var RibbonBuilder = /** @class */ (function () {
    function RibbonBuilder() {
    }
    /**
     * Creates a ribbon mesh. The ribbon is a parametric shape.  It has no predefined shape. Its final shape will depend on the input parameters
     * * The parameter `pathArray` is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry
     * * The parameter `closeArray` (boolean, default false) creates a seam between the first and the last paths of the path array
     * * The parameter `closePath` (boolean, default false) creates a seam between the first and the last points of each path of the path array
     * * The parameter `offset` (positive integer, default : rounded half size of the pathArray length), is taken in account only if the `pathArray` is containing a single path
     * * It's the offset to join the points from the same path. Ex : offset = 10 means the point 1 is joined to the point 11
     * * The optional parameter `instance` is an instance of an existing Ribbon object to be updated with the passed `pathArray` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#ribbon
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The parameter `uvs` is an optional flat array of `Vector2` to update/set each ribbon vertex with its own custom UV values instead of the computed ones
     * * The parameters `colors` is an optional flat array of `Color4` to set/update each ribbon vertex with its own custom color values
     * * Note that if you use the parameters `uvs` or `colors`, the passed arrays must be populated with the right number of elements, it is to say the number of ribbon vertices. Remember that if you set `closePath` to `true`, there's one extra vertex per path in the geometry
     * * Moreover, you can use the parameter `color` with `instance` (to update the ribbon), only if you previously used it at creation time
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the ribbon mesh
     * @see https://doc.babylonjs.com/how_to/ribbon_tutorial
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     */
    RibbonBuilder.CreateRibbon = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var pathArray = options.pathArray;
        var closeArray = options.closeArray;
        var closePath = options.closePath;
        var sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        var instance = options.instance;
        var updatable = options.updatable;
        if (instance) { // existing ribbon instance update
            // positionFunction : ribbon case
            // only pathArray and sideOrientation parameters are taken into account for positions update
            var minimum_1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0].setAll(Number.MAX_VALUE);
            var maximum_1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[1].setAll(-Number.MAX_VALUE);
            var positionFunction = function (positions) {
                var minlg = pathArray[0].length;
                var mesh = instance;
                var i = 0;
                var ns = (mesh._originalBuilderSideOrientation === _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].DOUBLESIDE) ? 2 : 1;
                for (var si = 1; si <= ns; ++si) {
                    for (var p = 0; p < pathArray.length; ++p) {
                        var path = pathArray[p];
                        var l = path.length;
                        minlg = (minlg < l) ? minlg : l;
                        for (var j = 0; j < minlg; ++j) {
                            var pathPoint = path[j];
                            positions[i] = pathPoint.x;
                            positions[i + 1] = pathPoint.y;
                            positions[i + 2] = pathPoint.z;
                            minimum_1.minimizeInPlaceFromFloats(pathPoint.x, pathPoint.y, pathPoint.z);
                            maximum_1.maximizeInPlaceFromFloats(pathPoint.x, pathPoint.y, pathPoint.z);
                            i += 3;
                        }
                        if (mesh._creationDataStorage && mesh._creationDataStorage.closePath) {
                            var pathPoint = path[0];
                            positions[i] = pathPoint.x;
                            positions[i + 1] = pathPoint.y;
                            positions[i + 2] = pathPoint.z;
                            i += 3;
                        }
                    }
                }
            };
            var positions = instance.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind);
            positionFunction(positions);
            if (instance._boundingInfo) {
                instance._boundingInfo.reConstruct(minimum_1, maximum_1, instance._worldMatrix);
            }
            else {
                instance._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_4__["BoundingInfo"](minimum_1, maximum_1, instance._worldMatrix);
            }
            instance.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, positions, false, false);
            if (options.colors) {
                var colors = instance.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind);
                for (var c = 0, colorIndex = 0; c < options.colors.length; c++, colorIndex += 4) {
                    var color = options.colors[c];
                    colors[colorIndex] = color.r;
                    colors[colorIndex + 1] = color.g;
                    colors[colorIndex + 2] = color.b;
                    colors[colorIndex + 3] = color.a;
                }
                instance.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind, colors, false, false);
            }
            if (options.uvs) {
                var uvs = instance.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].UVKind);
                for (var i = 0; i < options.uvs.length; i++) {
                    uvs[i * 2] = options.uvs[i].x;
                    uvs[i * 2 + 1] = options.uvs[i].y;
                }
                instance.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].UVKind, uvs, false, false);
            }
            if (!instance.areNormalsFrozen || instance.isFacetDataEnabled) {
                var indices = instance.getIndices();
                var normals = instance.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind);
                var params = instance.isFacetDataEnabled ? instance.getFacetDataParameters() : null;
                _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].ComputeNormals(positions, indices, normals, params);
                if (instance._creationDataStorage && instance._creationDataStorage.closePath) {
                    var indexFirst = 0;
                    var indexLast = 0;
                    for (var p = 0; p < pathArray.length; p++) {
                        indexFirst = instance._creationDataStorage.idx[p] * 3;
                        if (p + 1 < pathArray.length) {
                            indexLast = (instance._creationDataStorage.idx[p + 1] - 1) * 3;
                        }
                        else {
                            indexLast = normals.length - 3;
                        }
                        normals[indexFirst] = (normals[indexFirst] + normals[indexLast]) * 0.5;
                        normals[indexFirst + 1] = (normals[indexFirst + 1] + normals[indexLast + 1]) * 0.5;
                        normals[indexFirst + 2] = (normals[indexFirst + 2] + normals[indexLast + 2]) * 0.5;
                        normals[indexLast] = normals[indexFirst];
                        normals[indexLast + 1] = normals[indexFirst + 1];
                        normals[indexLast + 2] = normals[indexFirst + 2];
                    }
                }
                if (!(instance.areNormalsFrozen)) {
                    instance.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind, normals, false, false);
                }
            }
            return instance;
        }
        else { // new ribbon creation
            var ribbon = new _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"](name, scene);
            ribbon._originalBuilderSideOrientation = sideOrientation;
            ribbon._creationDataStorage = new _mesh__WEBPACK_IMPORTED_MODULE_1__["_CreationDataStorage"]();
            var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateRibbon(options);
            if (closePath) {
                ribbon._creationDataStorage.idx = vertexData._idx;
            }
            ribbon._creationDataStorage.closePath = closePath;
            ribbon._creationDataStorage.closeArray = closeArray;
            vertexData.applyToMesh(ribbon, updatable);
            return ribbon;
        }
    };
    return RibbonBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/shapeBuilder.ts":
/*!*****************************************!*\
  !*** ./Meshes/Builders/shapeBuilder.ts ***!
  \*****************************************/
/*! exports provided: ShapeBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShapeBuilder", function() { return ShapeBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ribbonBuilder */ "./Meshes/Builders/ribbonBuilder.ts");
/* harmony import */ var _Maths_math_path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.path */ "./Maths/math.path.ts");




_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].ExtrudeShape = function (name, shape, path, scale, rotation, cap, scene, updatable, sideOrientation, instance) {
    if (scene === void 0) { scene = null; }
    var options = {
        shape: shape,
        path: path,
        scale: scale,
        rotation: rotation,
        cap: (cap === 0) ? 0 : cap || _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP,
        sideOrientation: sideOrientation,
        instance: instance,
        updatable: updatable
    };
    return ShapeBuilder.ExtrudeShape(name, options, scene);
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].ExtrudeShapeCustom = function (name, shape, path, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, scene, updatable, sideOrientation, instance) {
    var options = {
        shape: shape,
        path: path,
        scaleFunction: scaleFunction,
        rotationFunction: rotationFunction,
        ribbonCloseArray: ribbonCloseArray,
        ribbonClosePath: ribbonClosePath,
        cap: (cap === 0) ? 0 : cap || _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP,
        sideOrientation: sideOrientation,
        instance: instance,
        updatable: updatable
    };
    return ShapeBuilder.ExtrudeShapeCustom(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var ShapeBuilder = /** @class */ (function () {
    function ShapeBuilder() {
    }
    /**
     * Creates an extruded shape mesh. The extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.
     * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis.
     * * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.
     * * The parameter `rotation` (float, default 0 radians) is the angle value to rotate the shape each step (each path point), from the former step (so rotation added each step) along the curve.
     * * The parameter `scale` (float, default 1) is the value to scale the shape.
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#extruded-shape
     * * Remember you can only change the shape or path point positions, not their number when updating an extruded shape.
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture.
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the extruded shape mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes
     */
    ShapeBuilder.ExtrudeShape = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var path = options.path;
        var shape = options.shape;
        var scale = options.scale || 1;
        var rotation = options.rotation || 0;
        var cap = (options.cap === 0) ? 0 : options.cap || _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP;
        var updatable = options.updatable;
        var sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        var instance = options.instance || null;
        var invertUV = options.invertUV || false;
        return ShapeBuilder._ExtrudeShapeGeneric(name, shape, path, scale, rotation, null, null, false, false, cap, false, scene, updatable ? true : false, sideOrientation, instance, invertUV, options.frontUVs || null, options.backUVs || null);
    };
    /**
     * Creates an custom extruded shape mesh.
     * The custom extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.
     * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis.
     * * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.
     * * The parameter `rotationFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path and the distance of this point from the begining of the path
     * * It must returns a float value that will be the rotation in radians applied to the shape on each path point.
     * * The parameter `scaleFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path and the distance of this point from the begining of the path
     * * It must returns a float value that will be the scale value applied to the shape on each path point
     * * The parameter `ribbonClosePath` (boolean, default false) forces the extrusion underlying ribbon to close all the paths in its `pathArray`
     * * The parameter `ribbonCloseArray` (boolean, default false) forces the extrusion underlying ribbon to close its `pathArray`
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#extruded-shape
     * * Remember you can only change the shape or path point positions, not their number when updating an extruded shape
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the custom extruded shape mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#custom-extruded-shapes
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes
     */
    ShapeBuilder.ExtrudeShapeCustom = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var path = options.path;
        var shape = options.shape;
        var scaleFunction = options.scaleFunction || (function () { return 1; });
        var rotationFunction = options.rotationFunction || (function () { return 0; });
        var ribbonCloseArray = options.ribbonCloseArray || false;
        var ribbonClosePath = options.ribbonClosePath || false;
        var cap = (options.cap === 0) ? 0 : options.cap || _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP;
        var updatable = options.updatable;
        var sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        var instance = options.instance;
        var invertUV = options.invertUV || false;
        return ShapeBuilder._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, true, scene, updatable ? true : false, sideOrientation, instance || null, invertUV, options.frontUVs || null, options.backUVs || null);
    };
    ShapeBuilder._ExtrudeShapeGeneric = function (name, shape, curve, scale, rotation, scaleFunction, rotateFunction, rbCA, rbCP, cap, custom, scene, updtbl, side, instance, invertUV, frontUVs, backUVs) {
        // extrusion geometry
        var extrusionPathArray = function (shape, curve, path3D, shapePaths, scale, rotation, scaleFunction, rotateFunction, cap, custom) {
            var tangents = path3D.getTangents();
            var normals = path3D.getNormals();
            var binormals = path3D.getBinormals();
            var distances = path3D.getDistances();
            var angle = 0;
            var returnScale = function () { return scale !== null ? scale : 1; };
            var returnRotation = function () { return rotation !== null ? rotation : 0; };
            var rotate = custom && rotateFunction ? rotateFunction : returnRotation;
            var scl = custom && scaleFunction ? scaleFunction : returnScale;
            var index = (cap === _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP || cap === _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_END) ? 0 : 2;
            var rotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
            for (var i = 0; i < curve.length; i++) {
                var shapePath = new Array();
                var angleStep = rotate(i, distances[i]);
                var scaleRatio = scl(i, distances[i]);
                for (var p = 0; p < shape.length; p++) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationAxisToRef(tangents[i], angle, rotationMatrix);
                    var planed = ((tangents[i].scale(shape[p].z)).add(normals[i].scale(shape[p].x)).add(binormals[i].scale(shape[p].y)));
                    var rotated = shapePath[p] ? shapePath[p] : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(planed, rotationMatrix, rotated);
                    rotated.scaleInPlace(scaleRatio).addInPlace(curve[i]);
                    shapePath[p] = rotated;
                }
                shapePaths[index] = shapePath;
                angle += angleStep;
                index++;
            }
            // cap
            var capPath = function (shapePath) {
                var pointCap = Array();
                var barycenter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                var i;
                for (i = 0; i < shapePath.length; i++) {
                    barycenter.addInPlace(shapePath[i]);
                }
                barycenter.scaleInPlace(1.0 / shapePath.length);
                for (i = 0; i < shapePath.length; i++) {
                    pointCap.push(barycenter);
                }
                return pointCap;
            };
            switch (cap) {
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP:
                    break;
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_START:
                    shapePaths[0] = capPath(shapePaths[2]);
                    shapePaths[1] = shapePaths[2];
                    break;
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_END:
                    shapePaths[index] = shapePaths[index - 1];
                    shapePaths[index + 1] = capPath(shapePaths[index - 1]);
                    break;
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_ALL:
                    shapePaths[0] = capPath(shapePaths[2]);
                    shapePaths[1] = shapePaths[2];
                    shapePaths[index] = shapePaths[index - 1];
                    shapePaths[index + 1] = capPath(shapePaths[index - 1]);
                    break;
                default:
                    break;
            }
            return shapePaths;
        };
        var path3D;
        var pathArray;
        if (instance) { // instance update
            var storage = instance._creationDataStorage;
            path3D = storage.path3D.update(curve);
            pathArray = extrusionPathArray(shape, curve, storage.path3D, storage.pathArray, scale, rotation, scaleFunction, rotateFunction, storage.cap, custom);
            instance = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateRibbon("", pathArray, false, false, 0, scene || undefined, false, 0, instance);
            return instance;
        }
        // extruded shape creation
        path3D = new _Maths_math_path__WEBPACK_IMPORTED_MODULE_3__["Path3D"](curve);
        var newShapePaths = new Array();
        cap = (cap < 0 || cap > 3) ? 0 : cap;
        pathArray = extrusionPathArray(shape, curve, path3D, newShapePaths, scale, rotation, scaleFunction, rotateFunction, cap, custom);
        var extrudedGeneric = _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__["RibbonBuilder"].CreateRibbon(name, { pathArray: pathArray, closeArray: rbCA, closePath: rbCP, updatable: updtbl, sideOrientation: side, invertUV: invertUV, frontUVs: frontUVs || undefined, backUVs: backUVs || undefined }, scene);
        extrudedGeneric._creationDataStorage.pathArray = pathArray;
        extrudedGeneric._creationDataStorage.path3D = path3D;
        extrudedGeneric._creationDataStorage.cap = cap;
        return extrudedGeneric;
    };
    return ShapeBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/sphereBuilder.ts":
/*!******************************************!*\
  !*** ./Meshes/Builders/sphereBuilder.ts ***!
  \******************************************/
/*! exports provided: SphereBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphereBuilder", function() { return SphereBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");



_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateSphere = function (options) {
    var segments = options.segments || 32;
    var diameterX = options.diameterX || options.diameter || 1;
    var diameterY = options.diameterY || options.diameter || 1;
    var diameterZ = options.diameterZ || options.diameter || 1;
    var arc = options.arc && (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
    var slice = options.slice && (options.slice <= 0) ? 1.0 : options.slice || 1.0;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].DEFAULTSIDE;
    var radius = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](diameterX / 2, diameterY / 2, diameterZ / 2);
    var totalZRotationSteps = 2 + segments;
    var totalYRotationSteps = 2 * totalZRotationSteps;
    var indices = [];
    var positions = [];
    var normals = [];
    var uvs = [];
    for (var zRotationStep = 0; zRotationStep <= totalZRotationSteps; zRotationStep++) {
        var normalizedZ = zRotationStep / totalZRotationSteps;
        var angleZ = normalizedZ * Math.PI * slice;
        for (var yRotationStep = 0; yRotationStep <= totalYRotationSteps; yRotationStep++) {
            var normalizedY = yRotationStep / totalYRotationSteps;
            var angleY = normalizedY * Math.PI * 2 * arc;
            var rotationZ = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationZ(-angleZ);
            var rotationY = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationY(angleY);
            var afterRotZ = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Up(), rotationZ);
            var complete = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(afterRotZ, rotationY);
            var vertex = complete.multiply(radius);
            var normal = complete.divide(radius).normalize();
            positions.push(vertex.x, vertex.y, vertex.z);
            normals.push(normal.x, normal.y, normal.z);
            uvs.push(normalizedY, normalizedZ);
        }
        if (zRotationStep > 0) {
            var verticesCount = positions.length / 3;
            for (var firstIndex = verticesCount - 2 * (totalYRotationSteps + 1); (firstIndex + totalYRotationSteps + 2) < verticesCount; firstIndex++) {
                indices.push((firstIndex));
                indices.push((firstIndex + 1));
                indices.push(firstIndex + totalYRotationSteps + 1);
                indices.push((firstIndex + totalYRotationSteps + 1));
                indices.push((firstIndex + 1));
                indices.push((firstIndex + totalYRotationSteps + 2));
            }
        }
    }
    // Sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateSphere = function (name, segments, diameter, scene, updatable, sideOrientation) {
    var options = {
        segments: segments,
        diameterX: diameter,
        diameterY: diameter,
        diameterZ: diameter,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return SphereBuilder.CreateSphere(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var SphereBuilder = /** @class */ (function () {
    function SphereBuilder() {
    }
    /**
     * Creates a sphere mesh
     * * The parameter `diameter` sets the diameter size (float) of the sphere (default 1)
     * * You can set some different sphere dimensions, for instance to build an ellipsoid, by using the parameters `diameterX`, `diameterY` and `diameterZ` (all by default have the same value of `diameter`)
     * * The parameter `segments` sets the sphere number of horizontal stripes (positive integer, default 32)
     * * You can create an unclosed sphere with the parameter `arc` (positive float, default 1), valued between 0 and 1, what is the ratio of the circumference (latitude) : 2 x PI x ratio
     * * You can create an unclosed sphere on its height with the parameter `slice` (positive float, default1), valued between 0 and 1, what is the height ratio (longitude)
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the sphere mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#sphere
     */
    SphereBuilder.CreateSphere = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var sphere = new _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        sphere._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateSphere(options);
        vertexData.applyToMesh(sphere, options.updatable);
        return sphere;
    };
    return SphereBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/tiledBoxBuilder.ts":
/*!********************************************!*\
  !*** ./Meshes/Builders/tiledBoxBuilder.ts ***!
  \********************************************/
/*! exports provided: TiledBoxBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TiledBoxBuilder", function() { return TiledBoxBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");




_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledBox = function (options) {
    var nbFaces = 6;
    var faceUV = options.faceUV || new Array(6);
    var faceColors = options.faceColors;
    var flipTile = options.pattern || _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].NO_FLIP;
    var width = options.width || options.size || 1;
    var height = options.height || options.size || 1;
    var depth = options.depth || options.size || 1;
    var tileWidth = options.tileWidth || options.tileSize || 1;
    var tileHeight = options.tileHeight || options.tileSize || 1;
    var alignH = options.alignHorizontal || 0;
    var alignV = options.alignVertical || 0;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DEFAULTSIDE;
    // default face colors and UV if undefined
    for (var f = 0; f < nbFaces; f++) {
        if (faceUV[f] === undefined) {
            faceUV[f] = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0, 0, 1, 1);
        }
        if (faceColors && faceColors[f] === undefined) {
            faceColors[f] = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1, 1, 1, 1);
        }
    }
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var halfDepth = depth / 2;
    var faceVertexData = [];
    for (var f = 0; f < 2; f++) { //front and back
        faceVertexData[f] = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledPlane({
            pattern: flipTile,
            tileWidth: tileWidth,
            tileHeight: tileHeight,
            width: width,
            height: height,
            alignVertical: alignV,
            alignHorizontal: alignH,
            sideOrientation: sideOrientation
        });
    }
    for (var f = 2; f < 4; f++) { //sides
        faceVertexData[f] = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledPlane({
            pattern: flipTile,
            tileWidth: tileWidth,
            tileHeight: tileHeight,
            width: depth,
            height: height,
            alignVertical: alignV,
            alignHorizontal: alignH,
            sideOrientation: sideOrientation
        });
    }
    var baseAlignV = alignV;
    if (alignV === _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].BOTTOM) {
        baseAlignV = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].TOP;
    }
    else if (alignV === _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].TOP) {
        baseAlignV = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].BOTTOM;
    }
    for (var f = 4; f < 6; f++) { //top and bottom
        faceVertexData[f] = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledPlane({
            pattern: flipTile,
            tileWidth: tileWidth,
            tileHeight: tileHeight,
            width: width,
            height: depth,
            alignVertical: baseAlignV,
            alignHorizontal: alignH,
            sideOrientation: sideOrientation
        });
    }
    var positions = [];
    var normals = [];
    var uvs = [];
    var indices = [];
    var colors = [];
    var facePositions = [];
    var faceNormals = [];
    var newFaceUV = [];
    var len = 0;
    var lu = 0;
    var li = 0;
    for (var f = 0; f < nbFaces; f++) {
        var len = faceVertexData[f].positions.length;
        facePositions[f] = [];
        faceNormals[f] = [];
        for (var p = 0; p < len / 3; p++) {
            facePositions[f].push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](faceVertexData[f].positions[3 * p], faceVertexData[f].positions[3 * p + 1], faceVertexData[f].positions[3 * p + 2]));
            faceNormals[f].push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](faceVertexData[f].normals[3 * p], faceVertexData[f].normals[3 * p + 1], faceVertexData[f].normals[3 * p + 2]));
        }
        // uvs
        lu = faceVertexData[f].uvs.length;
        newFaceUV[f] = [];
        for (var i = 0; i < lu; i += 2) {
            newFaceUV[f][i] = faceUV[f].x + (faceUV[f].z - faceUV[f].x) * faceVertexData[f].uvs[i];
            newFaceUV[f][i + 1] = faceUV[f].y + (faceUV[f].w - faceUV[f].y) * faceVertexData[f].uvs[i + 1];
        }
        uvs = uvs.concat(newFaceUV[f]);
        indices = indices.concat(faceVertexData[f].indices.map(function (x) { return x + li; }));
        li += facePositions[f].length;
        if (faceColors) {
            for (var c = 0; c < 4; c++) {
                colors.push(faceColors[f].r, faceColors[f].g, faceColors[f].b, faceColors[f].a);
            }
        }
    }
    var vec0 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, halfDepth);
    var mtrx0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationY(Math.PI);
    positions = facePositions[0].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx0).add(vec0); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []);
    normals = faceNormals[0].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx0); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []);
    positions = positions.concat(facePositions[1].map(function (entry) { return entry.subtract(vec0); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    normals = normals.concat(faceNormals[1].map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    var vec2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](halfWidth, 0, 0);
    var mtrx2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationY(-Math.PI / 2);
    positions = positions.concat(facePositions[2].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx2).add(vec2); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    normals = normals.concat(faceNormals[2].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx2); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    var mtrx3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationY(Math.PI / 2);
    positions = positions.concat(facePositions[3].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx3).subtract(vec2); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    normals = normals.concat(faceNormals[3].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx3); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    var vec4 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, halfHeight, 0);
    var mtrx4 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationX(Math.PI / 2);
    positions = positions.concat(facePositions[4].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx4).add(vec4); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    normals = normals.concat(faceNormals[4].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx4); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    var mtrx5 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationX(-Math.PI / 2);
    positions = positions.concat(facePositions[5].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx5).subtract(vec4); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    normals = normals.concat(faceNormals[5].map(function (entry) { return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(entry, mtrx5); }).map(function (entry) { return [entry.x, entry.y, entry.z]; }).reduce(function (accumulator, currentValue) { return accumulator.concat(currentValue); }, []));
    // sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    if (faceColors) {
        var totalColors = (sideOrientation === _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].DOUBLESIDE) ? colors.concat(colors) : colors;
        vertexData.colors = totalColors;
    }
    return vertexData;
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var TiledBoxBuilder = /** @class */ (function () {
    function TiledBoxBuilder() {
    }
    /**
     * Creates a box mesh
     * faceTiles sets the pattern, tile size and number of tiles for a face     * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of 6 Color3 elements) and `faceUV` (an array of 6 Vector4 elements)
     * * Please read this tutorial : https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the box mesh
     */
    TiledBoxBuilder.CreateTiledBox = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var box = new _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        box._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateTiledBox(options);
        vertexData.applyToMesh(box, options.updatable);
        return box;
    };
    return TiledBoxBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/tiledPlaneBuilder.ts":
/*!**********************************************!*\
  !*** ./Meshes/Builders/tiledPlaneBuilder.ts ***!
  \**********************************************/
/*! exports provided: TiledPlaneBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TiledPlaneBuilder", function() { return TiledPlaneBuilder; });
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");


_mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].CreateTiledPlane = function (options) {
    var flipTile = options.pattern || _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].NO_FLIP;
    var tileWidth = options.tileWidth || options.tileSize || 1;
    var tileHeight = options.tileHeight || options.tileSize || 1;
    var alignH = options.alignHorizontal || 0;
    var alignV = options.alignVertical || 0;
    var width = options.width || options.size || 1;
    var tilesX = Math.floor(width / tileWidth);
    var offsetX = width - tilesX * tileWidth;
    var height = options.height || options.size || 1;
    var tilesY = Math.floor(height / tileHeight);
    var offsetY = height - tilesY * tileHeight;
    var halfWidth = tileWidth * tilesX / 2;
    var halfHeight = tileHeight * tilesY / 2;
    var adjustX = 0;
    var adjustY = 0;
    var startX = 0;
    var startY = 0;
    var endX = 0;
    var endY = 0;
    //Part Tiles
    if (offsetX > 0 || offsetY > 0) {
        startX = -halfWidth;
        startY = -halfHeight;
        var endX = halfWidth;
        var endY = halfHeight;
        switch (alignH) {
            case _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CENTER:
                offsetX /= 2;
                startX -= offsetX;
                endX += offsetX;
                break;
            case _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].LEFT:
                endX += offsetX;
                adjustX = -offsetX / 2;
                break;
            case _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].RIGHT:
                startX -= offsetX;
                adjustX = offsetX / 2;
                break;
        }
        switch (alignV) {
            case _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CENTER:
                offsetY /= 2;
                startY -= offsetY;
                endY += offsetY;
                break;
            case _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].BOTTOM:
                endY += offsetY;
                adjustY = -offsetY / 2;
                break;
            case _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].TOP:
                startY -= offsetY;
                adjustY = offsetY / 2;
                break;
        }
    }
    var positions = [];
    var normals = [];
    var uvBase = [];
    uvBase[0] = [0, 0, 1, 0, 1, 1, 0, 1];
    uvBase[1] = [0, 0, 1, 0, 1, 1, 0, 1];
    if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW) {
        uvBase[1] = [1, 1, 0, 1, 0, 0, 1, 0];
    }
    if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW) {
        uvBase[1] = [1, 0, 0, 0, 0, 1, 1, 1];
    }
    if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
        uvBase[1] = [0, 1, 1, 1, 1, 0, 0, 0];
    }
    var uvs = [];
    var colors = [];
    var indices = [];
    var index = 0;
    for (var y = 0; y < tilesY; y++) {
        for (var x = 0; x < tilesX; x++) {
            positions.push(-halfWidth + x * tileWidth + adjustX, -halfHeight + y * tileHeight + adjustY, 0);
            positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, -halfHeight + y * tileHeight + adjustY, 0);
            positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);
            positions.push(-halfWidth + x * tileWidth + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);
            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE) {
                uvs = uvs.concat(uvBase[(x % 2 + y % 2) % 2]);
            }
            else if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                uvs = uvs.concat(uvBase[y % 2]);
            }
            else {
                uvs = uvs.concat(uvBase[0]);
            }
            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
            index += 4;
        }
    }
    //Part Tiles
    if (offsetX > 0 || offsetY > 0) {
        var partialBottomRow = (offsetY > 0 && (alignV === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CENTER || alignV === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].TOP));
        var partialTopRow = (offsetY > 0 && (alignV === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CENTER || alignV === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].BOTTOM));
        var partialLeftCol = (offsetX > 0 && (alignH === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CENTER || alignH === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].RIGHT));
        var partialRightCol = (offsetX > 0 && (alignH === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CENTER || alignH === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].LEFT));
        var uvPart = [];
        var a, b, c, d;
        //corners
        if (partialBottomRow && partialLeftCol) { //bottom left corner
            positions.push(startX + adjustX, startY + adjustY, 0);
            positions.push(-halfWidth + adjustX, startY + adjustY, 0);
            positions.push(-halfWidth + adjustX, startY + offsetY + adjustY, 0);
            positions.push(startX + adjustX, startY + offsetY + adjustY, 0);
            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
            index += 4;
            a = 1 - offsetX / tileWidth;
            b = 1 - offsetY / tileHeight;
            c = 1;
            d = 1;
            uvPart = [a, b, c, b, c, d, a, d];
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW) {
                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW) {
                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            uvs = uvs.concat(uvPart);
            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
        }
        if (partialBottomRow && partialRightCol) { //bottom right corner
            positions.push(halfWidth + adjustX, startY + adjustY, 0);
            positions.push(endX + adjustX, startY + adjustY, 0);
            positions.push(endX + adjustX, startY + offsetY + adjustY, 0);
            positions.push(halfWidth + adjustX, startY + offsetY + adjustY, 0);
            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
            index += 4;
            a = 0,
                b = 1 - offsetY / tileHeight;
            c = offsetX / tileWidth;
            d = 1;
            uvPart = [a, b, c, b, c, d, a, d];
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE && (tilesX % 2) === 0)) {
                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE && (tilesX % 2) === 0)) {
                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE && (tilesX % 2) === 0)) {
                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            uvs = uvs.concat(uvPart);
            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
        }
        if (partialTopRow && partialLeftCol) { //top left corner
            positions.push(startX + adjustX, halfHeight + adjustY, 0);
            positions.push(-halfWidth + adjustX, halfHeight + adjustY, 0);
            positions.push(-halfWidth + adjustX, endY + adjustY, 0);
            positions.push(startX + adjustX, endY + adjustY, 0);
            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
            index += 4;
            a = 1 - offsetX / tileWidth;
            b = 0;
            c = 1;
            d = offsetY / tileHeight;
            uvPart = [a, b, c, b, c, d, a, d];
            if ((flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW && (tilesY % 2) === 1) || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE && (tilesY % 1) === 0)) {
                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if ((flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW && (tilesY % 2) === 1) || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE && (tilesY % 2) === 0)) {
                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if ((flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW && (tilesY % 2) === 1) || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE && (tilesY % 2) === 0)) {
                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            uvs = uvs.concat(uvPart);
            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
        }
        if (partialTopRow && partialRightCol) { //top right corner
            positions.push(halfWidth + adjustX, halfHeight + adjustY, 0);
            positions.push(endX + adjustX, halfHeight + adjustY, 0);
            positions.push(endX + adjustX, endY + adjustY, 0);
            positions.push(halfWidth + adjustX, endY + adjustY, 0);
            indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
            index += 4;
            a = 0,
                b = 0;
            c = offsetX / tileWidth;
            d = offsetY / tileHeight;
            uvPart = [a, b, c, b, c, d, a, d];
            if ((flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW && (tilesY % 2) === 1) || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE && (tilesY + tilesX) % 2 === 1)) {
                uvPart = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if ((flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW && (tilesY % 2) === 1) || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE && (tilesY + tilesX) % 2 === 1)) {
                uvPart = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if ((flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW && (tilesY % 2) === 1) || (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE && (tilesY + tilesX) % 2 === 1)) {
                uvPart = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            uvs = uvs.concat(uvPart);
            colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
            normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
        }
        //part rows
        if (partialBottomRow) {
            var uvBaseBR = [];
            a = 0;
            b = 1 - offsetY / tileHeight;
            c = 1;
            d = 1;
            uvBaseBR[0] = [a, b, c, b, c, d, a, d];
            uvBaseBR[1] = [a, b, c, b, c, d, a, d];
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW) {
                uvBaseBR[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW) {
                uvBaseBR[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                uvBaseBR[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            for (var x = 0; x < tilesX; x++) {
                positions.push(-halfWidth + x * tileWidth + adjustX, startY + adjustY, 0);
                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, startY + adjustY, 0);
                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, startY + offsetY + adjustY, 0);
                positions.push(-halfWidth + x * tileWidth + adjustX, startY + offsetY + adjustY, 0);
                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
                index += 4;
                if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE) {
                    uvs = uvs.concat(uvBaseBR[(x + 1) % 2]);
                }
                else if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                    uvs = uvs.concat(uvBaseBR[1]);
                }
                else {
                    uvs = uvs.concat(uvBaseBR[0]);
                }
                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
            }
        }
        if (partialTopRow) {
            var uvBaseTR = [];
            a = 0;
            b = 0;
            c = 1;
            d = offsetY / tileHeight;
            uvBaseTR[0] = [a, b, c, b, c, d, a, d];
            uvBaseTR[1] = [a, b, c, b, c, d, a, d];
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW) {
                uvBaseTR[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW) {
                uvBaseTR[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                uvBaseTR[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            for (var x = 0; x < tilesX; x++) {
                positions.push(-halfWidth + x * tileWidth + adjustX, endY - offsetY + adjustY, 0);
                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, endY - offsetY + adjustY, 0);
                positions.push(-halfWidth + (x + 1) * tileWidth + adjustX, endY + adjustY, 0);
                positions.push(-halfWidth + x * tileWidth + adjustX, endY + adjustY, 0);
                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
                index += 4;
                if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE) {
                    uvs = uvs.concat(uvBaseTR[(x + tilesY) % 2]);
                }
                else if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                    uvs = uvs.concat(uvBaseTR[tilesY % 2]);
                }
                else {
                    uvs = uvs.concat(uvBaseTR[0]);
                }
                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
            }
        }
        if (partialLeftCol) {
            var uvBaseLC = [];
            a = 1 - offsetX / tileWidth;
            b = 0;
            c = 1;
            d = 1;
            uvBaseLC[0] = [a, b, c, b, c, d, a, d];
            uvBaseLC[1] = [a, b, c, b, c, d, a, d];
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW) {
                uvBaseLC[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW) {
                uvBaseLC[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                uvBaseLC[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            for (var y = 0; y < tilesY; y++) {
                positions.push(startX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);
                positions.push(startX + offsetX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);
                positions.push(startX + offsetX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);
                positions.push(startX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);
                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
                index += 4;
                if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE) {
                    uvs = uvs.concat(uvBaseLC[(y + 1) % 2]);
                }
                else if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                    uvs = uvs.concat(uvBaseLC[y % 2]);
                }
                else {
                    uvs = uvs.concat(uvBaseLC[0]);
                }
                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
            }
        }
        if (partialRightCol) {
            var uvBaseRC = [];
            a = 0;
            b = 0;
            c = offsetX / tileHeight;
            d = 1;
            uvBaseRC[0] = [a, b, c, b, c, d, a, d];
            uvBaseRC[1] = [a, b, c, b, c, d, a, d];
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW) {
                uvBaseRC[1] = [1 - a, 1 - b, 1 - c, 1 - b, 1 - c, 1 - d, 1 - a, 1 - d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW) {
                uvBaseRC[1] = [1 - a, b, 1 - c, b, 1 - c, d, 1 - a, d];
            }
            if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                uvBaseRC[1] = [a, 1 - b, c, 1 - b, c, 1 - d, a, 1 - d];
            }
            for (var y = 0; y < tilesY; y++) {
                positions.push(endX - offsetX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);
                positions.push(endX + adjustX, -halfHeight + y * tileHeight + adjustY, 0);
                positions.push(endX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);
                positions.push(endX - offsetX + adjustX, -halfHeight + (y + 1) * tileHeight + adjustY, 0);
                indices.push(index, index + 1, index + 3, index + 1, index + 2, index + 3);
                index += 4;
                if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_TILE || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_TILE) {
                    uvs = uvs.concat(uvBaseRC[(y + tilesX) % 2]);
                }
                else if (flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ROTATE_ROW || flipTile === _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].FLIP_N_ROTATE_ROW) {
                    uvs = uvs.concat(uvBaseRC[y % 2]);
                }
                else {
                    uvs = uvs.concat(uvBaseRC[0]);
                }
                colors.push(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
                normals.push(0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1);
            }
        }
    }
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].DEFAULTSIDE;
    // sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    var totalColors = (sideOrientation === _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].DOUBLESIDE) ? colors.concat(colors) : colors;
    vertexData.colors = totalColors;
    return vertexData;
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var TiledPlaneBuilder = /** @class */ (function () {
    function TiledPlaneBuilder() {
    }
    /**
     * Creates a tiled plane mesh
     * * The parameter `pattern` will, depending on value, do nothing or
     * * * flip (reflect about central vertical) alternate tiles across and up
     * * * flip every tile on alternate rows
     * * * rotate (180 degs) alternate tiles across and up
     * * * rotate every tile on alternate rows
     * * * flip and rotate alternate tiles across and up
     * * * flip and rotate every tile on alternate rows
     * * The parameter `tileSize` sets the size (float) of each tile side (default 1)
     * * You can set some different tile dimensions by using the parameters `tileWidth` and `tileHeight` (both by default have the same value of `tileSize`)
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @see https://doc.babylonjs.com/how_to/set_shapes#box
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the box mesh
     */
    TiledPlaneBuilder.CreateTiledPlane = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var plane = new _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        plane._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"].CreateTiledPlane(options);
        vertexData.applyToMesh(plane, options.updatable);
        return plane;
    };
    return TiledPlaneBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/torusBuilder.ts":
/*!*****************************************!*\
  !*** ./Meshes/Builders/torusBuilder.ts ***!
  \*****************************************/
/*! exports provided: TorusBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TorusBuilder", function() { return TorusBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");



_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateTorus = function (options) {
    var indices = [];
    var positions = [];
    var normals = [];
    var uvs = [];
    var diameter = options.diameter || 1;
    var thickness = options.thickness || 0.5;
    var tessellation = options.tessellation || 16;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].DEFAULTSIDE;
    var stride = tessellation + 1;
    for (var i = 0; i <= tessellation; i++) {
        var u = i / tessellation;
        var outerAngle = i * Math.PI * 2.0 / tessellation - Math.PI / 2.0;
        var transform = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Translation(diameter / 2.0, 0, 0).multiply(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationY(outerAngle));
        for (var j = 0; j <= tessellation; j++) {
            var v = 1 - j / tessellation;
            var innerAngle = j * Math.PI * 2.0 / tessellation + Math.PI;
            var dx = Math.cos(innerAngle);
            var dy = Math.sin(innerAngle);
            // Create a vertex.
            var normal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](dx, dy, 0);
            var position = normal.scale(thickness / 2);
            var textureCoordinate = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](u, v);
            position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(position, transform);
            normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(normal, transform);
            positions.push(position.x, position.y, position.z);
            normals.push(normal.x, normal.y, normal.z);
            uvs.push(textureCoordinate.x, textureCoordinate.y);
            // And create indices for two triangles.
            var nextI = (i + 1) % stride;
            var nextJ = (j + 1) % stride;
            indices.push(i * stride + j);
            indices.push(i * stride + nextJ);
            indices.push(nextI * stride + j);
            indices.push(i * stride + nextJ);
            indices.push(nextI * stride + nextJ);
            indices.push(nextI * stride + j);
        }
    }
    // Sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable, sideOrientation) {
    var options = {
        diameter: diameter,
        thickness: thickness,
        tessellation: tessellation,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return TorusBuilder.CreateTorus(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var TorusBuilder = /** @class */ (function () {
    function TorusBuilder() {
    }
    /**
     * Creates a torus mesh
     * * The parameter `diameter` sets the diameter size (float) of the torus (default 1)
     * * The parameter `thickness` sets the diameter size of the tube of the torus (float, default 0.5)
     * * The parameter `tessellation` sets the number of torus sides (postive integer, default 16)
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the torus mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#torus
     */
    TorusBuilder.CreateTorus = function (name, options, scene) {
        var torus = new _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        torus._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateTorus(options);
        vertexData.applyToMesh(torus, options.updatable);
        return torus;
    };
    return TorusBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/torusKnotBuilder.ts":
/*!*********************************************!*\
  !*** ./Meshes/Builders/torusKnotBuilder.ts ***!
  \*********************************************/
/*! exports provided: TorusKnotBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TorusKnotBuilder", function() { return TorusKnotBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../mesh.vertexData */ "./Meshes/mesh.vertexData.ts");



_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateTorusKnot = function (options) {
    var indices = new Array();
    var positions = new Array();
    var normals = new Array();
    var uvs = new Array();
    var radius = options.radius || 2;
    var tube = options.tube || 0.5;
    var radialSegments = options.radialSegments || 32;
    var tubularSegments = options.tubularSegments || 32;
    var p = options.p || 2;
    var q = options.q || 3;
    var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].DEFAULTSIDE;
    // Helper
    var getPos = function (angle) {
        var cu = Math.cos(angle);
        var su = Math.sin(angle);
        var quOverP = q / p * angle;
        var cs = Math.cos(quOverP);
        var tx = radius * (2 + cs) * 0.5 * cu;
        var ty = radius * (2 + cs) * su * 0.5;
        var tz = radius * Math.sin(quOverP) * 0.5;
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](tx, ty, tz);
    };
    // Vertices
    var i;
    var j;
    for (i = 0; i <= radialSegments; i++) {
        var modI = i % radialSegments;
        var u = modI / radialSegments * 2 * p * Math.PI;
        var p1 = getPos(u);
        var p2 = getPos(u + 0.01);
        var tang = p2.subtract(p1);
        var n = p2.add(p1);
        var bitan = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(tang, n);
        n = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(bitan, tang);
        bitan.normalize();
        n.normalize();
        for (j = 0; j < tubularSegments; j++) {
            var modJ = j % tubularSegments;
            var v = modJ / tubularSegments * 2 * Math.PI;
            var cx = -tube * Math.cos(v);
            var cy = tube * Math.sin(v);
            positions.push(p1.x + cx * n.x + cy * bitan.x);
            positions.push(p1.y + cx * n.y + cy * bitan.y);
            positions.push(p1.z + cx * n.z + cy * bitan.z);
            uvs.push(i / radialSegments);
            uvs.push(j / tubularSegments);
        }
    }
    for (i = 0; i < radialSegments; i++) {
        for (j = 0; j < tubularSegments; j++) {
            var jNext = (j + 1) % tubularSegments;
            var a = i * tubularSegments + j;
            var b = (i + 1) * tubularSegments + j;
            var c = (i + 1) * tubularSegments + jNext;
            var d = i * tubularSegments + jNext;
            indices.push(d);
            indices.push(b);
            indices.push(a);
            indices.push(d);
            indices.push(c);
            indices.push(b);
        }
    }
    // Normals
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].ComputeNormals(positions, indices, normals);
    // Sides
    _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]._ComputeSides(sideOrientation, positions, indices, normals, uvs, options.frontUVs, options.backUVs);
    // Result
    var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
    vertexData.indices = indices;
    vertexData.positions = positions;
    vertexData.normals = normals;
    vertexData.uvs = uvs;
    return vertexData;
};
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable, sideOrientation) {
    var options = {
        radius: radius,
        tube: tube,
        radialSegments: radialSegments,
        tubularSegments: tubularSegments,
        p: p,
        q: q,
        sideOrientation: sideOrientation,
        updatable: updatable
    };
    return TorusKnotBuilder.CreateTorusKnot(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var TorusKnotBuilder = /** @class */ (function () {
    function TorusKnotBuilder() {
    }
    /**
     * Creates a torus knot mesh
     * * The parameter `radius` sets the global radius size (float) of the torus knot (default 2)
     * * The parameter `radialSegments` sets the number of sides on each tube segments (positive integer, default 32)
     * * The parameter `tubularSegments` sets the number of tubes to decompose the knot into (positive integer, default 32)
     * * The parameters `p` and `q` are the number of windings on each axis (positive integers, default 2 and 3)
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the torus knot mesh
     * @see  https://doc.babylonjs.com/how_to/set_shapes#torus-knot
     */
    TorusKnotBuilder.CreateTorusKnot = function (name, options, scene) {
        var torusKnot = new _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"](name, scene);
        options.sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        torusKnot._originalBuilderSideOrientation = options.sideOrientation;
        var vertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].CreateTorusKnot(options);
        vertexData.applyToMesh(torusKnot, options.updatable);
        return torusKnot;
    };
    return TorusKnotBuilder;
}());



/***/ }),

/***/ "./Meshes/Builders/tubeBuilder.ts":
/*!****************************************!*\
  !*** ./Meshes/Builders/tubeBuilder.ts ***!
  \****************************************/
/*! exports provided: TubeBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TubeBuilder", function() { return TubeBuilder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ribbonBuilder */ "./Meshes/Builders/ribbonBuilder.ts");
/* harmony import */ var _Maths_math_path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.path */ "./Maths/math.path.ts");




_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CreateTube = function (name, path, radius, tessellation, radiusFunction, cap, scene, updatable, sideOrientation, instance) {
    var options = {
        path: path,
        radius: radius,
        tessellation: tessellation,
        radiusFunction: radiusFunction,
        arc: 1,
        cap: cap,
        updatable: updatable,
        sideOrientation: sideOrientation,
        instance: instance
    };
    return TubeBuilder.CreateTube(name, options, scene);
};
/**
 * Class containing static functions to help procedurally build meshes
 */
var TubeBuilder = /** @class */ (function () {
    function TubeBuilder() {
    }
    /**
     * Creates a tube mesh.
     * The tube is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters
     * * The parameter `path` is a required array of successive Vector3. It is the curve used as the axis of the tube
     * * The parameter `radius` (positive float, default 1) sets the tube radius size
     * * The parameter `tessellation` (positive float, default 64) is the number of sides on the tubular surface
     * * The parameter `radiusFunction` (javascript function, default null) is a vanilla javascript function. If it is not null, it overwrittes the parameter `radius`
     * * This function is called on each point of the tube path and is passed the index `i` of the i-th point and the distance of this point from the first point of the path. It must return a radius value (positive float)
     * * The parameter `arc` (positive float, maximum 1, default 1) is the ratio to apply to the tube circumference : 2 x PI x arc
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * The optional parameter `instance` is an instance of an existing Tube object to be updated with the passed `pathArray` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#tube
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the tube mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     * @see https://doc.babylonjs.com/how_to/set_shapes#tube
     */
    TubeBuilder.CreateTube = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        var path = options.path;
        var instance = options.instance;
        var radius = 1.0;
        if (options.radius !== undefined) {
            radius = options.radius;
        }
        else if (instance) {
            radius = instance._creationDataStorage.radius;
        }
        var tessellation = options.tessellation || 64 | 0;
        var radiusFunction = options.radiusFunction || null;
        var cap = options.cap || _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP;
        var invertUV = options.invertUV || false;
        var updatable = options.updatable;
        var sideOrientation = _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]._GetDefaultSideOrientation(options.sideOrientation);
        options.arc = options.arc && (options.arc <= 0.0 || options.arc > 1.0) ? 1.0 : options.arc || 1.0;
        // tube geometry
        var tubePathArray = function (path, path3D, circlePaths, radius, tessellation, radiusFunction, cap, arc) {
            var tangents = path3D.getTangents();
            var normals = path3D.getNormals();
            var distances = path3D.getDistances();
            var pi2 = Math.PI * 2;
            var step = pi2 / tessellation * arc;
            var returnRadius = function () { return radius; };
            var radiusFunctionFinal = radiusFunction || returnRadius;
            var circlePath;
            var rad;
            var normal;
            var rotated;
            var rotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
            var index = (cap === _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP || cap === _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_END) ? 0 : 2;
            for (var i = 0; i < path.length; i++) {
                rad = radiusFunctionFinal(i, distances[i]); // current radius
                circlePath = Array(); // current circle array
                normal = normals[i]; // current normal
                for (var t = 0; t < tessellation; t++) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].RotationAxisToRef(tangents[i], step * t, rotationMatrix);
                    rotated = circlePath[t] ? circlePath[t] : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(normal, rotationMatrix, rotated);
                    rotated.scaleInPlace(rad).addInPlace(path[i]);
                    circlePath[t] = rotated;
                }
                circlePaths[index] = circlePath;
                index++;
            }
            // cap
            var capPath = function (nbPoints, pathIndex) {
                var pointCap = Array();
                for (var i = 0; i < nbPoints; i++) {
                    pointCap.push(path[pathIndex]);
                }
                return pointCap;
            };
            switch (cap) {
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].NO_CAP:
                    break;
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_START:
                    circlePaths[0] = capPath(tessellation, 0);
                    circlePaths[1] = circlePaths[2].slice(0);
                    break;
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_END:
                    circlePaths[index] = circlePaths[index - 1].slice(0);
                    circlePaths[index + 1] = capPath(tessellation, path.length - 1);
                    break;
                case _mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].CAP_ALL:
                    circlePaths[0] = capPath(tessellation, 0);
                    circlePaths[1] = circlePaths[2].slice(0);
                    circlePaths[index] = circlePaths[index - 1].slice(0);
                    circlePaths[index + 1] = capPath(tessellation, path.length - 1);
                    break;
                default:
                    break;
            }
            return circlePaths;
        };
        var path3D;
        var pathArray;
        if (instance) { // tube update
            var storage = instance._creationDataStorage;
            var arc = options.arc || storage.arc;
            path3D = storage.path3D.update(path);
            pathArray = tubePathArray(path, path3D, storage.pathArray, radius, storage.tessellation, radiusFunction, storage.cap, arc);
            instance = _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__["RibbonBuilder"].CreateRibbon("", { pathArray: pathArray, instance: instance });
            // Update mode, no need to recreate the storage.
            storage.path3D = path3D;
            storage.pathArray = pathArray;
            storage.arc = arc;
            storage.radius = radius;
            return instance;
        }
        // tube creation
        path3D = new _Maths_math_path__WEBPACK_IMPORTED_MODULE_3__["Path3D"](path);
        var newPathArray = new Array();
        cap = (cap < 0 || cap > 3) ? 0 : cap;
        pathArray = tubePathArray(path, path3D, newPathArray, radius, tessellation, radiusFunction, cap, options.arc);
        var tube = _ribbonBuilder__WEBPACK_IMPORTED_MODULE_2__["RibbonBuilder"].CreateRibbon(name, { pathArray: pathArray, closePath: true, closeArray: false, updatable: updatable, sideOrientation: sideOrientation, invertUV: invertUV, frontUVs: options.frontUVs, backUVs: options.backUVs }, scene);
        tube._creationDataStorage.pathArray = pathArray;
        tube._creationDataStorage.path3D = path3D;
        tube._creationDataStorage.tessellation = tessellation;
        tube._creationDataStorage.cap = cap;
        tube._creationDataStorage.arc = options.arc;
        tube._creationDataStorage.radius = radius;
        return tube;
    };
    return TubeBuilder;
}());



/***/ }),

/***/ "./Meshes/Compression/dracoCompression.ts":
/*!************************************************!*\
  !*** ./Meshes/Compression/dracoCompression.ts ***!
  \************************************************/
/*! exports provided: DracoCompression */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DracoCompression", function() { return DracoCompression; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_workerPool__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/workerPool */ "./Misc/workerPool.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");



function loadScriptAsync(url) {
    if (typeof importScripts === "function") {
        importScripts(url);
        return Promise.resolve();
    }
    else {
        return new Promise(function (resolve, reject) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].LoadScript(url, function () {
                resolve();
            }, function (message) {
                reject(new Error(message));
            });
        });
    }
}
function loadFileAsync(url) {
    return new Promise(function (resolve, reject) {
        _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].LoadFile(url, function (data) {
            resolve(data);
        }, undefined, undefined, true, function (request, exception) {
            reject(exception);
        });
    });
}
function createDecoderAsync(wasmUrl, wasmBinary, fallbackUrl) {
    var decoderUrl = (wasmBinary && wasmUrl) || fallbackUrl;
    if (decoderUrl) {
        return loadScriptAsync(decoderUrl).then(function () {
            return new Promise(function (resolve) {
                DracoDecoderModule({ wasmBinary: wasmBinary }).then(function (module) {
                    resolve({ module: module });
                });
            });
        });
    }
    return undefined;
}
function decodeMesh(decoderModule, dataView, attributes, onIndicesData, onAttributeData) {
    var buffer = new decoderModule.DecoderBuffer();
    buffer.Init(dataView, dataView.byteLength);
    var decoder = new decoderModule.Decoder();
    var geometry;
    var status;
    try {
        var type = decoder.GetEncodedGeometryType(buffer);
        switch (type) {
            case decoderModule.TRIANGULAR_MESH:
                geometry = new decoderModule.Mesh();
                status = decoder.DecodeBufferToMesh(buffer, geometry);
                break;
            case decoderModule.POINT_CLOUD:
                geometry = new decoderModule.PointCloud();
                status = decoder.DecodeBufferToPointCloud(buffer, geometry);
                break;
            default:
                throw new Error("Invalid geometry type " + type);
        }
        if (!status.ok() || !geometry.ptr) {
            throw new Error(status.error_msg());
        }
        var numPoints_1 = geometry.num_points();
        if (type === decoderModule.TRIANGULAR_MESH) {
            var numFaces = geometry.num_faces();
            var faceIndices = new decoderModule.DracoInt32Array();
            try {
                var indices = new Uint32Array(numFaces * 3);
                for (var i = 0; i < numFaces; i++) {
                    decoder.GetFaceFromMesh(geometry, i, faceIndices);
                    var offset = i * 3;
                    indices[offset + 0] = faceIndices.GetValue(0);
                    indices[offset + 1] = faceIndices.GetValue(1);
                    indices[offset + 2] = faceIndices.GetValue(2);
                }
                onIndicesData(indices);
            }
            finally {
                decoderModule.destroy(faceIndices);
            }
        }
        var processAttribute = function (kind, attribute) {
            var dracoData = new decoderModule.DracoFloat32Array();
            try {
                decoder.GetAttributeFloatForAllPoints(geometry, attribute, dracoData);
                var babylonData = new Float32Array(numPoints_1 * attribute.num_components());
                for (var i = 0; i < babylonData.length; i++) {
                    babylonData[i] = dracoData.GetValue(i);
                }
                onAttributeData(kind, babylonData);
            }
            finally {
                decoderModule.destroy(dracoData);
            }
        };
        if (attributes) {
            for (var kind in attributes) {
                var id = attributes[kind];
                var attribute = decoder.GetAttributeByUniqueId(geometry, id);
                processAttribute(kind, attribute);
            }
        }
        else {
            var nativeAttributeTypes = {
                "position": "POSITION",
                "normal": "NORMAL",
                "color": "COLOR",
                "uv": "TEX_COORD"
            };
            for (var kind in nativeAttributeTypes) {
                var id = decoder.GetAttributeId(geometry, decoderModule[nativeAttributeTypes[kind]]);
                if (id !== -1) {
                    var attribute = decoder.GetAttribute(geometry, id);
                    processAttribute(kind, attribute);
                }
            }
        }
    }
    finally {
        if (geometry) {
            decoderModule.destroy(geometry);
        }
        decoderModule.destroy(decoder);
        decoderModule.destroy(buffer);
    }
}
/**
 * The worker function that gets converted to a blob url to pass into a worker.
 */
function worker() {
    var decoderPromise;
    onmessage = function (event) {
        var data = event.data;
        switch (data.id) {
            case "init": {
                var decoder = data.decoder;
                decoderPromise = createDecoderAsync(decoder.wasmUrl, decoder.wasmBinary, decoder.fallbackUrl);
                postMessage("done");
                break;
            }
            case "decodeMesh": {
                if (!decoderPromise) {
                    throw new Error("Draco decoder module is not available");
                }
                decoderPromise.then(function (decoder) {
                    decodeMesh(decoder.module, data.dataView, data.attributes, function (indices) {
                        postMessage({ id: "indices", value: indices }, [indices.buffer]);
                    }, function (kind, data) {
                        postMessage({ id: kind, value: data }, [data.buffer]);
                    });
                    postMessage("done");
                });
                break;
            }
        }
    };
}
function getAbsoluteUrl(url) {
    if (typeof document !== "object" || typeof url !== "string") {
        return url;
    }
    return _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetAbsoluteUrl(url);
}
/**
 * Draco compression (https://google.github.io/draco/)
 *
 * This class wraps the Draco module.
 *
 * **Encoder**
 *
 * The encoder is not currently implemented.
 *
 * **Decoder**
 *
 * By default, the configuration points to a copy of the Draco decoder files for glTF from the babylon.js preview cdn https://preview.babylonjs.com/draco_wasm_wrapper_gltf.js.
 *
 * To update the configuration, use the following code:
 * ```javascript
 *     DracoCompression.Configuration = {
 *         decoder: {
 *             wasmUrl: "<url to the WebAssembly library>",
 *             wasmBinaryUrl: "<url to the WebAssembly binary>",
 *             fallbackUrl: "<url to the fallback JavaScript library>",
 *         }
 *     };
 * ```
 *
 * Draco has two versions, one for WebAssembly and one for JavaScript. The decoder configuration can be set to only support Webssembly or only support the JavaScript version.
 * Decoding will automatically fallback to the JavaScript version if WebAssembly version is not configured or if WebAssembly is not supported by the browser.
 * Use `DracoCompression.DecoderAvailable` to determine if the decoder configuration is available for the current context.
 *
 * To decode Draco compressed data, get the default DracoCompression object and call decodeMeshAsync:
 * ```javascript
 *     var vertexData = await DracoCompression.Default.decodeMeshAsync(data);
 * ```
 *
 * @see https://www.babylonjs-playground.com/#N3EK4B#0
 */
var DracoCompression = /** @class */ (function () {
    /**
     * Constructor
     * @param numWorkers The number of workers for async operations. Specify `0` to disable web workers and run synchronously in the current context.
     */
    function DracoCompression(numWorkers) {
        if (numWorkers === void 0) { numWorkers = DracoCompression.DefaultNumWorkers; }
        var decoder = DracoCompression.Configuration.decoder;
        var decoderWasmBinaryPromise = (decoder.wasmUrl && decoder.wasmBinaryUrl && typeof WebAssembly === "object")
            ? loadFileAsync(getAbsoluteUrl(decoder.wasmBinaryUrl))
            : Promise.resolve(undefined);
        if (numWorkers && typeof Worker === "function") {
            this._workerPoolPromise = decoderWasmBinaryPromise.then(function (decoderWasmBinary) {
                var workerContent = "" + loadScriptAsync + createDecoderAsync + decodeMesh + "(" + worker + ")()";
                var workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: "application/javascript" }));
                var workerPromises = new Array(numWorkers);
                for (var i = 0; i < workerPromises.length; i++) {
                    workerPromises[i] = new Promise(function (resolve, reject) {
                        var worker = new Worker(workerBlobUrl);
                        var onError = function (error) {
                            worker.removeEventListener("error", onError);
                            worker.removeEventListener("message", onMessage);
                            reject(error);
                        };
                        var onMessage = function (message) {
                            if (message.data === "done") {
                                worker.removeEventListener("error", onError);
                                worker.removeEventListener("message", onMessage);
                                resolve(worker);
                            }
                        };
                        worker.addEventListener("error", onError);
                        worker.addEventListener("message", onMessage);
                        worker.postMessage({
                            id: "init",
                            decoder: {
                                wasmUrl: getAbsoluteUrl(decoder.wasmUrl),
                                wasmBinary: decoderWasmBinary,
                                fallbackUrl: getAbsoluteUrl(decoder.fallbackUrl)
                            }
                        });
                    });
                }
                return Promise.all(workerPromises).then(function (workers) {
                    return new _Misc_workerPool__WEBPACK_IMPORTED_MODULE_1__["WorkerPool"](workers);
                });
            });
        }
        else {
            this._decoderModulePromise = decoderWasmBinaryPromise.then(function (decoderWasmBinary) {
                return createDecoderAsync(decoder.wasmUrl, decoderWasmBinary, decoder.fallbackUrl);
            });
        }
    }
    Object.defineProperty(DracoCompression, "DecoderAvailable", {
        /**
         * Returns true if the decoder configuration is available.
         */
        get: function () {
            var decoder = DracoCompression.Configuration.decoder;
            return !!((decoder.wasmUrl && decoder.wasmBinaryUrl && typeof WebAssembly === "object") || decoder.fallbackUrl);
        },
        enumerable: true,
        configurable: true
    });
    DracoCompression.GetDefaultNumWorkers = function () {
        if (typeof navigator !== "object" || !navigator.hardwareConcurrency) {
            return 1;
        }
        // Use 50% of the available logical processors but capped at 4.
        return Math.min(Math.floor(navigator.hardwareConcurrency * 0.5), 4);
    };
    Object.defineProperty(DracoCompression, "Default", {
        /**
         * Default instance for the draco compression object.
         */
        get: function () {
            if (!DracoCompression._Default) {
                DracoCompression._Default = new DracoCompression();
            }
            return DracoCompression._Default;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Stop all async operations and release resources.
     */
    DracoCompression.prototype.dispose = function () {
        if (this._workerPoolPromise) {
            this._workerPoolPromise.then(function (workerPool) {
                workerPool.dispose();
            });
        }
        delete this._workerPoolPromise;
        delete this._decoderModulePromise;
    };
    /**
     * Returns a promise that resolves when ready. Call this manually to ensure draco compression is ready before use.
     * @returns a promise that resolves when ready
     */
    DracoCompression.prototype.whenReadyAsync = function () {
        if (this._workerPoolPromise) {
            return this._workerPoolPromise.then(function () { });
        }
        if (this._decoderModulePromise) {
            return this._decoderModulePromise.then(function () { });
        }
        return Promise.resolve();
    };
    /**
      * Decode Draco compressed mesh data to vertex data.
      * @param data The ArrayBuffer or ArrayBufferView for the Draco compression data
      * @param attributes A map of attributes from vertex buffer kinds to Draco unique ids
      * @returns A promise that resolves with the decoded vertex data
      */
    DracoCompression.prototype.decodeMeshAsync = function (data, attributes) {
        var dataView = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
        if (this._workerPoolPromise) {
            return this._workerPoolPromise.then(function (workerPool) {
                return new Promise(function (resolve, reject) {
                    workerPool.push(function (worker, onComplete) {
                        var vertexData = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
                        var onError = function (error) {
                            worker.removeEventListener("error", onError);
                            worker.removeEventListener("message", onMessage);
                            reject(error);
                            onComplete();
                        };
                        var onMessage = function (message) {
                            if (message.data === "done") {
                                worker.removeEventListener("error", onError);
                                worker.removeEventListener("message", onMessage);
                                resolve(vertexData);
                                onComplete();
                            }
                            else if (message.data.id === "indices") {
                                vertexData.indices = message.data.value;
                            }
                            else {
                                vertexData.set(message.data.value, message.data.id);
                            }
                        };
                        worker.addEventListener("error", onError);
                        worker.addEventListener("message", onMessage);
                        var dataViewCopy = new Uint8Array(dataView.byteLength);
                        dataViewCopy.set(new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength));
                        worker.postMessage({ id: "decodeMesh", dataView: dataViewCopy, attributes: attributes }, [dataViewCopy.buffer]);
                    });
                });
            });
        }
        if (this._decoderModulePromise) {
            return this._decoderModulePromise.then(function (decoder) {
                var vertexData = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
                decodeMesh(decoder.module, dataView, attributes, function (indices) {
                    vertexData.indices = indices;
                }, function (kind, data) {
                    vertexData.set(data, kind);
                });
                return vertexData;
            });
        }
        throw new Error("Draco decoder module is not available");
    };
    /**
     * The configuration. Defaults to the following urls:
     * - wasmUrl: "https://preview.babylonjs.com/draco_wasm_wrapper_gltf.js"
     * - wasmBinaryUrl: "https://preview.babylonjs.com/draco_decoder_gltf.wasm"
     * - fallbackUrl: "https://preview.babylonjs.com/draco_decoder_gltf.js"
     */
    DracoCompression.Configuration = {
        decoder: {
            wasmUrl: "https://preview.babylonjs.com/draco_wasm_wrapper_gltf.js",
            wasmBinaryUrl: "https://preview.babylonjs.com/draco_decoder_gltf.wasm",
            fallbackUrl: "https://preview.babylonjs.com/draco_decoder_gltf.js"
        }
    };
    /**
     * Default number of workers to create when creating the draco compression object.
     */
    DracoCompression.DefaultNumWorkers = DracoCompression.GetDefaultNumWorkers();
    DracoCompression._Default = null;
    return DracoCompression;
}());



/***/ }),

/***/ "./Meshes/Compression/index.ts":
/*!*************************************!*\
  !*** ./Meshes/Compression/index.ts ***!
  \*************************************/
/*! exports provided: DracoCompression */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _dracoCompression__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dracoCompression */ "./Meshes/Compression/dracoCompression.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DracoCompression", function() { return _dracoCompression__WEBPACK_IMPORTED_MODULE_0__["DracoCompression"]; });




/***/ }),

/***/ "./Meshes/WebGL/webGLDataBuffer.ts":
/*!*****************************************!*\
  !*** ./Meshes/WebGL/webGLDataBuffer.ts ***!
  \*****************************************/
/*! exports provided: WebGLDataBuffer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGLDataBuffer", function() { return WebGLDataBuffer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _dataBuffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../dataBuffer */ "./Meshes/dataBuffer.ts");


/** @hidden */
var WebGLDataBuffer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WebGLDataBuffer, _super);
    function WebGLDataBuffer(resource) {
        var _this = _super.call(this) || this;
        _this._buffer = resource;
        return _this;
    }
    Object.defineProperty(WebGLDataBuffer.prototype, "underlyingResource", {
        get: function () {
            return this._buffer;
        },
        enumerable: true,
        configurable: true
    });
    return WebGLDataBuffer;
}(_dataBuffer__WEBPACK_IMPORTED_MODULE_1__["DataBuffer"]));



/***/ }),

/***/ "./Meshes/WebGPU/webgpuDataBuffer.ts":
/*!*******************************************!*\
  !*** ./Meshes/WebGPU/webgpuDataBuffer.ts ***!
  \*******************************************/
/*! exports provided: WebGPUDataBuffer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebGPUDataBuffer", function() { return WebGPUDataBuffer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _dataBuffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../dataBuffer */ "./Meshes/dataBuffer.ts");


/** @hidden */
var WebGPUDataBuffer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WebGPUDataBuffer, _super);
    function WebGPUDataBuffer(resource) {
        var _this = _super.call(this) || this;
        _this._buffer = resource;
        return _this;
    }
    Object.defineProperty(WebGPUDataBuffer.prototype, "underlyingResource", {
        get: function () {
            return this._buffer;
        },
        enumerable: true,
        configurable: true
    });
    return WebGPUDataBuffer;
}(_dataBuffer__WEBPACK_IMPORTED_MODULE_1__["DataBuffer"]));



/***/ }),

/***/ "./Meshes/abstractMesh.ts":
/*!********************************!*\
  !*** ./Meshes/abstractMesh.ts ***!
  \********************************/
/*! exports provided: AbstractMesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractMesh", function() { return AbstractMesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Collisions/pickingInfo */ "./Collisions/pickingInfo.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Culling/boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Materials/uniformBuffer */ "./Materials/uniformBuffer.ts");
/* harmony import */ var _Collisions_meshCollisionData__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Collisions/meshCollisionData */ "./Collisions/meshCollisionData.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Maths_math_functions__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Maths/math.functions */ "./Maths/math.functions.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");


















/** @hidden */
var _FacetDataStorage = /** @class */ (function () {
    function _FacetDataStorage() {
        this.facetNb = 0; // facet number
        this.partitioningSubdivisions = 10; // number of subdivisions per axis in the partioning space
        this.partitioningBBoxRatio = 1.01; // the partioning array space is by default 1% bigger than the bounding box
        this.facetDataEnabled = false; // is the facet data feature enabled on this mesh ?
        this.facetParameters = {}; // keep a reference to the object parameters to avoid memory re-allocation
        this.bbSize = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero(); // bbox size approximated for facet data
        this.subDiv = {
            max: 1,
            X: 1,
            Y: 1,
            Z: 1
        };
        this.facetDepthSort = false; // is the facet depth sort to be computed
        this.facetDepthSortEnabled = false; // is the facet depth sort initialized
    }
    return _FacetDataStorage;
}());
/**
 * @hidden
 **/
var _InternalAbstractMeshDataInfo = /** @class */ (function () {
    function _InternalAbstractMeshDataInfo() {
        this._hasVertexAlpha = false;
        this._useVertexColors = true;
        this._numBoneInfluencers = 4;
        this._applyFog = true;
        this._receiveShadows = false;
        this._facetData = new _FacetDataStorage();
        this._visibility = 1.0;
        this._skeleton = null;
        this._layerMask = 0x0FFFFFFF;
        this._computeBonesUsingShaders = true;
        this._isActive = false;
        this._onlyForInstances = false;
        this._isActiveIntermediate = false;
        this._onlyForInstancesIntermediate = false;
    }
    return _InternalAbstractMeshDataInfo;
}());
/**
 * Class used to store all common mesh properties
 */
var AbstractMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AbstractMesh, _super);
    // Constructor
    /**
     * Creates a new AbstractMesh
     * @param name defines the name of the mesh
     * @param scene defines the hosting scene
     */
    function AbstractMesh(name, scene) {
        if (scene === void 0) { scene = null; }
        var _this = _super.call(this, name, scene, false) || this;
        // Internal data
        /** @hidden */
        _this._internalAbstractMeshDataInfo = new _InternalAbstractMeshDataInfo();
        /**
         * The culling strategy to use to check whether the mesh must be rendered or not.
         * This value can be changed at any time and will be used on the next render mesh selection.
         * The possible values are :
         * - AbstractMesh.CULLINGSTRATEGY_STANDARD
         * - AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY
         * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION
         * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY
         * Please read each static variable documentation to get details about the culling process.
         * */
        _this.cullingStrategy = AbstractMesh.CULLINGSTRATEGY_STANDARD;
        // Events
        /**
        * An event triggered when this mesh collides with another one
        */
        _this.onCollideObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
        * An event triggered when the collision's position changes
        */
        _this.onCollisionPositionChangeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
        * An event triggered when material is changed
        */
        _this.onMaterialChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        // Properties
        /**
         * Gets or sets the orientation for POV movement & rotation
         */
        _this.definedFacingForward = true;
        /** @hidden */
        _this._occlusionQuery = null;
        /** @hidden */
        _this._renderingGroup = null;
        /** Gets or sets the alpha index used to sort transparent meshes
         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#alpha-index
         */
        _this.alphaIndex = Number.MAX_VALUE;
        /**
         * Gets or sets a boolean indicating if the mesh is visible (renderable). Default is true
         */
        _this.isVisible = true;
        /**
         * Gets or sets a boolean indicating if the mesh can be picked (by scene.pick for instance or through actions). Default is true
         */
        _this.isPickable = true;
        /** Gets or sets a boolean indicating that bounding boxes of subMeshes must be rendered as well (false by default) */
        _this.showSubMeshesBoundingBox = false;
        /** Gets or sets a boolean indicating if the mesh must be considered as a ray blocker for lens flares (false by default)
         * @see http://doc.babylonjs.com/how_to/how_to_use_lens_flares
         */
        _this.isBlocker = false;
        /**
         * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
         */
        _this.enablePointerMoveEvents = false;
        /**
         * Specifies the rendering group id for this mesh (0 by default)
         * @see http://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
         */
        _this.renderingGroupId = 0;
        _this._material = null;
        /** Defines color to use when rendering outline */
        _this.outlineColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color3"].Red();
        /** Define width to use when rendering outline */
        _this.outlineWidth = 0.02;
        /** Defines color to use when rendering overlay */
        _this.overlayColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color3"].Red();
        /** Defines alpha to use when rendering overlay */
        _this.overlayAlpha = 0.5;
        /** Gets or sets a boolean indicating that internal octree (if available) can be used to boost submeshes selection (true by default) */
        _this.useOctreeForRenderingSelection = true;
        /** Gets or sets a boolean indicating that internal octree (if available) can be used to boost submeshes picking (true by default) */
        _this.useOctreeForPicking = true;
        /** Gets or sets a boolean indicating that internal octree (if available) can be used to boost submeshes collision (true by default) */
        _this.useOctreeForCollisions = true;
        /**
         * True if the mesh must be rendered in any case (this will shortcut the frustum clipping phase)
         */
        _this.alwaysSelectAsActiveMesh = false;
        /**
         * Gets or sets a boolean indicating that the bounding info does not need to be kept in sync (for performance reason)
         */
        _this.doNotSyncBoundingInfo = false;
        /**
         * Gets or sets the current action manager
         * @see http://doc.babylonjs.com/how_to/how_to_use_actions
         */
        _this.actionManager = null;
        // Collisions
        _this._meshCollisionData = new _Collisions_meshCollisionData__WEBPACK_IMPORTED_MODULE_12__["_MeshCollisionData"]();
        /**
         * Gets or sets the ellipsoid used to impersonate this mesh when using collision engine (default is (0.5, 1, 0.5))
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
         */
        _this.ellipsoid = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0.5, 1, 0.5);
        /**
         * Gets or sets the ellipsoid offset used to impersonate this mesh when using collision engine (default is (0, 0, 0))
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
         */
        _this.ellipsoidOffset = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
        // Edges
        /**
         * Defines edge width used when edgesRenderer is enabled
         * @see https://www.babylonjs-playground.com/#10OJSG#13
         */
        _this.edgesWidth = 1;
        /**
         * Defines edge color used when edgesRenderer is enabled
         * @see https://www.babylonjs-playground.com/#10OJSG#13
         */
        _this.edgesColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_15__["Color4"](1, 0, 0, 1);
        /** @hidden */
        _this._edgesRenderer = null;
        /** @hidden */
        _this._masterMesh = null;
        /** @hidden */
        _this._boundingInfo = null;
        /** @hidden */
        _this._renderId = 0;
        /** @hidden */
        _this._intersectionsInProgress = new Array();
        /** @hidden */
        _this._unIndexed = false;
        /** @hidden */
        _this._lightSources = new Array();
        // Loading properties
        /** @hidden */
        _this._waitingData = {
            lods: null,
            actions: null,
            freezeWorldMatrix: null
        };
        /** @hidden */
        _this._bonesTransformMatrices = null;
        /** @hidden */
        _this._transformMatrixTexture = null;
        /**
         * An event triggered when the mesh is rebuilt.
         */
        _this.onRebuildObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this._onCollisionPositionChange = function (collisionId, newPosition, collidedMesh) {
            if (collidedMesh === void 0) { collidedMesh = null; }
            newPosition.subtractToRef(_this._meshCollisionData._oldPositionForCollisions, _this._meshCollisionData._diffPositionForCollisions);
            if (_this._meshCollisionData._diffPositionForCollisions.length() > _Engines_engine__WEBPACK_IMPORTED_MODULE_4__["Engine"].CollisionsEpsilon) {
                _this.position.addInPlace(_this._meshCollisionData._diffPositionForCollisions);
            }
            if (collidedMesh) {
                _this.onCollideObservable.notifyObservers(collidedMesh);
            }
            _this.onCollisionPositionChangeObservable.notifyObservers(_this.position);
        };
        _this.getScene().addMesh(_this);
        _this._resyncLightSources();
        // Mesh Uniform Buffer.
        _this._uniformBuffer = new _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_11__["UniformBuffer"](_this.getScene().getEngine());
        _this._buildUniformLayout();
        return _this;
    }
    Object.defineProperty(AbstractMesh, "BILLBOARDMODE_NONE", {
        /**
         * No billboard
         */
        get: function () {
            return _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_NONE;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh, "BILLBOARDMODE_X", {
        /** Billboard on X axis */
        get: function () {
            return _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_X;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh, "BILLBOARDMODE_Y", {
        /** Billboard on Y axis */
        get: function () {
            return _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_Y;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh, "BILLBOARDMODE_Z", {
        /** Billboard on Z axis */
        get: function () {
            return _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_Z;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh, "BILLBOARDMODE_ALL", {
        /** Billboard on all axes */
        get: function () {
            return _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_ALL;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh, "BILLBOARDMODE_USE_POSITION", {
        /** Billboard on using position instead of orientation */
        get: function () {
            return _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_USE_POSITION;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "facetNb", {
        /**
         * Gets the number of facets in the mesh
         * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata#what-is-a-mesh-facet
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._facetData.facetNb;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "partitioningSubdivisions", {
        /**
         * Gets or set the number (integer) of subdivisions per axis in the partioning space
         * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata#tweaking-the-partitioning
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._facetData.partitioningSubdivisions;
        },
        set: function (nb) {
            this._internalAbstractMeshDataInfo._facetData.partitioningSubdivisions = nb;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "partitioningBBoxRatio", {
        /**
         * The ratio (float) to apply to the bouding box size to set to the partioning space.
         * Ex : 1.01 (default) the partioning space is 1% bigger than the bounding box
         * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata#tweaking-the-partitioning
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._facetData.partitioningBBoxRatio;
        },
        set: function (ratio) {
            this._internalAbstractMeshDataInfo._facetData.partitioningBBoxRatio = ratio;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "mustDepthSortFacets", {
        /**
         * Gets or sets a boolean indicating that the facets must be depth sorted on next call to `updateFacetData()`.
         * Works only for updatable meshes.
         * Doesn't work with multi-materials
         * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata#facet-depth-sort
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._facetData.facetDepthSort;
        },
        set: function (sort) {
            this._internalAbstractMeshDataInfo._facetData.facetDepthSort = sort;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "facetDepthSortFrom", {
        /**
         * The location (Vector3) where the facet depth sort must be computed from.
         * By default, the active camera position.
         * Used only when facet depth sort is enabled
         * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata#facet-depth-sort
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._facetData.facetDepthSortFrom;
        },
        set: function (location) {
            this._internalAbstractMeshDataInfo._facetData.facetDepthSortFrom = location;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "isFacetDataEnabled", {
        /**
         * gets a boolean indicating if facetData is enabled
         * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata#what-is-a-mesh-facet
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._facetData.facetDataEnabled;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    AbstractMesh.prototype._updateNonUniformScalingState = function (value) {
        if (!_super.prototype._updateNonUniformScalingState.call(this, value)) {
            return false;
        }
        this._markSubMeshesAsMiscDirty();
        return true;
    };
    Object.defineProperty(AbstractMesh.prototype, "onCollide", {
        /** Set a function to call when this mesh collides with another one */
        set: function (callback) {
            if (this._meshCollisionData._onCollideObserver) {
                this.onCollideObservable.remove(this._meshCollisionData._onCollideObserver);
            }
            this._meshCollisionData._onCollideObserver = this.onCollideObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "onCollisionPositionChange", {
        /** Set a function to call when the collision's position changes */
        set: function (callback) {
            if (this._meshCollisionData._onCollisionPositionChangeObserver) {
                this.onCollisionPositionChangeObservable.remove(this._meshCollisionData._onCollisionPositionChangeObserver);
            }
            this._meshCollisionData._onCollisionPositionChangeObserver = this.onCollisionPositionChangeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "visibility", {
        /**
         * Gets or sets mesh visibility between 0 and 1 (default is 1)
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._visibility;
        },
        /**
         * Gets or sets mesh visibility between 0 and 1 (default is 1)
         */
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._visibility === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._visibility = value;
            this._markSubMeshesAsMiscDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "material", {
        /** Gets or sets current material */
        get: function () {
            return this._material;
        },
        set: function (value) {
            if (this._material === value) {
                return;
            }
            // remove from material mesh map id needed
            if (this._material && this._material.meshMap) {
                this._material.meshMap[this.uniqueId] = undefined;
            }
            this._material = value;
            if (value && value.meshMap) {
                value.meshMap[this.uniqueId] = this;
            }
            if (this.onMaterialChangedObservable.hasObservers) {
                this.onMaterialChangedObservable.notifyObservers(this);
            }
            if (!this.subMeshes) {
                return;
            }
            this._unBindEffect();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "receiveShadows", {
        /**
         * Gets or sets a boolean indicating that this mesh can receive realtime shadows
         * @see http://doc.babylonjs.com/babylon101/shadows
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._receiveShadows;
        },
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._receiveShadows === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._receiveShadows = value;
            this._markSubMeshesAsLightDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "hasVertexAlpha", {
        /** Gets or sets a boolean indicating that this mesh contains vertex color data with alpha values */
        get: function () {
            return this._internalAbstractMeshDataInfo._hasVertexAlpha;
        },
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._hasVertexAlpha === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._hasVertexAlpha = value;
            this._markSubMeshesAsAttributesDirty();
            this._markSubMeshesAsMiscDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "useVertexColors", {
        /** Gets or sets a boolean indicating that this mesh needs to use vertex color data to render (if this kind of vertex data is available in the geometry) */
        get: function () {
            return this._internalAbstractMeshDataInfo._useVertexColors;
        },
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._useVertexColors === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._useVertexColors = value;
            this._markSubMeshesAsAttributesDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "computeBonesUsingShaders", {
        /**
         * Gets or sets a boolean indicating that bone animations must be computed by the CPU (false by default)
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._computeBonesUsingShaders;
        },
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._computeBonesUsingShaders === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._computeBonesUsingShaders = value;
            this._markSubMeshesAsAttributesDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "numBoneInfluencers", {
        /** Gets or sets the number of allowed bone influences per vertex (4 by default) */
        get: function () {
            return this._internalAbstractMeshDataInfo._numBoneInfluencers;
        },
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._numBoneInfluencers === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._numBoneInfluencers = value;
            this._markSubMeshesAsAttributesDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "applyFog", {
        /** Gets or sets a boolean indicating that this mesh will allow fog to be rendered on it (true by default) */
        get: function () {
            return this._internalAbstractMeshDataInfo._applyFog;
        },
        set: function (value) {
            if (this._internalAbstractMeshDataInfo._applyFog === value) {
                return;
            }
            this._internalAbstractMeshDataInfo._applyFog = value;
            this._markSubMeshesAsMiscDirty();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "layerMask", {
        /**
         * Gets or sets the current layer mask (default is 0x0FFFFFFF)
         * @see http://doc.babylonjs.com/how_to/layermasks_and_multi-cam_textures
         */
        get: function () {
            return this._internalAbstractMeshDataInfo._layerMask;
        },
        set: function (value) {
            if (value === this._internalAbstractMeshDataInfo._layerMask) {
                return;
            }
            this._internalAbstractMeshDataInfo._layerMask = value;
            this._resyncLightSources();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "collisionMask", {
        /**
         * Gets or sets a collision mask used to mask collisions (default is -1).
         * A collision between A and B will happen if A.collisionGroup & b.collisionMask !== 0
         */
        get: function () {
            return this._meshCollisionData._collisionMask;
        },
        set: function (mask) {
            this._meshCollisionData._collisionMask = !isNaN(mask) ? mask : -1;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "collisionGroup", {
        /**
         * Gets or sets the current collision group mask (-1 by default).
         * A collision between A and B will happen if A.collisionGroup & b.collisionMask !== 0
         */
        get: function () {
            return this._meshCollisionData._collisionGroup;
        },
        set: function (mask) {
            this._meshCollisionData._collisionGroup = !isNaN(mask) ? mask : -1;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "lightSources", {
        /** Gets the list of lights affecting that mesh */
        get: function () {
            return this._lightSources;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "_positions", {
        /** @hidden */
        get: function () {
            return null;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "skeleton", {
        get: function () {
            return this._internalAbstractMeshDataInfo._skeleton;
        },
        /**
         * Gets or sets a skeleton to apply skining transformations
         * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons
         */
        set: function (value) {
            var skeleton = this._internalAbstractMeshDataInfo._skeleton;
            if (skeleton && skeleton.needInitialSkinMatrix) {
                skeleton._unregisterMeshWithPoseMatrix(this);
            }
            if (value && value.needInitialSkinMatrix) {
                value._registerMeshWithPoseMatrix(this);
            }
            this._internalAbstractMeshDataInfo._skeleton = value;
            if (!this._internalAbstractMeshDataInfo._skeleton) {
                this._bonesTransformMatrices = null;
            }
            this._markSubMeshesAsAttributesDirty();
        },
        enumerable: true,
        configurable: true
    });
    AbstractMesh.prototype._buildUniformLayout = function () {
        this._uniformBuffer.addUniform("world", 16);
        this._uniformBuffer.addUniform("visibility", 1);
        this._uniformBuffer.create();
    };
    /**
     * Transfer the mesh values to its UBO.
     * @param world The world matrix associated with the mesh
     */
    AbstractMesh.prototype.transferToEffect = function (world) {
        var ubo = this._uniformBuffer;
        ubo.updateMatrix("world", world);
        ubo.updateFloat("visibility", this._internalAbstractMeshDataInfo._visibility);
        ubo.update();
    };
    /**
     * Gets the mesh uniform buffer.
     * @return the uniform buffer of the mesh.
     */
    AbstractMesh.prototype.getMeshUniformBuffer = function () {
        return this._uniformBuffer;
    };
    /**
     * Returns the string "AbstractMesh"
     * @returns "AbstractMesh"
     */
    AbstractMesh.prototype.getClassName = function () {
        return "AbstractMesh";
    };
    /**
     * Gets a string representation of the current mesh
     * @param fullDetails defines a boolean indicating if full details must be included
     * @returns a string representation of the current mesh
     */
    AbstractMesh.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name + ", isInstance: " + (this.getClassName() !== "InstancedMesh" ? "YES" : "NO");
        ret += ", # of submeshes: " + (this.subMeshes ? this.subMeshes.length : 0);
        var skeleton = this._internalAbstractMeshDataInfo._skeleton;
        if (skeleton) {
            ret += ", skeleton: " + skeleton.name;
        }
        if (fullDetails) {
            ret += ", billboard mode: " + (["NONE", "X", "Y", null, "Z", null, null, "ALL"])[this.billboardMode];
            ret += ", freeze wrld mat: " + (this._isWorldMatrixFrozen || this._waitingData.freezeWorldMatrix ? "YES" : "NO");
        }
        return ret;
    };
    /**
     * @hidden
     */
    AbstractMesh.prototype._getEffectiveParent = function () {
        if (this._masterMesh && this.billboardMode !== _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_NONE) {
            return this._masterMesh;
        }
        return _super.prototype._getEffectiveParent.call(this);
    };
    /** @hidden */
    AbstractMesh.prototype._getActionManagerForTrigger = function (trigger, initialCall) {
        if (initialCall === void 0) { initialCall = true; }
        if (this.actionManager && (initialCall || this.actionManager.isRecursive)) {
            if (trigger) {
                if (this.actionManager.hasSpecificTrigger(trigger)) {
                    return this.actionManager;
                }
            }
            else {
                return this.actionManager;
            }
        }
        if (!this.parent) {
            return null;
        }
        return this.parent._getActionManagerForTrigger(trigger, false);
    };
    /** @hidden */
    AbstractMesh.prototype._rebuild = function () {
        this.onRebuildObservable.notifyObservers(this);
        if (this._occlusionQuery) {
            this._occlusionQuery = null;
        }
        if (!this.subMeshes) {
            return;
        }
        for (var _i = 0, _a = this.subMeshes; _i < _a.length; _i++) {
            var subMesh = _a[_i];
            subMesh._rebuild();
        }
    };
    /** @hidden */
    AbstractMesh.prototype._resyncLightSources = function () {
        this._lightSources.length = 0;
        for (var _i = 0, _a = this.getScene().lights; _i < _a.length; _i++) {
            var light = _a[_i];
            if (!light.isEnabled()) {
                continue;
            }
            if (light.canAffectMesh(this)) {
                this._lightSources.push(light);
            }
        }
        this._markSubMeshesAsLightDirty();
    };
    /** @hidden */
    AbstractMesh.prototype._resyncLighSource = function (light) {
        var isIn = light.isEnabled() && light.canAffectMesh(this);
        var index = this._lightSources.indexOf(light);
        if (index === -1) {
            if (!isIn) {
                return;
            }
            this._lightSources.push(light);
        }
        else {
            if (isIn) {
                return;
            }
            this._lightSources.splice(index, 1);
        }
        this._markSubMeshesAsLightDirty();
    };
    /** @hidden */
    AbstractMesh.prototype._unBindEffect = function () {
        for (var _i = 0, _a = this.subMeshes; _i < _a.length; _i++) {
            var subMesh = _a[_i];
            subMesh.setEffect(null);
        }
    };
    /** @hidden */
    AbstractMesh.prototype._removeLightSource = function (light, dispose) {
        var index = this._lightSources.indexOf(light);
        if (index === -1) {
            return;
        }
        this._lightSources.splice(index, 1);
        this._markSubMeshesAsLightDirty(dispose);
    };
    AbstractMesh.prototype._markSubMeshesAsDirty = function (func) {
        if (!this.subMeshes) {
            return;
        }
        for (var _i = 0, _a = this.subMeshes; _i < _a.length; _i++) {
            var subMesh = _a[_i];
            if (subMesh._materialDefines) {
                func(subMesh._materialDefines);
            }
        }
    };
    /** @hidden */
    AbstractMesh.prototype._markSubMeshesAsLightDirty = function (dispose) {
        if (dispose === void 0) { dispose = false; }
        this._markSubMeshesAsDirty(function (defines) { return defines.markAsLightDirty(dispose); });
    };
    /** @hidden */
    AbstractMesh.prototype._markSubMeshesAsAttributesDirty = function () {
        this._markSubMeshesAsDirty(function (defines) { return defines.markAsAttributesDirty(); });
    };
    /** @hidden */
    AbstractMesh.prototype._markSubMeshesAsMiscDirty = function () {
        if (!this.subMeshes) {
            return;
        }
        for (var _i = 0, _a = this.subMeshes; _i < _a.length; _i++) {
            var subMesh = _a[_i];
            var material = subMesh.getMaterial();
            if (material) {
                material.markAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].MATERIAL_MiscDirtyFlag);
            }
        }
    };
    Object.defineProperty(AbstractMesh.prototype, "scaling", {
        /**
        * Gets or sets a Vector3 depicting the mesh scaling along each local axis X, Y, Z.  Default is (1.0, 1.0, 1.0)
        */
        get: function () {
            return this._scaling;
        },
        set: function (newScaling) {
            this._scaling = newScaling;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "isBlocked", {
        // Methods
        /**
         * Returns true if the mesh is blocked. Implemented by child classes
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the mesh itself by default. Implemented by child classes
     * @param camera defines the camera to use to pick the right LOD level
     * @returns the currentAbstractMesh
     */
    AbstractMesh.prototype.getLOD = function (camera) {
        return this;
    };
    /**
     * Returns 0 by default. Implemented by child classes
     * @returns an integer
     */
    AbstractMesh.prototype.getTotalVertices = function () {
        return 0;
    };
    /**
     * Returns a positive integer : the total number of indices in this mesh geometry.
     * @returns the numner of indices or zero if the mesh has no geometry.
     */
    AbstractMesh.prototype.getTotalIndices = function () {
        return 0;
    };
    /**
     * Returns null by default. Implemented by child classes
     * @returns null
     */
    AbstractMesh.prototype.getIndices = function () {
        return null;
    };
    /**
     * Returns the array of the requested vertex data kind. Implemented by child classes
     * @param kind defines the vertex data kind to use
     * @returns null
     */
    AbstractMesh.prototype.getVerticesData = function (kind) {
        return null;
    };
    /**
     * Sets the vertex data of the mesh geometry for the requested `kind`.
     * If the mesh has no geometry, a new Geometry object is set to the mesh and then passed this vertex data.
     * Note that a new underlying VertexBuffer object is created each call.
     * If the `kind` is the `PositionKind`, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
     * @param kind defines vertex data kind:
     * * VertexBuffer.PositionKind
     * * VertexBuffer.UVKind
     * * VertexBuffer.UV2Kind
     * * VertexBuffer.UV3Kind
     * * VertexBuffer.UV4Kind
     * * VertexBuffer.UV5Kind
     * * VertexBuffer.UV6Kind
     * * VertexBuffer.ColorKind
     * * VertexBuffer.MatricesIndicesKind
     * * VertexBuffer.MatricesIndicesExtraKind
     * * VertexBuffer.MatricesWeightsKind
     * * VertexBuffer.MatricesWeightsExtraKind
     * @param data defines the data source
     * @param updatable defines if the data must be flagged as updatable (or static)
     * @param stride defines the vertex stride (size of an entire vertex). Can be null and in this case will be deduced from vertex data kind
     * @returns the current mesh
     */
    AbstractMesh.prototype.setVerticesData = function (kind, data, updatable, stride) {
        return this;
    };
    /**
     * Updates the existing vertex data of the mesh geometry for the requested `kind`.
     * If the mesh has no geometry, it is simply returned as it is.
     * @param kind defines vertex data kind:
     * * VertexBuffer.PositionKind
     * * VertexBuffer.UVKind
     * * VertexBuffer.UV2Kind
     * * VertexBuffer.UV3Kind
     * * VertexBuffer.UV4Kind
     * * VertexBuffer.UV5Kind
     * * VertexBuffer.UV6Kind
     * * VertexBuffer.ColorKind
     * * VertexBuffer.MatricesIndicesKind
     * * VertexBuffer.MatricesIndicesExtraKind
     * * VertexBuffer.MatricesWeightsKind
     * * VertexBuffer.MatricesWeightsExtraKind
     * @param data defines the data source
     * @param updateExtends If `kind` is `PositionKind` and if `updateExtends` is true, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed
     * @param makeItUnique If true, a new global geometry is created from this data and is set to the mesh
     * @returns the current mesh
     */
    AbstractMesh.prototype.updateVerticesData = function (kind, data, updateExtends, makeItUnique) {
        return this;
    };
    /**
     * Sets the mesh indices,
     * If the mesh has no geometry, a new Geometry object is created and set to the mesh.
     * @param indices Expects an array populated with integers or a typed array (Int32Array, Uint32Array, Uint16Array)
     * @param totalVertices Defines the total number of vertices
     * @returns the current mesh
     */
    AbstractMesh.prototype.setIndices = function (indices, totalVertices) {
        return this;
    };
    /**
     * Gets a boolean indicating if specific vertex data is present
     * @param kind defines the vertex data kind to use
     * @returns true is data kind is present
     */
    AbstractMesh.prototype.isVerticesDataPresent = function (kind) {
        return false;
    };
    /**
     * Returns the mesh BoundingInfo object or creates a new one and returns if it was undefined.
     * Note that it returns a shallow bounding of the mesh (i.e. it does not include children).
     * To get the full bounding of all children, call `getHierarchyBoundingVectors` instead.
     * @returns a BoundingInfo
     */
    AbstractMesh.prototype.getBoundingInfo = function () {
        if (this._masterMesh) {
            return this._masterMesh.getBoundingInfo();
        }
        if (!this._boundingInfo) {
            // this._boundingInfo is being created here
            this._updateBoundingInfo();
        }
        // cannot be null.
        return this._boundingInfo;
    };
    /**
     * Uniformly scales the mesh to fit inside of a unit cube (1 X 1 X 1 units)
     * @param includeDescendants Use the hierarchy's bounding box instead of the mesh's bounding box. Default is false
     * @param ignoreRotation ignore rotation when computing the scale (ie. object will be axis aligned). Default is false
     * @param predicate predicate that is passed in to getHierarchyBoundingVectors when selecting which object should be included when scaling
     * @returns the current mesh
     */
    AbstractMesh.prototype.normalizeToUnitCube = function (includeDescendants, ignoreRotation, predicate) {
        if (includeDescendants === void 0) { includeDescendants = true; }
        if (ignoreRotation === void 0) { ignoreRotation = false; }
        return _super.prototype.normalizeToUnitCube.call(this, includeDescendants, ignoreRotation, predicate);
    };
    /**
     * Overwrite the current bounding info
     * @param boundingInfo defines the new bounding info
     * @returns the current mesh
     */
    AbstractMesh.prototype.setBoundingInfo = function (boundingInfo) {
        this._boundingInfo = boundingInfo;
        return this;
    };
    Object.defineProperty(AbstractMesh.prototype, "useBones", {
        /** Gets a boolean indicating if this mesh has skinning data and an attached skeleton */
        get: function () {
            return (this.skeleton && this.getScene().skeletonsEnabled && this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].MatricesIndicesKind) && this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].MatricesWeightsKind));
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    AbstractMesh.prototype._preActivate = function () {
    };
    /** @hidden */
    AbstractMesh.prototype._preActivateForIntermediateRendering = function (renderId) {
    };
    /** @hidden */
    AbstractMesh.prototype._activate = function (renderId, intermediateRendering) {
        this._renderId = renderId;
        return true;
    };
    /** @hidden */
    AbstractMesh.prototype._postActivate = function () {
        // Do nothing
    };
    /** @hidden */
    AbstractMesh.prototype._freeze = function () {
        // Do nothing
    };
    /** @hidden */
    AbstractMesh.prototype._unFreeze = function () {
        // Do nothing
    };
    /**
     * Gets the current world matrix
     * @returns a Matrix
     */
    AbstractMesh.prototype.getWorldMatrix = function () {
        if (this._masterMesh && this.billboardMode === _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"].BILLBOARDMODE_NONE) {
            return this._masterMesh.getWorldMatrix();
        }
        return _super.prototype.getWorldMatrix.call(this);
    };
    /** @hidden */
    AbstractMesh.prototype._getWorldMatrixDeterminant = function () {
        if (this._masterMesh) {
            return this._masterMesh._getWorldMatrixDeterminant();
        }
        return _super.prototype._getWorldMatrixDeterminant.call(this);
    };
    Object.defineProperty(AbstractMesh.prototype, "isAnInstance", {
        /**
         * Gets a boolean indicating if this mesh is an instance or a regular mesh
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "hasInstances", {
        /**
         * Gets a boolean indicating if this mesh has instances
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    // ================================== Point of View Movement =================================
    /**
     * Perform relative position change from the point of view of behind the front of the mesh.
     * This is performed taking into account the meshes current rotation, so you do not have to care.
     * Supports definition of mesh facing forward or backward
     * @param amountRight defines the distance on the right axis
     * @param amountUp defines the distance on the up axis
     * @param amountForward defines the distance on the forward axis
     * @returns the current mesh
     */
    AbstractMesh.prototype.movePOV = function (amountRight, amountUp, amountForward) {
        this.position.addInPlace(this.calcMovePOV(amountRight, amountUp, amountForward));
        return this;
    };
    /**
     * Calculate relative position change from the point of view of behind the front of the mesh.
     * This is performed taking into account the meshes current rotation, so you do not have to care.
     * Supports definition of mesh facing forward or backward
     * @param amountRight defines the distance on the right axis
     * @param amountUp defines the distance on the up axis
     * @param amountForward defines the distance on the forward axis
     * @returns the new displacement vector
     */
    AbstractMesh.prototype.calcMovePOV = function (amountRight, amountUp, amountForward) {
        var rotMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"]();
        var rotQuaternion = (this.rotationQuaternion) ? this.rotationQuaternion : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
        rotQuaternion.toRotationMatrix(rotMatrix);
        var translationDelta = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        var defForwardMult = this.definedFacingForward ? -1 : 1;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesFromFloatsToRef(amountRight * defForwardMult, amountUp, amountForward * defForwardMult, rotMatrix, translationDelta);
        return translationDelta;
    };
    // ================================== Point of View Rotation =================================
    /**
     * Perform relative rotation change from the point of view of behind the front of the mesh.
     * Supports definition of mesh facing forward or backward
     * @param flipBack defines the flip
     * @param twirlClockwise defines the twirl
     * @param tiltRight defines the tilt
     * @returns the current mesh
     */
    AbstractMesh.prototype.rotatePOV = function (flipBack, twirlClockwise, tiltRight) {
        this.rotation.addInPlace(this.calcRotatePOV(flipBack, twirlClockwise, tiltRight));
        return this;
    };
    /**
     * Calculate relative rotation change from the point of view of behind the front of the mesh.
     * Supports definition of mesh facing forward or backward.
     * @param flipBack defines the flip
     * @param twirlClockwise defines the twirl
     * @param tiltRight defines the tilt
     * @returns the new rotation vector
     */
    AbstractMesh.prototype.calcRotatePOV = function (flipBack, twirlClockwise, tiltRight) {
        var defForwardMult = this.definedFacingForward ? 1 : -1;
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](flipBack * defForwardMult, twirlClockwise, tiltRight * defForwardMult);
    };
    /**
     * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.
     * This means the mesh underlying bounding box and sphere are recomputed.
     * @param applySkeleton defines whether to apply the skeleton before computing the bounding info
     * @returns the current mesh
     */
    AbstractMesh.prototype.refreshBoundingInfo = function (applySkeleton) {
        if (applySkeleton === void 0) { applySkeleton = false; }
        if (this._boundingInfo && this._boundingInfo.isLocked) {
            return this;
        }
        this._refreshBoundingInfo(this._getPositionData(applySkeleton), null);
        return this;
    };
    /** @hidden */
    AbstractMesh.prototype._refreshBoundingInfo = function (data, bias) {
        if (data) {
            var extend = Object(_Maths_math_functions__WEBPACK_IMPORTED_MODULE_14__["extractMinAndMax"])(data, 0, this.getTotalVertices(), bias);
            if (this._boundingInfo) {
                this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
            }
            else {
                this._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_9__["BoundingInfo"](extend.minimum, extend.maximum);
            }
        }
        if (this.subMeshes) {
            for (var index = 0; index < this.subMeshes.length; index++) {
                this.subMeshes[index].refreshBoundingInfo(data);
            }
        }
        this._updateBoundingInfo();
    };
    /** @hidden */
    AbstractMesh.prototype._getPositionData = function (applySkeleton) {
        var data = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind);
        if (data && applySkeleton && this.skeleton) {
            data = _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].Slice(data);
            this._generatePointsArray();
            var matricesIndicesData = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].MatricesIndicesKind);
            var matricesWeightsData = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].MatricesWeightsKind);
            if (matricesWeightsData && matricesIndicesData) {
                var needExtras = this.numBoneInfluencers > 4;
                var matricesIndicesExtraData = needExtras ? this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].MatricesIndicesExtraKind) : null;
                var matricesWeightsExtraData = needExtras ? this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].MatricesWeightsExtraKind) : null;
                this.skeleton.prepare();
                var skeletonMatrices = this.skeleton.getTransformMatrices(this);
                var tempVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
                var finalMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
                var tempMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1];
                var matWeightIdx = 0;
                for (var index = 0; index < data.length; index += 3, matWeightIdx += 4) {
                    finalMatrix.reset();
                    var inf;
                    var weight;
                    for (inf = 0; inf < 4; inf++) {
                        weight = matricesWeightsData[matWeightIdx + inf];
                        if (weight > 0) {
                            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[matWeightIdx + inf] * 16), weight, tempMatrix);
                            finalMatrix.addToSelf(tempMatrix);
                        }
                    }
                    if (needExtras) {
                        for (inf = 0; inf < 4; inf++) {
                            weight = matricesWeightsExtraData[matWeightIdx + inf];
                            if (weight > 0) {
                                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[matWeightIdx + inf] * 16), weight, tempMatrix);
                                finalMatrix.addToSelf(tempMatrix);
                            }
                        }
                    }
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesFromFloatsToRef(data[index], data[index + 1], data[index + 2], finalMatrix, tempVector);
                    tempVector.toArray(data, index);
                    if (this._positions) {
                        this._positions[index / 3].copyFrom(tempVector);
                    }
                }
            }
        }
        return data;
    };
    /** @hidden */
    AbstractMesh.prototype._updateBoundingInfo = function () {
        var effectiveMesh = this._effectiveMesh;
        if (this._boundingInfo) {
            this._boundingInfo.update(effectiveMesh.worldMatrixFromCache);
        }
        else {
            this._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_9__["BoundingInfo"](this.absolutePosition, this.absolutePosition, effectiveMesh.worldMatrixFromCache);
        }
        this._updateSubMeshesBoundingInfo(effectiveMesh.worldMatrixFromCache);
        return this;
    };
    /** @hidden */
    AbstractMesh.prototype._updateSubMeshesBoundingInfo = function (matrix) {
        if (!this.subMeshes) {
            return this;
        }
        var count = this.subMeshes.length;
        for (var subIndex = 0; subIndex < count; subIndex++) {
            var subMesh = this.subMeshes[subIndex];
            if (count > 1 || !subMesh.IsGlobal) {
                subMesh.updateBoundingInfo(matrix);
            }
        }
        return this;
    };
    /** @hidden */
    AbstractMesh.prototype._afterComputeWorldMatrix = function () {
        if (this.doNotSyncBoundingInfo) {
            return;
        }
        // Bounding info
        this._updateBoundingInfo();
    };
    Object.defineProperty(AbstractMesh.prototype, "_effectiveMesh", {
        /** @hidden */
        get: function () {
            return (this.skeleton && this.skeleton.overrideMesh) || this;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns `true` if the mesh is within the frustum defined by the passed array of planes.
     * A mesh is in the frustum if its bounding box intersects the frustum
     * @param frustumPlanes defines the frustum to test
     * @returns true if the mesh is in the frustum planes
     */
    AbstractMesh.prototype.isInFrustum = function (frustumPlanes) {
        return this._boundingInfo !== null && this._boundingInfo.isInFrustum(frustumPlanes, this.cullingStrategy);
    };
    /**
     * Returns `true` if the mesh is completely in the frustum defined be the passed array of planes.
     * A mesh is completely in the frustum if its bounding box it completely inside the frustum.
     * @param frustumPlanes defines the frustum to test
     * @returns true if the mesh is completely in the frustum planes
     */
    AbstractMesh.prototype.isCompletelyInFrustum = function (frustumPlanes) {
        return this._boundingInfo !== null && this._boundingInfo.isCompletelyInFrustum(frustumPlanes);
    };
    /**
     * True if the mesh intersects another mesh or a SolidParticle object
     * @param mesh defines a target mesh or SolidParticle to test
     * @param precise Unless the parameter `precise` is set to `true` the intersection is computed according to Axis Aligned Bounding Boxes (AABB), else according to OBB (Oriented BBoxes)
     * @param includeDescendants Can be set to true to test if the mesh defined in parameters intersects with the current mesh or any child meshes
     * @returns true if there is an intersection
     */
    AbstractMesh.prototype.intersectsMesh = function (mesh, precise, includeDescendants) {
        if (precise === void 0) { precise = false; }
        if (!this._boundingInfo || !mesh._boundingInfo) {
            return false;
        }
        if (this._boundingInfo.intersects(mesh._boundingInfo, precise)) {
            return true;
        }
        if (includeDescendants) {
            for (var _i = 0, _a = this.getChildMeshes(); _i < _a.length; _i++) {
                var child = _a[_i];
                if (child.intersectsMesh(mesh, precise, true)) {
                    return true;
                }
            }
        }
        return false;
    };
    /**
     * Returns true if the passed point (Vector3) is inside the mesh bounding box
     * @param point defines the point to test
     * @returns true if there is an intersection
     */
    AbstractMesh.prototype.intersectsPoint = function (point) {
        if (!this._boundingInfo) {
            return false;
        }
        return this._boundingInfo.intersectsPoint(point);
    };
    Object.defineProperty(AbstractMesh.prototype, "checkCollisions", {
        // Collisions
        /**
         * Gets or sets a boolean indicating that this mesh can be used in the collision engine
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
         */
        get: function () {
            return this._meshCollisionData._checkCollisions;
        },
        set: function (collisionEnabled) {
            this._meshCollisionData._checkCollisions = collisionEnabled;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractMesh.prototype, "collider", {
        /**
         * Gets Collider object used to compute collisions (not physics)
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
         */
        get: function () {
            return this._meshCollisionData._collider;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Move the mesh using collision engine
     * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
     * @param displacement defines the requested displacement vector
     * @returns the current mesh
     */
    AbstractMesh.prototype.moveWithCollisions = function (displacement) {
        var globalPosition = this.getAbsolutePosition();
        globalPosition.addToRef(this.ellipsoidOffset, this._meshCollisionData._oldPositionForCollisions);
        var coordinator = this.getScene().collisionCoordinator;
        if (!this._meshCollisionData._collider) {
            this._meshCollisionData._collider = coordinator.createCollider();
        }
        this._meshCollisionData._collider._radius = this.ellipsoid;
        coordinator.getNewPosition(this._meshCollisionData._oldPositionForCollisions, displacement, this._meshCollisionData._collider, 3, this, this._onCollisionPositionChange, this.uniqueId);
        return this;
    };
    // Collisions
    /** @hidden */
    AbstractMesh.prototype._collideForSubMesh = function (subMesh, transformMatrix, collider) {
        this._generatePointsArray();
        if (!this._positions) {
            return this;
        }
        // Transformation
        if (!subMesh._lastColliderWorldVertices || !subMesh._lastColliderTransformMatrix.equals(transformMatrix)) {
            subMesh._lastColliderTransformMatrix = transformMatrix.clone();
            subMesh._lastColliderWorldVertices = [];
            subMesh._trianglePlanes = [];
            var start = subMesh.verticesStart;
            var end = (subMesh.verticesStart + subMesh.verticesCount);
            for (var i = start; i < end; i++) {
                subMesh._lastColliderWorldVertices.push(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinates(this._positions[i], transformMatrix));
            }
        }
        // Collide
        collider._collide(subMesh._trianglePlanes, subMesh._lastColliderWorldVertices, this.getIndices(), subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart, !!subMesh.getMaterial(), this);
        return this;
    };
    /** @hidden */
    AbstractMesh.prototype._processCollisionsForSubMeshes = function (collider, transformMatrix) {
        var subMeshes = this._scene.getCollidingSubMeshCandidates(this, collider);
        var len = subMeshes.length;
        for (var index = 0; index < len; index++) {
            var subMesh = subMeshes.data[index];
            // Bounding test
            if (len > 1 && !subMesh._checkCollision(collider)) {
                continue;
            }
            this._collideForSubMesh(subMesh, transformMatrix, collider);
        }
        return this;
    };
    /** @hidden */
    AbstractMesh.prototype._checkCollision = function (collider) {
        // Bounding box test
        if (!this._boundingInfo || !this._boundingInfo._checkCollision(collider)) {
            return this;
        }
        // Transformation matrix
        var collisionsScalingMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
        var collisionsTransformMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].ScalingToRef(1.0 / collider._radius.x, 1.0 / collider._radius.y, 1.0 / collider._radius.z, collisionsScalingMatrix);
        this.worldMatrixFromCache.multiplyToRef(collisionsScalingMatrix, collisionsTransformMatrix);
        this._processCollisionsForSubMeshes(collider, collisionsTransformMatrix);
        return this;
    };
    // Picking
    /** @hidden */
    AbstractMesh.prototype._generatePointsArray = function () {
        return false;
    };
    /**
     * Checks if the passed Ray intersects with the mesh
     * @param ray defines the ray to use
     * @param fastCheck defines if fast mode (but less precise) must be used (false by default)
     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
     * @returns the picking info
     * @see http://doc.babylonjs.com/babylon101/intersect_collisions_-_mesh
     */
    AbstractMesh.prototype.intersects = function (ray, fastCheck, trianglePredicate) {
        var pickingInfo = new _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_8__["PickingInfo"]();
        var intersectionThreshold = this.getClassName() === "InstancedLinesMesh" || this.getClassName() === "LinesMesh" ? this.intersectionThreshold : 0;
        var boundingInfo = this._boundingInfo;
        if (!this.subMeshes || !boundingInfo || !ray.intersectsSphere(boundingInfo.boundingSphere, intersectionThreshold) || !ray.intersectsBox(boundingInfo.boundingBox, intersectionThreshold)) {
            return pickingInfo;
        }
        if (!this._generatePointsArray()) {
            return pickingInfo;
        }
        var intersectInfo = null;
        var subMeshes = this._scene.getIntersectingSubMeshCandidates(this, ray);
        var len = subMeshes.length;
        for (var index = 0; index < len; index++) {
            var subMesh = subMeshes.data[index];
            // Bounding test
            if (len > 1 && !subMesh.canIntersects(ray)) {
                continue;
            }
            var currentIntersectInfo = subMesh.intersects(ray, this._positions, this.getIndices(), fastCheck, trianglePredicate);
            if (currentIntersectInfo) {
                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {
                    intersectInfo = currentIntersectInfo;
                    intersectInfo.subMeshId = index;
                    if (fastCheck) {
                        break;
                    }
                }
            }
        }
        if (intersectInfo) {
            // Get picked point
            var world = this.getWorldMatrix();
            var worldOrigin = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
            var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(ray.origin, world, worldOrigin);
            ray.direction.scaleToRef(intersectInfo.distance, direction);
            var worldDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(direction, world);
            var pickedPoint = worldDirection.addInPlace(worldOrigin);
            // Return result
            pickingInfo.hit = true;
            pickingInfo.distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Distance(worldOrigin, pickedPoint);
            pickingInfo.pickedPoint = pickedPoint;
            pickingInfo.pickedMesh = this;
            pickingInfo.bu = intersectInfo.bu || 0;
            pickingInfo.bv = intersectInfo.bv || 0;
            pickingInfo.faceId = intersectInfo.faceId;
            pickingInfo.subMeshId = intersectInfo.subMeshId;
            return pickingInfo;
        }
        return pickingInfo;
    };
    /**
     * Clones the current mesh
     * @param name defines the mesh name
     * @param newParent defines the new mesh parent
     * @param doNotCloneChildren defines a boolean indicating that children must not be cloned (false by default)
     * @returns the new mesh
     */
    AbstractMesh.prototype.clone = function (name, newParent, doNotCloneChildren) {
        return null;
    };
    /**
     * Disposes all the submeshes of the current meshnp
     * @returns the current mesh
     */
    AbstractMesh.prototype.releaseSubMeshes = function () {
        if (this.subMeshes) {
            while (this.subMeshes.length) {
                this.subMeshes[0].dispose();
            }
        }
        else {
            this.subMeshes = new Array();
        }
        return this;
    };
    /**
     * Releases resources associated with this abstract mesh.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    AbstractMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        var _this = this;
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        var index;
        // mesh map release.
        if (this._scene.useMaterialMeshMap) {
            // remove from material mesh map id needed
            if (this._material && this._material.meshMap) {
                this._material.meshMap[this.uniqueId] = undefined;
            }
        }
        // Smart Array Retainers.
        this.getScene().freeActiveMeshes();
        this.getScene().freeRenderingGroups();
        // Action manager
        if (this.actionManager !== undefined && this.actionManager !== null) {
            this.actionManager.dispose();
            this.actionManager = null;
        }
        // Skeleton
        this._internalAbstractMeshDataInfo._skeleton = null;
        if (this._transformMatrixTexture) {
            this._transformMatrixTexture.dispose();
            this._transformMatrixTexture = null;
        }
        // Intersections in progress
        for (index = 0; index < this._intersectionsInProgress.length; index++) {
            var other = this._intersectionsInProgress[index];
            var pos = other._intersectionsInProgress.indexOf(this);
            other._intersectionsInProgress.splice(pos, 1);
        }
        this._intersectionsInProgress = [];
        // Lights
        var lights = this.getScene().lights;
        lights.forEach(function (light) {
            var meshIndex = light.includedOnlyMeshes.indexOf(_this);
            if (meshIndex !== -1) {
                light.includedOnlyMeshes.splice(meshIndex, 1);
            }
            meshIndex = light.excludedMeshes.indexOf(_this);
            if (meshIndex !== -1) {
                light.excludedMeshes.splice(meshIndex, 1);
            }
            // Shadow generators
            var generator = light.getShadowGenerator();
            if (generator) {
                var shadowMap = generator.getShadowMap();
                if (shadowMap && shadowMap.renderList) {
                    meshIndex = shadowMap.renderList.indexOf(_this);
                    if (meshIndex !== -1) {
                        shadowMap.renderList.splice(meshIndex, 1);
                    }
                }
            }
        });
        // SubMeshes
        if (this.getClassName() !== "InstancedMesh" || this.getClassName() !== "InstancedLinesMesh") {
            this.releaseSubMeshes();
        }
        // Query
        var engine = this.getScene().getEngine();
        if (this._occlusionQuery) {
            this.isOcclusionQueryInProgress = false;
            engine.deleteQuery(this._occlusionQuery);
            this._occlusionQuery = null;
        }
        // Engine
        engine.wipeCaches();
        // Remove from scene
        this.getScene().removeMesh(this);
        if (disposeMaterialAndTextures) {
            if (this.material) {
                if (this.material.getClassName() === "MultiMaterial") {
                    this.material.dispose(false, true, true);
                }
                else {
                    this.material.dispose(false, true);
                }
            }
        }
        if (!doNotRecurse) {
            // Particles
            for (index = 0; index < this.getScene().particleSystems.length; index++) {
                if (this.getScene().particleSystems[index].emitter === this) {
                    this.getScene().particleSystems[index].dispose();
                    index--;
                }
            }
        }
        // facet data
        if (this._internalAbstractMeshDataInfo._facetData.facetDataEnabled) {
            this.disableFacetData();
        }
        this.onAfterWorldMatrixUpdateObservable.clear();
        this.onCollideObservable.clear();
        this.onCollisionPositionChangeObservable.clear();
        this.onRebuildObservable.clear();
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    /**
     * Adds the passed mesh as a child to the current mesh
     * @param mesh defines the child mesh
     * @returns the current mesh
     */
    AbstractMesh.prototype.addChild = function (mesh) {
        mesh.setParent(this);
        return this;
    };
    /**
     * Removes the passed mesh from the current mesh children list
     * @param mesh defines the child mesh
     * @returns the current mesh
     */
    AbstractMesh.prototype.removeChild = function (mesh) {
        mesh.setParent(null);
        return this;
    };
    // Facet data
    /** @hidden */
    AbstractMesh.prototype._initFacetData = function () {
        var data = this._internalAbstractMeshDataInfo._facetData;
        if (!data.facetNormals) {
            data.facetNormals = new Array();
        }
        if (!data.facetPositions) {
            data.facetPositions = new Array();
        }
        if (!data.facetPartitioning) {
            data.facetPartitioning = new Array();
        }
        data.facetNb = (this.getIndices().length / 3) | 0;
        data.partitioningSubdivisions = (data.partitioningSubdivisions) ? data.partitioningSubdivisions : 10; // default nb of partitioning subdivisions = 10
        data.partitioningBBoxRatio = (data.partitioningBBoxRatio) ? data.partitioningBBoxRatio : 1.01; // default ratio 1.01 = the partitioning is 1% bigger than the bounding box
        for (var f = 0; f < data.facetNb; f++) {
            data.facetNormals[f] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
            data.facetPositions[f] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        }
        data.facetDataEnabled = true;
        return this;
    };
    /**
     * Updates the mesh facetData arrays and the internal partitioning when the mesh is morphed or updated.
     * This method can be called within the render loop.
     * You don't need to call this method by yourself in the render loop when you update/morph a mesh with the methods CreateXXX() as they automatically manage this computation
     * @returns the current mesh
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.updateFacetData = function () {
        var data = this._internalAbstractMeshDataInfo._facetData;
        if (!data.facetDataEnabled) {
            this._initFacetData();
        }
        var positions = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind);
        var indices = this.getIndices();
        var normals = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind);
        var bInfo = this.getBoundingInfo();
        if (data.facetDepthSort && !data.facetDepthSortEnabled) {
            // init arrays, matrix and sort function on first call
            data.facetDepthSortEnabled = true;
            if (indices instanceof Uint16Array) {
                data.depthSortedIndices = new Uint16Array(indices);
            }
            else if (indices instanceof Uint32Array) {
                data.depthSortedIndices = new Uint32Array(indices);
            }
            else {
                var needs32bits = false;
                for (var i = 0; i < indices.length; i++) {
                    if (indices[i] > 65535) {
                        needs32bits = true;
                        break;
                    }
                }
                if (needs32bits) {
                    data.depthSortedIndices = new Uint32Array(indices);
                }
                else {
                    data.depthSortedIndices = new Uint16Array(indices);
                }
            }
            data.facetDepthSortFunction = function (f1, f2) {
                return (f2.sqDistance - f1.sqDistance);
            };
            if (!data.facetDepthSortFrom) {
                var camera = this.getScene().activeCamera;
                data.facetDepthSortFrom = (camera) ? camera.position : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
            }
            data.depthSortedFacets = [];
            for (var f = 0; f < data.facetNb; f++) {
                var depthSortedFacet = { ind: f * 3, sqDistance: 0.0 };
                data.depthSortedFacets.push(depthSortedFacet);
            }
            data.invertedMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
            data.facetDepthSortOrigin = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        }
        data.bbSize.x = (bInfo.maximum.x - bInfo.minimum.x > _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__["Epsilon"]) ? bInfo.maximum.x - bInfo.minimum.x : _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__["Epsilon"];
        data.bbSize.y = (bInfo.maximum.y - bInfo.minimum.y > _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__["Epsilon"]) ? bInfo.maximum.y - bInfo.minimum.y : _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__["Epsilon"];
        data.bbSize.z = (bInfo.maximum.z - bInfo.minimum.z > _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__["Epsilon"]) ? bInfo.maximum.z - bInfo.minimum.z : _Maths_math_constants__WEBPACK_IMPORTED_MODULE_16__["Epsilon"];
        var bbSizeMax = (data.bbSize.x > data.bbSize.y) ? data.bbSize.x : data.bbSize.y;
        bbSizeMax = (bbSizeMax > data.bbSize.z) ? bbSizeMax : data.bbSize.z;
        data.subDiv.max = data.partitioningSubdivisions;
        data.subDiv.X = Math.floor(data.subDiv.max * data.bbSize.x / bbSizeMax); // adjust the number of subdivisions per axis
        data.subDiv.Y = Math.floor(data.subDiv.max * data.bbSize.y / bbSizeMax); // according to each bbox size per axis
        data.subDiv.Z = Math.floor(data.subDiv.max * data.bbSize.z / bbSizeMax);
        data.subDiv.X = data.subDiv.X < 1 ? 1 : data.subDiv.X; // at least one subdivision
        data.subDiv.Y = data.subDiv.Y < 1 ? 1 : data.subDiv.Y;
        data.subDiv.Z = data.subDiv.Z < 1 ? 1 : data.subDiv.Z;
        // set the parameters for ComputeNormals()
        data.facetParameters.facetNormals = this.getFacetLocalNormals();
        data.facetParameters.facetPositions = this.getFacetLocalPositions();
        data.facetParameters.facetPartitioning = this.getFacetLocalPartitioning();
        data.facetParameters.bInfo = bInfo;
        data.facetParameters.bbSize = data.bbSize;
        data.facetParameters.subDiv = data.subDiv;
        data.facetParameters.ratio = this.partitioningBBoxRatio;
        data.facetParameters.depthSort = data.facetDepthSort;
        if (data.facetDepthSort && data.facetDepthSortEnabled) {
            this.computeWorldMatrix(true);
            this._worldMatrix.invertToRef(data.invertedMatrix);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(data.facetDepthSortFrom, data.invertedMatrix, data.facetDepthSortOrigin);
            data.facetParameters.distanceTo = data.facetDepthSortOrigin;
        }
        data.facetParameters.depthSortedFacets = data.depthSortedFacets;
        _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_6__["VertexData"].ComputeNormals(positions, indices, normals, data.facetParameters);
        if (data.facetDepthSort && data.facetDepthSortEnabled) {
            data.depthSortedFacets.sort(data.facetDepthSortFunction);
            var l = (data.depthSortedIndices.length / 3) | 0;
            for (var f = 0; f < l; f++) {
                var sind = data.depthSortedFacets[f].ind;
                data.depthSortedIndices[f * 3] = indices[sind];
                data.depthSortedIndices[f * 3 + 1] = indices[sind + 1];
                data.depthSortedIndices[f * 3 + 2] = indices[sind + 2];
            }
            this.updateIndices(data.depthSortedIndices, undefined, true);
        }
        return this;
    };
    /**
     * Returns the facetLocalNormals array.
     * The normals are expressed in the mesh local spac
     * @returns an array of Vector3
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetLocalNormals = function () {
        var facetData = this._internalAbstractMeshDataInfo._facetData;
        if (!facetData.facetNormals) {
            this.updateFacetData();
        }
        return facetData.facetNormals;
    };
    /**
     * Returns the facetLocalPositions array.
     * The facet positions are expressed in the mesh local space
     * @returns an array of Vector3
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetLocalPositions = function () {
        var facetData = this._internalAbstractMeshDataInfo._facetData;
        if (!facetData.facetPositions) {
            this.updateFacetData();
        }
        return facetData.facetPositions;
    };
    /**
     * Returns the facetLocalPartioning array
     * @returns an array of array of numbers
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetLocalPartitioning = function () {
        var facetData = this._internalAbstractMeshDataInfo._facetData;
        if (!facetData.facetPartitioning) {
            this.updateFacetData();
        }
        return facetData.facetPartitioning;
    };
    /**
     * Returns the i-th facet position in the world system.
     * This method allocates a new Vector3 per call
     * @param i defines the facet index
     * @returns a new Vector3
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetPosition = function (i) {
        var pos = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this.getFacetPositionToRef(i, pos);
        return pos;
    };
    /**
     * Sets the reference Vector3 with the i-th facet position in the world system
     * @param i defines the facet index
     * @param ref defines the target vector
     * @returns the current mesh
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetPositionToRef = function (i, ref) {
        var localPos = (this.getFacetLocalPositions())[i];
        var world = this.getWorldMatrix();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(localPos, world, ref);
        return this;
    };
    /**
     * Returns the i-th facet normal in the world system.
     * This method allocates a new Vector3 per call
     * @param i defines the facet index
     * @returns a new Vector3
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetNormal = function (i) {
        var norm = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this.getFacetNormalToRef(i, norm);
        return norm;
    };
    /**
     * Sets the reference Vector3 with the i-th facet normal in the world system
     * @param i defines the facet index
     * @param ref defines the target vector
     * @returns the current mesh
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetNormalToRef = function (i, ref) {
        var localNorm = (this.getFacetLocalNormals())[i];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormalToRef(localNorm, this.getWorldMatrix(), ref);
        return this;
    };
    /**
     * Returns the facets (in an array) in the same partitioning block than the one the passed coordinates are located (expressed in the mesh local system)
     * @param x defines x coordinate
     * @param y defines y coordinate
     * @param z defines z coordinate
     * @returns the array of facet indexes
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetsAtLocalCoordinates = function (x, y, z) {
        var bInfo = this.getBoundingInfo();
        var data = this._internalAbstractMeshDataInfo._facetData;
        var ox = Math.floor((x - bInfo.minimum.x * data.partitioningBBoxRatio) * data.subDiv.X * data.partitioningBBoxRatio / data.bbSize.x);
        var oy = Math.floor((y - bInfo.minimum.y * data.partitioningBBoxRatio) * data.subDiv.Y * data.partitioningBBoxRatio / data.bbSize.y);
        var oz = Math.floor((z - bInfo.minimum.z * data.partitioningBBoxRatio) * data.subDiv.Z * data.partitioningBBoxRatio / data.bbSize.z);
        if (ox < 0 || ox > data.subDiv.max || oy < 0 || oy > data.subDiv.max || oz < 0 || oz > data.subDiv.max) {
            return null;
        }
        return data.facetPartitioning[ox + data.subDiv.max * oy + data.subDiv.max * data.subDiv.max * oz];
    };
    /**
     * Returns the closest mesh facet index at (x,y,z) World coordinates, null if not found
     * @param projected sets as the (x,y,z) world projection on the facet
     * @param checkFace if true (default false), only the facet "facing" to (x,y,z) or only the ones "turning their backs", according to the parameter "facing" are returned
     * @param facing if facing and checkFace are true, only the facet "facing" to (x, y, z) are returned : positive dot (x, y, z) * facet position. If facing si false and checkFace is true, only the facet "turning their backs" to (x, y, z) are returned : negative dot (x, y, z) * facet position
     * @param x defines x coordinate
     * @param y defines y coordinate
     * @param z defines z coordinate
     * @returns the face index if found (or null instead)
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getClosestFacetAtCoordinates = function (x, y, z, projected, checkFace, facing) {
        if (checkFace === void 0) { checkFace = false; }
        if (facing === void 0) { facing = true; }
        var world = this.getWorldMatrix();
        var invMat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[5];
        world.invertToRef(invMat);
        var invVect = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[8];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesFromFloatsToRef(x, y, z, invMat, invVect); // transform (x,y,z) to coordinates in the mesh local space
        var closest = this.getClosestFacetAtLocalCoordinates(invVect.x, invVect.y, invVect.z, projected, checkFace, facing);
        if (projected) {
            // tranform the local computed projected vector to world coordinates
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesFromFloatsToRef(projected.x, projected.y, projected.z, world, projected);
        }
        return closest;
    };
    /**
     * Returns the closest mesh facet index at (x,y,z) local coordinates, null if not found
     * @param projected sets as the (x,y,z) local projection on the facet
     * @param checkFace if true (default false), only the facet "facing" to (x,y,z) or only the ones "turning their backs", according to the parameter "facing" are returned
     * @param facing if facing and checkFace are true, only the facet "facing" to (x, y, z) are returned : positive dot (x, y, z) * facet position. If facing si false and checkFace is true, only the facet "turning their backs" to (x, y, z) are returned : negative dot (x, y, z) * facet position
     * @param x defines x coordinate
     * @param y defines y coordinate
     * @param z defines z coordinate
     * @returns the face index if found (or null instead)
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getClosestFacetAtLocalCoordinates = function (x, y, z, projected, checkFace, facing) {
        if (checkFace === void 0) { checkFace = false; }
        if (facing === void 0) { facing = true; }
        var closest = null;
        var tmpx = 0.0;
        var tmpy = 0.0;
        var tmpz = 0.0;
        var d = 0.0; // tmp dot facet normal * facet position
        var t0 = 0.0;
        var projx = 0.0;
        var projy = 0.0;
        var projz = 0.0;
        // Get all the facets in the same partitioning block than (x, y, z)
        var facetPositions = this.getFacetLocalPositions();
        var facetNormals = this.getFacetLocalNormals();
        var facetsInBlock = this.getFacetsAtLocalCoordinates(x, y, z);
        if (!facetsInBlock) {
            return null;
        }
        // Get the closest facet to (x, y, z)
        var shortest = Number.MAX_VALUE; // init distance vars
        var tmpDistance = shortest;
        var fib; // current facet in the block
        var norm; // current facet normal
        var p0; // current facet barycenter position
        // loop on all the facets in the current partitioning block
        for (var idx = 0; idx < facetsInBlock.length; idx++) {
            fib = facetsInBlock[idx];
            norm = facetNormals[fib];
            p0 = facetPositions[fib];
            d = (x - p0.x) * norm.x + (y - p0.y) * norm.y + (z - p0.z) * norm.z;
            if (!checkFace || (checkFace && facing && d >= 0.0) || (checkFace && !facing && d <= 0.0)) {
                // compute (x,y,z) projection on the facet = (projx, projy, projz)
                d = norm.x * p0.x + norm.y * p0.y + norm.z * p0.z;
                t0 = -(norm.x * x + norm.y * y + norm.z * z - d) / (norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);
                projx = x + norm.x * t0;
                projy = y + norm.y * t0;
                projz = z + norm.z * t0;
                tmpx = projx - x;
                tmpy = projy - y;
                tmpz = projz - z;
                tmpDistance = tmpx * tmpx + tmpy * tmpy + tmpz * tmpz; // compute length between (x, y, z) and its projection on the facet
                if (tmpDistance < shortest) { // just keep the closest facet to (x, y, z)
                    shortest = tmpDistance;
                    closest = fib;
                    if (projected) {
                        projected.x = projx;
                        projected.y = projy;
                        projected.z = projz;
                    }
                }
            }
        }
        return closest;
    };
    /**
     * Returns the object "parameter" set with all the expected parameters for facetData computation by ComputeNormals()
     * @returns the parameters
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.getFacetDataParameters = function () {
        return this._internalAbstractMeshDataInfo._facetData.facetParameters;
    };
    /**
     * Disables the feature FacetData and frees the related memory
     * @returns the current mesh
     * @see http://doc.babylonjs.com/how_to/how_to_use_facetdata
     */
    AbstractMesh.prototype.disableFacetData = function () {
        var facetData = this._internalAbstractMeshDataInfo._facetData;
        if (facetData.facetDataEnabled) {
            facetData.facetDataEnabled = false;
            facetData.facetPositions = new Array();
            facetData.facetNormals = new Array();
            facetData.facetPartitioning = new Array();
            facetData.facetParameters = null;
            facetData.depthSortedIndices = new Uint32Array(0);
        }
        return this;
    };
    /**
     * Updates the AbstractMesh indices array
     * @param indices defines the data source
     * @param offset defines the offset in the index buffer where to store the new data (can be null)
     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)
     * @returns the current mesh
     */
    AbstractMesh.prototype.updateIndices = function (indices, offset, gpuMemoryOnly) {
        if (gpuMemoryOnly === void 0) { gpuMemoryOnly = false; }
        return this;
    };
    /**
     * Creates new normals data for the mesh
     * @param updatable defines if the normal vertex buffer must be flagged as updatable
     * @returns the current mesh
     */
    AbstractMesh.prototype.createNormals = function (updatable) {
        var positions = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind);
        var indices = this.getIndices();
        var normals;
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind)) {
            normals = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind);
        }
        else {
            normals = [];
        }
        _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_6__["VertexData"].ComputeNormals(positions, indices, normals, { useRightHandedSystem: this.getScene().useRightHandedSystem });
        this.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].NormalKind, normals, updatable);
        return this;
    };
    /**
     * Align the mesh with a normal
     * @param normal defines the normal to use
     * @param upDirection can be used to redefined the up vector to use (will use the (0, 1, 0) by default)
     * @returns the current mesh
     */
    AbstractMesh.prototype.alignWithNormal = function (normal, upDirection) {
        if (!upDirection) {
            upDirection = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_17__["Axis"].Y;
        }
        var axisX = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
        var axisZ = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].CrossToRef(upDirection, normal, axisZ);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].CrossToRef(normal, axisZ, axisX);
        if (this.rotationQuaternion) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationQuaternionFromAxisToRef(axisX, normal, axisZ, this.rotationQuaternion);
        }
        else {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].RotationFromAxisToRef(axisX, normal, axisZ, this.rotation);
        }
        return this;
    };
    /** @hidden */
    AbstractMesh.prototype._checkOcclusionQuery = function () {
        return false;
    };
    /**
     * Disables the mesh edge rendering mode
     * @returns the currentAbstractMesh
     */
    AbstractMesh.prototype.disableEdgesRendering = function () {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_13__["_DevTools"].WarnImport("EdgesRenderer");
    };
    /**
     * Enables the edge rendering mode on the mesh.
     * This mode makes the mesh edges visible
     * @param epsilon defines the maximal distance between two angles to detect a face
     * @param checkVerticesInsteadOfIndices indicates that we should check vertex list directly instead of faces
     * @returns the currentAbstractMesh
     * @see https://www.babylonjs-playground.com/#19O9TU#0
     */
    AbstractMesh.prototype.enableEdgesRendering = function (epsilon, checkVerticesInsteadOfIndices) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_13__["_DevTools"].WarnImport("EdgesRenderer");
    };
    /** No occlusion */
    AbstractMesh.OCCLUSION_TYPE_NONE = 0;
    /** Occlusion set to optimisitic */
    AbstractMesh.OCCLUSION_TYPE_OPTIMISTIC = 1;
    /** Occlusion set to strict */
    AbstractMesh.OCCLUSION_TYPE_STRICT = 2;
    /** Use an accurante occlusion algorithm */
    AbstractMesh.OCCLUSION_ALGORITHM_TYPE_ACCURATE = 0;
    /** Use a conservative occlusion algorithm */
    AbstractMesh.OCCLUSION_ALGORITHM_TYPE_CONSERVATIVE = 1;
    /** Default culling strategy : this is an exclusion test and it's the more accurate.
     *  Test order :
     *  Is the bounding sphere outside the frustum ?
     *  If not, are the bounding box vertices outside the frustum ?
     *  It not, then the cullable object is in the frustum.
     */
    AbstractMesh.CULLINGSTRATEGY_STANDARD = _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].MESHES_CULLINGSTRATEGY_STANDARD;
    /** Culling strategy : Bounding Sphere Only.
     *  This is an exclusion test. It's faster than the standard strategy because the bounding box is not tested.
     *  It's also less accurate than the standard because some not visible objects can still be selected.
     *  Test : is the bounding sphere outside the frustum ?
     *  If not, then the cullable object is in the frustum.
     */
    AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY = _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].MESHES_CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;
    /** Culling strategy : Optimistic Inclusion.
     *  This in an inclusion test first, then the standard exclusion test.
     *  This can be faster when a cullable object is expected to be almost always in the camera frustum.
     *  This could also be a little slower than the standard test when the tested object center is not the frustum but one of its bounding box vertex is still inside.
     *  Anyway, it's as accurate as the standard strategy.
     *  Test :
     *  Is the cullable object bounding sphere center in the frustum ?
     *  If not, apply the default culling strategy.
     */
    AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION = _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION;
    /** Culling strategy : Optimistic Inclusion then Bounding Sphere Only.
     *  This in an inclusion test first, then the bounding sphere only exclusion test.
     *  This can be the fastest test when a cullable object is expected to be almost always in the camera frustum.
     *  This could also be a little slower than the BoundingSphereOnly strategy when the tested object center is not in the frustum but its bounding sphere still intersects it.
     *  It's less accurate than the standard strategy and as accurate as the BoundingSphereOnly strategy.
     *  Test :
     *  Is the cullable object bounding sphere center in the frustum ?
     *  If not, apply the Bounding Sphere Only strategy. No Bounding Box is tested here.
     */
    AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY = _Engines_constants__WEBPACK_IMPORTED_MODULE_10__["Constants"].MESHES_CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY;
    return AbstractMesh;
}(_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_7__["TransformNode"]));



/***/ }),

/***/ "./Meshes/buffer.ts":
/*!**************************!*\
  !*** ./Meshes/buffer.ts ***!
  \**************************/
/*! exports provided: Buffer, VertexBuffer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Buffer", function() { return Buffer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VertexBuffer", function() { return VertexBuffer; });
/**
 * Class used to store data that will be store in GPU memory
 */
var Buffer = /** @class */ (function () {
    /**
     * Constructor
     * @param engine the engine
     * @param data the data to use for this buffer
     * @param updatable whether the data is updatable
     * @param stride the stride (optional)
     * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
     * @param instanced whether the buffer is instanced (optional)
     * @param useBytes set to true if the stride in in bytes (optional)
     */
    function Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes) {
        if (stride === void 0) { stride = 0; }
        if (postponeInternalCreation === void 0) { postponeInternalCreation = false; }
        if (instanced === void 0) { instanced = false; }
        if (useBytes === void 0) { useBytes = false; }
        if (engine.getScene) { // old versions of VertexBuffer accepted 'mesh' instead of 'engine'
            this._engine = engine.getScene().getEngine();
        }
        else {
            this._engine = engine;
        }
        this._updatable = updatable;
        this._instanced = instanced;
        this._data = data;
        this.byteStride = useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT;
        if (!postponeInternalCreation) { // by default
            this.create();
        }
    }
    /**
     * Create a new VertexBuffer based on the current buffer
     * @param kind defines the vertex buffer kind (position, normal, etc.)
     * @param offset defines offset in the buffer (0 by default)
     * @param size defines the size in floats of attributes (position is 3 for instance)
     * @param stride defines the stride size in floats in the buffer (the offset to apply to reach next value when data is interleaved)
     * @param instanced defines if the vertex buffer contains indexed data
     * @param useBytes defines if the offset and stride are in bytes
     * @returns the new vertex buffer
     */
    Buffer.prototype.createVertexBuffer = function (kind, offset, size, stride, instanced, useBytes) {
        if (useBytes === void 0) { useBytes = false; }
        var byteOffset = useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT;
        var byteStride = stride ? (useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT) : this.byteStride;
        // a lot of these parameters are ignored as they are overriden by the buffer
        return new VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
    };
    // Properties
    /**
     * Gets a boolean indicating if the Buffer is updatable?
     * @returns true if the buffer is updatable
     */
    Buffer.prototype.isUpdatable = function () {
        return this._updatable;
    };
    /**
     * Gets current buffer's data
     * @returns a DataArray or null
     */
    Buffer.prototype.getData = function () {
        return this._data;
    };
    /**
     * Gets underlying native buffer
     * @returns underlying native buffer
     */
    Buffer.prototype.getBuffer = function () {
        return this._buffer;
    };
    /**
     * Gets the stride in float32 units (i.e. byte stride / 4).
     * May not be an integer if the byte stride is not divisible by 4.
     * DEPRECATED. Use byteStride instead.
     * @returns the stride in float32 units
     */
    Buffer.prototype.getStrideSize = function () {
        return this.byteStride / Float32Array.BYTES_PER_ELEMENT;
    };
    // Methods
    /**
     * Store data into the buffer. If the buffer was already used it will be either recreated or updated depending on isUpdatable property
     * @param data defines the data to store
     */
    Buffer.prototype.create = function (data) {
        if (data === void 0) { data = null; }
        if (!data && this._buffer) {
            return; // nothing to do
        }
        data = data || this._data;
        if (!data) {
            return;
        }
        if (!this._buffer) { // create buffer
            if (this._updatable) {
                this._buffer = this._engine.createDynamicVertexBuffer(data);
                this._data = data;
            }
            else {
                this._buffer = this._engine.createVertexBuffer(data);
            }
        }
        else if (this._updatable) { // update buffer
            this._engine.updateDynamicVertexBuffer(this._buffer, data);
            this._data = data;
        }
    };
    /** @hidden */
    Buffer.prototype._rebuild = function () {
        this._buffer = null;
        this.create(this._data);
    };
    /**
     * Update current buffer data
     * @param data defines the data to store
     */
    Buffer.prototype.update = function (data) {
        this.create(data);
    };
    /**
     * Updates the data directly.
     * @param data the new data
     * @param offset the new offset
     * @param vertexCount the vertex count (optional)
     * @param useBytes set to true if the offset is in bytes
     */
    Buffer.prototype.updateDirectly = function (data, offset, vertexCount, useBytes) {
        if (useBytes === void 0) { useBytes = false; }
        if (!this._buffer) {
            return;
        }
        if (this._updatable) { // update buffer
            this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT, (vertexCount ? vertexCount * this.byteStride : undefined));
            this._data = null;
        }
    };
    /**
     * Release all resources
     */
    Buffer.prototype.dispose = function () {
        if (!this._buffer) {
            return;
        }
        if (this._engine._releaseBuffer(this._buffer)) {
            this._buffer = null;
        }
    };
    return Buffer;
}());

/**
     * Specialized buffer used to store vertex data
     */
var VertexBuffer = /** @class */ (function () {
    /**
     * Constructor
     * @param engine the engine
     * @param data the data to use for this vertex buffer
     * @param kind the vertex buffer kind
     * @param updatable whether the data is updatable
     * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
     * @param stride the stride (optional)
     * @param instanced whether the buffer is instanced (optional)
     * @param offset the offset of the data (optional)
     * @param size the number of components (optional)
     * @param type the type of the component (optional)
     * @param normalized whether the data contains normalized data (optional)
     * @param useBytes set to true if stride and offset are in bytes (optional)
     */
    function VertexBuffer(engine, data, kind, updatable, postponeInternalCreation, stride, instanced, offset, size, type, normalized, useBytes) {
        if (normalized === void 0) { normalized = false; }
        if (useBytes === void 0) { useBytes = false; }
        if (data instanceof Buffer) {
            this._buffer = data;
            this._ownsBuffer = false;
        }
        else {
            this._buffer = new Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
            this._ownsBuffer = true;
        }
        this._kind = kind;
        if (type == undefined) {
            var data_1 = this.getData();
            this.type = VertexBuffer.FLOAT;
            if (data_1 instanceof Int8Array) {
                this.type = VertexBuffer.BYTE;
            }
            else if (data_1 instanceof Uint8Array) {
                this.type = VertexBuffer.UNSIGNED_BYTE;
            }
            else if (data_1 instanceof Int16Array) {
                this.type = VertexBuffer.SHORT;
            }
            else if (data_1 instanceof Uint16Array) {
                this.type = VertexBuffer.UNSIGNED_SHORT;
            }
            else if (data_1 instanceof Int32Array) {
                this.type = VertexBuffer.INT;
            }
            else if (data_1 instanceof Uint32Array) {
                this.type = VertexBuffer.UNSIGNED_INT;
            }
        }
        else {
            this.type = type;
        }
        var typeByteLength = VertexBuffer.GetTypeByteLength(this.type);
        if (useBytes) {
            this._size = size || (stride ? (stride / typeByteLength) : VertexBuffer.DeduceStride(kind));
            this.byteStride = stride || this._buffer.byteStride || (this._size * typeByteLength);
            this.byteOffset = offset || 0;
        }
        else {
            this._size = size || stride || VertexBuffer.DeduceStride(kind);
            this.byteStride = stride ? (stride * typeByteLength) : (this._buffer.byteStride || (this._size * typeByteLength));
            this.byteOffset = (offset || 0) * typeByteLength;
        }
        this.normalized = normalized;
        this._instanced = instanced !== undefined ? instanced : false;
        this._instanceDivisor = instanced ? 1 : 0;
    }
    Object.defineProperty(VertexBuffer.prototype, "instanceDivisor", {
        /**
         * Gets or sets the instance divisor when in instanced mode
         */
        get: function () {
            return this._instanceDivisor;
        },
        set: function (value) {
            this._instanceDivisor = value;
            if (value == 0) {
                this._instanced = false;
            }
            else {
                this._instanced = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    VertexBuffer.prototype._rebuild = function () {
        if (!this._buffer) {
            return;
        }
        this._buffer._rebuild();
    };
    /**
     * Returns the kind of the VertexBuffer (string)
     * @returns a string
     */
    VertexBuffer.prototype.getKind = function () {
        return this._kind;
    };
    // Properties
    /**
     * Gets a boolean indicating if the VertexBuffer is updatable?
     * @returns true if the buffer is updatable
     */
    VertexBuffer.prototype.isUpdatable = function () {
        return this._buffer.isUpdatable();
    };
    /**
     * Gets current buffer's data
     * @returns a DataArray or null
     */
    VertexBuffer.prototype.getData = function () {
        return this._buffer.getData();
    };
    /**
     * Gets underlying native buffer
     * @returns underlying native buffer
     */
    VertexBuffer.prototype.getBuffer = function () {
        return this._buffer.getBuffer();
    };
    /**
     * Gets the stride in float32 units (i.e. byte stride / 4).
     * May not be an integer if the byte stride is not divisible by 4.
     * DEPRECATED. Use byteStride instead.
     * @returns the stride in float32 units
     */
    VertexBuffer.prototype.getStrideSize = function () {
        return this.byteStride / VertexBuffer.GetTypeByteLength(this.type);
    };
    /**
     * Returns the offset as a multiple of the type byte length.
     * DEPRECATED. Use byteOffset instead.
     * @returns the offset in bytes
     */
    VertexBuffer.prototype.getOffset = function () {
        return this.byteOffset / VertexBuffer.GetTypeByteLength(this.type);
    };
    /**
     * Returns the number of components per vertex attribute (integer)
     * @returns the size in float
     */
    VertexBuffer.prototype.getSize = function () {
        return this._size;
    };
    /**
     * Gets a boolean indicating is the internal buffer of the VertexBuffer is instanced
     * @returns true if this buffer is instanced
     */
    VertexBuffer.prototype.getIsInstanced = function () {
        return this._instanced;
    };
    /**
     * Returns the instancing divisor, zero for non-instanced (integer).
     * @returns a number
     */
    VertexBuffer.prototype.getInstanceDivisor = function () {
        return this._instanceDivisor;
    };
    // Methods
    /**
     * Store data into the buffer. If the buffer was already used it will be either recreated or updated depending on isUpdatable property
     * @param data defines the data to store
     */
    VertexBuffer.prototype.create = function (data) {
        this._buffer.create(data);
    };
    /**
     * Updates the underlying buffer according to the passed numeric array or Float32Array.
     * This function will create a new buffer if the current one is not updatable
     * @param data defines the data to store
     */
    VertexBuffer.prototype.update = function (data) {
        this._buffer.update(data);
    };
    /**
     * Updates directly the underlying WebGLBuffer according to the passed numeric array or Float32Array.
     * Returns the directly updated WebGLBuffer.
     * @param data the new data
     * @param offset the new offset
     * @param useBytes set to true if the offset is in bytes
     */
    VertexBuffer.prototype.updateDirectly = function (data, offset, useBytes) {
        if (useBytes === void 0) { useBytes = false; }
        this._buffer.updateDirectly(data, offset, undefined, useBytes);
    };
    /**
     * Disposes the VertexBuffer and the underlying WebGLBuffer.
     */
    VertexBuffer.prototype.dispose = function () {
        if (this._ownsBuffer) {
            this._buffer.dispose();
        }
    };
    /**
     * Enumerates each value of this vertex buffer as numbers.
     * @param count the number of values to enumerate
     * @param callback the callback function called for each value
     */
    VertexBuffer.prototype.forEach = function (count, callback) {
        VertexBuffer.ForEach(this._buffer.getData(), this.byteOffset, this.byteStride, this._size, this.type, count, this.normalized, callback);
    };
    /**
     * Deduces the stride given a kind.
     * @param kind The kind string to deduce
     * @returns The deduced stride
     */
    VertexBuffer.DeduceStride = function (kind) {
        switch (kind) {
            case VertexBuffer.UVKind:
            case VertexBuffer.UV2Kind:
            case VertexBuffer.UV3Kind:
            case VertexBuffer.UV4Kind:
            case VertexBuffer.UV5Kind:
            case VertexBuffer.UV6Kind:
                return 2;
            case VertexBuffer.NormalKind:
            case VertexBuffer.PositionKind:
                return 3;
            case VertexBuffer.ColorKind:
            case VertexBuffer.MatricesIndicesKind:
            case VertexBuffer.MatricesIndicesExtraKind:
            case VertexBuffer.MatricesWeightsKind:
            case VertexBuffer.MatricesWeightsExtraKind:
            case VertexBuffer.TangentKind:
                return 4;
            default:
                throw new Error("Invalid kind '" + kind + "'");
        }
    };
    /**
     * Gets the byte length of the given type.
     * @param type the type
     * @returns the number of bytes
     */
    VertexBuffer.GetTypeByteLength = function (type) {
        switch (type) {
            case VertexBuffer.BYTE:
            case VertexBuffer.UNSIGNED_BYTE:
                return 1;
            case VertexBuffer.SHORT:
            case VertexBuffer.UNSIGNED_SHORT:
                return 2;
            case VertexBuffer.INT:
            case VertexBuffer.UNSIGNED_INT:
            case VertexBuffer.FLOAT:
                return 4;
            default:
                throw new Error("Invalid type '" + type + "'");
        }
    };
    /**
     * Enumerates each value of the given parameters as numbers.
     * @param data the data to enumerate
     * @param byteOffset the byte offset of the data
     * @param byteStride the byte stride of the data
     * @param componentCount the number of components per element
     * @param componentType the type of the component
     * @param count the number of values to enumerate
     * @param normalized whether the data is normalized
     * @param callback the callback function called for each value
     */
    VertexBuffer.ForEach = function (data, byteOffset, byteStride, componentCount, componentType, count, normalized, callback) {
        if (data instanceof Array) {
            var offset = byteOffset / 4;
            var stride = byteStride / 4;
            for (var index = 0; index < count; index += componentCount) {
                for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
                    callback(data[offset + componentIndex], index + componentIndex);
                }
                offset += stride;
            }
        }
        else {
            var dataView = data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
            var componentByteLength = VertexBuffer.GetTypeByteLength(componentType);
            for (var index = 0; index < count; index += componentCount) {
                var componentByteOffset = byteOffset;
                for (var componentIndex = 0; componentIndex < componentCount; componentIndex++) {
                    var value = VertexBuffer._GetFloatValue(dataView, componentType, componentByteOffset, normalized);
                    callback(value, index + componentIndex);
                    componentByteOffset += componentByteLength;
                }
                byteOffset += byteStride;
            }
        }
    };
    VertexBuffer._GetFloatValue = function (dataView, type, byteOffset, normalized) {
        switch (type) {
            case VertexBuffer.BYTE: {
                var value = dataView.getInt8(byteOffset);
                if (normalized) {
                    value = Math.max(value / 127, -1);
                }
                return value;
            }
            case VertexBuffer.UNSIGNED_BYTE: {
                var value = dataView.getUint8(byteOffset);
                if (normalized) {
                    value = value / 255;
                }
                return value;
            }
            case VertexBuffer.SHORT: {
                var value = dataView.getInt16(byteOffset, true);
                if (normalized) {
                    value = Math.max(value / 32767, -1);
                }
                return value;
            }
            case VertexBuffer.UNSIGNED_SHORT: {
                var value = dataView.getUint16(byteOffset, true);
                if (normalized) {
                    value = value / 65535;
                }
                return value;
            }
            case VertexBuffer.INT: {
                return dataView.getInt32(byteOffset, true);
            }
            case VertexBuffer.UNSIGNED_INT: {
                return dataView.getUint32(byteOffset, true);
            }
            case VertexBuffer.FLOAT: {
                return dataView.getFloat32(byteOffset, true);
            }
            default: {
                throw new Error("Invalid component type " + type);
            }
        }
    };
    /**
     * The byte type.
     */
    VertexBuffer.BYTE = 5120;
    /**
     * The unsigned byte type.
     */
    VertexBuffer.UNSIGNED_BYTE = 5121;
    /**
     * The short type.
     */
    VertexBuffer.SHORT = 5122;
    /**
     * The unsigned short type.
     */
    VertexBuffer.UNSIGNED_SHORT = 5123;
    /**
     * The integer type.
     */
    VertexBuffer.INT = 5124;
    /**
     * The unsigned integer type.
     */
    VertexBuffer.UNSIGNED_INT = 5125;
    /**
     * The float type.
     */
    VertexBuffer.FLOAT = 5126;
    // Enums
    /**
     * Positions
     */
    VertexBuffer.PositionKind = "position";
    /**
     * Normals
     */
    VertexBuffer.NormalKind = "normal";
    /**
     * Tangents
     */
    VertexBuffer.TangentKind = "tangent";
    /**
     * Texture coordinates
     */
    VertexBuffer.UVKind = "uv";
    /**
     * Texture coordinates 2
     */
    VertexBuffer.UV2Kind = "uv2";
    /**
     * Texture coordinates 3
     */
    VertexBuffer.UV3Kind = "uv3";
    /**
     * Texture coordinates 4
     */
    VertexBuffer.UV4Kind = "uv4";
    /**
     * Texture coordinates 5
     */
    VertexBuffer.UV5Kind = "uv5";
    /**
     * Texture coordinates 6
     */
    VertexBuffer.UV6Kind = "uv6";
    /**
     * Colors
     */
    VertexBuffer.ColorKind = "color";
    /**
     * Matrix indices (for bones)
     */
    VertexBuffer.MatricesIndicesKind = "matricesIndices";
    /**
     * Matrix weights (for bones)
     */
    VertexBuffer.MatricesWeightsKind = "matricesWeights";
    /**
     * Additional matrix indices (for bones)
     */
    VertexBuffer.MatricesIndicesExtraKind = "matricesIndicesExtra";
    /**
     * Additional matrix weights (for bones)
     */
    VertexBuffer.MatricesWeightsExtraKind = "matricesWeightsExtra";
    return VertexBuffer;
}());



/***/ }),

/***/ "./Meshes/csg.ts":
/*!***********************!*\
  !*** ./Meshes/csg.ts ***!
  \***********************/
/*! exports provided: CSG */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CSG", function() { return CSG; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/subMesh */ "./Meshes/subMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");




/**
 * Unique ID when we import meshes from Babylon to CSG
 */
var currentCSGMeshId = 0;
/**
 * Represents a vertex of a polygon. Use your own vertex class instead of this
 * one to provide additional features like texture coordinates and vertex
 * colors. Custom vertex classes need to provide a `pos` property and `clone()`,
 * `flip()`, and `interpolate()` methods that behave analogous to the ones
 * defined by `BABYLON.CSG.Vertex`. This class provides `normal` so convenience
 * functions like `BABYLON.CSG.sphere()` can return a smooth vertex normal, but `normal`
 * is not used anywhere else.
 * Same goes for uv, it allows to keep the original vertex uv coordinates of the 2 meshes
 */
var Vertex = /** @class */ (function () {
    /**
     * Initializes the vertex
     * @param pos The position of the vertex
     * @param normal The normal of the vertex
     * @param uv The texture coordinate of the vertex
     */
    function Vertex(
    /**
     * The position of the vertex
     */
    pos,
    /**
     * The normal of the vertex
     */
    normal,
    /**
     * The texture coordinate of the vertex
     */
    uv) {
        this.pos = pos;
        this.normal = normal;
        this.uv = uv;
    }
    /**
     * Make a clone, or deep copy, of the vertex
     * @returns A new Vertex
     */
    Vertex.prototype.clone = function () {
        return new Vertex(this.pos.clone(), this.normal.clone(), this.uv.clone());
    };
    /**
     * Invert all orientation-specific data (e.g. vertex normal). Called when the
     * orientation of a polygon is flipped.
     */
    Vertex.prototype.flip = function () {
        this.normal = this.normal.scale(-1);
    };
    /**
     * Create a new vertex between this vertex and `other` by linearly
     * interpolating all properties using a parameter of `t`. Subclasses should
     * override this to interpolate additional properties.
     * @param other the vertex to interpolate against
     * @param t The factor used to linearly interpolate between the vertices
     */
    Vertex.prototype.interpolate = function (other, t) {
        return new Vertex(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(this.pos, other.pos, t), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Lerp(this.normal, other.normal, t), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Lerp(this.uv, other.uv, t));
    };
    return Vertex;
}());
/**
 * Represents a plane in 3D space.
 */
var Plane = /** @class */ (function () {
    /**
     * Initializes the plane
     * @param normal The normal for the plane
     * @param w
     */
    function Plane(normal, w) {
        this.normal = normal;
        this.w = w;
    }
    /**
     * Construct a plane from three points
     * @param a Point a
     * @param b Point b
     * @param c Point c
     */
    Plane.FromPoints = function (a, b, c) {
        var v0 = c.subtract(a);
        var v1 = b.subtract(a);
        if (v0.lengthSquared() === 0 || v1.lengthSquared() === 0) {
            return null;
        }
        var n = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Normalize(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(v0, v1));
        return new Plane(n, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(n, a));
    };
    /**
     * Clone, or make a deep copy of the plane
     * @returns a new Plane
     */
    Plane.prototype.clone = function () {
        return new Plane(this.normal.clone(), this.w);
    };
    /**
     * Flip the face of the plane
     */
    Plane.prototype.flip = function () {
        this.normal.scaleInPlace(-1);
        this.w = -this.w;
    };
    /**
     * Split `polygon` by this plane if needed, then put the polygon or polygon
     * fragments in the appropriate lists. Coplanar polygons go into either
    `* coplanarFront` or `coplanarBack` depending on their orientation with
     * respect to this plane. Polygons in front or in back of this plane go into
     * either `front` or `back`
     * @param polygon The polygon to be split
     * @param coplanarFront Will contain polygons coplanar with the plane that are oriented to the front of the plane
     * @param coplanarBack Will contain polygons coplanar with the plane that are oriented to the back of the plane
     * @param front Will contain the polygons in front of the plane
     * @param back Will contain the polygons begind the plane
     */
    Plane.prototype.splitPolygon = function (polygon, coplanarFront, coplanarBack, front, back) {
        var COPLANAR = 0;
        var FRONT = 1;
        var BACK = 2;
        var SPANNING = 3;
        // Classify each point as well as the entire polygon into one of the above
        // four classes.
        var polygonType = 0;
        var types = [];
        var i;
        var t;
        for (i = 0; i < polygon.vertices.length; i++) {
            t = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this.normal, polygon.vertices[i].pos) - this.w;
            var type = (t < -Plane.EPSILON) ? BACK : (t > Plane.EPSILON) ? FRONT : COPLANAR;
            polygonType |= type;
            types.push(type);
        }
        // Put the polygon in the correct list, splitting it when necessary
        switch (polygonType) {
            case COPLANAR:
                (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this.normal, polygon.plane.normal) > 0 ? coplanarFront : coplanarBack).push(polygon);
                break;
            case FRONT:
                front.push(polygon);
                break;
            case BACK:
                back.push(polygon);
                break;
            case SPANNING:
                var f = [], b = [];
                for (i = 0; i < polygon.vertices.length; i++) {
                    var j = (i + 1) % polygon.vertices.length;
                    var ti = types[i], tj = types[j];
                    var vi = polygon.vertices[i], vj = polygon.vertices[j];
                    if (ti !== BACK) {
                        f.push(vi);
                    }
                    if (ti !== FRONT) {
                        b.push(ti !== BACK ? vi.clone() : vi);
                    }
                    if ((ti | tj) === SPANNING) {
                        t = (this.w - _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this.normal, vi.pos)) / _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this.normal, vj.pos.subtract(vi.pos));
                        var v = vi.interpolate(vj, t);
                        f.push(v);
                        b.push(v.clone());
                    }
                }
                var poly;
                if (f.length >= 3) {
                    poly = new Polygon(f, polygon.shared);
                    if (poly.plane) {
                        front.push(poly);
                    }
                }
                if (b.length >= 3) {
                    poly = new Polygon(b, polygon.shared);
                    if (poly.plane) {
                        back.push(poly);
                    }
                }
                break;
        }
    };
    /**
     * `CSG.Plane.EPSILON` is the tolerance used by `splitPolygon()` to decide if a
     * point is on the plane
     */
    Plane.EPSILON = 1e-5;
    return Plane;
}());
/**
 * Represents a convex polygon. The vertices used to initialize a polygon must
 * be coplanar and form a convex loop.
 *
 * Each convex polygon has a `shared` property, which is shared between all
 * polygons that are clones of each other or were split from the same polygon.
 * This can be used to define per-polygon properties (such as surface color)
 */
var Polygon = /** @class */ (function () {
    /**
     * Initializes the polygon
     * @param vertices The vertices of the polygon
     * @param shared The properties shared across all polygons
     */
    function Polygon(vertices, shared) {
        this.vertices = vertices;
        this.shared = shared;
        this.plane = Plane.FromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos);
    }
    /**
     * Clones, or makes a deep copy, or the polygon
     */
    Polygon.prototype.clone = function () {
        var vertices = this.vertices.map(function (v) { return v.clone(); });
        return new Polygon(vertices, this.shared);
    };
    /**
     * Flips the faces of the polygon
     */
    Polygon.prototype.flip = function () {
        this.vertices.reverse().map(function (v) { v.flip(); });
        this.plane.flip();
    };
    return Polygon;
}());
/**
 * Holds a node in a BSP tree. A BSP tree is built from a collection of polygons
 * by picking a polygon to split along. That polygon (and all other coplanar
 * polygons) are added directly to that node and the other polygons are added to
 * the front and/or back subtrees. This is not a leafy BSP tree since there is
 * no distinction between internal and leaf nodes
 */
var Node = /** @class */ (function () {
    /**
     * Initializes the node
     * @param polygons A collection of polygons held in the node
     */
    function Node(polygons) {
        this.plane = null;
        this.front = null;
        this.back = null;
        this.polygons = new Array();
        if (polygons) {
            this.build(polygons);
        }
    }
    /**
     * Clones, or makes a deep copy, of the node
     * @returns The cloned node
     */
    Node.prototype.clone = function () {
        var node = new Node();
        node.plane = this.plane && this.plane.clone();
        node.front = this.front && this.front.clone();
        node.back = this.back && this.back.clone();
        node.polygons = this.polygons.map(function (p) { return p.clone(); });
        return node;
    };
    /**
     * Convert solid space to empty space and empty space to solid space
     */
    Node.prototype.invert = function () {
        for (var i = 0; i < this.polygons.length; i++) {
            this.polygons[i].flip();
        }
        if (this.plane) {
            this.plane.flip();
        }
        if (this.front) {
            this.front.invert();
        }
        if (this.back) {
            this.back.invert();
        }
        var temp = this.front;
        this.front = this.back;
        this.back = temp;
    };
    /**
     * Recursively remove all polygons in `polygons` that are inside this BSP
     * tree.
     * @param polygons Polygons to remove from the BSP
     * @returns Polygons clipped from the BSP
     */
    Node.prototype.clipPolygons = function (polygons) {
        if (!this.plane) {
            return polygons.slice();
        }
        var front = new Array(), back = new Array();
        for (var i = 0; i < polygons.length; i++) {
            this.plane.splitPolygon(polygons[i], front, back, front, back);
        }
        if (this.front) {
            front = this.front.clipPolygons(front);
        }
        if (this.back) {
            back = this.back.clipPolygons(back);
        }
        else {
            back = [];
        }
        return front.concat(back);
    };
    /**
     * Remove all polygons in this BSP tree that are inside the other BSP tree
     * `bsp`.
     * @param bsp BSP containing polygons to remove from this BSP
     */
    Node.prototype.clipTo = function (bsp) {
        this.polygons = bsp.clipPolygons(this.polygons);
        if (this.front) {
            this.front.clipTo(bsp);
        }
        if (this.back) {
            this.back.clipTo(bsp);
        }
    };
    /**
     * Return a list of all polygons in this BSP tree
     * @returns List of all polygons in this BSP tree
     */
    Node.prototype.allPolygons = function () {
        var polygons = this.polygons.slice();
        if (this.front) {
            polygons = polygons.concat(this.front.allPolygons());
        }
        if (this.back) {
            polygons = polygons.concat(this.back.allPolygons());
        }
        return polygons;
    };
    /**
     * Build a BSP tree out of `polygons`. When called on an existing tree, the
     * new polygons are filtered down to the bottom of the tree and become new
     * nodes there. Each set of polygons is partitioned using the first polygon
     * (no heuristic is used to pick a good split)
     * @param polygons Polygons used to construct the BSP tree
     */
    Node.prototype.build = function (polygons) {
        if (!polygons.length) {
            return;
        }
        if (!this.plane) {
            this.plane = polygons[0].plane.clone();
        }
        var front = new Array(), back = new Array();
        for (var i = 0; i < polygons.length; i++) {
            this.plane.splitPolygon(polygons[i], this.polygons, this.polygons, front, back);
        }
        if (front.length) {
            if (!this.front) {
                this.front = new Node();
            }
            this.front.build(front);
        }
        if (back.length) {
            if (!this.back) {
                this.back = new Node();
            }
            this.back.build(back);
        }
    };
    return Node;
}());
/**
 * Class for building Constructive Solid Geometry
 */
var CSG = /** @class */ (function () {
    function CSG() {
        this.polygons = new Array();
    }
    /**
     * Convert the Mesh to CSG
     * @param mesh The Mesh to convert to CSG
     * @returns A new CSG from the Mesh
     */
    CSG.FromMesh = function (mesh) {
        var vertex, normal, uv, position, polygon, polygons = new Array(), vertices;
        var matrix, meshPosition, meshRotation, meshRotationQuaternion = null, meshScaling;
        if (mesh instanceof _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"]) {
            mesh.computeWorldMatrix(true);
            matrix = mesh.getWorldMatrix();
            meshPosition = mesh.position.clone();
            meshRotation = mesh.rotation.clone();
            if (mesh.rotationQuaternion) {
                meshRotationQuaternion = mesh.rotationQuaternion.clone();
            }
            meshScaling = mesh.scaling.clone();
        }
        else {
            throw 'BABYLON.CSG: Wrong Mesh type, must be BABYLON.Mesh';
        }
        var indices = mesh.getIndices(), positions = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind), normals = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind), uvs = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind);
        var subMeshes = mesh.subMeshes;
        for (var sm = 0, sml = subMeshes.length; sm < sml; sm++) {
            for (var i = subMeshes[sm].indexStart, il = subMeshes[sm].indexCount + subMeshes[sm].indexStart; i < il; i += 3) {
                vertices = [];
                for (var j = 0; j < 3; j++) {
                    var sourceNormal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
                    uv = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](uvs[indices[i + j] * 2], uvs[indices[i + j] * 2 + 1]);
                    var sourcePosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
                    position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(sourcePosition, matrix);
                    normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(sourceNormal, matrix);
                    vertex = new Vertex(position, normal, uv);
                    vertices.push(vertex);
                }
                polygon = new Polygon(vertices, { subMeshId: sm, meshId: currentCSGMeshId, materialIndex: subMeshes[sm].materialIndex });
                // To handle the case of degenerated triangle
                // polygon.plane == null <=> the polygon does not represent 1 single plane <=> the triangle is degenerated
                if (polygon.plane) {
                    polygons.push(polygon);
                }
            }
        }
        var csg = CSG.FromPolygons(polygons);
        csg.matrix = matrix;
        csg.position = meshPosition;
        csg.rotation = meshRotation;
        csg.scaling = meshScaling;
        csg.rotationQuaternion = meshRotationQuaternion;
        currentCSGMeshId++;
        return csg;
    };
    /**
     * Construct a CSG solid from a list of `CSG.Polygon` instances.
     * @param polygons Polygons used to construct a CSG solid
     */
    CSG.FromPolygons = function (polygons) {
        var csg = new CSG();
        csg.polygons = polygons;
        return csg;
    };
    /**
     * Clones, or makes a deep copy, of the CSG
     * @returns A new CSG
     */
    CSG.prototype.clone = function () {
        var csg = new CSG();
        csg.polygons = this.polygons.map(function (p) { return p.clone(); });
        csg.copyTransformAttributes(this);
        return csg;
    };
    /**
     * Unions this CSG with another CSG
     * @param csg The CSG to union against this CSG
     * @returns The unioned CSG
     */
    CSG.prototype.union = function (csg) {
        var a = new Node(this.clone().polygons);
        var b = new Node(csg.clone().polygons);
        a.clipTo(b);
        b.clipTo(a);
        b.invert();
        b.clipTo(a);
        b.invert();
        a.build(b.allPolygons());
        return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
    };
    /**
     * Unions this CSG with another CSG in place
     * @param csg The CSG to union against this CSG
     */
    CSG.prototype.unionInPlace = function (csg) {
        var a = new Node(this.polygons);
        var b = new Node(csg.polygons);
        a.clipTo(b);
        b.clipTo(a);
        b.invert();
        b.clipTo(a);
        b.invert();
        a.build(b.allPolygons());
        this.polygons = a.allPolygons();
    };
    /**
     * Subtracts this CSG with another CSG
     * @param csg The CSG to subtract against this CSG
     * @returns A new CSG
     */
    CSG.prototype.subtract = function (csg) {
        var a = new Node(this.clone().polygons);
        var b = new Node(csg.clone().polygons);
        a.invert();
        a.clipTo(b);
        b.clipTo(a);
        b.invert();
        b.clipTo(a);
        b.invert();
        a.build(b.allPolygons());
        a.invert();
        return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
    };
    /**
     * Subtracts this CSG with another CSG in place
     * @param csg The CSG to subtact against this CSG
     */
    CSG.prototype.subtractInPlace = function (csg) {
        var a = new Node(this.polygons);
        var b = new Node(csg.polygons);
        a.invert();
        a.clipTo(b);
        b.clipTo(a);
        b.invert();
        b.clipTo(a);
        b.invert();
        a.build(b.allPolygons());
        a.invert();
        this.polygons = a.allPolygons();
    };
    /**
     * Intersect this CSG with another CSG
     * @param csg The CSG to intersect against this CSG
     * @returns A new CSG
     */
    CSG.prototype.intersect = function (csg) {
        var a = new Node(this.clone().polygons);
        var b = new Node(csg.clone().polygons);
        a.invert();
        b.clipTo(a);
        b.invert();
        a.clipTo(b);
        b.clipTo(a);
        a.build(b.allPolygons());
        a.invert();
        return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
    };
    /**
     * Intersects this CSG with another CSG in place
     * @param csg The CSG to intersect against this CSG
     */
    CSG.prototype.intersectInPlace = function (csg) {
        var a = new Node(this.polygons);
        var b = new Node(csg.polygons);
        a.invert();
        b.clipTo(a);
        b.invert();
        a.clipTo(b);
        b.clipTo(a);
        a.build(b.allPolygons());
        a.invert();
        this.polygons = a.allPolygons();
    };
    /**
     * Return a new CSG solid with solid and empty space switched. This solid is
     * not modified.
     * @returns A new CSG solid with solid and empty space switched
     */
    CSG.prototype.inverse = function () {
        var csg = this.clone();
        csg.inverseInPlace();
        return csg;
    };
    /**
     * Inverses the CSG in place
     */
    CSG.prototype.inverseInPlace = function () {
        this.polygons.map(function (p) { p.flip(); });
    };
    /**
     * This is used to keep meshes transformations so they can be restored
     * when we build back a Babylon Mesh
     * NB : All CSG operations are performed in world coordinates
     * @param csg The CSG to copy the transform attributes from
     * @returns This CSG
     */
    CSG.prototype.copyTransformAttributes = function (csg) {
        this.matrix = csg.matrix;
        this.position = csg.position;
        this.rotation = csg.rotation;
        this.scaling = csg.scaling;
        this.rotationQuaternion = csg.rotationQuaternion;
        return this;
    };
    /**
     * Build Raw mesh from CSG
     * Coordinates here are in world space
     * @param name The name of the mesh geometry
     * @param scene The Scene
     * @param keepSubMeshes Specifies if the submeshes should be kept
     * @returns A new Mesh
     */
    CSG.prototype.buildMeshGeometry = function (name, scene, keepSubMeshes) {
        var matrix = this.matrix.clone();
        matrix.invert();
        var mesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"](name, scene), vertices = [], indices = [], normals = [], uvs = [], vertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(), uv = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"].Zero(), polygons = this.polygons, polygonIndices = [0, 0, 0], polygon, vertice_dict = {}, vertex_idx, currentIndex = 0, subMesh_dict = {}, subMesh_obj;
        if (keepSubMeshes) {
            // Sort Polygons, since subMeshes are indices range
            polygons.sort(function (a, b) {
                if (a.shared.meshId === b.shared.meshId) {
                    return a.shared.subMeshId - b.shared.subMeshId;
                }
                else {
                    return a.shared.meshId - b.shared.meshId;
                }
            });
        }
        for (var i = 0, il = polygons.length; i < il; i++) {
            polygon = polygons[i];
            // Building SubMeshes
            if (!subMesh_dict[polygon.shared.meshId]) {
                subMesh_dict[polygon.shared.meshId] = {};
            }
            if (!subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId]) {
                subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId] = {
                    indexStart: +Infinity,
                    indexEnd: -Infinity,
                    materialIndex: polygon.shared.materialIndex
                };
            }
            subMesh_obj = subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId];
            for (var j = 2, jl = polygon.vertices.length; j < jl; j++) {
                polygonIndices[0] = 0;
                polygonIndices[1] = j - 1;
                polygonIndices[2] = j;
                for (var k = 0; k < 3; k++) {
                    vertex.copyFrom(polygon.vertices[polygonIndices[k]].pos);
                    normal.copyFrom(polygon.vertices[polygonIndices[k]].normal);
                    uv.copyFrom(polygon.vertices[polygonIndices[k]].uv);
                    var localVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(vertex, matrix);
                    var localNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(normal, matrix);
                    vertex_idx = vertice_dict[localVertex.x + ',' + localVertex.y + ',' + localVertex.z];
                    // Check if 2 points can be merged
                    if (!(typeof vertex_idx !== 'undefined' &&
                        normals[vertex_idx * 3] === localNormal.x &&
                        normals[vertex_idx * 3 + 1] === localNormal.y &&
                        normals[vertex_idx * 3 + 2] === localNormal.z &&
                        uvs[vertex_idx * 2] === uv.x &&
                        uvs[vertex_idx * 2 + 1] === uv.y)) {
                        vertices.push(localVertex.x, localVertex.y, localVertex.z);
                        uvs.push(uv.x, uv.y);
                        normals.push(normal.x, normal.y, normal.z);
                        vertex_idx = vertice_dict[localVertex.x + ',' + localVertex.y + ',' + localVertex.z] = (vertices.length / 3) - 1;
                    }
                    indices.push(vertex_idx);
                    subMesh_obj.indexStart = Math.min(currentIndex, subMesh_obj.indexStart);
                    subMesh_obj.indexEnd = Math.max(currentIndex, subMesh_obj.indexEnd);
                    currentIndex++;
                }
            }
        }
        mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, vertices);
        mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, normals);
        mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind, uvs);
        mesh.setIndices(indices, null);
        if (keepSubMeshes) {
            // We offset the materialIndex by the previous number of materials in the CSG mixed meshes
            var materialIndexOffset = 0, materialMaxIndex;
            mesh.subMeshes = new Array();
            for (var m in subMesh_dict) {
                materialMaxIndex = -1;
                for (var sm in subMesh_dict[m]) {
                    subMesh_obj = subMesh_dict[m][sm];
                    _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_2__["SubMesh"].CreateFromIndices(subMesh_obj.materialIndex + materialIndexOffset, subMesh_obj.indexStart, subMesh_obj.indexEnd - subMesh_obj.indexStart + 1, mesh);
                    materialMaxIndex = Math.max(subMesh_obj.materialIndex, materialMaxIndex);
                }
                materialIndexOffset += ++materialMaxIndex;
            }
        }
        return mesh;
    };
    /**
     * Build Mesh from CSG taking material and transforms into account
     * @param name The name of the Mesh
     * @param material The material of the Mesh
     * @param scene The Scene
     * @param keepSubMeshes Specifies if submeshes should be kept
     * @returns The new Mesh
     */
    CSG.prototype.toMesh = function (name, material, scene, keepSubMeshes) {
        if (material === void 0) { material = null; }
        var mesh = this.buildMeshGeometry(name, scene, keepSubMeshes);
        mesh.material = material;
        mesh.position.copyFrom(this.position);
        mesh.rotation.copyFrom(this.rotation);
        if (this.rotationQuaternion) {
            mesh.rotationQuaternion = this.rotationQuaternion.clone();
        }
        mesh.scaling.copyFrom(this.scaling);
        mesh.computeWorldMatrix(true);
        return mesh;
    };
    return CSG;
}());



/***/ }),

/***/ "./Meshes/dataBuffer.ts":
/*!******************************!*\
  !*** ./Meshes/dataBuffer.ts ***!
  \******************************/
/*! exports provided: DataBuffer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DataBuffer", function() { return DataBuffer; });
/**
 * Class used to store gfx data (like WebGLBuffer)
 */
var DataBuffer = /** @class */ (function () {
    function DataBuffer() {
        /**
         * Gets or sets the number of objects referencing this buffer
         */
        this.references = 0;
        /** Gets or sets the size of the underlying buffer */
        this.capacity = 0;
        /**
         * Gets or sets a boolean indicating if the buffer contains 32bits indices
         */
        this.is32Bits = false;
    }
    Object.defineProperty(DataBuffer.prototype, "underlyingResource", {
        /**
         * Gets the underlying buffer
         */
        get: function () {
            return null;
        },
        enumerable: true,
        configurable: true
    });
    return DataBuffer;
}());



/***/ }),

/***/ "./Meshes/geometry.ts":
/*!****************************!*\
  !*** ./Meshes/geometry.ts ***!
  \****************************/
/*! exports provided: Geometry */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Geometry", function() { return Geometry; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/subMesh */ "./Meshes/subMesh.ts");
/* harmony import */ var _Loading_sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Loading/sceneLoaderFlags */ "./Loading/sceneLoaderFlags.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Culling/boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_tags__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/tags */ "./Misc/tags.ts");
/* harmony import */ var _Maths_math_functions__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Maths/math.functions */ "./Maths/math.functions.ts");











/**
 * Class used to store geometry data (vertex buffers + index buffer)
 */
var Geometry = /** @class */ (function () {
    /**
     * Creates a new geometry
     * @param id defines the unique ID
     * @param scene defines the hosting scene
     * @param vertexData defines the VertexData used to get geometry data
     * @param updatable defines if geometry must be updatable (false by default)
     * @param mesh defines the mesh that will be associated with the geometry
     */
    function Geometry(id, scene, vertexData, updatable, mesh) {
        if (updatable === void 0) { updatable = false; }
        if (mesh === void 0) { mesh = null; }
        /**
         * Gets the delay loading state of the geometry (none by default which means not delayed)
         */
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_NONE;
        this._totalVertices = 0;
        this._isDisposed = false;
        this._indexBufferIsUpdatable = false;
        this.id = id;
        this.uniqueId = scene.getUniqueId();
        this._engine = scene.getEngine();
        this._meshes = [];
        this._scene = scene;
        //Init vertex buffer cache
        this._vertexBuffers = {};
        this._indices = [];
        this._updatable = updatable;
        // vertexData
        if (vertexData) {
            this.setAllVerticesData(vertexData, updatable);
        }
        else {
            this._totalVertices = 0;
            this._indices = [];
        }
        if (this._engine.getCaps().vertexArrayObject) {
            this._vertexArrayObjects = {};
        }
        // applyToMesh
        if (mesh) {
            this.applyToMesh(mesh);
            mesh.computeWorldMatrix(true);
        }
    }
    Object.defineProperty(Geometry.prototype, "boundingBias", {
        /**
         *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y
         */
        get: function () {
            return this._boundingBias;
        },
        /**
         *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y
         */
        set: function (value) {
            if (this._boundingBias) {
                this._boundingBias.copyFrom(value);
            }
            else {
                this._boundingBias = value.clone();
            }
            this._updateBoundingInfo(true, null);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Static function used to attach a new empty geometry to a mesh
     * @param mesh defines the mesh to attach the geometry to
     * @returns the new Geometry
     */
    Geometry.CreateGeometryForMesh = function (mesh) {
        var geometry = new Geometry(Geometry.RandomId(), mesh.getScene());
        geometry.applyToMesh(mesh);
        return geometry;
    };
    Object.defineProperty(Geometry.prototype, "extend", {
        /**
         * Gets the current extend of the geometry
         */
        get: function () {
            return this._extend;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the hosting scene
     * @returns the hosting Scene
     */
    Geometry.prototype.getScene = function () {
        return this._scene;
    };
    /**
     * Gets the hosting engine
     * @returns the hosting Engine
     */
    Geometry.prototype.getEngine = function () {
        return this._engine;
    };
    /**
     * Defines if the geometry is ready to use
     * @returns true if the geometry is ready to be used
     */
    Geometry.prototype.isReady = function () {
        return this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_LOADED || this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_NONE;
    };
    Object.defineProperty(Geometry.prototype, "doNotSerialize", {
        /**
         * Gets a value indicating that the geometry should not be serialized
         */
        get: function () {
            for (var index = 0; index < this._meshes.length; index++) {
                if (!this._meshes[index].doNotSerialize) {
                    return false;
                }
            }
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    Geometry.prototype._rebuild = function () {
        if (this._vertexArrayObjects) {
            this._vertexArrayObjects = {};
        }
        // Index buffer
        if (this._meshes.length !== 0 && this._indices) {
            this._indexBuffer = this._engine.createIndexBuffer(this._indices);
        }
        // Vertex buffers
        for (var key in this._vertexBuffers) {
            var vertexBuffer = this._vertexBuffers[key];
            vertexBuffer._rebuild();
        }
    };
    /**
     * Affects all geometry data in one call
     * @param vertexData defines the geometry data
     * @param updatable defines if the geometry must be flagged as updatable (false as default)
     */
    Geometry.prototype.setAllVerticesData = function (vertexData, updatable) {
        vertexData.applyToGeometry(this, updatable);
        this.notifyUpdate();
    };
    /**
     * Set specific vertex data
     * @param kind defines the data kind (Position, normal, etc...)
     * @param data defines the vertex data to use
     * @param updatable defines if the vertex must be flagged as updatable (false as default)
     * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified
     */
    Geometry.prototype.setVerticesData = function (kind, data, updatable, stride) {
        if (updatable === void 0) { updatable = false; }
        var buffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"](this._engine, data, kind, updatable, this._meshes.length === 0, stride);
        this.setVerticesBuffer(buffer);
    };
    /**
     * Removes a specific vertex data
     * @param kind defines the data kind (Position, normal, etc...)
     */
    Geometry.prototype.removeVerticesData = function (kind) {
        if (this._vertexBuffers[kind]) {
            this._vertexBuffers[kind].dispose();
            delete this._vertexBuffers[kind];
        }
    };
    /**
     * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data
     * @param buffer defines the vertex buffer to use
     * @param totalVertices defines the total number of vertices for position kind (could be null)
     */
    Geometry.prototype.setVerticesBuffer = function (buffer, totalVertices) {
        if (totalVertices === void 0) { totalVertices = null; }
        var kind = buffer.getKind();
        if (this._vertexBuffers[kind]) {
            this._vertexBuffers[kind].dispose();
        }
        this._vertexBuffers[kind] = buffer;
        if (kind === _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind) {
            var data = buffer.getData();
            if (totalVertices != null) {
                this._totalVertices = totalVertices;
            }
            else {
                if (data != null) {
                    this._totalVertices = data.length / (buffer.byteStride / 4);
                }
            }
            this._updateExtend(data);
            this._resetPointsArrayCache();
            var meshes = this._meshes;
            var numOfMeshes = meshes.length;
            for (var index = 0; index < numOfMeshes; index++) {
                var mesh = meshes[index];
                mesh._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_6__["BoundingInfo"](this._extend.minimum, this._extend.maximum);
                mesh._createGlobalSubMesh(false);
                mesh.computeWorldMatrix(true);
            }
        }
        this.notifyUpdate(kind);
        if (this._vertexArrayObjects) {
            this._disposeVertexArrayObjects();
            this._vertexArrayObjects = {}; // Will trigger a rebuild of the VAO if supported
        }
    };
    /**
     * Update a specific vertex buffer
     * This function will directly update the underlying DataBuffer according to the passed numeric array or Float32Array
     * It will do nothing if the buffer is not updatable
     * @param kind defines the data kind (Position, normal, etc...)
     * @param data defines the data to use
     * @param offset defines the offset in the target buffer where to store the data
     * @param useBytes set to true if the offset is in bytes
     */
    Geometry.prototype.updateVerticesDataDirectly = function (kind, data, offset, useBytes) {
        if (useBytes === void 0) { useBytes = false; }
        var vertexBuffer = this.getVertexBuffer(kind);
        if (!vertexBuffer) {
            return;
        }
        vertexBuffer.updateDirectly(data, offset, useBytes);
        this.notifyUpdate(kind);
    };
    /**
     * Update a specific vertex buffer
     * This function will create a new buffer if the current one is not updatable
     * @param kind defines the data kind (Position, normal, etc...)
     * @param data defines the data to use
     * @param updateExtends defines if the geometry extends must be recomputed (false by default)
     */
    Geometry.prototype.updateVerticesData = function (kind, data, updateExtends) {
        if (updateExtends === void 0) { updateExtends = false; }
        var vertexBuffer = this.getVertexBuffer(kind);
        if (!vertexBuffer) {
            return;
        }
        vertexBuffer.update(data);
        if (kind === _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind) {
            this._updateBoundingInfo(updateExtends, data);
        }
        this.notifyUpdate(kind);
    };
    Geometry.prototype._updateBoundingInfo = function (updateExtends, data) {
        if (updateExtends) {
            this._updateExtend(data);
        }
        this._resetPointsArrayCache();
        if (updateExtends) {
            var meshes = this._meshes;
            for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
                var mesh = meshes_1[_i];
                if (mesh._boundingInfo) {
                    mesh._boundingInfo.reConstruct(this._extend.minimum, this._extend.maximum);
                }
                else {
                    mesh._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_6__["BoundingInfo"](this._extend.minimum, this._extend.maximum);
                }
                var subMeshes = mesh.subMeshes;
                for (var _a = 0, subMeshes_1 = subMeshes; _a < subMeshes_1.length; _a++) {
                    var subMesh = subMeshes_1[_a];
                    subMesh.refreshBoundingInfo();
                }
            }
        }
    };
    /** @hidden */
    Geometry.prototype._bind = function (effect, indexToBind) {
        if (!effect) {
            return;
        }
        if (indexToBind === undefined) {
            indexToBind = this._indexBuffer;
        }
        var vbs = this.getVertexBuffers();
        if (!vbs) {
            return;
        }
        if (indexToBind != this._indexBuffer || !this._vertexArrayObjects) {
            this._engine.bindBuffers(vbs, indexToBind, effect);
            return;
        }
        // Using VAO
        if (!this._vertexArrayObjects[effect.key]) {
            this._vertexArrayObjects[effect.key] = this._engine.recordVertexArrayObject(vbs, indexToBind, effect);
        }
        this._engine.bindVertexArrayObject(this._vertexArrayObjects[effect.key], indexToBind);
    };
    /**
     * Gets total number of vertices
     * @returns the total number of vertices
     */
    Geometry.prototype.getTotalVertices = function () {
        if (!this.isReady()) {
            return 0;
        }
        return this._totalVertices;
    };
    /**
     * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
     * @param kind defines the data kind (Position, normal, etc...)
     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
     * @returns a float array containing vertex data
     */
    Geometry.prototype.getVerticesData = function (kind, copyWhenShared, forceCopy) {
        var vertexBuffer = this.getVertexBuffer(kind);
        if (!vertexBuffer) {
            return null;
        }
        var data = vertexBuffer.getData();
        if (!data) {
            return null;
        }
        var tightlyPackedByteStride = vertexBuffer.getSize() * _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].GetTypeByteLength(vertexBuffer.type);
        var count = this._totalVertices * vertexBuffer.getSize();
        if (vertexBuffer.type !== _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].FLOAT || vertexBuffer.byteStride !== tightlyPackedByteStride) {
            var copy_1 = [];
            vertexBuffer.forEach(count, function (value) { return copy_1.push(value); });
            return copy_1;
        }
        if (!((data instanceof Array) || (data instanceof Float32Array)) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
            if (data instanceof Array) {
                var offset = vertexBuffer.byteOffset / 4;
                return _Misc_tools__WEBPACK_IMPORTED_MODULE_8__["Tools"].Slice(data, offset, offset + count);
            }
            else if (data instanceof ArrayBuffer) {
                return new Float32Array(data, vertexBuffer.byteOffset, count);
            }
            else {
                var offset = data.byteOffset + vertexBuffer.byteOffset;
                if (forceCopy || (copyWhenShared && this._meshes.length !== 1)) {
                    var result = new Float32Array(count);
                    var source = new Float32Array(data.buffer, offset, count);
                    result.set(source);
                    return result;
                }
                return new Float32Array(data.buffer, offset, count);
            }
        }
        if (forceCopy || (copyWhenShared && this._meshes.length !== 1)) {
            return _Misc_tools__WEBPACK_IMPORTED_MODULE_8__["Tools"].Slice(data);
        }
        return data;
    };
    /**
     * Returns a boolean defining if the vertex data for the requested `kind` is updatable
     * @param kind defines the data kind (Position, normal, etc...)
     * @returns true if the vertex buffer with the specified kind is updatable
     */
    Geometry.prototype.isVertexBufferUpdatable = function (kind) {
        var vb = this._vertexBuffers[kind];
        if (!vb) {
            return false;
        }
        return vb.isUpdatable();
    };
    /**
     * Gets a specific vertex buffer
     * @param kind defines the data kind (Position, normal, etc...)
     * @returns a VertexBuffer
     */
    Geometry.prototype.getVertexBuffer = function (kind) {
        if (!this.isReady()) {
            return null;
        }
        return this._vertexBuffers[kind];
    };
    /**
     * Returns all vertex buffers
     * @return an object holding all vertex buffers indexed by kind
     */
    Geometry.prototype.getVertexBuffers = function () {
        if (!this.isReady()) {
            return null;
        }
        return this._vertexBuffers;
    };
    /**
     * Gets a boolean indicating if specific vertex buffer is present
     * @param kind defines the data kind (Position, normal, etc...)
     * @returns true if data is present
     */
    Geometry.prototype.isVerticesDataPresent = function (kind) {
        if (!this._vertexBuffers) {
            if (this._delayInfo) {
                return this._delayInfo.indexOf(kind) !== -1;
            }
            return false;
        }
        return this._vertexBuffers[kind] !== undefined;
    };
    /**
     * Gets a list of all attached data kinds (Position, normal, etc...)
     * @returns a list of string containing all kinds
     */
    Geometry.prototype.getVerticesDataKinds = function () {
        var result = [];
        var kind;
        if (!this._vertexBuffers && this._delayInfo) {
            for (kind in this._delayInfo) {
                result.push(kind);
            }
        }
        else {
            for (kind in this._vertexBuffers) {
                result.push(kind);
            }
        }
        return result;
    };
    /**
     * Update index buffer
     * @param indices defines the indices to store in the index buffer
     * @param offset defines the offset in the target buffer where to store the data
     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)
     */
    Geometry.prototype.updateIndices = function (indices, offset, gpuMemoryOnly) {
        if (gpuMemoryOnly === void 0) { gpuMemoryOnly = false; }
        if (!this._indexBuffer) {
            return;
        }
        if (!this._indexBufferIsUpdatable) {
            this.setIndices(indices, null, true);
        }
        else {
            var needToUpdateSubMeshes = indices.length !== this._indices.length;
            if (!gpuMemoryOnly) {
                this._indices = indices.slice();
            }
            this._engine.updateDynamicIndexBuffer(this._indexBuffer, indices, offset);
            if (needToUpdateSubMeshes) {
                for (var _i = 0, _a = this._meshes; _i < _a.length; _i++) {
                    var mesh = _a[_i];
                    mesh._createGlobalSubMesh(true);
                }
            }
        }
    };
    /**
     * Creates a new index buffer
     * @param indices defines the indices to store in the index buffer
     * @param totalVertices defines the total number of vertices (could be null)
     * @param updatable defines if the index buffer must be flagged as updatable (false by default)
     */
    Geometry.prototype.setIndices = function (indices, totalVertices, updatable) {
        if (totalVertices === void 0) { totalVertices = null; }
        if (updatable === void 0) { updatable = false; }
        if (this._indexBuffer) {
            this._engine._releaseBuffer(this._indexBuffer);
        }
        this._disposeVertexArrayObjects();
        this._indices = indices;
        this._indexBufferIsUpdatable = updatable;
        if (this._meshes.length !== 0 && this._indices) {
            this._indexBuffer = this._engine.createIndexBuffer(this._indices, updatable);
        }
        if (totalVertices != undefined) { // including null and undefined
            this._totalVertices = totalVertices;
        }
        for (var _i = 0, _a = this._meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            mesh._createGlobalSubMesh(true);
        }
        this.notifyUpdate();
    };
    /**
     * Return the total number of indices
     * @returns the total number of indices
     */
    Geometry.prototype.getTotalIndices = function () {
        if (!this.isReady()) {
            return 0;
        }
        return this._indices.length;
    };
    /**
     * Gets the index buffer array
     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
     * @returns the index buffer array
     */
    Geometry.prototype.getIndices = function (copyWhenShared, forceCopy) {
        if (!this.isReady()) {
            return null;
        }
        var orig = this._indices;
        if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
            return orig;
        }
        else {
            var len = orig.length;
            var copy = [];
            for (var i = 0; i < len; i++) {
                copy.push(orig[i]);
            }
            return copy;
        }
    };
    /**
     * Gets the index buffer
     * @return the index buffer
     */
    Geometry.prototype.getIndexBuffer = function () {
        if (!this.isReady()) {
            return null;
        }
        return this._indexBuffer;
    };
    /** @hidden */
    Geometry.prototype._releaseVertexArrayObject = function (effect) {
        if (effect === void 0) { effect = null; }
        if (!effect || !this._vertexArrayObjects) {
            return;
        }
        if (this._vertexArrayObjects[effect.key]) {
            this._engine.releaseVertexArrayObject(this._vertexArrayObjects[effect.key]);
            delete this._vertexArrayObjects[effect.key];
        }
    };
    /**
     * Release the associated resources for a specific mesh
     * @param mesh defines the source mesh
     * @param shouldDispose defines if the geometry must be disposed if there is no more mesh pointing to it
     */
    Geometry.prototype.releaseForMesh = function (mesh, shouldDispose) {
        var meshes = this._meshes;
        var index = meshes.indexOf(mesh);
        if (index === -1) {
            return;
        }
        meshes.splice(index, 1);
        mesh._geometry = null;
        if (meshes.length === 0 && shouldDispose) {
            this.dispose();
        }
    };
    /**
     * Apply current geometry to a given mesh
     * @param mesh defines the mesh to apply geometry to
     */
    Geometry.prototype.applyToMesh = function (mesh) {
        if (mesh._geometry === this) {
            return;
        }
        var previousGeometry = mesh._geometry;
        if (previousGeometry) {
            previousGeometry.releaseForMesh(mesh);
        }
        var meshes = this._meshes;
        // must be done before setting vertexBuffers because of mesh._createGlobalSubMesh()
        mesh._geometry = this;
        this._scene.pushGeometry(this);
        meshes.push(mesh);
        if (this.isReady()) {
            this._applyToMesh(mesh);
        }
        else {
            mesh._boundingInfo = this._boundingInfo;
        }
    };
    Geometry.prototype._updateExtend = function (data) {
        if (data === void 0) { data = null; }
        if (!data) {
            data = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind);
        }
        this._extend = Object(_Maths_math_functions__WEBPACK_IMPORTED_MODULE_10__["extractMinAndMax"])(data, 0, this._totalVertices, this.boundingBias, 3);
    };
    Geometry.prototype._applyToMesh = function (mesh) {
        var numOfMeshes = this._meshes.length;
        // vertexBuffers
        for (var kind in this._vertexBuffers) {
            if (numOfMeshes === 1) {
                this._vertexBuffers[kind].create();
            }
            var buffer = this._vertexBuffers[kind].getBuffer();
            if (buffer) {
                buffer.references = numOfMeshes;
            }
            if (kind === _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind) {
                if (!this._extend) {
                    this._updateExtend();
                }
                mesh._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_6__["BoundingInfo"](this._extend.minimum, this._extend.maximum);
                mesh._createGlobalSubMesh(false);
                //bounding info was just created again, world matrix should be applied again.
                mesh._updateBoundingInfo();
            }
        }
        // indexBuffer
        if (numOfMeshes === 1 && this._indices && this._indices.length > 0) {
            this._indexBuffer = this._engine.createIndexBuffer(this._indices);
        }
        if (this._indexBuffer) {
            this._indexBuffer.references = numOfMeshes;
        }
        // morphTargets
        mesh._syncGeometryWithMorphTargetManager();
        // instances
        mesh.synchronizeInstances();
    };
    Geometry.prototype.notifyUpdate = function (kind) {
        if (this.onGeometryUpdated) {
            this.onGeometryUpdated(this, kind);
        }
        for (var _i = 0, _a = this._meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            mesh._markSubMeshesAsAttributesDirty();
        }
    };
    /**
     * Load the geometry if it was flagged as delay loaded
     * @param scene defines the hosting scene
     * @param onLoaded defines a callback called when the geometry is loaded
     */
    Geometry.prototype.load = function (scene, onLoaded) {
        if (this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_LOADING) {
            return;
        }
        if (this.isReady()) {
            if (onLoaded) {
                onLoaded();
            }
            return;
        }
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_LOADING;
        this._queueLoad(scene, onLoaded);
    };
    Geometry.prototype._queueLoad = function (scene, onLoaded) {
        var _this = this;
        if (!this.delayLoadingFile) {
            return;
        }
        scene._addPendingData(this);
        scene._loadFile(this.delayLoadingFile, function (data) {
            if (!_this._delayLoadingFunction) {
                return;
            }
            _this._delayLoadingFunction(JSON.parse(data), _this);
            _this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_LOADED;
            _this._delayInfo = [];
            scene._removePendingData(_this);
            var meshes = _this._meshes;
            var numOfMeshes = meshes.length;
            for (var index = 0; index < numOfMeshes; index++) {
                _this._applyToMesh(meshes[index]);
            }
            if (onLoaded) {
                onLoaded();
            }
        }, undefined, true);
    };
    /**
     * Invert the geometry to move from a right handed system to a left handed one.
     */
    Geometry.prototype.toLeftHanded = function () {
        // Flip faces
        var tIndices = this.getIndices(false);
        if (tIndices != null && tIndices.length > 0) {
            for (var i = 0; i < tIndices.length; i += 3) {
                var tTemp = tIndices[i + 0];
                tIndices[i + 0] = tIndices[i + 2];
                tIndices[i + 2] = tTemp;
            }
            this.setIndices(tIndices);
        }
        // Negate position.z
        var tPositions = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, false);
        if (tPositions != null && tPositions.length > 0) {
            for (var i = 0; i < tPositions.length; i += 3) {
                tPositions[i + 2] = -tPositions[i + 2];
            }
            this.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, tPositions, false);
        }
        // Negate normal.z
        var tNormals = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind, false);
        if (tNormals != null && tNormals.length > 0) {
            for (var i = 0; i < tNormals.length; i += 3) {
                tNormals[i + 2] = -tNormals[i + 2];
            }
            this.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind, tNormals, false);
        }
    };
    // Cache
    /** @hidden */
    Geometry.prototype._resetPointsArrayCache = function () {
        this._positions = null;
    };
    /** @hidden */
    Geometry.prototype._generatePointsArray = function () {
        if (this._positions) {
            return true;
        }
        var data = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind);
        if (!data || data.length === 0) {
            return false;
        }
        this._positions = [];
        for (var index = 0; index < data.length; index += 3) {
            this._positions.push(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(data, index));
        }
        return true;
    };
    /**
     * Gets a value indicating if the geometry is disposed
     * @returns true if the geometry was disposed
     */
    Geometry.prototype.isDisposed = function () {
        return this._isDisposed;
    };
    Geometry.prototype._disposeVertexArrayObjects = function () {
        if (this._vertexArrayObjects) {
            for (var kind in this._vertexArrayObjects) {
                this._engine.releaseVertexArrayObject(this._vertexArrayObjects[kind]);
            }
            this._vertexArrayObjects = {};
        }
    };
    /**
     * Free all associated resources
     */
    Geometry.prototype.dispose = function () {
        var meshes = this._meshes;
        var numOfMeshes = meshes.length;
        var index;
        for (index = 0; index < numOfMeshes; index++) {
            this.releaseForMesh(meshes[index]);
        }
        this._meshes = [];
        this._disposeVertexArrayObjects();
        for (var kind in this._vertexBuffers) {
            this._vertexBuffers[kind].dispose();
        }
        this._vertexBuffers = {};
        this._totalVertices = 0;
        if (this._indexBuffer) {
            this._engine._releaseBuffer(this._indexBuffer);
        }
        this._indexBuffer = null;
        this._indices = [];
        this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_NONE;
        this.delayLoadingFile = null;
        this._delayLoadingFunction = null;
        this._delayInfo = [];
        this._boundingInfo = null;
        this._scene.removeGeometry(this);
        this._isDisposed = true;
    };
    /**
     * Clone the current geometry into a new geometry
     * @param id defines the unique ID of the new geometry
     * @returns a new geometry object
     */
    Geometry.prototype.copy = function (id) {
        var vertexData = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"]();
        vertexData.indices = [];
        var indices = this.getIndices();
        if (indices) {
            for (var index = 0; index < indices.length; index++) {
                vertexData.indices.push(indices[index]);
            }
        }
        var updatable = false;
        var stopChecking = false;
        var kind;
        for (kind in this._vertexBuffers) {
            // using slice() to make a copy of the array and not just reference it
            var data = this.getVerticesData(kind);
            if (data) {
                if (data instanceof Float32Array) {
                    vertexData.set(new Float32Array(data), kind);
                }
                else {
                    vertexData.set(data.slice(0), kind);
                }
                if (!stopChecking) {
                    var vb = this.getVertexBuffer(kind);
                    if (vb) {
                        updatable = vb.isUpdatable();
                        stopChecking = !updatable;
                    }
                }
            }
        }
        var geometry = new Geometry(id, this._scene, vertexData, updatable);
        geometry.delayLoadState = this.delayLoadState;
        geometry.delayLoadingFile = this.delayLoadingFile;
        geometry._delayLoadingFunction = this._delayLoadingFunction;
        for (kind in this._delayInfo) {
            geometry._delayInfo = geometry._delayInfo || [];
            geometry._delayInfo.push(kind);
        }
        // Bounding info
        geometry._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_6__["BoundingInfo"](this._extend.minimum, this._extend.maximum);
        return geometry;
    };
    /**
     * Serialize the current geometry info (and not the vertices data) into a JSON object
     * @return a JSON representation of the current geometry data (without the vertices data)
     */
    Geometry.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.id = this.id;
        serializationObject.updatable = this._updatable;
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_9__["Tags"] && _Misc_tags__WEBPACK_IMPORTED_MODULE_9__["Tags"].HasTags(this)) {
            serializationObject.tags = _Misc_tags__WEBPACK_IMPORTED_MODULE_9__["Tags"].GetTags(this);
        }
        return serializationObject;
    };
    Geometry.prototype.toNumberArray = function (origin) {
        if (Array.isArray(origin)) {
            return origin;
        }
        else {
            return Array.prototype.slice.call(origin);
        }
    };
    /**
     * Serialize all vertices data into a JSON oject
     * @returns a JSON representation of the current geometry data
     */
    Geometry.prototype.serializeVerticeData = function () {
        var serializationObject = this.serialize();
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind)) {
            serializationObject.positions = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind)) {
                serializationObject.positions._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind)) {
            serializationObject.normals = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind)) {
                serializationObject.normals._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind)) {
            serializationObject.tangets = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind)) {
                serializationObject.tangets._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind)) {
            serializationObject.uvs = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind)) {
                serializationObject.uvs._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind)) {
            serializationObject.uv2s = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind)) {
                serializationObject.uv2s._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV3Kind)) {
            serializationObject.uv3s = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV3Kind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV3Kind)) {
                serializationObject.uv3s._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV4Kind)) {
            serializationObject.uv4s = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV4Kind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV4Kind)) {
                serializationObject.uv4s._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV5Kind)) {
            serializationObject.uv5s = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV5Kind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV5Kind)) {
                serializationObject.uv5s._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV6Kind)) {
            serializationObject.uv6s = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV6Kind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV6Kind)) {
                serializationObject.uv6s._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind)) {
            serializationObject.colors = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind)) {
                serializationObject.colors._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind)) {
            serializationObject.matricesIndices = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind));
            serializationObject.matricesIndices._isExpanded = true;
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind)) {
                serializationObject.matricesIndices._updatable = true;
            }
        }
        if (this.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind)) {
            serializationObject.matricesWeights = this.toNumberArray(this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind));
            if (this.isVertexBufferUpdatable(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind)) {
                serializationObject.matricesWeights._updatable = true;
            }
        }
        serializationObject.indices = this.toNumberArray(this.getIndices());
        return serializationObject;
    };
    // Statics
    /**
     * Extracts a clone of a mesh geometry
     * @param mesh defines the source mesh
     * @param id defines the unique ID of the new geometry object
     * @returns the new geometry object
     */
    Geometry.ExtractFromMesh = function (mesh, id) {
        var geometry = mesh._geometry;
        if (!geometry) {
            return null;
        }
        return geometry.copy(id);
    };
    /**
     * You should now use Tools.RandomId(), this method is still here for legacy reasons.
     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
     * Be aware Math.random() could cause collisions, but:
     * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
     * @returns a string containing a new GUID
     */
    Geometry.RandomId = function () {
        return _Misc_tools__WEBPACK_IMPORTED_MODULE_8__["Tools"].RandomId();
    };
    /** @hidden */
    Geometry._ImportGeometry = function (parsedGeometry, mesh) {
        var scene = mesh.getScene();
        // Geometry
        var geometryId = parsedGeometry.geometryId;
        if (geometryId) {
            var geometry = scene.getGeometryByID(geometryId);
            if (geometry) {
                geometry.applyToMesh(mesh);
            }
        }
        else if (parsedGeometry instanceof ArrayBuffer) {
            var binaryInfo = mesh._binaryInfo;
            if (binaryInfo.positionsAttrDesc && binaryInfo.positionsAttrDesc.count > 0) {
                var positionsData = new Float32Array(parsedGeometry, binaryInfo.positionsAttrDesc.offset, binaryInfo.positionsAttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, positionsData, false);
            }
            if (binaryInfo.normalsAttrDesc && binaryInfo.normalsAttrDesc.count > 0) {
                var normalsData = new Float32Array(parsedGeometry, binaryInfo.normalsAttrDesc.offset, binaryInfo.normalsAttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind, normalsData, false);
            }
            if (binaryInfo.tangetsAttrDesc && binaryInfo.tangetsAttrDesc.count > 0) {
                var tangentsData = new Float32Array(parsedGeometry, binaryInfo.tangetsAttrDesc.offset, binaryInfo.tangetsAttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind, tangentsData, false);
            }
            if (binaryInfo.uvsAttrDesc && binaryInfo.uvsAttrDesc.count > 0) {
                var uvsData = new Float32Array(parsedGeometry, binaryInfo.uvsAttrDesc.offset, binaryInfo.uvsAttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind, uvsData, false);
            }
            if (binaryInfo.uvs2AttrDesc && binaryInfo.uvs2AttrDesc.count > 0) {
                var uvs2Data = new Float32Array(parsedGeometry, binaryInfo.uvs2AttrDesc.offset, binaryInfo.uvs2AttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind, uvs2Data, false);
            }
            if (binaryInfo.uvs3AttrDesc && binaryInfo.uvs3AttrDesc.count > 0) {
                var uvs3Data = new Float32Array(parsedGeometry, binaryInfo.uvs3AttrDesc.offset, binaryInfo.uvs3AttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV3Kind, uvs3Data, false);
            }
            if (binaryInfo.uvs4AttrDesc && binaryInfo.uvs4AttrDesc.count > 0) {
                var uvs4Data = new Float32Array(parsedGeometry, binaryInfo.uvs4AttrDesc.offset, binaryInfo.uvs4AttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV4Kind, uvs4Data, false);
            }
            if (binaryInfo.uvs5AttrDesc && binaryInfo.uvs5AttrDesc.count > 0) {
                var uvs5Data = new Float32Array(parsedGeometry, binaryInfo.uvs5AttrDesc.offset, binaryInfo.uvs5AttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV5Kind, uvs5Data, false);
            }
            if (binaryInfo.uvs6AttrDesc && binaryInfo.uvs6AttrDesc.count > 0) {
                var uvs6Data = new Float32Array(parsedGeometry, binaryInfo.uvs6AttrDesc.offset, binaryInfo.uvs6AttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV6Kind, uvs6Data, false);
            }
            if (binaryInfo.colorsAttrDesc && binaryInfo.colorsAttrDesc.count > 0) {
                var colorsData = new Float32Array(parsedGeometry, binaryInfo.colorsAttrDesc.offset, binaryInfo.colorsAttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind, colorsData, false, binaryInfo.colorsAttrDesc.stride);
            }
            if (binaryInfo.matricesIndicesAttrDesc && binaryInfo.matricesIndicesAttrDesc.count > 0) {
                var matricesIndicesData = new Int32Array(parsedGeometry, binaryInfo.matricesIndicesAttrDesc.offset, binaryInfo.matricesIndicesAttrDesc.count);
                var floatIndices = [];
                for (var i = 0; i < matricesIndicesData.length; i++) {
                    var index = matricesIndicesData[i];
                    floatIndices.push(index & 0x000000FF);
                    floatIndices.push((index & 0x0000FF00) >> 8);
                    floatIndices.push((index & 0x00FF0000) >> 16);
                    floatIndices.push(index >> 24);
                }
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind, floatIndices, false);
            }
            if (binaryInfo.matricesWeightsAttrDesc && binaryInfo.matricesWeightsAttrDesc.count > 0) {
                var matricesWeightsData = new Float32Array(parsedGeometry, binaryInfo.matricesWeightsAttrDesc.offset, binaryInfo.matricesWeightsAttrDesc.count);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind, matricesWeightsData, false);
            }
            if (binaryInfo.indicesAttrDesc && binaryInfo.indicesAttrDesc.count > 0) {
                var indicesData = new Int32Array(parsedGeometry, binaryInfo.indicesAttrDesc.offset, binaryInfo.indicesAttrDesc.count);
                mesh.setIndices(indicesData, null);
            }
            if (binaryInfo.subMeshesAttrDesc && binaryInfo.subMeshesAttrDesc.count > 0) {
                var subMeshesData = new Int32Array(parsedGeometry, binaryInfo.subMeshesAttrDesc.offset, binaryInfo.subMeshesAttrDesc.count * 5);
                mesh.subMeshes = [];
                for (var i = 0; i < binaryInfo.subMeshesAttrDesc.count; i++) {
                    var materialIndex = subMeshesData[(i * 5) + 0];
                    var verticesStart = subMeshesData[(i * 5) + 1];
                    var verticesCount = subMeshesData[(i * 5) + 2];
                    var indexStart = subMeshesData[(i * 5) + 3];
                    var indexCount = subMeshesData[(i * 5) + 4];
                    _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_4__["SubMesh"].AddToMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh);
                }
            }
        }
        else if (parsedGeometry.positions && parsedGeometry.normals && parsedGeometry.indices) {
            mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, parsedGeometry.positions, parsedGeometry.positions._updatable);
            mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind, parsedGeometry.normals, parsedGeometry.normals._updatable);
            if (parsedGeometry.tangents) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind, parsedGeometry.tangents, parsedGeometry.tangents._updatable);
            }
            if (parsedGeometry.uvs) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind, parsedGeometry.uvs, parsedGeometry.uvs._updatable);
            }
            if (parsedGeometry.uvs2) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind, parsedGeometry.uvs2, parsedGeometry.uvs2._updatable);
            }
            if (parsedGeometry.uvs3) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV3Kind, parsedGeometry.uvs3, parsedGeometry.uvs3._updatable);
            }
            if (parsedGeometry.uvs4) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV4Kind, parsedGeometry.uvs4, parsedGeometry.uvs4._updatable);
            }
            if (parsedGeometry.uvs5) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV5Kind, parsedGeometry.uvs5, parsedGeometry.uvs5._updatable);
            }
            if (parsedGeometry.uvs6) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV6Kind, parsedGeometry.uvs6, parsedGeometry.uvs6._updatable);
            }
            if (parsedGeometry.colors) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind, _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"].CheckColors4(parsedGeometry.colors, parsedGeometry.positions.length / 3), parsedGeometry.colors._updatable);
            }
            if (parsedGeometry.matricesIndices) {
                if (!parsedGeometry.matricesIndices._isExpanded) {
                    var floatIndices = [];
                    for (var i = 0; i < parsedGeometry.matricesIndices.length; i++) {
                        var matricesIndex = parsedGeometry.matricesIndices[i];
                        floatIndices.push(matricesIndex & 0x000000FF);
                        floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
                        floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
                        floatIndices.push(matricesIndex >> 24);
                    }
                    mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind, floatIndices, parsedGeometry.matricesIndices._updatable);
                }
                else {
                    delete parsedGeometry.matricesIndices._isExpanded;
                    mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind, parsedGeometry.matricesIndices, parsedGeometry.matricesIndices._updatable);
                }
            }
            if (parsedGeometry.matricesIndicesExtra) {
                if (!parsedGeometry.matricesIndicesExtra._isExpanded) {
                    var floatIndices = [];
                    for (var i = 0; i < parsedGeometry.matricesIndicesExtra.length; i++) {
                        var matricesIndex = parsedGeometry.matricesIndicesExtra[i];
                        floatIndices.push(matricesIndex & 0x000000FF);
                        floatIndices.push((matricesIndex & 0x0000FF00) >> 8);
                        floatIndices.push((matricesIndex & 0x00FF0000) >> 16);
                        floatIndices.push(matricesIndex >> 24);
                    }
                    mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind, floatIndices, parsedGeometry.matricesIndicesExtra._updatable);
                }
                else {
                    delete parsedGeometry.matricesIndices._isExpanded;
                    mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind, parsedGeometry.matricesIndicesExtra, parsedGeometry.matricesIndicesExtra._updatable);
                }
            }
            if (parsedGeometry.matricesWeights) {
                Geometry._CleanMatricesWeights(parsedGeometry, mesh);
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind, parsedGeometry.matricesWeights, parsedGeometry.matricesWeights._updatable);
            }
            if (parsedGeometry.matricesWeightsExtra) {
                mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, parsedGeometry.matricesWeights._updatable);
            }
            mesh.setIndices(parsedGeometry.indices, null);
        }
        // SubMeshes
        if (parsedGeometry.subMeshes) {
            mesh.subMeshes = [];
            for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
                var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
                _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_4__["SubMesh"].AddToMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
            }
        }
        // Flat shading
        if (mesh._shouldGenerateFlatShading) {
            mesh.convertToFlatShadedMesh();
            delete mesh._shouldGenerateFlatShading;
        }
        // Update
        mesh.computeWorldMatrix(true);
        scene.onMeshImportedObservable.notifyObservers(mesh);
    };
    Geometry._CleanMatricesWeights = function (parsedGeometry, mesh) {
        var epsilon = 1e-3;
        if (!_Loading_sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_5__["SceneLoaderFlags"].CleanBoneMatrixWeights) {
            return;
        }
        var noInfluenceBoneIndex = 0.0;
        if (parsedGeometry.skeletonId > -1) {
            var skeleton = mesh.getScene().getLastSkeletonByID(parsedGeometry.skeletonId);
            if (!skeleton) {
                return;
            }
            noInfluenceBoneIndex = skeleton.bones.length;
        }
        else {
            return;
        }
        var matricesIndices = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind);
        var matricesIndicesExtra = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind);
        var matricesWeights = parsedGeometry.matricesWeights;
        var matricesWeightsExtra = parsedGeometry.matricesWeightsExtra;
        var influencers = parsedGeometry.numBoneInfluencer;
        var size = matricesWeights.length;
        for (var i = 0; i < size; i += 4) {
            var weight = 0.0;
            var firstZeroWeight = -1;
            for (var j = 0; j < 4; j++) {
                var w = matricesWeights[i + j];
                weight += w;
                if (w < epsilon && firstZeroWeight < 0) {
                    firstZeroWeight = j;
                }
            }
            if (matricesWeightsExtra) {
                for (var j = 0; j < 4; j++) {
                    var w = matricesWeightsExtra[i + j];
                    weight += w;
                    if (w < epsilon && firstZeroWeight < 0) {
                        firstZeroWeight = j + 4;
                    }
                }
            }
            if (firstZeroWeight < 0 || firstZeroWeight > (influencers - 1)) {
                firstZeroWeight = influencers - 1;
            }
            if (weight > epsilon) {
                var mweight = 1.0 / weight;
                for (var j = 0; j < 4; j++) {
                    matricesWeights[i + j] *= mweight;
                }
                if (matricesWeightsExtra) {
                    for (var j = 0; j < 4; j++) {
                        matricesWeightsExtra[i + j] *= mweight;
                    }
                }
            }
            else {
                if (firstZeroWeight >= 4) {
                    matricesWeightsExtra[i + firstZeroWeight - 4] = 1.0 - weight;
                    matricesIndicesExtra[i + firstZeroWeight - 4] = noInfluenceBoneIndex;
                }
                else {
                    matricesWeights[i + firstZeroWeight] = 1.0 - weight;
                    matricesIndices[i + firstZeroWeight] = noInfluenceBoneIndex;
                }
            }
        }
        mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind, matricesIndices);
        if (parsedGeometry.matricesWeightsExtra) {
            mesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesExtraKind, matricesIndicesExtra);
        }
    };
    /**
     * Create a new geometry from persisted data (Using .babylon file format)
     * @param parsedVertexData defines the persisted data
     * @param scene defines the hosting scene
     * @param rootUrl defines the root url to use to load assets (like delayed data)
     * @returns the new geometry object
     */
    Geometry.Parse = function (parsedVertexData, scene, rootUrl) {
        if (scene.getGeometryByID(parsedVertexData.id)) {
            return null; // null since geometry could be something else than a box...
        }
        var geometry = new Geometry(parsedVertexData.id, scene, undefined, parsedVertexData.updatable);
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_9__["Tags"]) {
            _Misc_tags__WEBPACK_IMPORTED_MODULE_9__["Tags"].AddTagsTo(geometry, parsedVertexData.tags);
        }
        if (parsedVertexData.delayLoadingFile) {
            geometry.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].DELAYLOADSTATE_NOTLOADED;
            geometry.delayLoadingFile = rootUrl + parsedVertexData.delayLoadingFile;
            geometry._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_6__["BoundingInfo"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(parsedVertexData.boundingBoxMinimum), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(parsedVertexData.boundingBoxMaximum));
            geometry._delayInfo = [];
            if (parsedVertexData.hasUVs) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind);
            }
            if (parsedVertexData.hasUVs2) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV2Kind);
            }
            if (parsedVertexData.hasUVs3) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV3Kind);
            }
            if (parsedVertexData.hasUVs4) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV4Kind);
            }
            if (parsedVertexData.hasUVs5) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV5Kind);
            }
            if (parsedVertexData.hasUVs6) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UV6Kind);
            }
            if (parsedVertexData.hasColors) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].ColorKind);
            }
            if (parsedVertexData.hasMatricesIndices) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesIndicesKind);
            }
            if (parsedVertexData.hasMatricesWeights) {
                geometry._delayInfo.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].MatricesWeightsKind);
            }
            geometry._delayLoadingFunction = _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].ImportVertexData;
        }
        else {
            _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_2__["VertexData"].ImportVertexData(parsedVertexData, geometry);
        }
        scene.pushGeometry(geometry, true);
        return geometry;
    };
    return Geometry;
}());



/***/ }),

/***/ "./Meshes/groundMesh.ts":
/*!******************************!*\
  !*** ./Meshes/groundMesh.ts ***!
  \******************************/
/*! exports provided: GroundMesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GroundMesh", function() { return GroundMesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");




_Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"]._GroundMeshParser = function (parsedMesh, scene) {
    return GroundMesh.Parse(parsedMesh, scene);
};
/**
 * Mesh representing the gorund
 */
var GroundMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GroundMesh, _super);
    function GroundMesh(name, scene) {
        var _this = _super.call(this, name, scene) || this;
        /** If octree should be generated */
        _this.generateOctree = false;
        return _this;
    }
    /**
     * "GroundMesh"
     * @returns "GroundMesh"
     */
    GroundMesh.prototype.getClassName = function () {
        return "GroundMesh";
    };
    Object.defineProperty(GroundMesh.prototype, "subdivisions", {
        /**
         * The minimum of x and y subdivisions
         */
        get: function () {
            return Math.min(this._subdivisionsX, this._subdivisionsY);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GroundMesh.prototype, "subdivisionsX", {
        /**
         * X subdivisions
         */
        get: function () {
            return this._subdivisionsX;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GroundMesh.prototype, "subdivisionsY", {
        /**
         * Y subdivisions
         */
        get: function () {
            return this._subdivisionsY;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * This function will update an octree to help to select the right submeshes for rendering, picking and collision computations.
     * Please note that you must have a decent number of submeshes to get performance improvements when using an octree
     * @param chunksCount the number of subdivisions for x and y
     * @param octreeBlocksSize (Default: 32)
     */
    GroundMesh.prototype.optimize = function (chunksCount, octreeBlocksSize) {
        if (octreeBlocksSize === void 0) { octreeBlocksSize = 32; }
        this._subdivisionsX = chunksCount;
        this._subdivisionsY = chunksCount;
        this.subdivide(chunksCount);
        // Call the octree system optimization if it is defined.
        var thisAsAny = this;
        if (thisAsAny.createOrUpdateSubmeshesOctree) {
            thisAsAny.createOrUpdateSubmeshesOctree(octreeBlocksSize);
        }
    };
    /**
     * Returns a height (y) value in the Worl system :
     * the ground altitude at the coordinates (x, z) expressed in the World system.
     * @param x x coordinate
     * @param z z coordinate
     * @returns the ground y position if (x, z) are outside the ground surface.
     */
    GroundMesh.prototype.getHeightAtCoordinates = function (x, z) {
        var world = this.getWorldMatrix();
        var invMat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Matrix[5];
        world.invertToRef(invMat);
        var tmpVect = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[8];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(x, 0.0, z, invMat, tmpVect); // transform x,z in the mesh local space
        x = tmpVect.x;
        z = tmpVect.z;
        if (x < this._minX || x > this._maxX || z < this._minZ || z > this._maxZ) {
            return this.position.y;
        }
        if (!this._heightQuads || this._heightQuads.length == 0) {
            this._initHeightQuads();
            this._computeHeightQuads();
        }
        var facet = this._getFacetAt(x, z);
        var y = -(facet.x * x + facet.z * z + facet.w) / facet.y;
        // return y in the World system
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(0.0, y, 0.0, world, tmpVect);
        return tmpVect.y;
    };
    /**
     * Returns a normalized vector (Vector3) orthogonal to the ground
     * at the ground coordinates (x, z) expressed in the World system.
     * @param x x coordinate
     * @param z z coordinate
     * @returns Vector3(0.0, 1.0, 0.0) if (x, z) are outside the ground surface.
     */
    GroundMesh.prototype.getNormalAtCoordinates = function (x, z) {
        var normal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0.0, 1.0, 0.0);
        this.getNormalAtCoordinatesToRef(x, z, normal);
        return normal;
    };
    /**
     * Updates the Vector3 passed a reference with a normalized vector orthogonal to the ground
     * at the ground coordinates (x, z) expressed in the World system.
     * Doesn't uptade the reference Vector3 if (x, z) are outside the ground surface.
     * @param x x coordinate
     * @param z z coordinate
     * @param ref vector to store the result
     * @returns the GroundMesh.
     */
    GroundMesh.prototype.getNormalAtCoordinatesToRef = function (x, z, ref) {
        var world = this.getWorldMatrix();
        var tmpMat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Matrix[5];
        world.invertToRef(tmpMat);
        var tmpVect = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[8];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(x, 0.0, z, tmpMat, tmpVect); // transform x,z in the mesh local space
        x = tmpVect.x;
        z = tmpVect.z;
        if (x < this._minX || x > this._maxX || z < this._minZ || z > this._maxZ) {
            return this;
        }
        if (!this._heightQuads || this._heightQuads.length == 0) {
            this._initHeightQuads();
            this._computeHeightQuads();
        }
        var facet = this._getFacetAt(x, z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(facet.x, facet.y, facet.z, world, ref);
        return this;
    };
    /**
    * Force the heights to be recomputed for getHeightAtCoordinates() or getNormalAtCoordinates()
    * if the ground has been updated.
    * This can be used in the render loop.
    * @returns the GroundMesh.
    */
    GroundMesh.prototype.updateCoordinateHeights = function () {
        if (!this._heightQuads || this._heightQuads.length == 0) {
            this._initHeightQuads();
        }
        this._computeHeightQuads();
        return this;
    };
    // Returns the element "facet" from the heightQuads array relative to (x, z) local coordinates
    GroundMesh.prototype._getFacetAt = function (x, z) {
        // retrieve col and row from x, z coordinates in the ground local system
        var col = Math.floor((x + this._maxX) * this._subdivisionsX / this._width);
        var row = Math.floor(-(z + this._maxZ) * this._subdivisionsY / this._height + this._subdivisionsY);
        var quad = this._heightQuads[row * this._subdivisionsX + col];
        var facet;
        if (z < quad.slope.x * x + quad.slope.y) {
            facet = quad.facet1;
        }
        else {
            facet = quad.facet2;
        }
        return facet;
    };
    //  Creates and populates the heightMap array with "facet" elements :
    // a quad is two triangular facets separated by a slope, so a "facet" element is 1 slope + 2 facets
    // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
    // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
    // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
    // Returns the GroundMesh.
    GroundMesh.prototype._initHeightQuads = function () {
        var subdivisionsX = this._subdivisionsX;
        var subdivisionsY = this._subdivisionsY;
        this._heightQuads = new Array();
        for (var row = 0; row < subdivisionsY; row++) {
            for (var col = 0; col < subdivisionsX; col++) {
                var quad = { slope: _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"].Zero(), facet1: new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"](0.0, 0.0, 0.0, 0.0), facet2: new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"](0.0, 0.0, 0.0, 0.0) };
                this._heightQuads[row * subdivisionsX + col] = quad;
            }
        }
        return this;
    };
    // Compute each quad element values and update the the heightMap array :
    // slope : Vector2(c, h) = 2D diagonal line equation setting appart two triangular facets in a quad : z = cx + h
    // facet1 : Vector4(a, b, c, d) = first facet 3D plane equation : ax + by + cz + d = 0
    // facet2 :  Vector4(a, b, c, d) = second facet 3D plane equation : ax + by + cz + d = 0
    // Returns the GroundMesh.
    GroundMesh.prototype._computeHeightQuads = function () {
        var positions = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind);
        if (!positions) {
            return this;
        }
        var v1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[3];
        var v2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[2];
        var v3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[1];
        var v4 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[0];
        var v1v2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[4];
        var v1v3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[5];
        var v1v4 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[6];
        var norm1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[7];
        var norm2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[8];
        var i = 0;
        var j = 0;
        var k = 0;
        var cd = 0; // 2D slope coefficient : z = cd * x + h
        var h = 0;
        var d1 = 0; // facet plane equation : ax + by + cz + d = 0
        var d2 = 0;
        var subdivisionsX = this._subdivisionsX;
        var subdivisionsY = this._subdivisionsY;
        for (var row = 0; row < subdivisionsY; row++) {
            for (var col = 0; col < subdivisionsX; col++) {
                i = col * 3;
                j = row * (subdivisionsX + 1) * 3;
                k = (row + 1) * (subdivisionsX + 1) * 3;
                v1.x = positions[j + i];
                v1.y = positions[j + i + 1];
                v1.z = positions[j + i + 2];
                v2.x = positions[j + i + 3];
                v2.y = positions[j + i + 4];
                v2.z = positions[j + i + 5];
                v3.x = positions[k + i];
                v3.y = positions[k + i + 1];
                v3.z = positions[k + i + 2];
                v4.x = positions[k + i + 3];
                v4.y = positions[k + i + 4];
                v4.z = positions[k + i + 5];
                // 2D slope V1V4
                cd = (v4.z - v1.z) / (v4.x - v1.x);
                h = v1.z - cd * v1.x; // v1 belongs to the slope
                // facet equations :
                // we compute each facet normal vector
                // the equation of the facet plane is : norm.x * x + norm.y * y + norm.z * z + d = 0
                // we compute the value d by applying the equation to v1 which belongs to the plane
                // then we store the facet equation in a Vector4
                v2.subtractToRef(v1, v1v2);
                v3.subtractToRef(v1, v1v3);
                v4.subtractToRef(v1, v1v4);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(v1v4, v1v3, norm1); // caution : CrossToRef uses the Tmp class
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CrossToRef(v1v2, v1v4, norm2);
                norm1.normalize();
                norm2.normalize();
                d1 = -(norm1.x * v1.x + norm1.y * v1.y + norm1.z * v1.z);
                d2 = -(norm2.x * v2.x + norm2.y * v2.y + norm2.z * v2.z);
                var quad = this._heightQuads[row * subdivisionsX + col];
                quad.slope.copyFromFloats(cd, h);
                quad.facet1.copyFromFloats(norm1.x, norm1.y, norm1.z, d1);
                quad.facet2.copyFromFloats(norm2.x, norm2.y, norm2.z, d2);
            }
        }
        return this;
    };
    /**
     * Serializes this ground mesh
     * @param serializationObject object to write serialization to
     */
    GroundMesh.prototype.serialize = function (serializationObject) {
        _super.prototype.serialize.call(this, serializationObject);
        serializationObject.subdivisionsX = this._subdivisionsX;
        serializationObject.subdivisionsY = this._subdivisionsY;
        serializationObject.minX = this._minX;
        serializationObject.maxX = this._maxX;
        serializationObject.minZ = this._minZ;
        serializationObject.maxZ = this._maxZ;
        serializationObject.width = this._width;
        serializationObject.height = this._height;
    };
    /**
     * Parses a serialized ground mesh
     * @param parsedMesh the serialized mesh
     * @param scene the scene to create the ground mesh in
     * @returns the created ground mesh
     */
    GroundMesh.Parse = function (parsedMesh, scene) {
        var result = new GroundMesh(parsedMesh.name, scene);
        result._subdivisionsX = parsedMesh.subdivisionsX || 1;
        result._subdivisionsY = parsedMesh.subdivisionsY || 1;
        result._minX = parsedMesh.minX;
        result._maxX = parsedMesh.maxX;
        result._minZ = parsedMesh.minZ;
        result._maxZ = parsedMesh.maxZ;
        result._width = parsedMesh.width;
        result._height = parsedMesh.height;
        return result;
    };
    return GroundMesh;
}(_Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"]));



/***/ }),

/***/ "./Meshes/index.ts":
/*!*************************!*\
  !*** ./Meshes/index.ts ***!
  \*************************/
/*! exports provided: AbstractMesh, Buffer, VertexBuffer, CSG, Geometry, GroundMesh, TrailMesh, InstancedMesh, LinesMesh, InstancedLinesMesh, _CreationDataStorage, _InstancesBatch, Mesh, VertexData, MeshBuilder, SimplificationSettings, SimplificationQueue, SimplificationType, SimplicationQueueSceneComponent, Polygon, PolygonMeshBuilder, BaseSubMesh, SubMesh, MeshLODLevel, TransformNode, BoxBuilder, SphereBuilder, CylinderBuilder, TorusBuilder, LinesBuilder, PlaneBuilder, GroundBuilder, DataBuffer, WebGLDataBuffer, WebGPUDataBuffer, DracoCompression, TiledBoxBuilder, DiscBuilder, RibbonBuilder, HemisphereBuilder, TorusKnotBuilder, PolygonBuilder, ShapeBuilder, LatheBuilder, TiledPlaneBuilder, TubeBuilder, PolyhedronBuilder, IcoSphereBuilder, DecalBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _abstractMesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractMesh", function() { return _abstractMesh__WEBPACK_IMPORTED_MODULE_0__["AbstractMesh"]; });

/* harmony import */ var _buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./buffer */ "./Meshes/buffer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Buffer", function() { return _buffer__WEBPACK_IMPORTED_MODULE_1__["Buffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexBuffer", function() { return _buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"]; });

/* harmony import */ var _Compression_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Compression/index */ "./Meshes/Compression/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DracoCompression", function() { return _Compression_index__WEBPACK_IMPORTED_MODULE_2__["DracoCompression"]; });

/* harmony import */ var _csg__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./csg */ "./Meshes/csg.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CSG", function() { return _csg__WEBPACK_IMPORTED_MODULE_3__["CSG"]; });

/* harmony import */ var _geometry__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./geometry */ "./Meshes/geometry.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Geometry", function() { return _geometry__WEBPACK_IMPORTED_MODULE_4__["Geometry"]; });

/* harmony import */ var _groundMesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./groundMesh */ "./Meshes/groundMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundMesh", function() { return _groundMesh__WEBPACK_IMPORTED_MODULE_5__["GroundMesh"]; });

/* harmony import */ var _trailMesh__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./trailMesh */ "./Meshes/trailMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrailMesh", function() { return _trailMesh__WEBPACK_IMPORTED_MODULE_6__["TrailMesh"]; });

/* harmony import */ var _instancedMesh__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./instancedMesh */ "./Meshes/instancedMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancedMesh", function() { return _instancedMesh__WEBPACK_IMPORTED_MODULE_7__["InstancedMesh"]; });

/* harmony import */ var _linesMesh__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./linesMesh */ "./Meshes/linesMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesMesh", function() { return _linesMesh__WEBPACK_IMPORTED_MODULE_8__["LinesMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancedLinesMesh", function() { return _linesMesh__WEBPACK_IMPORTED_MODULE_8__["InstancedLinesMesh"]; });

/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./mesh */ "./Meshes/mesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_CreationDataStorage", function() { return _mesh__WEBPACK_IMPORTED_MODULE_9__["_CreationDataStorage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_InstancesBatch", function() { return _mesh__WEBPACK_IMPORTED_MODULE_9__["_InstancesBatch"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Mesh", function() { return _mesh__WEBPACK_IMPORTED_MODULE_9__["Mesh"]; });

/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexData", function() { return _mesh_vertexData__WEBPACK_IMPORTED_MODULE_10__["VertexData"]; });

/* harmony import */ var _meshBuilder__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./meshBuilder */ "./Meshes/meshBuilder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshBuilder", function() { return _meshBuilder__WEBPACK_IMPORTED_MODULE_11__["MeshBuilder"]; });

/* harmony import */ var _meshSimplification__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./meshSimplification */ "./Meshes/meshSimplification.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationSettings", function() { return _meshSimplification__WEBPACK_IMPORTED_MODULE_12__["SimplificationSettings"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationQueue", function() { return _meshSimplification__WEBPACK_IMPORTED_MODULE_12__["SimplificationQueue"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationType", function() { return _meshSimplification__WEBPACK_IMPORTED_MODULE_12__["SimplificationType"]; });

/* harmony import */ var _meshSimplificationSceneComponent__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./meshSimplificationSceneComponent */ "./Meshes/meshSimplificationSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplicationQueueSceneComponent", function() { return _meshSimplificationSceneComponent__WEBPACK_IMPORTED_MODULE_13__["SimplicationQueueSceneComponent"]; });

/* harmony import */ var _polygonMesh__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./polygonMesh */ "./Meshes/polygonMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Polygon", function() { return _polygonMesh__WEBPACK_IMPORTED_MODULE_14__["Polygon"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonMeshBuilder", function() { return _polygonMesh__WEBPACK_IMPORTED_MODULE_14__["PolygonMeshBuilder"]; });

/* harmony import */ var _subMesh__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./subMesh */ "./Meshes/subMesh.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseSubMesh", function() { return _subMesh__WEBPACK_IMPORTED_MODULE_15__["BaseSubMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubMesh", function() { return _subMesh__WEBPACK_IMPORTED_MODULE_15__["SubMesh"]; });

/* harmony import */ var _meshLODLevel__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./meshLODLevel */ "./Meshes/meshLODLevel.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshLODLevel", function() { return _meshLODLevel__WEBPACK_IMPORTED_MODULE_16__["MeshLODLevel"]; });

/* harmony import */ var _transformNode__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./transformNode */ "./Meshes/transformNode.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformNode", function() { return _transformNode__WEBPACK_IMPORTED_MODULE_17__["TransformNode"]; });

/* harmony import */ var _Builders_index__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Builders/index */ "./Meshes/Builders/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["BoxBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["SphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["CylinderBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["TorusBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["LinesBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["PlaneBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["GroundBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledBoxBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["TiledBoxBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DiscBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["DiscBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RibbonBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["RibbonBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphereBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["HemisphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusKnotBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["TorusKnotBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["PolygonBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShapeBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["ShapeBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LatheBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["LatheBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledPlaneBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["TiledPlaneBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TubeBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["TubeBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolyhedronBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["PolyhedronBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IcoSphereBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["IcoSphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DecalBuilder", function() { return _Builders_index__WEBPACK_IMPORTED_MODULE_18__["DecalBuilder"]; });

/* harmony import */ var _dataBuffer__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./dataBuffer */ "./Meshes/dataBuffer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DataBuffer", function() { return _dataBuffer__WEBPACK_IMPORTED_MODULE_19__["DataBuffer"]; });

/* harmony import */ var _WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./WebGL/webGLDataBuffer */ "./Meshes/WebGL/webGLDataBuffer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGLDataBuffer", function() { return _WebGL_webGLDataBuffer__WEBPACK_IMPORTED_MODULE_20__["WebGLDataBuffer"]; });

/* harmony import */ var _WebGPU_webgpuDataBuffer__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./WebGPU/webgpuDataBuffer */ "./Meshes/WebGPU/webgpuDataBuffer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUDataBuffer", function() { return _WebGPU_webgpuDataBuffer__WEBPACK_IMPORTED_MODULE_21__["WebGPUDataBuffer"]; });

























/***/ }),

/***/ "./Meshes/instancedMesh.ts":
/*!*********************************!*\
  !*** ./Meshes/instancedMesh.ts ***!
  \*********************************/
/*! exports provided: InstancedMesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancedMesh", function() { return InstancedMesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _transformNode__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./transformNode */ "./Meshes/transformNode.ts");







_Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]._instancedMeshFactory = function (name, mesh) {
    return new InstancedMesh(name, mesh);
};
/**
 * Creates an instance based on a source mesh.
 */
var InstancedMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InstancedMesh, _super);
    function InstancedMesh(name, source) {
        var _this = _super.call(this, name, source.getScene()) || this;
        /** @hidden */
        _this._indexInSourceMeshInstanceArray = -1;
        source.addInstance(_this);
        _this._sourceMesh = source;
        _this._unIndexed = source._unIndexed;
        _this.position.copyFrom(source.position);
        _this.rotation.copyFrom(source.rotation);
        _this.scaling.copyFrom(source.scaling);
        if (source.rotationQuaternion) {
            _this.rotationQuaternion = source.rotationQuaternion.clone();
        }
        _this.infiniteDistance = source.infiniteDistance;
        _this.setPivotMatrix(source.getPivotMatrix());
        _this.refreshBoundingInfo();
        _this._syncSubMeshes();
        return _this;
    }
    /**
     * Returns the string "InstancedMesh".
     */
    InstancedMesh.prototype.getClassName = function () {
        return "InstancedMesh";
    };
    Object.defineProperty(InstancedMesh.prototype, "lightSources", {
        /** Gets the list of lights affecting that mesh */
        get: function () {
            return this._sourceMesh._lightSources;
        },
        enumerable: true,
        configurable: true
    });
    InstancedMesh.prototype._resyncLightSources = function () {
        // Do nothing as all the work will be done by source mesh
    };
    InstancedMesh.prototype._resyncLighSource = function (light) {
        // Do nothing as all the work will be done by source mesh
    };
    InstancedMesh.prototype._removeLightSource = function (light, dispose) {
        // Do nothing as all the work will be done by source mesh
    };
    Object.defineProperty(InstancedMesh.prototype, "receiveShadows", {
        // Methods
        /**
         * If the source mesh receives shadows
         */
        get: function () {
            return this._sourceMesh.receiveShadows;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancedMesh.prototype, "material", {
        /**
         * The material of the source mesh
         */
        get: function () {
            return this._sourceMesh.material;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancedMesh.prototype, "visibility", {
        /**
         * Visibility of the source mesh
         */
        get: function () {
            return this._sourceMesh.visibility;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancedMesh.prototype, "skeleton", {
        /**
         * Skeleton of the source mesh
         */
        get: function () {
            return this._sourceMesh.skeleton;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(InstancedMesh.prototype, "renderingGroupId", {
        /**
         * Rendering ground id of the source mesh
         */
        get: function () {
            return this._sourceMesh.renderingGroupId;
        },
        set: function (value) {
            if (!this._sourceMesh || value === this._sourceMesh.renderingGroupId) {
                return;
            }
            //no-op with warning
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Note - setting renderingGroupId of an instanced mesh has no effect on the scene");
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the total number of vertices (integer).
     */
    InstancedMesh.prototype.getTotalVertices = function () {
        return this._sourceMesh ? this._sourceMesh.getTotalVertices() : 0;
    };
    /**
     * Returns a positive integer : the total number of indices in this mesh geometry.
     * @returns the numner of indices or zero if the mesh has no geometry.
     */
    InstancedMesh.prototype.getTotalIndices = function () {
        return this._sourceMesh.getTotalIndices();
    };
    Object.defineProperty(InstancedMesh.prototype, "sourceMesh", {
        /**
         * The source mesh of the instance
         */
        get: function () {
            return this._sourceMesh;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Is this node ready to be used/rendered
     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
     * @return {boolean} is it ready
     */
    InstancedMesh.prototype.isReady = function (completeCheck) {
        if (completeCheck === void 0) { completeCheck = false; }
        return this._sourceMesh.isReady(completeCheck, true);
    };
    /**
     * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.
     * @param kind kind of verticies to retreive (eg. positons, normals, uvs, etc.)
     * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
     * @returns a float array or a Float32Array of the requested kind of data : positons, normals, uvs, etc.
     */
    InstancedMesh.prototype.getVerticesData = function (kind, copyWhenShared) {
        return this._sourceMesh.getVerticesData(kind, copyWhenShared);
    };
    /**
     * Sets the vertex data of the mesh geometry for the requested `kind`.
     * If the mesh has no geometry, a new Geometry object is set to the mesh and then passed this vertex data.
     * The `data` are either a numeric array either a Float32Array.
     * The parameter `updatable` is passed as is to the underlying Geometry object constructor (if initianilly none) or updater.
     * The parameter `stride` is an optional positive integer, it is usually automatically deducted from the `kind` (3 for positions or normals, 2 for UV, etc).
     * Note that a new underlying VertexBuffer object is created each call.
     * If the `kind` is the `PositionKind`, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
     *
     * Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     *
     * Returns the Mesh.
     */
    InstancedMesh.prototype.setVerticesData = function (kind, data, updatable, stride) {
        if (this.sourceMesh) {
            this.sourceMesh.setVerticesData(kind, data, updatable, stride);
        }
        return this.sourceMesh;
    };
    /**
     * Updates the existing vertex data of the mesh geometry for the requested `kind`.
     * If the mesh has no geometry, it is simply returned as it is.
     * The `data` are either a numeric array either a Float32Array.
     * No new underlying VertexBuffer object is created.
     * If the `kind` is the `PositionKind` and if `updateExtends` is true, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
     * If the parameter `makeItUnique` is true, a new global geometry is created from this positions and is set to the mesh.
     *
     * Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     *
     * Returns the Mesh.
     */
    InstancedMesh.prototype.updateVerticesData = function (kind, data, updateExtends, makeItUnique) {
        if (this.sourceMesh) {
            this.sourceMesh.updateVerticesData(kind, data, updateExtends, makeItUnique);
        }
        return this.sourceMesh;
    };
    /**
     * Sets the mesh indices.
     * Expects an array populated with integers or a typed array (Int32Array, Uint32Array, Uint16Array).
     * If the mesh has no geometry, a new Geometry object is created and set to the mesh.
     * This method creates a new index buffer each call.
     * Returns the Mesh.
     */
    InstancedMesh.prototype.setIndices = function (indices, totalVertices) {
        if (totalVertices === void 0) { totalVertices = null; }
        if (this.sourceMesh) {
            this.sourceMesh.setIndices(indices, totalVertices);
        }
        return this.sourceMesh;
    };
    /**
     * Boolean : True if the mesh owns the requested kind of data.
     */
    InstancedMesh.prototype.isVerticesDataPresent = function (kind) {
        return this._sourceMesh.isVerticesDataPresent(kind);
    };
    /**
     * Returns an array of indices (IndicesArray).
     */
    InstancedMesh.prototype.getIndices = function () {
        return this._sourceMesh.getIndices();
    };
    Object.defineProperty(InstancedMesh.prototype, "_positions", {
        get: function () {
            return this._sourceMesh._positions;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.
     * This means the mesh underlying bounding box and sphere are recomputed.
     * @param applySkeleton defines whether to apply the skeleton before computing the bounding info
     * @returns the current mesh
     */
    InstancedMesh.prototype.refreshBoundingInfo = function (applySkeleton) {
        if (applySkeleton === void 0) { applySkeleton = false; }
        if (this._boundingInfo && this._boundingInfo.isLocked) {
            return this;
        }
        var bias = this._sourceMesh.geometry ? this._sourceMesh.geometry.boundingBias : null;
        this._refreshBoundingInfo(this._sourceMesh._getPositionData(applySkeleton), bias);
        return this;
    };
    /** @hidden */
    InstancedMesh.prototype._preActivate = function () {
        if (this._currentLOD) {
            this._currentLOD._preActivate();
        }
        return this;
    };
    /** @hidden */
    InstancedMesh.prototype._activate = function (renderId, intermediateRendering) {
        if (!this._sourceMesh.subMeshes) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Instances should only be created for meshes with geometry.");
        }
        if (this._currentLOD) {
            this._currentLOD._registerInstanceForRenderId(this, renderId);
            if (intermediateRendering) {
                if (!this._currentLOD._internalAbstractMeshDataInfo._isActiveIntermediate) {
                    this._currentLOD._internalAbstractMeshDataInfo._onlyForInstancesIntermediate = true;
                    return true;
                }
            }
            else {
                if (!this._currentLOD._internalAbstractMeshDataInfo._isActive) {
                    this._currentLOD._internalAbstractMeshDataInfo._onlyForInstances = true;
                    return true;
                }
            }
        }
        return false;
    };
    /** @hidden */
    InstancedMesh.prototype._postActivate = function () {
        if (this._edgesRenderer && this._edgesRenderer.isEnabled && this._sourceMesh._renderingGroup) {
            this._sourceMesh._renderingGroup._edgesRenderers.push(this._edgesRenderer);
        }
    };
    InstancedMesh.prototype.getWorldMatrix = function () {
        if (this._currentLOD && this._currentLOD.billboardMode !== _transformNode__WEBPACK_IMPORTED_MODULE_6__["TransformNode"].BILLBOARDMODE_NONE && this._currentLOD._masterMesh !== this) {
            var tempMaster = this._currentLOD._masterMesh;
            this._currentLOD._masterMesh = this;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Matrix[0].copyFrom(this._currentLOD.computeWorldMatrix(true));
            this._currentLOD._masterMesh = tempMaster;
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Matrix[0];
        }
        return _super.prototype.getWorldMatrix.call(this);
    };
    Object.defineProperty(InstancedMesh.prototype, "isAnInstance", {
        get: function () {
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the current associated LOD AbstractMesh.
     */
    InstancedMesh.prototype.getLOD = function (camera) {
        if (!camera) {
            return this;
        }
        var boundingInfo = this.getBoundingInfo();
        this._currentLOD = this.sourceMesh.getLOD(camera, boundingInfo.boundingSphere);
        if (this._currentLOD === this.sourceMesh) {
            return this.sourceMesh;
        }
        return this._currentLOD;
    };
    /** @hidden */
    InstancedMesh.prototype._syncSubMeshes = function () {
        this.releaseSubMeshes();
        if (this._sourceMesh.subMeshes) {
            for (var index = 0; index < this._sourceMesh.subMeshes.length; index++) {
                this._sourceMesh.subMeshes[index].clone(this, this._sourceMesh);
            }
        }
        return this;
    };
    /** @hidden */
    InstancedMesh.prototype._generatePointsArray = function () {
        return this._sourceMesh._generatePointsArray();
    };
    /**
     * Creates a new InstancedMesh from the current mesh.
     * - name (string) : the cloned mesh name
     * - newParent (optional Node) : the optional Node to parent the clone to.
     * - doNotCloneChildren (optional boolean, default `false`) : if `true` the model children aren't cloned.
     *
     * Returns the clone.
     */
    InstancedMesh.prototype.clone = function (name, newParent, doNotCloneChildren) {
        if (newParent === void 0) { newParent = null; }
        var result = this._sourceMesh.createInstance(name);
        // Deep copy
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_5__["DeepCopier"].DeepCopy(this, result, ["name", "subMeshes", "uniqueId"], []);
        // Bounding info
        this.refreshBoundingInfo();
        // Parent
        if (newParent) {
            result.parent = newParent;
        }
        if (!doNotCloneChildren) {
            // Children
            for (var index = 0; index < this.getScene().meshes.length; index++) {
                var mesh = this.getScene().meshes[index];
                if (mesh.parent === this) {
                    mesh.clone(mesh.name, result);
                }
            }
        }
        result.computeWorldMatrix(true);
        return result;
    };
    /**
     * Disposes the InstancedMesh.
     * Returns nothing.
     */
    InstancedMesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        // Remove from mesh
        this._sourceMesh.removeInstance(this);
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    return InstancedMesh;
}(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__["AbstractMesh"]));



/***/ }),

/***/ "./Meshes/linesMesh.ts":
/*!*****************************!*\
  !*** ./Meshes/linesMesh.ts ***!
  \*****************************/
/*! exports provided: LinesMesh, InstancedLinesMesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinesMesh", function() { return LinesMesh; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstancedLinesMesh", function() { return InstancedLinesMesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_instancedMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/instancedMesh */ "./Meshes/instancedMesh.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_shaderMaterial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/shaderMaterial */ "./Materials/shaderMaterial.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Shaders_color_fragment__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Shaders/color.fragment */ "./Shaders/color.fragment.ts");
/* harmony import */ var _Shaders_color_vertex__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Shaders/color.vertex */ "./Shaders/color.vertex.ts");










/**
 * Line mesh
 * @see https://doc.babylonjs.com/babylon101/parametric_shapes
 */
var LinesMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LinesMesh, _super);
    /**
     * Creates a new LinesMesh
     * @param name defines the name
     * @param scene defines the hosting scene
     * @param parent defines the parent mesh if any
     * @param source defines the optional source LinesMesh used to clone data from
     * @param doNotCloneChildren When cloning, skip cloning child meshes of source, default False.
     * When false, achieved by calling a clone(), also passing False.
     * This will make creation of children, recursive.
     * @param useVertexColor defines if this LinesMesh supports vertex color
     * @param useVertexAlpha defines if this LinesMesh supports vertex alpha
     */
    function LinesMesh(name, scene, parent, source, doNotCloneChildren,
    /**
     * If vertex color should be applied to the mesh
     */
    useVertexColor,
    /**
     * If vertex alpha should be applied to the mesh
     */
    useVertexAlpha) {
        if (scene === void 0) { scene = null; }
        if (parent === void 0) { parent = null; }
        if (source === void 0) { source = null; }
        var _this = _super.call(this, name, scene, parent, source, doNotCloneChildren) || this;
        _this.useVertexColor = useVertexColor;
        _this.useVertexAlpha = useVertexAlpha;
        /**
         * Color of the line (Default: White)
         */
        _this.color = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color3"](1, 1, 1);
        /**
         * Alpha of the line (Default: 1)
         */
        _this.alpha = 1;
        if (source) {
            _this.color = source.color.clone();
            _this.alpha = source.alpha;
            _this.useVertexColor = source.useVertexColor;
            _this.useVertexAlpha = source.useVertexAlpha;
        }
        _this.intersectionThreshold = 0.1;
        var defines = [];
        var options = {
            attributes: [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, "world0", "world1", "world2", "world3"],
            uniforms: ["vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "world", "viewProjection"],
            needAlphaBlending: true,
            defines: defines
        };
        if (useVertexAlpha === false) {
            options.needAlphaBlending = false;
        }
        if (!useVertexColor) {
            options.uniforms.push("color");
            _this.color4 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"]();
        }
        else {
            options.defines.push("#define VERTEXCOLOR");
            options.attributes.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind);
        }
        _this._colorShader = new _Materials_shaderMaterial__WEBPACK_IMPORTED_MODULE_6__["ShaderMaterial"]("colorShader", _this.getScene(), "color", options);
        return _this;
    }
    LinesMesh.prototype._addClipPlaneDefine = function (label) {
        var define = "#define " + label;
        var index = this._colorShader.options.defines.indexOf(define);
        if (index !== -1) {
            return;
        }
        this._colorShader.options.defines.push(define);
    };
    LinesMesh.prototype._removeClipPlaneDefine = function (label) {
        var define = "#define " + label;
        var index = this._colorShader.options.defines.indexOf(define);
        if (index === -1) {
            return;
        }
        this._colorShader.options.defines.splice(index, 1);
    };
    LinesMesh.prototype.isReady = function () {
        var scene = this.getScene();
        // Clip planes
        scene.clipPlane ? this._addClipPlaneDefine("CLIPPLANE") : this._removeClipPlaneDefine("CLIPPLANE");
        scene.clipPlane2 ? this._addClipPlaneDefine("CLIPPLANE2") : this._removeClipPlaneDefine("CLIPPLANE2");
        scene.clipPlane3 ? this._addClipPlaneDefine("CLIPPLANE3") : this._removeClipPlaneDefine("CLIPPLANE3");
        scene.clipPlane4 ? this._addClipPlaneDefine("CLIPPLANE4") : this._removeClipPlaneDefine("CLIPPLANE4");
        if (!this._colorShader.isReady()) {
            return false;
        }
        return _super.prototype.isReady.call(this);
    };
    /**
     * Returns the string "LineMesh"
     */
    LinesMesh.prototype.getClassName = function () {
        return "LinesMesh";
    };
    Object.defineProperty(LinesMesh.prototype, "material", {
        /**
         * @hidden
         */
        get: function () {
            return this._colorShader;
        },
        /**
         * @hidden
         */
        set: function (value) {
            // Do nothing
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LinesMesh.prototype, "checkCollisions", {
        /**
         * @hidden
         */
        get: function () {
            return false;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    LinesMesh.prototype._bind = function (subMesh, effect, fillMode) {
        if (!this._geometry) {
            return this;
        }
        var colorEffect = this._colorShader.getEffect();
        // VBOs
        var indexToBind = this.isUnIndexed ? null : this._geometry.getIndexBuffer();
        this._geometry._bind(colorEffect, indexToBind);
        // Color
        if (!this.useVertexColor) {
            var _a = this.color, r = _a.r, g = _a.g, b = _a.b;
            this.color4.set(r, g, b, this.alpha);
            this._colorShader.setColor4("color", this.color4);
        }
        // Clip planes
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_7__["MaterialHelper"].BindClipPlane(colorEffect, this.getScene());
        return this;
    };
    /** @hidden */
    LinesMesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
        if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
            return this;
        }
        var engine = this.getScene().getEngine();
        // Draw order
        if (this._unIndexed) {
            engine.drawArraysType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].LineListDrawMode, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
        }
        else {
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].LineListDrawMode, subMesh.indexStart, subMesh.indexCount, instancesCount);
        }
        return this;
    };
    /**
     * Disposes of the line mesh
     * @param doNotRecurse If children should be disposed
     */
    LinesMesh.prototype.dispose = function (doNotRecurse) {
        this._colorShader.dispose(false, false, true);
        _super.prototype.dispose.call(this, doNotRecurse);
    };
    /**
     * Returns a new LineMesh object cloned from the current one.
     */
    LinesMesh.prototype.clone = function (name, newParent, doNotCloneChildren) {
        if (newParent === void 0) { newParent = null; }
        return new LinesMesh(name, this.getScene(), newParent, this, doNotCloneChildren);
    };
    /**
     * Creates a new InstancedLinesMesh object from the mesh model.
     * @see http://doc.babylonjs.com/how_to/how_to_use_instances
     * @param name defines the name of the new instance
     * @returns a new InstancedLinesMesh
     */
    LinesMesh.prototype.createInstance = function (name) {
        return new InstancedLinesMesh(name, this);
    };
    return LinesMesh;
}(_Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"]));

/**
 * Creates an instance based on a source LinesMesh
 */
var InstancedLinesMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](InstancedLinesMesh, _super);
    function InstancedLinesMesh(name, source) {
        var _this = _super.call(this, name, source) || this;
        _this.intersectionThreshold = source.intersectionThreshold;
        return _this;
    }
    /**
     * Returns the string "InstancedLinesMesh".
     */
    InstancedLinesMesh.prototype.getClassName = function () {
        return "InstancedLinesMesh";
    };
    return InstancedLinesMesh;
}(_Meshes_instancedMesh__WEBPACK_IMPORTED_MODULE_4__["InstancedMesh"]));



/***/ }),

/***/ "./Meshes/mesh.ts":
/*!************************!*\
  !*** ./Meshes/mesh.ts ***!
  \************************/
/*! exports provided: _CreationDataStorage, _InstancesBatch, Mesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_CreationDataStorage", function() { return _CreationDataStorage; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_InstancesBatch", function() { return _InstancesBatch; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Mesh", function() { return Mesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Misc_tags__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/tags */ "./Misc/tags.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _buffer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _geometry__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./geometry */ "./Meshes/geometry.ts");
/* harmony import */ var _abstractMesh__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _subMesh__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./subMesh */ "./Meshes/subMesh.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Culling/boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Materials/multiMaterial */ "./Materials/multiMaterial.ts");
/* harmony import */ var _Loading_sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Loading/sceneLoaderFlags */ "./Loading/sceneLoaderFlags.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _meshLODLevel__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./meshLODLevel */ "./Meshes/meshLODLevel.ts");

























/**
 * @hidden
 **/
var _CreationDataStorage = /** @class */ (function () {
    function _CreationDataStorage() {
    }
    return _CreationDataStorage;
}());

/**
 * @hidden
 **/
var _InstanceDataStorage = /** @class */ (function () {
    function _InstanceDataStorage() {
        this.visibleInstances = {};
        this.batchCache = new _InstancesBatch();
        this.instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
    }
    return _InstanceDataStorage;
}());
/**
 * @hidden
 **/
var _InstancesBatch = /** @class */ (function () {
    function _InstancesBatch() {
        this.mustReturn = false;
        this.visibleInstances = new Array();
        this.renderSelf = new Array();
        this.hardwareInstancedRendering = new Array();
    }
    return _InstancesBatch;
}());

/**
 * @hidden
 **/
var _InternalMeshDataInfo = /** @class */ (function () {
    function _InternalMeshDataInfo() {
        this._areNormalsFrozen = false; // Will be used by ribbons mainly
        // Will be used to save a source mesh reference, If any
        this._source = null;
        // Will be used to for fast cloned mesh lookup
        this.meshMap = null;
        this._preActivateId = -1;
        this._LODLevels = new Array();
        // Morph
        this._morphTargetManager = null;
    }
    return _InternalMeshDataInfo;
}());
/**
 * Class used to represent renderable models
 */
var Mesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Mesh, _super);
    /**
     * @constructor
     * @param name The value used by scene.getMeshByName() to do a lookup.
     * @param scene The scene to add this mesh to.
     * @param parent The parent of this mesh, if it has one
     * @param source An optional Mesh from which geometry is shared, cloned.
     * @param doNotCloneChildren When cloning, skip cloning child meshes of source, default False.
     *                  When false, achieved by calling a clone(), also passing False.
     *                  This will make creation of children, recursive.
     * @param clonePhysicsImpostor When cloning, include cloning mesh physics impostor, default True.
     */
    function Mesh(name, scene, parent, source, doNotCloneChildren, clonePhysicsImpostor) {
        if (scene === void 0) { scene = null; }
        if (parent === void 0) { parent = null; }
        if (source === void 0) { source = null; }
        if (clonePhysicsImpostor === void 0) { clonePhysicsImpostor = true; }
        var _this = _super.call(this, name, scene) || this;
        // Internal data
        _this._internalMeshDataInfo = new _InternalMeshDataInfo();
        // Members
        /**
         * Gets the delay loading state of the mesh (when delay loading is turned on)
         * @see http://doc.babylonjs.com/how_to/using_the_incremental_loading_system
         */
        _this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_NONE;
        /**
         * Gets the list of instances created from this mesh
         * it is not supposed to be modified manually.
         * Note also that the order of the InstancedMesh wihin the array is not significant and might change.
         * @see http://doc.babylonjs.com/how_to/how_to_use_instances
         */
        _this.instances = new Array();
        // Private
        /** @hidden */
        _this._creationDataStorage = null;
        /** @hidden */
        _this._geometry = null;
        /** @hidden */
        _this._instanceDataStorage = new _InstanceDataStorage();
        _this._effectiveMaterial = null;
        /** @hidden */
        _this._shouldGenerateFlatShading = false;
        // Use by builder only to know what orientation were the mesh build in.
        /** @hidden */
        _this._originalBuilderSideOrientation = Mesh.DEFAULTSIDE;
        /**
         * Use this property to change the original side orientation defined at construction time
         */
        _this.overrideMaterialSideOrientation = null;
        scene = _this.getScene();
        if (source) {
            // Geometry
            if (source._geometry) {
                source._geometry.applyToMesh(_this);
            }
            // Deep copy
            _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__["DeepCopier"].DeepCopy(source, _this, ["name", "material", "skeleton", "instances", "parent", "uniqueId",
                "source", "metadata", "hasLODLevels", "geometry", "isBlocked", "areNormalsFrozen",
                "onBeforeDrawObservable", "onBeforeRenderObservable", "onAfterRenderObservable", "onBeforeDraw",
                "onAfterWorldMatrixUpdateObservable", "onCollideObservable", "onCollisionPositionChangeObservable", "onRebuildObservable",
                "onDisposeObservable", "lightSources"
            ], ["_poseMatrix"]);
            // Source mesh
            _this._internalMeshDataInfo._source = source;
            if (scene.useClonedMeshhMap) {
                if (!source._internalMeshDataInfo.meshMap) {
                    source._internalMeshDataInfo.meshMap = {};
                }
                source._internalMeshDataInfo.meshMap[_this.uniqueId] = _this;
            }
            // Construction Params
            // Clone parameters allowing mesh to be updated in case of parametric shapes.
            _this._originalBuilderSideOrientation = source._originalBuilderSideOrientation;
            _this._creationDataStorage = source._creationDataStorage;
            // Animation ranges
            if (source._ranges) {
                var ranges = source._ranges;
                for (var name in ranges) {
                    if (!ranges.hasOwnProperty(name)) {
                        continue;
                    }
                    if (!ranges[name]) {
                        continue;
                    }
                    _this.createAnimationRange(name, ranges[name].from, ranges[name].to);
                }
            }
            // Metadata
            if (source.metadata && source.metadata.clone) {
                _this.metadata = source.metadata.clone();
            }
            else {
                _this.metadata = source.metadata;
            }
            // Tags
            if (_Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"] && _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].HasTags(source)) {
                _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].AddTagsTo(_this, _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].GetTags(source, true));
            }
            // Parent
            _this.parent = source.parent;
            // Pivot
            _this.setPivotMatrix(source.getPivotMatrix());
            _this.id = name + "." + source.id;
            // Material
            _this.material = source.material;
            var index;
            if (!doNotCloneChildren) {
                // Children
                var directDescendants = source.getDescendants(true);
                for (var index_1 = 0; index_1 < directDescendants.length; index_1++) {
                    var child = directDescendants[index_1];
                    if (child.clone) {
                        child.clone(name + "." + child.name, _this);
                    }
                }
            }
            // Physics clone
            if (scene.getPhysicsEngine) {
                var physicsEngine = scene.getPhysicsEngine();
                if (clonePhysicsImpostor && physicsEngine) {
                    var impostor = physicsEngine.getImpostorForPhysicsObject(source);
                    if (impostor) {
                        _this.physicsImpostor = impostor.clone(_this);
                    }
                }
            }
            // Particles
            for (index = 0; index < scene.particleSystems.length; index++) {
                var system = scene.particleSystems[index];
                if (system.emitter === source) {
                    system.clone(system.name, _this);
                }
            }
            _this.refreshBoundingInfo();
            _this.computeWorldMatrix(true);
        }
        // Parent
        if (parent !== null) {
            _this.parent = parent;
        }
        _this._instanceDataStorage.hardwareInstancedRendering = _this.getEngine().getCaps().instancedArrays;
        return _this;
    }
    /**
     * Gets the default side orientation.
     * @param orientation the orientation to value to attempt to get
     * @returns the default orientation
     * @hidden
     */
    Mesh._GetDefaultSideOrientation = function (orientation) {
        return orientation || Mesh.FRONTSIDE; // works as Mesh.FRONTSIDE is 0
    };
    Object.defineProperty(Mesh.prototype, "onBeforeRenderObservable", {
        /**
         * An event triggered before rendering the mesh
         */
        get: function () {
            if (!this._internalMeshDataInfo._onBeforeRenderObservable) {
                this._internalMeshDataInfo._onBeforeRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
            }
            return this._internalMeshDataInfo._onBeforeRenderObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "onBeforeBindObservable", {
        /**
         * An event triggered before binding the mesh
         */
        get: function () {
            if (!this._internalMeshDataInfo._onBeforeBindObservable) {
                this._internalMeshDataInfo._onBeforeBindObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
            }
            return this._internalMeshDataInfo._onBeforeBindObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "onAfterRenderObservable", {
        /**
        * An event triggered after rendering the mesh
        */
        get: function () {
            if (!this._internalMeshDataInfo._onAfterRenderObservable) {
                this._internalMeshDataInfo._onAfterRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
            }
            return this._internalMeshDataInfo._onAfterRenderObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "onBeforeDrawObservable", {
        /**
        * An event triggered before drawing the mesh
        */
        get: function () {
            if (!this._internalMeshDataInfo._onBeforeDrawObservable) {
                this._internalMeshDataInfo._onBeforeDrawObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
            }
            return this._internalMeshDataInfo._onBeforeDrawObservable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "onBeforeDraw", {
        /**
         * Sets a callback to call before drawing the mesh. It is recommended to use onBeforeDrawObservable instead
         */
        set: function (callback) {
            if (this._onBeforeDrawObserver) {
                this.onBeforeDrawObservable.remove(this._onBeforeDrawObserver);
            }
            this._onBeforeDrawObserver = this.onBeforeDrawObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "hasInstances", {
        get: function () {
            return this.instances.length > 0;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "morphTargetManager", {
        /**
         * Gets or sets the morph target manager
         * @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
         */
        get: function () {
            return this._internalMeshDataInfo._morphTargetManager;
        },
        set: function (value) {
            if (this._internalMeshDataInfo._morphTargetManager === value) {
                return;
            }
            this._internalMeshDataInfo._morphTargetManager = value;
            this._syncGeometryWithMorphTargetManager();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "source", {
        /**
         * Gets the source mesh (the one used to clone this one from)
         */
        get: function () {
            return this._internalMeshDataInfo._source;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Mesh.prototype, "isUnIndexed", {
        /**
         * Gets or sets a boolean indicating that this mesh does not use index buffer
         */
        get: function () {
            return this._unIndexed;
        },
        set: function (value) {
            if (this._unIndexed !== value) {
                this._unIndexed = value;
                this._markSubMeshesAsAttributesDirty();
            }
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    Mesh.prototype.instantiateHierarychy = function (newParent) {
        if (newParent === void 0) { newParent = null; }
        var instance = this.createInstance("instance of " + (this.name || this.id));
        instance.parent = newParent || this.parent;
        instance.position = this.position.clone();
        instance.scaling = this.scaling.clone();
        if (this.rotationQuaternion) {
            instance.rotationQuaternion = this.rotationQuaternion.clone();
        }
        else {
            instance.rotation = this.rotation.clone();
        }
        for (var _i = 0, _a = this.getChildTransformNodes(true); _i < _a.length; _i++) {
            var child = _a[_i];
            child.instantiateHierarychy(instance);
        }
        return instance;
    };
    /**
     * Gets the class name
     * @returns the string "Mesh".
     */
    Mesh.prototype.getClassName = function () {
        return "Mesh";
    };
    Object.defineProperty(Mesh.prototype, "_isMesh", {
        /** @hidden */
        get: function () {
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns a description of this mesh
     * @param fullDetails define if full details about this mesh must be used
     * @returns a descriptive string representing this mesh
     */
    Mesh.prototype.toString = function (fullDetails) {
        var ret = _super.prototype.toString.call(this, fullDetails);
        ret += ", n vertices: " + this.getTotalVertices();
        ret += ", parent: " + (this._waitingParentId ? this._waitingParentId : (this.parent ? this.parent.name : "NONE"));
        if (this.animations) {
            for (var i = 0; i < this.animations.length; i++) {
                ret += ", animation[0]: " + this.animations[i].toString(fullDetails);
            }
        }
        if (fullDetails) {
            if (this._geometry) {
                var ib = this.getIndices();
                var vb = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind);
                if (vb && ib) {
                    ret += ", flat shading: " + (vb.length / 3 === ib.length ? "YES" : "NO");
                }
            }
            else {
                ret += ", flat shading: UNKNOWN";
            }
        }
        return ret;
    };
    /** @hidden */
    Mesh.prototype._unBindEffect = function () {
        _super.prototype._unBindEffect.call(this);
        for (var _i = 0, _a = this.instances; _i < _a.length; _i++) {
            var instance = _a[_i];
            instance._unBindEffect();
        }
    };
    Object.defineProperty(Mesh.prototype, "hasLODLevels", {
        /**
         * Gets a boolean indicating if this mesh has LOD
         */
        get: function () {
            return this._internalMeshDataInfo._LODLevels.length > 0;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the list of MeshLODLevel associated with the current mesh
     * @returns an array of MeshLODLevel
     */
    Mesh.prototype.getLODLevels = function () {
        return this._internalMeshDataInfo._LODLevels;
    };
    Mesh.prototype._sortLODLevels = function () {
        this._internalMeshDataInfo._LODLevels.sort(function (a, b) {
            if (a.distance < b.distance) {
                return 1;
            }
            if (a.distance > b.distance) {
                return -1;
            }
            return 0;
        });
    };
    /**
     * Add a mesh as LOD level triggered at the given distance.
     * @see https://doc.babylonjs.com/how_to/how_to_use_lod
     * @param distance The distance from the center of the object to show this level
     * @param mesh The mesh to be added as LOD level (can be null)
     * @return This mesh (for chaining)
     */
    Mesh.prototype.addLODLevel = function (distance, mesh) {
        if (mesh && mesh._masterMesh) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Warn("You cannot use a mesh as LOD level twice");
            return this;
        }
        var level = new _meshLODLevel__WEBPACK_IMPORTED_MODULE_23__["MeshLODLevel"](distance, mesh);
        this._internalMeshDataInfo._LODLevels.push(level);
        if (mesh) {
            mesh._masterMesh = this;
        }
        this._sortLODLevels();
        return this;
    };
    /**
     * Returns the LOD level mesh at the passed distance or null if not found.
     * @see https://doc.babylonjs.com/how_to/how_to_use_lod
     * @param distance The distance from the center of the object to show this level
     * @returns a Mesh or `null`
     */
    Mesh.prototype.getLODLevelAtDistance = function (distance) {
        var internalDataInfo = this._internalMeshDataInfo;
        for (var index = 0; index < internalDataInfo._LODLevels.length; index++) {
            var level = internalDataInfo._LODLevels[index];
            if (level.distance === distance) {
                return level.mesh;
            }
        }
        return null;
    };
    /**
     * Remove a mesh from the LOD array
     * @see https://doc.babylonjs.com/how_to/how_to_use_lod
     * @param mesh defines the mesh to be removed
     * @return This mesh (for chaining)
     */
    Mesh.prototype.removeLODLevel = function (mesh) {
        var internalDataInfo = this._internalMeshDataInfo;
        for (var index = 0; index < internalDataInfo._LODLevels.length; index++) {
            if (internalDataInfo._LODLevels[index].mesh === mesh) {
                internalDataInfo._LODLevels.splice(index, 1);
                if (mesh) {
                    mesh._masterMesh = null;
                }
            }
        }
        this._sortLODLevels();
        return this;
    };
    /**
     * Returns the registered LOD mesh distant from the parameter `camera` position if any, else returns the current mesh.
     * @see https://doc.babylonjs.com/how_to/how_to_use_lod
     * @param camera defines the camera to use to compute distance
     * @param boundingSphere defines a custom bounding sphere to use instead of the one from this mesh
     * @return This mesh (for chaining)
     */
    Mesh.prototype.getLOD = function (camera, boundingSphere) {
        var internalDataInfo = this._internalMeshDataInfo;
        if (!internalDataInfo._LODLevels || internalDataInfo._LODLevels.length === 0) {
            return this;
        }
        var bSphere;
        if (boundingSphere) {
            bSphere = boundingSphere;
        }
        else {
            var boundingInfo = this.getBoundingInfo();
            bSphere = boundingInfo.boundingSphere;
        }
        var distanceToCamera = bSphere.centerWorld.subtract(camera.globalPosition).length();
        if (internalDataInfo._LODLevels[internalDataInfo._LODLevels.length - 1].distance > distanceToCamera) {
            if (this.onLODLevelSelection) {
                this.onLODLevelSelection(distanceToCamera, this, internalDataInfo._LODLevels[internalDataInfo._LODLevels.length - 1].mesh);
            }
            return this;
        }
        for (var index = 0; index < internalDataInfo._LODLevels.length; index++) {
            var level = internalDataInfo._LODLevels[index];
            if (level.distance < distanceToCamera) {
                if (level.mesh) {
                    level.mesh._preActivate();
                    level.mesh._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);
                }
                if (this.onLODLevelSelection) {
                    this.onLODLevelSelection(distanceToCamera, this, level.mesh);
                }
                return level.mesh;
            }
        }
        if (this.onLODLevelSelection) {
            this.onLODLevelSelection(distanceToCamera, this, this);
        }
        return this;
    };
    Object.defineProperty(Mesh.prototype, "geometry", {
        /**
         * Gets the mesh internal Geometry object
         */
        get: function () {
            return this._geometry;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the total number of vertices within the mesh geometry or zero if the mesh has no geometry.
     * @returns the total number of vertices
     */
    Mesh.prototype.getTotalVertices = function () {
        if (this._geometry === null || this._geometry === undefined) {
            return 0;
        }
        return this._geometry.getTotalVertices();
    };
    /**
     * Returns the content of an associated vertex buffer
     * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @param copyWhenShared defines a boolean indicating that if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one
     * @param forceCopy defines a boolean forcing the copy of the buffer no matter what the value of copyWhenShared is
     * @returns a FloatArray or null if the mesh has no geometry or no vertex buffer for this kind.
     */
    Mesh.prototype.getVerticesData = function (kind, copyWhenShared, forceCopy) {
        if (!this._geometry) {
            return null;
        }
        return this._geometry.getVerticesData(kind, copyWhenShared, forceCopy);
    };
    /**
     * Returns the mesh VertexBuffer object from the requested `kind`
     * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.NormalKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @returns a FloatArray or null if the mesh has no vertex buffer for this kind.
     */
    Mesh.prototype.getVertexBuffer = function (kind) {
        if (!this._geometry) {
            return null;
        }
        return this._geometry.getVertexBuffer(kind);
    };
    /**
     * Tests if a specific vertex buffer is associated with this mesh
     * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.NormalKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @returns a boolean
     */
    Mesh.prototype.isVerticesDataPresent = function (kind) {
        if (!this._geometry) {
            if (this._delayInfo) {
                return this._delayInfo.indexOf(kind) !== -1;
            }
            return false;
        }
        return this._geometry.isVerticesDataPresent(kind);
    };
    /**
     * Returns a boolean defining if the vertex data for the requested `kind` is updatable.
     * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @returns a boolean
     */
    Mesh.prototype.isVertexBufferUpdatable = function (kind) {
        if (!this._geometry) {
            if (this._delayInfo) {
                return this._delayInfo.indexOf(kind) !== -1;
            }
            return false;
        }
        return this._geometry.isVertexBufferUpdatable(kind);
    };
    /**
     * Returns a string which contains the list of existing `kinds` of Vertex Data associated with this mesh.
     * @param kind defines which buffer to read from (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.NormalKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @returns an array of strings
     */
    Mesh.prototype.getVerticesDataKinds = function () {
        if (!this._geometry) {
            var result = new Array();
            if (this._delayInfo) {
                this._delayInfo.forEach(function (kind) {
                    result.push(kind);
                });
            }
            return result;
        }
        return this._geometry.getVerticesDataKinds();
    };
    /**
     * Returns a positive integer : the total number of indices in this mesh geometry.
     * @returns the numner of indices or zero if the mesh has no geometry.
     */
    Mesh.prototype.getTotalIndices = function () {
        if (!this._geometry) {
            return 0;
        }
        return this._geometry.getTotalIndices();
    };
    /**
     * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.
     * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
     * @returns the indices array or an empty array if the mesh has no geometry
     */
    Mesh.prototype.getIndices = function (copyWhenShared, forceCopy) {
        if (!this._geometry) {
            return [];
        }
        return this._geometry.getIndices(copyWhenShared, forceCopy);
    };
    Object.defineProperty(Mesh.prototype, "isBlocked", {
        get: function () {
            return this._masterMesh !== null && this._masterMesh !== undefined;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Determine if the current mesh is ready to be rendered
     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
     * @param forceInstanceSupport will check if the mesh will be ready when used with instances (false by default)
     * @returns true if all associated assets are ready (material, textures, shaders)
     */
    Mesh.prototype.isReady = function (completeCheck, forceInstanceSupport) {
        if (completeCheck === void 0) { completeCheck = false; }
        if (forceInstanceSupport === void 0) { forceInstanceSupport = false; }
        if (this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_LOADING) {
            return false;
        }
        if (!_super.prototype.isReady.call(this, completeCheck)) {
            return false;
        }
        if (!this.subMeshes || this.subMeshes.length === 0) {
            return true;
        }
        if (!completeCheck) {
            return true;
        }
        var engine = this.getEngine();
        var scene = this.getScene();
        var hardwareInstancedRendering = forceInstanceSupport || engine.getCaps().instancedArrays && this.instances.length > 0;
        this.computeWorldMatrix();
        var mat = this.material || scene.defaultMaterial;
        if (mat) {
            if (mat._storeEffectOnSubMeshes) {
                for (var _i = 0, _a = this.subMeshes; _i < _a.length; _i++) {
                    var subMesh = _a[_i];
                    var effectiveMaterial = subMesh.getMaterial();
                    if (effectiveMaterial) {
                        if (effectiveMaterial._storeEffectOnSubMeshes) {
                            if (!effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
                                return false;
                            }
                        }
                        else {
                            if (!effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
                                return false;
                            }
                        }
                    }
                }
            }
            else {
                if (!mat.isReady(this, hardwareInstancedRendering)) {
                    return false;
                }
            }
        }
        // Shadows
        for (var _b = 0, _c = this.lightSources; _b < _c.length; _b++) {
            var light = _c[_b];
            var generator = light.getShadowGenerator();
            if (generator) {
                for (var _d = 0, _e = this.subMeshes; _d < _e.length; _d++) {
                    var subMesh = _e[_d];
                    if (!generator.isReady(subMesh, hardwareInstancedRendering)) {
                        return false;
                    }
                }
            }
        }
        // LOD
        for (var _f = 0, _g = this._internalMeshDataInfo._LODLevels; _f < _g.length; _f++) {
            var lod = _g[_f];
            if (lod.mesh && !lod.mesh.isReady(hardwareInstancedRendering)) {
                return false;
            }
        }
        return true;
    };
    Object.defineProperty(Mesh.prototype, "areNormalsFrozen", {
        /**
         * Gets a boolean indicating if the normals aren't to be recomputed on next mesh `positions` array update. This property is pertinent only for updatable parametric shapes.
         */
        get: function () {
            return this._internalMeshDataInfo._areNormalsFrozen;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * This function affects parametric shapes on vertex position update only : ribbons, tubes, etc. It has no effect at all on other shapes. It prevents the mesh normals from being recomputed on next `positions` array update.
     * @returns the current mesh
     */
    Mesh.prototype.freezeNormals = function () {
        this._internalMeshDataInfo._areNormalsFrozen = true;
        return this;
    };
    /**
     * This function affects parametric shapes on vertex position update only : ribbons, tubes, etc. It has no effect at all on other shapes. It reactivates the mesh normals computation if it was previously frozen
     * @returns the current mesh
     */
    Mesh.prototype.unfreezeNormals = function () {
        this._internalMeshDataInfo._areNormalsFrozen = false;
        return this;
    };
    Object.defineProperty(Mesh.prototype, "overridenInstanceCount", {
        /**
         * Sets a value overriding the instance count. Only applicable when custom instanced InterleavedVertexBuffer are used rather than InstancedMeshs
         */
        set: function (count) {
            this._instanceDataStorage.overridenInstanceCount = count;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /** @hidden */
    Mesh.prototype._preActivate = function () {
        var internalDataInfo = this._internalMeshDataInfo;
        var sceneRenderId = this.getScene().getRenderId();
        if (internalDataInfo._preActivateId === sceneRenderId) {
            return this;
        }
        internalDataInfo._preActivateId = sceneRenderId;
        this._instanceDataStorage.visibleInstances = null;
        return this;
    };
    /** @hidden */
    Mesh.prototype._preActivateForIntermediateRendering = function (renderId) {
        if (this._instanceDataStorage.visibleInstances) {
            this._instanceDataStorage.visibleInstances.intermediateDefaultRenderId = renderId;
        }
        return this;
    };
    /** @hidden */
    Mesh.prototype._registerInstanceForRenderId = function (instance, renderId) {
        if (!this._instanceDataStorage.visibleInstances) {
            this._instanceDataStorage.visibleInstances = {
                defaultRenderId: renderId,
                selfDefaultRenderId: this._renderId
            };
        }
        if (!this._instanceDataStorage.visibleInstances[renderId]) {
            this._instanceDataStorage.visibleInstances[renderId] = new Array();
        }
        this._instanceDataStorage.visibleInstances[renderId].push(instance);
        return this;
    };
    /**
     * This method recomputes and sets a new BoundingInfo to the mesh unless it is locked.
     * This means the mesh underlying bounding box and sphere are recomputed.
     * @param applySkeleton defines whether to apply the skeleton before computing the bounding info
     * @returns the current mesh
     */
    Mesh.prototype.refreshBoundingInfo = function (applySkeleton) {
        if (applySkeleton === void 0) { applySkeleton = false; }
        if (this._boundingInfo && this._boundingInfo.isLocked) {
            return this;
        }
        var bias = this.geometry ? this.geometry.boundingBias : null;
        this._refreshBoundingInfo(this._getPositionData(applySkeleton), bias);
        return this;
    };
    /** @hidden */
    Mesh.prototype._createGlobalSubMesh = function (force) {
        var totalVertices = this.getTotalVertices();
        if (!totalVertices || !this.getIndices()) {
            return null;
        }
        // Check if we need to recreate the submeshes
        if (this.subMeshes && this.subMeshes.length > 0) {
            var ib = this.getIndices();
            if (!ib) {
                return null;
            }
            var totalIndices = ib.length;
            var needToRecreate = false;
            if (force) {
                needToRecreate = true;
            }
            else {
                for (var _i = 0, _a = this.subMeshes; _i < _a.length; _i++) {
                    var submesh = _a[_i];
                    if (submesh.indexStart + submesh.indexCount >= totalIndices) {
                        needToRecreate = true;
                        break;
                    }
                    if (submesh.verticesStart + submesh.verticesCount >= totalVertices) {
                        needToRecreate = true;
                        break;
                    }
                }
            }
            if (!needToRecreate) {
                return this.subMeshes[0];
            }
        }
        this.releaseSubMeshes();
        return new _subMesh__WEBPACK_IMPORTED_MODULE_12__["SubMesh"](0, 0, totalVertices, 0, this.getTotalIndices(), this);
    };
    /**
     * This function will subdivide the mesh into multiple submeshes
     * @param count defines the expected number of submeshes
     */
    Mesh.prototype.subdivide = function (count) {
        if (count < 1) {
            return;
        }
        var totalIndices = this.getTotalIndices();
        var subdivisionSize = (totalIndices / count) | 0;
        var offset = 0;
        // Ensure that subdivisionSize is a multiple of 3
        while (subdivisionSize % 3 !== 0) {
            subdivisionSize++;
        }
        this.releaseSubMeshes();
        for (var index = 0; index < count; index++) {
            if (offset >= totalIndices) {
                break;
            }
            _subMesh__WEBPACK_IMPORTED_MODULE_12__["SubMesh"].CreateFromIndices(0, offset, Math.min(subdivisionSize, totalIndices - offset), this);
            offset += subdivisionSize;
        }
        this.synchronizeInstances();
    };
    /**
     * Copy a FloatArray into a specific associated vertex buffer
     * @param kind defines which buffer to write to (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @param data defines the data source
     * @param updatable defines if the updated vertex buffer must be flagged as updatable
     * @param stride defines the data stride size (can be null)
     * @returns the current mesh
     */
    Mesh.prototype.setVerticesData = function (kind, data, updatable, stride) {
        if (updatable === void 0) { updatable = false; }
        if (!this._geometry) {
            var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"]();
            vertexData.set(data, kind);
            var scene = this.getScene();
            new _geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"](_geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"].RandomId(), scene, vertexData, updatable, this);
        }
        else {
            this._geometry.setVerticesData(kind, data, updatable, stride);
        }
        return this;
    };
    /**
     * Flags an associated vertex buffer as updatable
     * @param kind defines which buffer to use (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @param updatable defines if the updated vertex buffer must be flagged as updatable
     */
    Mesh.prototype.markVerticesDataAsUpdatable = function (kind, updatable) {
        if (updatable === void 0) { updatable = true; }
        var vb = this.getVertexBuffer(kind);
        if (!vb || vb.isUpdatable() === updatable) {
            return;
        }
        this.setVerticesData(kind, this.getVerticesData(kind), updatable);
    };
    /**
     * Sets the mesh global Vertex Buffer
     * @param buffer defines the buffer to use
     * @returns the current mesh
     */
    Mesh.prototype.setVerticesBuffer = function (buffer) {
        if (!this._geometry) {
            this._geometry = _geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"].CreateGeometryForMesh(this);
        }
        this._geometry.setVerticesBuffer(buffer);
        return this;
    };
    /**
     * Update a specific associated vertex buffer
     * @param kind defines which buffer to write to (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @param data defines the data source
     * @param updateExtends defines if extends info of the mesh must be updated (can be null). This is mostly useful for "position" kind
     * @param makeItUnique defines if the geometry associated with the mesh must be cloned to make the change only for this mesh (and not all meshes associated with the same geometry)
     * @returns the current mesh
     */
    Mesh.prototype.updateVerticesData = function (kind, data, updateExtends, makeItUnique) {
        if (!this._geometry) {
            return this;
        }
        if (!makeItUnique) {
            this._geometry.updateVerticesData(kind, data, updateExtends);
        }
        else {
            this.makeGeometryUnique();
            this.updateVerticesData(kind, data, updateExtends, false);
        }
        return this;
    };
    /**
     * This method updates the vertex positions of an updatable mesh according to the `positionFunction` returned values.
     * @see http://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#other-shapes-updatemeshpositions
     * @param positionFunction is a simple JS function what is passed the mesh `positions` array. It doesn't need to return anything
     * @param computeNormals is a boolean (default true) to enable/disable the mesh normal recomputation after the vertex position update
     * @returns the current mesh
     */
    Mesh.prototype.updateMeshPositions = function (positionFunction, computeNormals) {
        if (computeNormals === void 0) { computeNormals = true; }
        var positions = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind);
        if (!positions) {
            return this;
        }
        positionFunction(positions);
        this.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, positions, false, false);
        if (computeNormals) {
            var indices = this.getIndices();
            var normals = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind);
            if (!normals) {
                return this;
            }
            _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ComputeNormals(positions, indices, normals);
            this.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, normals, false, false);
        }
        return this;
    };
    /**
     * Creates a un-shared specific occurence of the geometry for the mesh.
     * @returns the current mesh
     */
    Mesh.prototype.makeGeometryUnique = function () {
        if (!this._geometry) {
            return this;
        }
        var oldGeometry = this._geometry;
        var geometry = this._geometry.copy(_geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"].RandomId());
        oldGeometry.releaseForMesh(this, true);
        geometry.applyToMesh(this);
        return this;
    };
    /**
     * Set the index buffer of this mesh
     * @param indices defines the source data
     * @param totalVertices defines the total number of vertices referenced by this index data (can be null)
     * @param updatable defines if the updated index buffer must be flagged as updatable (default is false)
     * @returns the current mesh
     */
    Mesh.prototype.setIndices = function (indices, totalVertices, updatable) {
        if (totalVertices === void 0) { totalVertices = null; }
        if (updatable === void 0) { updatable = false; }
        if (!this._geometry) {
            var vertexData = new _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"]();
            vertexData.indices = indices;
            var scene = this.getScene();
            new _geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"](_geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"].RandomId(), scene, vertexData, updatable, this);
        }
        else {
            this._geometry.setIndices(indices, totalVertices, updatable);
        }
        return this;
    };
    /**
     * Update the current index buffer
     * @param indices defines the source data
     * @param offset defines the offset in the index buffer where to store the new data (can be null)
     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)
     * @returns the current mesh
     */
    Mesh.prototype.updateIndices = function (indices, offset, gpuMemoryOnly) {
        if (gpuMemoryOnly === void 0) { gpuMemoryOnly = false; }
        if (!this._geometry) {
            return this;
        }
        this._geometry.updateIndices(indices, offset, gpuMemoryOnly);
        return this;
    };
    /**
     * Invert the geometry to move from a right handed system to a left handed one.
     * @returns the current mesh
     */
    Mesh.prototype.toLeftHanded = function () {
        if (!this._geometry) {
            return this;
        }
        this._geometry.toLeftHanded();
        return this;
    };
    /** @hidden */
    Mesh.prototype._bind = function (subMesh, effect, fillMode) {
        if (!this._geometry) {
            return this;
        }
        var engine = this.getScene().getEngine();
        // Wireframe
        var indexToBind;
        if (this._unIndexed) {
            indexToBind = null;
        }
        else {
            switch (fillMode) {
                case _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].PointFillMode:
                    indexToBind = null;
                    break;
                case _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].WireFrameFillMode:
                    indexToBind = subMesh._getLinesIndexBuffer(this.getIndices(), engine);
                    break;
                default:
                case _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].TriangleFillMode:
                    indexToBind = this._geometry.getIndexBuffer();
                    break;
            }
        }
        // VBOs
        this._geometry._bind(effect, indexToBind);
        return this;
    };
    /** @hidden */
    Mesh.prototype._draw = function (subMesh, fillMode, instancesCount) {
        if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
            return this;
        }
        if (this._internalMeshDataInfo._onBeforeDrawObservable) {
            this._internalMeshDataInfo._onBeforeDrawObservable.notifyObservers(this);
        }
        var scene = this.getScene();
        var engine = scene.getEngine();
        if (this._unIndexed || fillMode == _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].PointFillMode) {
            // or triangles as points
            engine.drawArraysType(fillMode, subMesh.verticesStart, subMesh.verticesCount, instancesCount);
        }
        else if (fillMode == _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].WireFrameFillMode) {
            // Triangles as wireframe
            engine.drawElementsType(fillMode, 0, subMesh._linesIndexCount, instancesCount);
        }
        else {
            engine.drawElementsType(fillMode, subMesh.indexStart, subMesh.indexCount, instancesCount);
        }
        return this;
    };
    /**
     * Registers for this mesh a javascript function called just before the rendering process
     * @param func defines the function to call before rendering this mesh
     * @returns the current mesh
     */
    Mesh.prototype.registerBeforeRender = function (func) {
        this.onBeforeRenderObservable.add(func);
        return this;
    };
    /**
     * Disposes a previously registered javascript function called before the rendering
     * @param func defines the function to remove
     * @returns the current mesh
     */
    Mesh.prototype.unregisterBeforeRender = function (func) {
        this.onBeforeRenderObservable.removeCallback(func);
        return this;
    };
    /**
     * Registers for this mesh a javascript function called just after the rendering is complete
     * @param func defines the function to call after rendering this mesh
     * @returns the current mesh
     */
    Mesh.prototype.registerAfterRender = function (func) {
        this.onAfterRenderObservable.add(func);
        return this;
    };
    /**
     * Disposes a previously registered javascript function called after the rendering.
     * @param func defines the function to remove
     * @returns the current mesh
     */
    Mesh.prototype.unregisterAfterRender = function (func) {
        this.onAfterRenderObservable.removeCallback(func);
        return this;
    };
    /** @hidden */
    Mesh.prototype._getInstancesRenderList = function (subMeshId) {
        if (this._instanceDataStorage.isFrozen && this._instanceDataStorage.previousBatch) {
            return this._instanceDataStorage.previousBatch;
        }
        var scene = this.getScene();
        var isInIntermediateRendering = scene._isInIntermediateRendering();
        var onlyForInstances = isInIntermediateRendering ? this._internalAbstractMeshDataInfo._onlyForInstancesIntermediate : this._internalAbstractMeshDataInfo._onlyForInstances;
        var batchCache = this._instanceDataStorage.batchCache;
        batchCache.mustReturn = false;
        batchCache.renderSelf[subMeshId] = !onlyForInstances && this.isEnabled() && this.isVisible;
        batchCache.visibleInstances[subMeshId] = null;
        if (this._instanceDataStorage.visibleInstances) {
            var visibleInstances = this._instanceDataStorage.visibleInstances;
            var currentRenderId = scene.getRenderId();
            var defaultRenderId = (isInIntermediateRendering ? visibleInstances.intermediateDefaultRenderId : visibleInstances.defaultRenderId);
            batchCache.visibleInstances[subMeshId] = visibleInstances[currentRenderId];
            if (!batchCache.visibleInstances[subMeshId] && defaultRenderId) {
                batchCache.visibleInstances[subMeshId] = visibleInstances[defaultRenderId];
            }
        }
        batchCache.hardwareInstancedRendering[subMeshId] = this._instanceDataStorage.hardwareInstancedRendering && (batchCache.visibleInstances[subMeshId] !== null) && (batchCache.visibleInstances[subMeshId] !== undefined);
        this._instanceDataStorage.previousBatch = batchCache;
        return batchCache;
    };
    /** @hidden */
    Mesh.prototype._renderWithInstances = function (subMesh, fillMode, batch, effect, engine) {
        var visibleInstances = batch.visibleInstances[subMesh._id];
        if (!visibleInstances) {
            return this;
        }
        var instanceStorage = this._instanceDataStorage;
        var currentInstancesBufferSize = instanceStorage.instancesBufferSize;
        var instancesBuffer = instanceStorage.instancesBuffer;
        var matricesCount = visibleInstances.length + 1;
        var bufferSize = matricesCount * 16 * 4;
        while (instanceStorage.instancesBufferSize < bufferSize) {
            instanceStorage.instancesBufferSize *= 2;
        }
        if (!instanceStorage.instancesData || currentInstancesBufferSize != instanceStorage.instancesBufferSize) {
            instanceStorage.instancesData = new Float32Array(instanceStorage.instancesBufferSize / 4);
        }
        var offset = 0;
        var instancesCount = 0;
        var world = this._effectiveMesh.getWorldMatrix();
        if (batch.renderSelf[subMesh._id]) {
            world.copyToArray(instanceStorage.instancesData, offset);
            offset += 16;
            instancesCount++;
        }
        if (visibleInstances) {
            for (var instanceIndex = 0; instanceIndex < visibleInstances.length; instanceIndex++) {
                var instance = visibleInstances[instanceIndex];
                instance.getWorldMatrix().copyToArray(instanceStorage.instancesData, offset);
                offset += 16;
                instancesCount++;
            }
        }
        if (!instancesBuffer || currentInstancesBufferSize != instanceStorage.instancesBufferSize) {
            if (instancesBuffer) {
                instancesBuffer.dispose();
            }
            instancesBuffer = new _buffer__WEBPACK_IMPORTED_MODULE_8__["Buffer"](engine, instanceStorage.instancesData, true, 16, false, true);
            instanceStorage.instancesBuffer = instancesBuffer;
            this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world0", 0, 4));
            this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world1", 4, 4));
            this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world2", 8, 4));
            this.setVerticesBuffer(instancesBuffer.createVertexBuffer("world3", 12, 4));
        }
        else {
            instancesBuffer.updateDirectly(instanceStorage.instancesData, 0, instancesCount);
        }
        this._bind(subMesh, effect, fillMode);
        this._draw(subMesh, fillMode, instancesCount);
        engine.unbindInstanceAttributes();
        return this;
    };
    /** @hidden */
    Mesh.prototype._processRendering = function (subMesh, effect, fillMode, batch, hardwareInstancedRendering, onBeforeDraw, effectiveMaterial) {
        var scene = this.getScene();
        var engine = scene.getEngine();
        if (hardwareInstancedRendering) {
            this._renderWithInstances(subMesh, fillMode, batch, effect, engine);
        }
        else {
            if (batch.renderSelf[subMesh._id]) {
                // Draw
                if (onBeforeDraw) {
                    onBeforeDraw(false, this._effectiveMesh.getWorldMatrix(), effectiveMaterial);
                }
                this._draw(subMesh, fillMode, this._instanceDataStorage.overridenInstanceCount);
            }
            var visibleInstancesForSubMesh = batch.visibleInstances[subMesh._id];
            if (visibleInstancesForSubMesh) {
                for (var instanceIndex = 0; instanceIndex < visibleInstancesForSubMesh.length; instanceIndex++) {
                    var instance = visibleInstancesForSubMesh[instanceIndex];
                    // World
                    var world = instance.getWorldMatrix();
                    if (onBeforeDraw) {
                        onBeforeDraw(true, world, effectiveMaterial);
                    }
                    // Draw
                    this._draw(subMesh, fillMode);
                }
            }
        }
        return this;
    };
    /** @hidden */
    Mesh.prototype._rebuild = function () {
        if (this._instanceDataStorage.instancesBuffer) {
            // Dispose instance buffer to be recreated in _renderWithInstances when rendered
            this._instanceDataStorage.instancesBuffer.dispose();
            this._instanceDataStorage.instancesBuffer = null;
        }
        _super.prototype._rebuild.call(this);
    };
    /** @hidden */
    Mesh.prototype._freeze = function () {
        if (!this.subMeshes) {
            return;
        }
        // Prepare batches
        for (var index = 0; index < this.subMeshes.length; index++) {
            this._getInstancesRenderList(index);
        }
        this._effectiveMaterial = null;
        this._instanceDataStorage.isFrozen = true;
    };
    /** @hidden */
    Mesh.prototype._unFreeze = function () {
        this._instanceDataStorage.isFrozen = false;
        this._instanceDataStorage.previousBatch = null;
    };
    /**
     * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
     * @param subMesh defines the subMesh to render
     * @param enableAlphaMode defines if alpha mode can be changed
     * @returns the current mesh
     */
    Mesh.prototype.render = function (subMesh, enableAlphaMode) {
        var scene = this.getScene();
        if (scene._isInIntermediateRendering()) {
            this._internalAbstractMeshDataInfo._isActiveIntermediate = false;
        }
        else {
            this._internalAbstractMeshDataInfo._isActive = false;
        }
        if (this._checkOcclusionQuery()) {
            return this;
        }
        // Managing instances
        var batch = this._getInstancesRenderList(subMesh._id);
        if (batch.mustReturn) {
            return this;
        }
        // Checking geometry state
        if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
            return this;
        }
        if (this._internalMeshDataInfo._onBeforeRenderObservable) {
            this._internalMeshDataInfo._onBeforeRenderObservable.notifyObservers(this);
        }
        var engine = scene.getEngine();
        var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
        var instanceDataStorage = this._instanceDataStorage;
        var material = subMesh.getMaterial();
        if (!material) {
            return this;
        }
        // Material
        if (!instanceDataStorage.isFrozen || !this._effectiveMaterial || this._effectiveMaterial !== material) {
            this._effectiveMaterial = material;
            if (this._effectiveMaterial._storeEffectOnSubMeshes) {
                if (!this._effectiveMaterial.isReadyForSubMesh(this, subMesh, hardwareInstancedRendering)) {
                    return this;
                }
            }
            else if (!this._effectiveMaterial.isReady(this, hardwareInstancedRendering)) {
                return this;
            }
        }
        // Alpha mode
        if (enableAlphaMode) {
            engine.setAlphaMode(this._effectiveMaterial.alphaMode);
        }
        for (var _i = 0, _a = scene._beforeRenderingMeshStage; _i < _a.length; _i++) {
            var step = _a[_i];
            step.action(this, subMesh, batch);
        }
        var effect;
        if (this._effectiveMaterial._storeEffectOnSubMeshes) {
            effect = subMesh.effect;
        }
        else {
            effect = this._effectiveMaterial.getEffect();
        }
        if (!effect) {
            return this;
        }
        var effectiveMesh = this._effectiveMesh;
        var sideOrientation;
        if (!instanceDataStorage.isFrozen) {
            sideOrientation = this.overrideMaterialSideOrientation;
            if (sideOrientation == null) {
                sideOrientation = this._effectiveMaterial.sideOrientation;
            }
            if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
                sideOrientation = (sideOrientation === _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].ClockWiseSideOrientation ? _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].CounterClockWiseSideOrientation : _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].ClockWiseSideOrientation);
            }
            instanceDataStorage.sideOrientation = sideOrientation;
        }
        else {
            sideOrientation = instanceDataStorage.sideOrientation;
        }
        var reverse = this._effectiveMaterial._preBind(effect, sideOrientation);
        if (this._effectiveMaterial.forceDepthWrite) {
            engine.setDepthWrite(true);
        }
        // Bind
        var fillMode = scene.forcePointsCloud ? _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].PointFillMode : (scene.forceWireframe ? _Materials_material__WEBPACK_IMPORTED_MODULE_14__["Material"].WireFrameFillMode : this._effectiveMaterial.fillMode);
        if (this._internalMeshDataInfo._onBeforeBindObservable) {
            this._internalMeshDataInfo._onBeforeBindObservable.notifyObservers(this);
        }
        if (!hardwareInstancedRendering) { // Binding will be done later because we need to add more info to the VB
            this._bind(subMesh, effect, fillMode);
        }
        var world = effectiveMesh.getWorldMatrix();
        if (this._effectiveMaterial._storeEffectOnSubMeshes) {
            this._effectiveMaterial.bindForSubMesh(world, this, subMesh);
        }
        else {
            this._effectiveMaterial.bind(world, this);
        }
        if (!this._effectiveMaterial.backFaceCulling && this._effectiveMaterial.separateCullingPass) {
            engine.setState(true, this._effectiveMaterial.zOffset, false, !reverse);
            this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
            engine.setState(true, this._effectiveMaterial.zOffset, false, reverse);
        }
        // Draw
        this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
        // Unbind
        this._effectiveMaterial.unbind();
        for (var _b = 0, _c = scene._afterRenderingMeshStage; _b < _c.length; _b++) {
            var step = _c[_b];
            step.action(this, subMesh, batch);
        }
        if (this._internalMeshDataInfo._onAfterRenderObservable) {
            this._internalMeshDataInfo._onAfterRenderObservable.notifyObservers(this);
        }
        return this;
    };
    Mesh.prototype._onBeforeDraw = function (isInstance, world, effectiveMaterial) {
        if (isInstance && effectiveMaterial) {
            effectiveMaterial.bindOnlyWorldMatrix(world);
        }
    };
    /**
     *   Renormalize the mesh and patch it up if there are no weights
     *   Similar to normalization by adding the weights compute the reciprocal and multiply all elements, this wil ensure that everything adds to 1.
     *   However in the case of zero weights then we set just a single influence to 1.
     *   We check in the function for extra's present and if so we use the normalizeSkinWeightsWithExtras rather than the FourWeights version.
     */
    Mesh.prototype.cleanMatrixWeights = function () {
        if (this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind)) {
            if (this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsExtraKind)) {
                this.normalizeSkinWeightsAndExtra();
            }
            else {
                this.normalizeSkinFourWeights();
            }
        }
    };
    // faster 4 weight version.
    Mesh.prototype.normalizeSkinFourWeights = function () {
        var matricesWeights = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind);
        var numWeights = matricesWeights.length;
        for (var a = 0; a < numWeights; a += 4) {
            // accumulate weights
            var t = matricesWeights[a] + matricesWeights[a + 1] + matricesWeights[a + 2] + matricesWeights[a + 3];
            // check for invalid weight and just set it to 1.
            if (t === 0) {
                matricesWeights[a] = 1;
            }
            else {
                // renormalize so everything adds to 1 use reciprical
                var recip = 1 / t;
                matricesWeights[a] *= recip;
                matricesWeights[a + 1] *= recip;
                matricesWeights[a + 2] *= recip;
                matricesWeights[a + 3] *= recip;
            }
        }
        this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind, matricesWeights);
    };
    // handle special case of extra verts.  (in theory gltf can handle 12 influences)
    Mesh.prototype.normalizeSkinWeightsAndExtra = function () {
        var matricesWeightsExtra = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsExtraKind);
        var matricesWeights = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind);
        var numWeights = matricesWeights.length;
        for (var a = 0; a < numWeights; a += 4) {
            // accumulate weights
            var t = matricesWeights[a] + matricesWeights[a + 1] + matricesWeights[a + 2] + matricesWeights[a + 3];
            t += matricesWeightsExtra[a] + matricesWeightsExtra[a + 1] + matricesWeightsExtra[a + 2] + matricesWeightsExtra[a + 3];
            // check for invalid weight and just set it to 1.
            if (t === 0) {
                matricesWeights[a] = 1;
            }
            else {
                // renormalize so everything adds to 1 use reciprical
                var recip = 1 / t;
                matricesWeights[a] *= recip;
                matricesWeights[a + 1] *= recip;
                matricesWeights[a + 2] *= recip;
                matricesWeights[a + 3] *= recip;
                // same goes for extras
                matricesWeightsExtra[a] *= recip;
                matricesWeightsExtra[a + 1] *= recip;
                matricesWeightsExtra[a + 2] *= recip;
                matricesWeightsExtra[a + 3] *= recip;
            }
        }
        this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind, matricesWeights);
        this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind, matricesWeightsExtra);
    };
    /**
     * ValidateSkinning is used to determine that a mesh has valid skinning data along with skin metrics, if missing weights,
     * or not normalized it is returned as invalid mesh the string can be used for console logs, or on screen messages to let
     * the user know there was an issue with importing the mesh
     * @returns a validation object with skinned, valid and report string
     */
    Mesh.prototype.validateSkinning = function () {
        var matricesWeightsExtra = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsExtraKind);
        var matricesWeights = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind);
        if (matricesWeights === null || this.skeleton == null) {
            return { skinned: false, valid: true, report: "not skinned" };
        }
        var numWeights = matricesWeights.length;
        var numberNotSorted = 0;
        var missingWeights = 0;
        var maxUsedWeights = 0;
        var numberNotNormalized = 0;
        var numInfluences = matricesWeightsExtra === null ? 4 : 8;
        var usedWeightCounts = new Array();
        for (var a = 0; a <= numInfluences; a++) {
            usedWeightCounts[a] = 0;
        }
        var toleranceEpsilon = 0.001;
        for (var a = 0; a < numWeights; a += 4) {
            var lastWeight = matricesWeights[a];
            var t = lastWeight;
            var usedWeights = t === 0 ? 0 : 1;
            for (var b = 1; b < numInfluences; b++) {
                var d = b < 4 ? matricesWeights[a + b] : matricesWeightsExtra[a + b - 4];
                if (d > lastWeight) {
                    numberNotSorted++;
                }
                if (d !== 0) {
                    usedWeights++;
                }
                t += d;
                lastWeight = d;
            }
            // count the buffer weights usage
            usedWeightCounts[usedWeights]++;
            // max influences
            if (usedWeights > maxUsedWeights) {
                maxUsedWeights = usedWeights;
            }
            // check for invalid weight and just set it to 1.
            if (t === 0) {
                missingWeights++;
            }
            else {
                // renormalize so everything adds to 1 use reciprical
                var recip = 1 / t;
                var tolerance = 0;
                for (b = 0; b < numInfluences; b++) {
                    if (b < 4) {
                        tolerance += Math.abs(matricesWeights[a + b] - (matricesWeights[a + b] * recip));
                    }
                    else {
                        tolerance += Math.abs(matricesWeightsExtra[a + b - 4] - (matricesWeightsExtra[a + b - 4] * recip));
                    }
                }
                // arbitary epsilon value for dicdating not normalized
                if (tolerance > toleranceEpsilon) {
                    numberNotNormalized++;
                }
            }
        }
        // validate bone indices are in range of the skeleton
        var numBones = this.skeleton.bones.length;
        var matricesIndices = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesIndicesKind);
        var matricesIndicesExtra = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesIndicesExtraKind);
        var numBadBoneIndices = 0;
        for (var a = 0; a < numWeights; a++) {
            for (var b = 0; b < numInfluences; b++) {
                var index = b < 4 ? matricesIndices[b] : matricesIndicesExtra[b - 4];
                if (index >= numBones || index < 0) {
                    numBadBoneIndices++;
                }
            }
        }
        // log mesh stats
        var output = "Number of Weights = " + numWeights / 4 + "\nMaximum influences = " + maxUsedWeights +
            "\nMissing Weights = " + missingWeights + "\nNot Sorted = " + numberNotSorted +
            "\nNot Normalized = " + numberNotNormalized + "\nWeightCounts = [" + usedWeightCounts + "]" +
            "\nNumber of bones = " + numBones + "\nBad Bone Indices = " + numBadBoneIndices;
        return { skinned: true, valid: missingWeights === 0 && numberNotNormalized === 0 && numBadBoneIndices === 0, report: output };
    };
    /** @hidden */
    Mesh.prototype._checkDelayState = function () {
        var scene = this.getScene();
        if (this._geometry) {
            this._geometry.load(scene);
        }
        else if (this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_NOTLOADED) {
            this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_LOADING;
            this._queueLoad(scene);
        }
        return this;
    };
    Mesh.prototype._queueLoad = function (scene) {
        var _this = this;
        scene._addPendingData(this);
        var getBinaryData = (this.delayLoadingFile.indexOf(".babylonbinarymeshdata") !== -1);
        _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].LoadFile(this.delayLoadingFile, function (data) {
            if (data instanceof ArrayBuffer) {
                _this._delayLoadingFunction(data, _this);
            }
            else {
                _this._delayLoadingFunction(JSON.parse(data), _this);
            }
            _this.instances.forEach(function (instance) {
                instance.refreshBoundingInfo();
                instance._syncSubMeshes();
            });
            _this.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_LOADED;
            scene._removePendingData(_this);
        }, function () { }, scene.offlineProvider, getBinaryData);
        return this;
    };
    /**
     * Returns `true` if the mesh is within the frustum defined by the passed array of planes.
     * A mesh is in the frustum if its bounding box intersects the frustum
     * @param frustumPlanes defines the frustum to test
     * @returns true if the mesh is in the frustum planes
     */
    Mesh.prototype.isInFrustum = function (frustumPlanes) {
        if (this.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_LOADING) {
            return false;
        }
        if (!_super.prototype.isInFrustum.call(this, frustumPlanes)) {
            return false;
        }
        this._checkDelayState();
        return true;
    };
    /**
     * Sets the mesh material by the material or multiMaterial `id` property
     * @param id is a string identifying the material or the multiMaterial
     * @returns the current mesh
     */
    Mesh.prototype.setMaterialByID = function (id) {
        var materials = this.getScene().materials;
        var index;
        for (index = materials.length - 1; index > -1; index--) {
            if (materials[index].id === id) {
                this.material = materials[index];
                return this;
            }
        }
        // Multi
        var multiMaterials = this.getScene().multiMaterials;
        for (index = multiMaterials.length - 1; index > -1; index--) {
            if (multiMaterials[index].id === id) {
                this.material = multiMaterials[index];
                return this;
            }
        }
        return this;
    };
    /**
     * Returns as a new array populated with the mesh material and/or skeleton, if any.
     * @returns an array of IAnimatable
     */
    Mesh.prototype.getAnimatables = function () {
        var results = new Array();
        if (this.material) {
            results.push(this.material);
        }
        if (this.skeleton) {
            results.push(this.skeleton);
        }
        return results;
    };
    /**
     * Modifies the mesh geometry according to the passed transformation matrix.
     * This method returns nothing but it really modifies the mesh even if it's originally not set as updatable.
     * The mesh normals are modified using the same transformation.
     * Note that, under the hood, this method sets a new VertexBuffer each call.
     * @param transform defines the transform matrix to use
     * @see http://doc.babylonjs.com/resources/baking_transformations
     * @returns the current mesh
     */
    Mesh.prototype.bakeTransformIntoVertices = function (transform) {
        // Position
        if (!this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind)) {
            return this;
        }
        var submeshes = this.subMeshes.splice(0);
        this._resetPointsArrayCache();
        var data = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind);
        var temp = new Array();
        var index;
        for (index = 0; index < data.length; index += 3) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].TransformCoordinates(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(data, index), transform).toArray(temp, index);
        }
        this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, temp, this.getVertexBuffer(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind).isUpdatable());
        // Normals
        if (this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind)) {
            data = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind);
            temp = [];
            for (index = 0; index < data.length; index += 3) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].TransformNormal(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(data, index), transform).normalize().toArray(temp, index);
            }
            this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, temp, this.getVertexBuffer(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind).isUpdatable());
        }
        // flip faces?
        if (transform.m[0] * transform.m[5] * transform.m[10] < 0) {
            this.flipFaces();
        }
        // Restore submeshes
        this.releaseSubMeshes();
        this.subMeshes = submeshes;
        return this;
    };
    /**
     * Modifies the mesh geometry according to its own current World Matrix.
     * The mesh World Matrix is then reset.
     * This method returns nothing but really modifies the mesh even if it's originally not set as updatable.
     * Note that, under the hood, this method sets a new VertexBuffer each call.
     * @see http://doc.babylonjs.com/resources/baking_transformations
     * @returns the current mesh
     */
    Mesh.prototype.bakeCurrentTransformIntoVertices = function () {
        this.bakeTransformIntoVertices(this.computeWorldMatrix(true));
        this.scaling.copyFromFloats(1, 1, 1);
        this.position.copyFromFloats(0, 0, 0);
        this.rotation.copyFromFloats(0, 0, 0);
        //only if quaternion is already set
        if (this.rotationQuaternion) {
            this.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Quaternion"].Identity();
        }
        this._worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].Identity();
        return this;
    };
    Object.defineProperty(Mesh.prototype, "_positions", {
        // Cache
        /** @hidden */
        get: function () {
            if (this._geometry) {
                return this._geometry._positions;
            }
            return null;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    Mesh.prototype._resetPointsArrayCache = function () {
        if (this._geometry) {
            this._geometry._resetPointsArrayCache();
        }
        return this;
    };
    /** @hidden */
    Mesh.prototype._generatePointsArray = function () {
        if (this._geometry) {
            return this._geometry._generatePointsArray();
        }
        return false;
    };
    /**
     * Returns a new Mesh object generated from the current mesh properties.
     * This method must not get confused with createInstance()
     * @param name is a string, the name given to the new mesh
     * @param newParent can be any Node object (default `null`)
     * @param doNotCloneChildren allows/denies the recursive cloning of the original mesh children if any (default `false`)
     * @param clonePhysicsImpostor allows/denies the cloning in the same time of the original mesh `body` used by the physics engine, if any (default `true`)
     * @returns a new mesh
     */
    Mesh.prototype.clone = function (name, newParent, doNotCloneChildren, clonePhysicsImpostor) {
        if (name === void 0) { name = ""; }
        if (newParent === void 0) { newParent = null; }
        if (clonePhysicsImpostor === void 0) { clonePhysicsImpostor = true; }
        return new Mesh(name, this.getScene(), newParent, this, doNotCloneChildren, clonePhysicsImpostor);
    };
    /**
     * Releases resources associated with this mesh.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    Mesh.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        this.morphTargetManager = null;
        if (this._geometry) {
            this._geometry.releaseForMesh(this, true);
        }
        var internalDataInfo = this._internalMeshDataInfo;
        if (internalDataInfo._onBeforeDrawObservable) {
            internalDataInfo._onBeforeDrawObservable.clear();
        }
        if (internalDataInfo._onBeforeBindObservable) {
            internalDataInfo._onBeforeBindObservable.clear();
        }
        if (internalDataInfo._onBeforeRenderObservable) {
            internalDataInfo._onBeforeRenderObservable.clear();
        }
        if (internalDataInfo._onAfterRenderObservable) {
            internalDataInfo._onAfterRenderObservable.clear();
        }
        // Sources
        if (this._scene.useClonedMeshhMap) {
            if (internalDataInfo.meshMap) {
                for (var uniqueId in internalDataInfo.meshMap) {
                    var mesh = internalDataInfo.meshMap[uniqueId];
                    if (mesh) {
                        mesh._internalMeshDataInfo._source = null;
                        internalDataInfo.meshMap[uniqueId] = undefined;
                    }
                }
            }
            if (internalDataInfo._source && internalDataInfo._source._internalMeshDataInfo.meshMap) {
                internalDataInfo._source._internalMeshDataInfo.meshMap[this.uniqueId] = undefined;
            }
        }
        else {
            var meshes = this.getScene().meshes;
            for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
                var abstractMesh = meshes_1[_i];
                var mesh = abstractMesh;
                if (mesh._internalMeshDataInfo && mesh._internalMeshDataInfo._source && mesh._internalMeshDataInfo._source === this) {
                    mesh._internalMeshDataInfo._source = null;
                }
            }
        }
        internalDataInfo._source = null;
        // Instances
        if (this._instanceDataStorage.instancesBuffer) {
            this._instanceDataStorage.instancesBuffer.dispose();
            this._instanceDataStorage.instancesBuffer = null;
        }
        while (this.instances.length) {
            this.instances[0].dispose();
        }
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    /**
     * Modifies the mesh geometry according to a displacement map.
     * A displacement map is a colored image. Each pixel color value (actually a gradient computed from red, green, blue values) will give the displacement to apply to each mesh vertex.
     * The mesh must be set as updatable. Its internal geometry is directly modified, no new buffer are allocated.
     * @param url is a string, the URL from the image file is to be downloaded.
     * @param minHeight is the lower limit of the displacement.
     * @param maxHeight is the upper limit of the displacement.
     * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
     * @param uvOffset is an optional vector2 used to offset UV.
     * @param uvScale is an optional vector2 used to scale UV.
     * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
     * @returns the Mesh.
     */
    Mesh.prototype.applyDisplacementMap = function (url, minHeight, maxHeight, onSuccess, uvOffset, uvScale, forceUpdate) {
        var _this = this;
        if (forceUpdate === void 0) { forceUpdate = false; }
        var scene = this.getScene();
        var onload = function (img) {
            // Getting height map data
            var canvas = document.createElement("canvas");
            var context = canvas.getContext("2d");
            var heightMapWidth = img.width;
            var heightMapHeight = img.height;
            canvas.width = heightMapWidth;
            canvas.height = heightMapHeight;
            context.drawImage(img, 0, 0);
            // Create VertexData from map data
            //Cast is due to wrong definition in lib.d.ts from ts 1.3 - https://github.com/Microsoft/TypeScript/issues/949
            var buffer = context.getImageData(0, 0, heightMapWidth, heightMapHeight).data;
            _this.applyDisplacementMapFromBuffer(buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight, uvOffset, uvScale, forceUpdate);
            //execute success callback, if set
            if (onSuccess) {
                onSuccess(_this);
            }
        };
        _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].LoadImage(url, onload, function () { }, scene.offlineProvider);
        return this;
    };
    /**
     * Modifies the mesh geometry according to a displacementMap buffer.
     * A displacement map is a colored image. Each pixel color value (actually a gradient computed from red, green, blue values) will give the displacement to apply to each mesh vertex.
     * The mesh must be set as updatable. Its internal geometry is directly modified, no new buffer are allocated.
     * @param buffer is a `Uint8Array` buffer containing series of `Uint8` lower than 255, the red, green, blue and alpha values of each successive pixel.
     * @param heightMapWidth is the width of the buffer image.
     * @param heightMapHeight is the height of the buffer image.
     * @param minHeight is the lower limit of the displacement.
     * @param maxHeight is the upper limit of the displacement.
     * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
     * @param uvOffset is an optional vector2 used to offset UV.
     * @param uvScale is an optional vector2 used to scale UV.
     * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
     * @returns the Mesh.
     */
    Mesh.prototype.applyDisplacementMapFromBuffer = function (buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight, uvOffset, uvScale, forceUpdate) {
        if (forceUpdate === void 0) { forceUpdate = false; }
        if (!this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind)
            || !this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind)
            || !this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UVKind)) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Warn("Cannot call applyDisplacementMap: Given mesh is not complete. Position, Normal or UV are missing");
            return this;
        }
        var positions = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, true, true);
        var normals = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind);
        var uvs = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UVKind);
        var position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
        var normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
        var uv = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"].Zero();
        uvOffset = uvOffset || _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"].Zero();
        uvScale = uvScale || new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"](1, 1);
        for (var index = 0; index < positions.length; index += 3) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArrayToRef(positions, index, position);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArrayToRef(normals, index, normal);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"].FromArrayToRef(uvs, (index / 3) * 2, uv);
            // Compute height
            var u = ((Math.abs(uv.x * uvScale.x + uvOffset.x) * heightMapWidth) % heightMapWidth) | 0;
            var v = ((Math.abs(uv.y * uvScale.y + uvOffset.y) * heightMapHeight) % heightMapHeight) | 0;
            var pos = (u + v * heightMapWidth) * 4;
            var r = buffer[pos] / 255.0;
            var g = buffer[pos + 1] / 255.0;
            var b = buffer[pos + 2] / 255.0;
            var gradient = r * 0.3 + g * 0.59 + b * 0.11;
            normal.normalize();
            normal.scaleInPlace(minHeight + (maxHeight - minHeight) * gradient);
            position = position.add(normal);
            position.toArray(positions, index);
        }
        _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ComputeNormals(positions, this.getIndices(), normals);
        if (forceUpdate) {
            this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, positions);
            this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, normals);
        }
        else {
            this.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, positions);
            this.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, normals);
        }
        return this;
    };
    /**
     * Modify the mesh to get a flat shading rendering.
     * This means each mesh facet will then have its own normals. Usually new vertices are added in the mesh geometry to get this result.
     * Warning : the mesh is really modified even if not set originally as updatable and, under the hood, a new VertexBuffer is allocated.
     * @returns current mesh
     */
    Mesh.prototype.convertToFlatShadedMesh = function () {
        var kinds = this.getVerticesDataKinds();
        var vbs = {};
        var data = {};
        var newdata = {};
        var updatableNormals = false;
        var kindIndex;
        var kind;
        for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
            kind = kinds[kindIndex];
            var vertexBuffer = this.getVertexBuffer(kind);
            if (kind === _buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind) {
                updatableNormals = vertexBuffer.isUpdatable();
                kinds.splice(kindIndex, 1);
                kindIndex--;
                continue;
            }
            vbs[kind] = vertexBuffer;
            data[kind] = vbs[kind].getData();
            newdata[kind] = [];
        }
        // Save previous submeshes
        var previousSubmeshes = this.subMeshes.slice(0);
        var indices = this.getIndices();
        var totalIndices = this.getTotalIndices();
        // Generating unique vertices per face
        var index;
        for (index = 0; index < totalIndices; index++) {
            var vertexIndex = indices[index];
            for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
                kind = kinds[kindIndex];
                var stride = vbs[kind].getStrideSize();
                for (var offset = 0; offset < stride; offset++) {
                    newdata[kind].push(data[kind][vertexIndex * stride + offset]);
                }
            }
        }
        // Updating faces & normal
        var normals = [];
        var positions = newdata[_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind];
        for (index = 0; index < totalIndices; index += 3) {
            indices[index] = index;
            indices[index + 1] = index + 1;
            indices[index + 2] = index + 2;
            var p1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(positions, index * 3);
            var p2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(positions, (index + 1) * 3);
            var p3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(positions, (index + 2) * 3);
            var p1p2 = p1.subtract(p2);
            var p3p2 = p3.subtract(p2);
            var normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Normalize(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Cross(p1p2, p3p2));
            // Store same normals for every vertex
            for (var localIndex = 0; localIndex < 3; localIndex++) {
                normals.push(normal.x);
                normals.push(normal.y);
                normals.push(normal.z);
            }
        }
        this.setIndices(indices);
        this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, normals, updatableNormals);
        // Updating vertex buffers
        for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
            kind = kinds[kindIndex];
            this.setVerticesData(kind, newdata[kind], vbs[kind].isUpdatable());
        }
        // Updating submeshes
        this.releaseSubMeshes();
        for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
            var previousOne = previousSubmeshes[submeshIndex];
            _subMesh__WEBPACK_IMPORTED_MODULE_12__["SubMesh"].AddToMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
        }
        this.synchronizeInstances();
        return this;
    };
    /**
     * This method removes all the mesh indices and add new vertices (duplication) in order to unfold facets into buffers.
     * In other words, more vertices, no more indices and a single bigger VBO.
     * The mesh is really modified even if not set originally as updatable. Under the hood, a new VertexBuffer is allocated.
     * @returns current mesh
     */
    Mesh.prototype.convertToUnIndexedMesh = function () {
        var kinds = this.getVerticesDataKinds();
        var vbs = {};
        var data = {};
        var newdata = {};
        var kindIndex;
        var kind;
        for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
            kind = kinds[kindIndex];
            var vertexBuffer = this.getVertexBuffer(kind);
            vbs[kind] = vertexBuffer;
            data[kind] = vbs[kind].getData();
            newdata[kind] = [];
        }
        // Save previous submeshes
        var previousSubmeshes = this.subMeshes.slice(0);
        var indices = this.getIndices();
        var totalIndices = this.getTotalIndices();
        // Generating unique vertices per face
        var index;
        for (index = 0; index < totalIndices; index++) {
            var vertexIndex = indices[index];
            for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
                kind = kinds[kindIndex];
                var stride = vbs[kind].getStrideSize();
                for (var offset = 0; offset < stride; offset++) {
                    newdata[kind].push(data[kind][vertexIndex * stride + offset]);
                }
            }
        }
        // Updating indices
        for (index = 0; index < totalIndices; index += 3) {
            indices[index] = index;
            indices[index + 1] = index + 1;
            indices[index + 2] = index + 2;
        }
        this.setIndices(indices);
        // Updating vertex buffers
        for (kindIndex = 0; kindIndex < kinds.length; kindIndex++) {
            kind = kinds[kindIndex];
            this.setVerticesData(kind, newdata[kind], vbs[kind].isUpdatable());
        }
        // Updating submeshes
        this.releaseSubMeshes();
        for (var submeshIndex = 0; submeshIndex < previousSubmeshes.length; submeshIndex++) {
            var previousOne = previousSubmeshes[submeshIndex];
            _subMesh__WEBPACK_IMPORTED_MODULE_12__["SubMesh"].AddToMesh(previousOne.materialIndex, previousOne.indexStart, previousOne.indexCount, previousOne.indexStart, previousOne.indexCount, this);
        }
        this._unIndexed = true;
        this.synchronizeInstances();
        return this;
    };
    /**
     * Inverses facet orientations.
     * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.
     * @param flipNormals will also inverts the normals
     * @returns current mesh
     */
    Mesh.prototype.flipFaces = function (flipNormals) {
        if (flipNormals === void 0) { flipNormals = false; }
        var vertex_data = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ExtractFromMesh(this);
        var i;
        if (flipNormals && this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind) && vertex_data.normals) {
            for (i = 0; i < vertex_data.normals.length; i++) {
                vertex_data.normals[i] *= -1;
            }
        }
        if (vertex_data.indices) {
            var temp;
            for (i = 0; i < vertex_data.indices.length; i += 3) {
                // reassign indices
                temp = vertex_data.indices[i + 1];
                vertex_data.indices[i + 1] = vertex_data.indices[i + 2];
                vertex_data.indices[i + 2] = temp;
            }
        }
        vertex_data.applyToMesh(this, this.isVertexBufferUpdatable(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind));
        return this;
    };
    /**
     * Increase the number of facets and hence vertices in a mesh
     * Vertex normals are interpolated from existing vertex normals
     * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.
     * @param numberPerEdge the number of new vertices to add to each edge of a facet, optional default 1
     */
    Mesh.prototype.increaseVertices = function (numberPerEdge) {
        var vertex_data = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ExtractFromMesh(this);
        var uvs = vertex_data.uvs;
        var currentIndices = vertex_data.indices;
        var positions = vertex_data.positions;
        var normals = vertex_data.normals;
        if (currentIndices === null || positions === null || normals === null || uvs === null) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Warn("VertexData contains null entries");
        }
        else {
            var segments = numberPerEdge + 1; //segments per current facet edge, become sides of new facets
            var tempIndices = new Array();
            for (var i = 0; i < segments + 1; i++) {
                tempIndices[i] = new Array();
            }
            var a; //vertex index of one end of a side
            var b; //vertex index of other end of the side
            var deltaPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"](0, 0, 0);
            var deltaNormal = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"](0, 0, 0);
            var deltaUV = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"](0, 0);
            var indices = new Array();
            var vertexIndex = new Array();
            var side = new Array();
            var len;
            var positionPtr = positions.length;
            var uvPtr = uvs.length;
            for (var i = 0; i < currentIndices.length; i += 3) {
                vertexIndex[0] = currentIndices[i];
                vertexIndex[1] = currentIndices[i + 1];
                vertexIndex[2] = currentIndices[i + 2];
                for (var j = 0; j < 3; j++) {
                    a = vertexIndex[j];
                    b = vertexIndex[(j + 1) % 3];
                    if (side[a] === undefined && side[b] === undefined) {
                        side[a] = new Array();
                        side[b] = new Array();
                    }
                    else {
                        if (side[a] === undefined) {
                            side[a] = new Array();
                        }
                        if (side[b] === undefined) {
                            side[b] = new Array();
                        }
                    }
                    if (side[a][b] === undefined && side[b][a] === undefined) {
                        side[a][b] = [];
                        deltaPosition.x = (positions[3 * b] - positions[3 * a]) / segments;
                        deltaPosition.y = (positions[3 * b + 1] - positions[3 * a + 1]) / segments;
                        deltaPosition.z = (positions[3 * b + 2] - positions[3 * a + 2]) / segments;
                        deltaNormal.x = (normals[3 * b] - normals[3 * a]) / segments;
                        deltaNormal.y = (normals[3 * b + 1] - normals[3 * a + 1]) / segments;
                        deltaNormal.z = (normals[3 * b + 2] - normals[3 * a + 2]) / segments;
                        deltaUV.x = (uvs[2 * b] - uvs[2 * a]) / segments;
                        deltaUV.y = (uvs[2 * b + 1] - uvs[2 * a + 1]) / segments;
                        side[a][b].push(a);
                        for (var k = 1; k < segments; k++) {
                            side[a][b].push(positions.length / 3);
                            positions[positionPtr] = positions[3 * a] + k * deltaPosition.x;
                            normals[positionPtr++] = normals[3 * a] + k * deltaNormal.x;
                            positions[positionPtr] = positions[3 * a + 1] + k * deltaPosition.y;
                            normals[positionPtr++] = normals[3 * a + 1] + k * deltaNormal.y;
                            positions[positionPtr] = positions[3 * a + 2] + k * deltaPosition.z;
                            normals[positionPtr++] = normals[3 * a + 2] + k * deltaNormal.z;
                            uvs[uvPtr++] = uvs[2 * a] + k * deltaUV.x;
                            uvs[uvPtr++] = uvs[2 * a + 1] + k * deltaUV.y;
                        }
                        side[a][b].push(b);
                        side[b][a] = new Array();
                        len = side[a][b].length;
                        for (var idx = 0; idx < len; idx++) {
                            side[b][a][idx] = side[a][b][len - 1 - idx];
                        }
                    }
                }
                //Calculate positions, normals and uvs of new internal vertices
                tempIndices[0][0] = currentIndices[i];
                tempIndices[1][0] = side[currentIndices[i]][currentIndices[i + 1]][1];
                tempIndices[1][1] = side[currentIndices[i]][currentIndices[i + 2]][1];
                for (var k = 2; k < segments; k++) {
                    tempIndices[k][0] = side[currentIndices[i]][currentIndices[i + 1]][k];
                    tempIndices[k][k] = side[currentIndices[i]][currentIndices[i + 2]][k];
                    deltaPosition.x = (positions[3 * tempIndices[k][k]] - positions[3 * tempIndices[k][0]]) / k;
                    deltaPosition.y = (positions[3 * tempIndices[k][k] + 1] - positions[3 * tempIndices[k][0] + 1]) / k;
                    deltaPosition.z = (positions[3 * tempIndices[k][k] + 2] - positions[3 * tempIndices[k][0] + 2]) / k;
                    deltaNormal.x = (normals[3 * tempIndices[k][k]] - normals[3 * tempIndices[k][0]]) / k;
                    deltaNormal.y = (normals[3 * tempIndices[k][k] + 1] - normals[3 * tempIndices[k][0] + 1]) / k;
                    deltaNormal.z = (normals[3 * tempIndices[k][k] + 2] - normals[3 * tempIndices[k][0] + 2]) / k;
                    deltaUV.x = (uvs[2 * tempIndices[k][k]] - uvs[2 * tempIndices[k][0]]) / k;
                    deltaUV.y = (uvs[2 * tempIndices[k][k] + 1] - uvs[2 * tempIndices[k][0] + 1]) / k;
                    for (var j = 1; j < k; j++) {
                        tempIndices[k][j] = positions.length / 3;
                        positions[positionPtr] = positions[3 * tempIndices[k][0]] + j * deltaPosition.x;
                        normals[positionPtr++] = normals[3 * tempIndices[k][0]] + j * deltaNormal.x;
                        positions[positionPtr] = positions[3 * tempIndices[k][0] + 1] + j * deltaPosition.y;
                        normals[positionPtr++] = normals[3 * tempIndices[k][0] + 1] + j * deltaNormal.y;
                        positions[positionPtr] = positions[3 * tempIndices[k][0] + 2] + j * deltaPosition.z;
                        normals[positionPtr++] = normals[3 * tempIndices[k][0] + 2] + j * deltaNormal.z;
                        uvs[uvPtr++] = uvs[2 * tempIndices[k][0]] + j * deltaUV.x;
                        uvs[uvPtr++] = uvs[2 * tempIndices[k][0] + 1] + j * deltaUV.y;
                    }
                }
                tempIndices[segments] = side[currentIndices[i + 1]][currentIndices[i + 2]];
                // reform indices
                indices.push(tempIndices[0][0], tempIndices[1][0], tempIndices[1][1]);
                for (var k = 1; k < segments; k++) {
                    for (var j = 0; j < k; j++) {
                        indices.push(tempIndices[k][j], tempIndices[k + 1][j], tempIndices[k + 1][j + 1]);
                        indices.push(tempIndices[k][j], tempIndices[k + 1][j + 1], tempIndices[k][j + 1]);
                    }
                    indices.push(tempIndices[k][j], tempIndices[k + 1][j], tempIndices[k + 1][j + 1]);
                }
            }
            vertex_data.indices = indices;
            vertex_data.applyToMesh(this, this.isVertexBufferUpdatable(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind));
        }
    };
    /**
     * Force adjacent facets to share vertices and remove any facets that have all vertices in a line
     * This will undo any application of covertToFlatShadedMesh
     * Warning : the mesh is really modified even if not set originally as updatable. A new VertexBuffer is created under the hood each call.
     */
    Mesh.prototype.forceSharedVertices = function () {
        var vertex_data = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ExtractFromMesh(this);
        var currentUVs = vertex_data.uvs;
        var currentIndices = vertex_data.indices;
        var currentPositions = vertex_data.positions;
        var currentColors = vertex_data.colors;
        if (currentIndices === void 0 || currentPositions === void 0 || currentIndices === null || currentPositions === null) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Warn("VertexData contains empty entries");
        }
        else {
            var positions = new Array();
            var indices = new Array();
            var uvs = new Array();
            var colors = new Array();
            var pstring = new Array(); //lists facet vertex positions (a,b,c) as string "a|b|c"
            var indexPtr = 0; // pointer to next available index value
            var uniquePositions = new Array(); // unique vertex positions
            var ptr; // pointer to element in uniquePositions
            var facet;
            for (var i = 0; i < currentIndices.length; i += 3) {
                facet = [currentIndices[i], currentIndices[i + 1], currentIndices[i + 2]]; //facet vertex indices
                pstring = new Array();
                for (var j = 0; j < 3; j++) {
                    pstring[j] = "";
                    for (var k = 0; k < 3; k++) {
                        //small values make 0
                        if (Math.abs(currentPositions[3 * facet[j] + k]) < 0.00000001) {
                            currentPositions[3 * facet[j] + k] = 0;
                        }
                        pstring[j] += currentPositions[3 * facet[j] + k] + "|";
                    }
                    pstring[j] = pstring[j].slice(0, -1);
                }
                //check facet vertices to see that none are repeated
                // do not process any facet that has a repeated vertex, ie is a line
                if (!(pstring[0] == pstring[1] || pstring[0] == pstring[2] || pstring[1] == pstring[2])) {
                    //for each facet position check if already listed in uniquePositions
                    // if not listed add to uniquePositions and set index pointer
                    // if listed use its index in uniquePositions and new index pointer
                    for (var j = 0; j < 3; j++) {
                        ptr = uniquePositions.indexOf(pstring[j]);
                        if (ptr < 0) {
                            uniquePositions.push(pstring[j]);
                            ptr = indexPtr++;
                            //not listed so add individual x, y, z coordinates to positions
                            for (var k = 0; k < 3; k++) {
                                positions.push(currentPositions[3 * facet[j] + k]);
                            }
                            if (currentColors !== null && currentColors !== void 0) {
                                for (var k = 0; k < 4; k++) {
                                    colors.push(currentColors[4 * facet[j] + k]);
                                }
                            }
                            if (currentUVs !== null && currentUVs !== void 0) {
                                for (var k = 0; k < 2; k++) {
                                    uvs.push(currentUVs[2 * facet[j] + k]);
                                }
                            }
                        }
                        // add new index pointer to indices array
                        indices.push(ptr);
                    }
                }
            }
            var normals = new Array();
            _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ComputeNormals(positions, indices, normals);
            //create new vertex data object and update
            vertex_data.positions = positions;
            vertex_data.indices = indices;
            vertex_data.normals = normals;
            if (currentUVs !== null && currentUVs !== void 0) {
                vertex_data.uvs = uvs;
            }
            if (currentColors !== null && currentColors !== void 0) {
                vertex_data.colors = colors;
            }
            vertex_data.applyToMesh(this, this.isVertexBufferUpdatable(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind));
        }
    };
    // Instances
    /** @hidden */
    Mesh._instancedMeshFactory = function (name, mesh) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("InstancedMesh");
    };
    /** @hidden */
    Mesh._PhysicsImpostorParser = function (scene, physicObject, jsonObject) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("PhysicsImpostor");
    };
    /**
     * Creates a new InstancedMesh object from the mesh model.
     * @see http://doc.babylonjs.com/how_to/how_to_use_instances
     * @param name defines the name of the new instance
     * @returns a new InstancedMesh
     */
    Mesh.prototype.createInstance = function (name) {
        return Mesh._instancedMeshFactory(name, this);
    };
    /**
     * Synchronises all the mesh instance submeshes to the current mesh submeshes, if any.
     * After this call, all the mesh instances have the same submeshes than the current mesh.
     * @returns the current mesh
     */
    Mesh.prototype.synchronizeInstances = function () {
        for (var instanceIndex = 0; instanceIndex < this.instances.length; instanceIndex++) {
            var instance = this.instances[instanceIndex];
            instance._syncSubMeshes();
        }
        return this;
    };
    /**
     * Optimization of the mesh's indices, in case a mesh has duplicated vertices.
     * The function will only reorder the indices and will not remove unused vertices to avoid problems with submeshes.
     * This should be used together with the simplification to avoid disappearing triangles.
     * @param successCallback an optional success callback to be called after the optimization finished.
     * @returns the current mesh
     */
    Mesh.prototype.optimizeIndices = function (successCallback) {
        var _this = this;
        var indices = this.getIndices();
        var positions = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind);
        if (!positions || !indices) {
            return this;
        }
        var vectorPositions = new Array();
        for (var pos = 0; pos < positions.length; pos = pos + 3) {
            vectorPositions.push(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(positions, pos));
        }
        var dupes = new Array();
        _Misc_tools__WEBPACK_IMPORTED_MODULE_2__["AsyncLoop"].SyncAsyncForLoop(vectorPositions.length, 40, function (iteration) {
            var realPos = vectorPositions.length - 1 - iteration;
            var testedPosition = vectorPositions[realPos];
            for (var j = 0; j < realPos; ++j) {
                var againstPosition = vectorPositions[j];
                if (testedPosition.equals(againstPosition)) {
                    dupes[realPos] = j;
                    break;
                }
            }
        }, function () {
            for (var i = 0; i < indices.length; ++i) {
                indices[i] = dupes[indices[i]] || indices[i];
            }
            //indices are now reordered
            var originalSubMeshes = _this.subMeshes.slice(0);
            _this.setIndices(indices);
            _this.subMeshes = originalSubMeshes;
            if (successCallback) {
                successCallback(_this);
            }
        });
        return this;
    };
    /**
     * Serialize current mesh
     * @param serializationObject defines the object which will receive the serialization data
     */
    Mesh.prototype.serialize = function (serializationObject) {
        serializationObject.name = this.name;
        serializationObject.id = this.id;
        serializationObject.type = this.getClassName();
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"] && _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].HasTags(this)) {
            serializationObject.tags = _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].GetTags(this);
        }
        serializationObject.position = this.position.asArray();
        if (this.rotationQuaternion) {
            serializationObject.rotationQuaternion = this.rotationQuaternion.asArray();
        }
        else if (this.rotation) {
            serializationObject.rotation = this.rotation.asArray();
        }
        serializationObject.scaling = this.scaling.asArray();
        if (this._postMultiplyPivotMatrix) {
            serializationObject.pivotMatrix = this.getPivotMatrix().asArray();
        }
        else {
            serializationObject.localMatrix = this.getPivotMatrix().asArray();
        }
        serializationObject.isEnabled = this.isEnabled(false);
        serializationObject.isVisible = this.isVisible;
        serializationObject.infiniteDistance = this.infiniteDistance;
        serializationObject.pickable = this.isPickable;
        serializationObject.receiveShadows = this.receiveShadows;
        serializationObject.billboardMode = this.billboardMode;
        serializationObject.visibility = this.visibility;
        serializationObject.checkCollisions = this.checkCollisions;
        serializationObject.isBlocker = this.isBlocker;
        // Parent
        if (this.parent) {
            serializationObject.parentId = this.parent.id;
        }
        // Geometry
        serializationObject.isUnIndexed = this.isUnIndexed;
        var geometry = this._geometry;
        if (geometry) {
            var geometryId = geometry.id;
            serializationObject.geometryId = geometryId;
            // SubMeshes
            serializationObject.subMeshes = [];
            for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
                var subMesh = this.subMeshes[subIndex];
                serializationObject.subMeshes.push({
                    materialIndex: subMesh.materialIndex,
                    verticesStart: subMesh.verticesStart,
                    verticesCount: subMesh.verticesCount,
                    indexStart: subMesh.indexStart,
                    indexCount: subMesh.indexCount
                });
            }
        }
        // Material
        if (this.material) {
            if (!this.material.doNotSerialize) {
                serializationObject.materialId = this.material.id;
            }
        }
        else {
            this.material = null;
        }
        // Morph targets
        if (this.morphTargetManager) {
            serializationObject.morphTargetManagerId = this.morphTargetManager.uniqueId;
        }
        // Skeleton
        if (this.skeleton) {
            serializationObject.skeletonId = this.skeleton.id;
        }
        // Physics
        //TODO implement correct serialization for physics impostors.
        if (this.getScene()._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_22__["SceneComponentConstants"].NAME_PHYSICSENGINE)) {
            var impostor = this.getPhysicsImpostor();
            if (impostor) {
                serializationObject.physicsMass = impostor.getParam("mass");
                serializationObject.physicsFriction = impostor.getParam("friction");
                serializationObject.physicsRestitution = impostor.getParam("mass");
                serializationObject.physicsImpostor = impostor.type;
            }
        }
        // Metadata
        if (this.metadata) {
            serializationObject.metadata = this.metadata;
        }
        // Instances
        serializationObject.instances = [];
        for (var index = 0; index < this.instances.length; index++) {
            var instance = this.instances[index];
            if (instance.doNotSerialize) {
                continue;
            }
            var serializationInstance = {
                name: instance.name,
                id: instance.id,
                position: instance.position.asArray(),
                scaling: instance.scaling.asArray()
            };
            if (instance.parent) {
                serializationInstance.parentId = instance.parent.id;
            }
            if (instance.rotationQuaternion) {
                serializationInstance.rotationQuaternion = instance.rotationQuaternion.asArray();
            }
            else if (instance.rotation) {
                serializationInstance.rotation = instance.rotation.asArray();
            }
            serializationObject.instances.push(serializationInstance);
            // Animations
            _Misc_decorators__WEBPACK_IMPORTED_MODULE_18__["SerializationHelper"].AppendSerializedAnimations(instance, serializationInstance);
            serializationInstance.ranges = instance.serializeAnimationRanges();
        }
        //
        // Animations
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_18__["SerializationHelper"].AppendSerializedAnimations(this, serializationObject);
        serializationObject.ranges = this.serializeAnimationRanges();
        // Layer mask
        serializationObject.layerMask = this.layerMask;
        // Alpha
        serializationObject.alphaIndex = this.alphaIndex;
        serializationObject.hasVertexAlpha = this.hasVertexAlpha;
        // Overlay
        serializationObject.overlayAlpha = this.overlayAlpha;
        serializationObject.overlayColor = this.overlayColor.asArray();
        serializationObject.renderOverlay = this.renderOverlay;
        // Fog
        serializationObject.applyFog = this.applyFog;
        // Action Manager
        if (this.actionManager) {
            serializationObject.actions = this.actionManager.serialize(this.name);
        }
    };
    /** @hidden */
    Mesh.prototype._syncGeometryWithMorphTargetManager = function () {
        if (!this.geometry) {
            return;
        }
        this._markSubMeshesAsAttributesDirty();
        var morphTargetManager = this._internalMeshDataInfo._morphTargetManager;
        if (morphTargetManager && morphTargetManager.vertexCount) {
            if (morphTargetManager.vertexCount !== this.getTotalVertices()) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Error("Mesh is incompatible with morph targets. Targets and mesh must all have the same vertices count.");
                this.morphTargetManager = null;
                return;
            }
            for (var index = 0; index < morphTargetManager.numInfluencers; index++) {
                var morphTarget = morphTargetManager.getActiveTarget(index);
                var positions = morphTarget.getPositions();
                if (!positions) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Error("Invalid morph target. Target must have positions.");
                    return;
                }
                this.geometry.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind + index, positions, false, 3);
                var normals = morphTarget.getNormals();
                if (normals) {
                    this.geometry.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind + index, normals, false, 3);
                }
                var tangents = morphTarget.getTangents();
                if (tangents) {
                    this.geometry.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].TangentKind + index, tangents, false, 3);
                }
                var uvs = morphTarget.getUVs();
                if (uvs) {
                    this.geometry.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UVKind + "_" + index, uvs, false, 2);
                }
            }
        }
        else {
            var index = 0;
            // Positions
            while (this.geometry.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind + index)) {
                this.geometry.removeVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind + index);
                if (this.geometry.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind + index)) {
                    this.geometry.removeVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind + index);
                }
                if (this.geometry.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].TangentKind + index)) {
                    this.geometry.removeVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].TangentKind + index);
                }
                if (this.geometry.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UVKind + index)) {
                    this.geometry.removeVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UVKind + "_" + index);
                }
                index++;
            }
        }
    };
    /**
     * Returns a new Mesh object parsed from the source provided.
     * @param parsedMesh is the source
     * @param scene defines the hosting scene
     * @param rootUrl is the root URL to prefix the `delayLoadingFile` property with
     * @returns a new Mesh
     */
    Mesh.Parse = function (parsedMesh, scene, rootUrl) {
        var mesh;
        if (parsedMesh.type && parsedMesh.type === "GroundMesh") {
            mesh = Mesh._GroundMeshParser(parsedMesh, scene);
        }
        else {
            mesh = new Mesh(parsedMesh.name, scene);
        }
        mesh.id = parsedMesh.id;
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"]) {
            _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].AddTagsTo(mesh, parsedMesh.tags);
        }
        mesh.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedMesh.position);
        if (parsedMesh.metadata !== undefined) {
            mesh.metadata = parsedMesh.metadata;
        }
        if (parsedMesh.rotationQuaternion) {
            mesh.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Quaternion"].FromArray(parsedMesh.rotationQuaternion);
        }
        else if (parsedMesh.rotation) {
            mesh.rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedMesh.rotation);
        }
        mesh.scaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedMesh.scaling);
        if (parsedMesh.localMatrix) {
            mesh.setPreTransformMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].FromArray(parsedMesh.localMatrix));
        }
        else if (parsedMesh.pivotMatrix) {
            mesh.setPivotMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].FromArray(parsedMesh.pivotMatrix));
        }
        mesh.setEnabled(parsedMesh.isEnabled);
        mesh.isVisible = parsedMesh.isVisible;
        mesh.infiniteDistance = parsedMesh.infiniteDistance;
        mesh.showBoundingBox = parsedMesh.showBoundingBox;
        mesh.showSubMeshesBoundingBox = parsedMesh.showSubMeshesBoundingBox;
        if (parsedMesh.applyFog !== undefined) {
            mesh.applyFog = parsedMesh.applyFog;
        }
        if (parsedMesh.pickable !== undefined) {
            mesh.isPickable = parsedMesh.pickable;
        }
        if (parsedMesh.alphaIndex !== undefined) {
            mesh.alphaIndex = parsedMesh.alphaIndex;
        }
        mesh.receiveShadows = parsedMesh.receiveShadows;
        mesh.billboardMode = parsedMesh.billboardMode;
        if (parsedMesh.visibility !== undefined) {
            mesh.visibility = parsedMesh.visibility;
        }
        mesh.checkCollisions = parsedMesh.checkCollisions;
        if (parsedMesh.isBlocker !== undefined) {
            mesh.isBlocker = parsedMesh.isBlocker;
        }
        mesh._shouldGenerateFlatShading = parsedMesh.useFlatShading;
        // freezeWorldMatrix
        if (parsedMesh.freezeWorldMatrix) {
            mesh._waitingData.freezeWorldMatrix = parsedMesh.freezeWorldMatrix;
        }
        // Parent
        if (parsedMesh.parentId) {
            mesh._waitingParentId = parsedMesh.parentId;
        }
        // Actions
        if (parsedMesh.actions !== undefined) {
            mesh._waitingData.actions = parsedMesh.actions;
        }
        // Overlay
        if (parsedMesh.overlayAlpha !== undefined) {
            mesh.overlayAlpha = parsedMesh.overlayAlpha;
        }
        if (parsedMesh.overlayColor !== undefined) {
            mesh.overlayColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_6__["Color3"].FromArray(parsedMesh.overlayColor);
        }
        if (parsedMesh.renderOverlay !== undefined) {
            mesh.renderOverlay = parsedMesh.renderOverlay;
        }
        // Geometry
        mesh.isUnIndexed = !!parsedMesh.isUnIndexed;
        mesh.hasVertexAlpha = parsedMesh.hasVertexAlpha;
        if (parsedMesh.delayLoadingFile) {
            mesh.delayLoadState = _Engines_constants__WEBPACK_IMPORTED_MODULE_17__["Constants"].DELAYLOADSTATE_NOTLOADED;
            mesh.delayLoadingFile = rootUrl + parsedMesh.delayLoadingFile;
            mesh._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_13__["BoundingInfo"](_Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedMesh.boundingBoxMinimum), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedMesh.boundingBoxMaximum));
            if (parsedMesh._binaryInfo) {
                mesh._binaryInfo = parsedMesh._binaryInfo;
            }
            mesh._delayInfo = [];
            if (parsedMesh.hasUVs) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UVKind);
            }
            if (parsedMesh.hasUVs2) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UV2Kind);
            }
            if (parsedMesh.hasUVs3) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UV3Kind);
            }
            if (parsedMesh.hasUVs4) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UV4Kind);
            }
            if (parsedMesh.hasUVs5) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UV5Kind);
            }
            if (parsedMesh.hasUVs6) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].UV6Kind);
            }
            if (parsedMesh.hasColors) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].ColorKind);
            }
            if (parsedMesh.hasMatricesIndices) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesIndicesKind);
            }
            if (parsedMesh.hasMatricesWeights) {
                mesh._delayInfo.push(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind);
            }
            mesh._delayLoadingFunction = _geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"]._ImportGeometry;
            if (_Loading_sceneLoaderFlags__WEBPACK_IMPORTED_MODULE_16__["SceneLoaderFlags"].ForceFullSceneLoadingForIncremental) {
                mesh._checkDelayState();
            }
        }
        else {
            _geometry__WEBPACK_IMPORTED_MODULE_10__["Geometry"]._ImportGeometry(parsedMesh, mesh);
        }
        // Material
        if (parsedMesh.materialId) {
            mesh.setMaterialByID(parsedMesh.materialId);
        }
        else {
            mesh.material = null;
        }
        // Morph targets
        if (parsedMesh.morphTargetManagerId > -1) {
            mesh.morphTargetManager = scene.getMorphTargetManagerById(parsedMesh.morphTargetManagerId);
        }
        // Skeleton
        if (parsedMesh.skeletonId > -1) {
            mesh.skeleton = scene.getLastSkeletonByID(parsedMesh.skeletonId);
            if (parsedMesh.numBoneInfluencers) {
                mesh.numBoneInfluencers = parsedMesh.numBoneInfluencers;
            }
        }
        // Animations
        if (parsedMesh.animations) {
            for (var animationIndex = 0; animationIndex < parsedMesh.animations.length; animationIndex++) {
                var parsedAnimation = parsedMesh.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_20__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    mesh.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
            _node__WEBPACK_IMPORTED_MODULE_7__["Node"].ParseAnimationRanges(mesh, parsedMesh, scene);
        }
        if (parsedMesh.autoAnimate) {
            scene.beginAnimation(mesh, parsedMesh.autoAnimateFrom, parsedMesh.autoAnimateTo, parsedMesh.autoAnimateLoop, parsedMesh.autoAnimateSpeed || 1.0);
        }
        // Layer Mask
        if (parsedMesh.layerMask && (!isNaN(parsedMesh.layerMask))) {
            mesh.layerMask = Math.abs(parseInt(parsedMesh.layerMask));
        }
        else {
            mesh.layerMask = 0x0FFFFFFF;
        }
        // Physics
        if (parsedMesh.physicsImpostor) {
            Mesh._PhysicsImpostorParser(scene, mesh, parsedMesh);
        }
        // Levels
        if (parsedMesh.lodMeshIds) {
            mesh._waitingData.lods = {
                ids: parsedMesh.lodMeshIds,
                distances: (parsedMesh.lodDistances) ? parsedMesh.lodDistances : null,
                coverages: (parsedMesh.lodCoverages) ? parsedMesh.lodCoverages : null
            };
        }
        // Instances
        if (parsedMesh.instances) {
            for (var index = 0; index < parsedMesh.instances.length; index++) {
                var parsedInstance = parsedMesh.instances[index];
                var instance = mesh.createInstance(parsedInstance.name);
                if (parsedInstance.id) {
                    instance.id = parsedInstance.id;
                }
                if (_Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"]) {
                    if (parsedInstance.tags) {
                        _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].AddTagsTo(instance, parsedInstance.tags);
                    }
                    else {
                        _Misc_tags__WEBPACK_IMPORTED_MODULE_4__["Tags"].AddTagsTo(instance, parsedMesh.tags);
                    }
                }
                instance.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedInstance.position);
                if (parsedInstance.metadata !== undefined) {
                    instance.metadata = parsedInstance.metadata;
                }
                if (parsedInstance.parentId) {
                    instance._waitingParentId = parsedInstance.parentId;
                }
                if (parsedInstance.rotationQuaternion) {
                    instance.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Quaternion"].FromArray(parsedInstance.rotationQuaternion);
                }
                else if (parsedInstance.rotation) {
                    instance.rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedInstance.rotation);
                }
                instance.scaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].FromArray(parsedInstance.scaling);
                if (parsedInstance.checkCollisions != undefined && parsedInstance.checkCollisions != null) {
                    instance.checkCollisions = parsedInstance.checkCollisions;
                }
                if (parsedInstance.pickable != undefined && parsedInstance.pickable != null) {
                    instance.isPickable = parsedInstance.pickable;
                }
                if (parsedInstance.showBoundingBox != undefined && parsedInstance.showBoundingBox != null) {
                    instance.showBoundingBox = parsedInstance.showBoundingBox;
                }
                if (parsedInstance.showSubMeshesBoundingBox != undefined && parsedInstance.showSubMeshesBoundingBox != null) {
                    instance.showSubMeshesBoundingBox = parsedInstance.showSubMeshesBoundingBox;
                }
                if (parsedInstance.alphaIndex != undefined && parsedInstance.showSubMeshesBoundingBox != null) {
                    instance.alphaIndex = parsedInstance.alphaIndex;
                }
                // Physics
                if (parsedInstance.physicsImpostor) {
                    Mesh._PhysicsImpostorParser(scene, instance, parsedInstance);
                }
                // Animation
                if (parsedInstance.animations) {
                    for (animationIndex = 0; animationIndex < parsedInstance.animations.length; animationIndex++) {
                        parsedAnimation = parsedInstance.animations[animationIndex];
                        var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_20__["_TypeStore"].GetClass("BABYLON.Animation");
                        if (internalClass) {
                            instance.animations.push(internalClass.Parse(parsedAnimation));
                        }
                    }
                    _node__WEBPACK_IMPORTED_MODULE_7__["Node"].ParseAnimationRanges(instance, parsedInstance, scene);
                    if (parsedInstance.autoAnimate) {
                        scene.beginAnimation(instance, parsedInstance.autoAnimateFrom, parsedInstance.autoAnimateTo, parsedInstance.autoAnimateLoop, parsedInstance.autoAnimateSpeed || 1.0);
                    }
                }
            }
        }
        return mesh;
    };
    /**
     * Creates a ribbon mesh. Please consider using the same method from the MeshBuilder class instead
     * @see http://doc.babylonjs.com/how_to/parametric_shapes
     * @param name defines the name of the mesh to create
     * @param pathArray is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry.
     * @param closeArray creates a seam between the first and the last paths of the path array (default is false)
     * @param closePath creates a seam between the first and the last points of each path of the path array
     * @param offset is taken in account only if the `pathArray` is containing a single path
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @param instance defines an instance of an existing Ribbon object to be updated with the passed `pathArray` parameter (http://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#ribbon)
     * @returns a new Mesh
     */
    Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation, instance) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
      * Creates a plane polygonal mesh.  By default, this is a disc. Please consider using the same method from the MeshBuilder class instead
      * @param name defines the name of the mesh to create
      * @param radius sets the radius size (float) of the polygon (default 0.5)
      * @param tessellation sets the number of polygon sides (positive integer, default 64). So a tessellation valued to 3 will build a triangle, to 4 a square, etc
      * @param scene defines the hosting scene
      * @param updatable defines if the mesh must be flagged as updatable
      * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
      * @returns a new Mesh
      */
    Mesh.CreateDisc = function (name, radius, tessellation, scene, updatable, sideOrientation) {
        if (scene === void 0) { scene = null; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a box mesh. Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param size sets the size (float) of each box side (default 1)
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @returns a new Mesh
     */
    Mesh.CreateBox = function (name, size, scene, updatable, sideOrientation) {
        if (scene === void 0) { scene = null; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
      * Creates a sphere mesh. Please consider using the same method from the MeshBuilder class instead
      * @param name defines the name of the mesh to create
      * @param segments sets the sphere number of horizontal stripes (positive integer, default 32)
      * @param diameter sets the diameter size (float) of the sphere (default 1)
      * @param scene defines the hosting scene
      * @param updatable defines if the mesh must be flagged as updatable
      * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
      * @returns a new Mesh
      */
    Mesh.CreateSphere = function (name, segments, diameter, scene, updatable, sideOrientation) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
      * Creates a hemisphere mesh. Please consider using the same method from the MeshBuilder class instead
      * @param name defines the name of the mesh to create
      * @param segments sets the sphere number of horizontal stripes (positive integer, default 32)
      * @param diameter sets the diameter size (float) of the sphere (default 1)
      * @param scene defines the hosting scene
      * @returns a new Mesh
      */
    Mesh.CreateHemisphere = function (name, segments, diameter, scene) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a cylinder or a cone mesh. Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param height sets the height size (float) of the cylinder/cone (float, default 2)
     * @param diameterTop set the top cap diameter (floats, default 1)
     * @param diameterBottom set the bottom cap diameter (floats, default 1). This value can't be zero
     * @param tessellation sets the number of cylinder sides (positive integer, default 24). Set it to 3 to get a prism for instance
     * @param subdivisions sets the number of rings along the cylinder height (positive integer, default 1)
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @returns a new Mesh
     */
    Mesh.CreateCylinder = function (name, height, diameterTop, diameterBottom, tessellation, subdivisions, scene, updatable, sideOrientation) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    // Torus  (Code from SharpDX.org)
    /**
     * Creates a torus mesh. Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param diameter sets the diameter size (float) of the torus (default 1)
     * @param thickness sets the diameter size of the tube of the torus (float, default 0.5)
     * @param tessellation sets the number of torus sides (postive integer, default 16)
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @returns a new Mesh
     */
    Mesh.CreateTorus = function (name, diameter, thickness, tessellation, scene, updatable, sideOrientation) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a torus knot mesh. Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param radius sets the global radius size (float) of the torus knot (default 2)
     * @param tube sets the diameter size of the tube of the torus (float, default 0.5)
     * @param radialSegments sets the number of sides on each tube segments (positive integer, default 32)
     * @param tubularSegments sets the number of tubes to decompose the knot into (positive integer, default 32)
     * @param p the number of windings on X axis (positive integers, default 2)
     * @param q the number of windings on Y axis (positive integers, default 3)
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @returns a new Mesh
     */
    Mesh.CreateTorusKnot = function (name, radius, tube, radialSegments, tubularSegments, p, q, scene, updatable, sideOrientation) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a line mesh. Please consider using the same method from the MeshBuilder class instead.
     * @param name defines the name of the mesh to create
     * @param points is an array successive Vector3
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param instance is an instance of an existing LineMesh object to be updated with the passed `points` parameter (http://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#lines-and-dashedlines).
     * @returns a new Mesh
     */
    Mesh.CreateLines = function (name, points, scene, updatable, instance) {
        if (scene === void 0) { scene = null; }
        if (updatable === void 0) { updatable = false; }
        if (instance === void 0) { instance = null; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a dashed line mesh. Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param points is an array successive Vector3
     * @param dashSize is the size of the dashes relatively the dash number (positive float, default 3)
     * @param gapSize is the size of the gap between two successive dashes relatively the dash number (positive float, default 1)
     * @param dashNb is the intended total number of dashes (positive integer, default 200)
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param instance is an instance of an existing LineMesh object to be updated with the passed `points` parameter (http://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#lines-and-dashedlines)
     * @returns a new Mesh
     */
    Mesh.CreateDashedLines = function (name, points, dashSize, gapSize, dashNb, scene, updatable, instance) {
        if (scene === void 0) { scene = null; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a polygon mesh.Please consider using the same method from the MeshBuilder class instead
     * The polygon's shape will depend on the input parameters and is constructed parallel to a ground mesh.
     * The parameter `shape` is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors.
     * You can set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * Remember you can only change the shape positions, not their number when updating a polygon.
     * @see http://doc.babylonjs.com/how_to/parametric_shapes#non-regular-polygon
     * @param name defines the name of the mesh to create
     * @param shape is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors
     * @param scene defines the hosting scene
     * @param holes is a required array of arrays of successive Vector3 used to defines holes in the polygon
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @param earcutInjection can be used to inject your own earcut reference
     * @returns a new Mesh
     */
    Mesh.CreatePolygon = function (name, shape, scene, holes, updatable, sideOrientation, earcutInjection) {
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates an extruded polygon mesh, with depth in the Y direction. Please consider using the same method from the MeshBuilder class instead.
     * @see http://doc.babylonjs.com/how_to/parametric_shapes#extruded-non-regular-polygon
     * @param name defines the name of the mesh to create
     * @param shape is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors
     * @param depth defines the height of extrusion
     * @param scene defines the hosting scene
     * @param holes is a required array of arrays of successive Vector3 used to defines holes in the polygon
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @param earcutInjection can be used to inject your own earcut reference
     * @returns a new Mesh
     */
    Mesh.ExtrudePolygon = function (name, shape, depth, scene, holes, updatable, sideOrientation, earcutInjection) {
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates an extruded shape mesh.
     * The extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters. Please consider using the same method from the MeshBuilder class instead
     * @see http://doc.babylonjs.com/how_to/parametric_shapes
     * @see http://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes
     * @param name defines the name of the mesh to create
     * @param shape is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis
     * @param path is a required array of successive Vector3. This is the axis curve the shape is extruded along
     * @param scale is the value to scale the shape
     * @param rotation is the angle value to rotate the shape each step (each path point), from the former step (so rotation added each step) along the curve
     * @param cap sets the way the extruded shape is capped. Possible values : Mesh.NO_CAP (default), Mesh.CAP_START, Mesh.CAP_END, Mesh.CAP_ALL
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @param instance is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters (http://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#extruded-shape)
     * @returns a new Mesh
     */
    Mesh.ExtrudeShape = function (name, shape, path, scale, rotation, cap, scene, updatable, sideOrientation, instance) {
        if (scene === void 0) { scene = null; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates an custom extruded shape mesh.
     * The custom extrusion is a parametric shape.
     * It has no predefined shape. Its final shape will depend on the input parameters.
     * Please consider using the same method from the MeshBuilder class instead
     * @see http://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes
     * @param name defines the name of the mesh to create
     * @param shape is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis
     * @param path is a required array of successive Vector3. This is the axis curve the shape is extruded along
     * @param scaleFunction is a custom Javascript function called on each path point
     * @param rotationFunction is a custom Javascript function called on each path point
     * @param ribbonCloseArray forces the extrusion underlying ribbon to close all the paths in its `pathArray`
     * @param ribbonClosePath forces the extrusion underlying ribbon to close its `pathArray`
     * @param cap sets the way the extruded shape is capped. Possible values : Mesh.NO_CAP (default), Mesh.CAP_START, Mesh.CAP_END, Mesh.CAP_ALL
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @param instance is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters (http://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#extruded-shape)
     * @returns a new Mesh
     */
    Mesh.ExtrudeShapeCustom = function (name, shape, path, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, scene, updatable, sideOrientation, instance) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates lathe mesh.
     * The lathe is a shape with a symetry axis : a 2D model shape is rotated around this axis to design the lathe.
     * Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param shape is a required array of successive Vector3. This array depicts the shape to be rotated in its local space : the shape must be designed in the xOy plane and will be rotated around the Y axis. It's usually a 2D shape, so the Vector3 z coordinates are often set to zero
     * @param radius is the radius value of the lathe
     * @param tessellation is the side number of the lathe.
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @returns a new Mesh
     */
    Mesh.CreateLathe = function (name, shape, radius, tessellation, scene, updatable, sideOrientation) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a plane mesh. Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param size sets the size (float) of both sides of the plane at once (default 1)
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @returns a new Mesh
     */
    Mesh.CreatePlane = function (name, size, scene, updatable, sideOrientation) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a ground mesh.
     * Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param width set the width of the ground
     * @param height set the height of the ground
     * @param subdivisions sets the number of subdivisions per side
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @returns a new Mesh
     */
    Mesh.CreateGround = function (name, width, height, subdivisions, scene, updatable) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a tiled ground mesh.
     * Please consider using the same method from the MeshBuilder class instead
     * @param name defines the name of the mesh to create
     * @param xmin set the ground minimum X coordinate
     * @param zmin set the ground minimum Y coordinate
     * @param xmax set the ground maximum X coordinate
     * @param zmax set the ground maximum Z coordinate
     * @param subdivisions is an object `{w: positive integer, h: positive integer}` (default `{w: 6, h: 6}`). `w` and `h` are the numbers of subdivisions on the ground width and height. Each subdivision is called a tile
     * @param precision is an object `{w: positive integer, h: positive integer}` (default `{w: 2, h: 2}`). `w` and `h` are the numbers of subdivisions on the ground width and height of each tile
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @returns a new Mesh
     */
    Mesh.CreateTiledGround = function (name, xmin, zmin, xmax, zmax, subdivisions, precision, scene, updatable) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a ground mesh from a height map.
     * Please consider using the same method from the MeshBuilder class instead
     * @see http://doc.babylonjs.com/babylon101/height_map
     * @param name defines the name of the mesh to create
     * @param url sets the URL of the height map image resource
     * @param width set the ground width size
     * @param height set the ground height size
     * @param subdivisions sets the number of subdivision per side
     * @param minHeight is the minimum altitude on the ground
     * @param maxHeight is the maximum altitude on the ground
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param onReady  is a callback function that will be called  once the mesh is built (the height map download can last some time)
     * @param alphaFilter will filter any data where the alpha channel is below this value, defaults 0 (all data visible)
     * @returns a new Mesh
     */
    Mesh.CreateGroundFromHeightMap = function (name, url, width, height, subdivisions, minHeight, maxHeight, scene, updatable, onReady, alphaFilter) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a tube mesh.
     * The tube is a parametric shape.
     * It has no predefined shape. Its final shape will depend on the input parameters.
     * Please consider using the same method from the MeshBuilder class instead
     * @see http://doc.babylonjs.com/how_to/parametric_shapes
     * @param name defines the name of the mesh to create
     * @param path is a required array of successive Vector3. It is the curve used as the axis of the tube
     * @param radius sets the tube radius size
     * @param tessellation is the number of sides on the tubular surface
     * @param radiusFunction is a custom function. If it is not null, it overwrittes the parameter `radius`. This function is called on each point of the tube path and is passed the index `i` of the i-th point and the distance of this point from the first point of the path
     * @param cap sets the way the extruded shape is capped. Possible values : Mesh.NO_CAP (default), Mesh.CAP_START, Mesh.CAP_END, Mesh.CAP_ALL
     * @param scene defines the hosting scene
     * @param updatable defines if the mesh must be flagged as updatable
     * @param sideOrientation defines the mesh side orientation (http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation)
     * @param instance is an instance of an existing Tube object to be updated with the passed `pathArray` parameter (http://doc.babylonjs.com/how_to/How_to_dynamically_morph_a_mesh#tube)
     * @returns a new Mesh
     */
    Mesh.CreateTube = function (name, path, radius, tessellation, radiusFunction, cap, scene, updatable, sideOrientation, instance) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
      * Creates a polyhedron mesh.
      * Please consider using the same method from the MeshBuilder class instead.
      * * The parameter `type` (positive integer, max 14, default 0) sets the polyhedron type to build among the 15 embbeded types. Please refer to the type sheet in the tutorial to choose the wanted type
      * * The parameter `size` (positive float, default 1) sets the polygon size
      * * You can overwrite the `size` on each dimension bu using the parameters `sizeX`, `sizeY` or `sizeZ` (positive floats, default to `size` value)
      * * You can build other polyhedron types than the 15 embbeded ones by setting the parameter `custom` (`polyhedronObject`, default null). If you set the parameter `custom`, this overwrittes the parameter `type`
      * * A `polyhedronObject` is a formatted javascript object. You'll find a full file with pre-set polyhedra here : https://github.com/BabylonJS/Extensions/tree/master/Polyhedron
      * * You can set the color and the UV of each side of the polyhedron with the parameters `faceColors` (Color4, default `(1, 1, 1, 1)`) and faceUV (Vector4, default `(0, 0, 1, 1)`)
      * * To understand how to set `faceUV` or `faceColors`, please read this by considering the right number of faces of your polyhedron, instead of only 6 for the box : https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
      * * The parameter `flat` (boolean, default true). If set to false, it gives the polyhedron a single global face, so less vertices and shared normals. In this case, `faceColors` and `faceUV` are ignored
      * * You can also set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
      * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
      * @param name defines the name of the mesh to create
      * @param options defines the options used to create the mesh
      * @param scene defines the hosting scene
      * @returns a new Mesh
      */
    Mesh.CreatePolyhedron = function (name, options, scene) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a sphere based upon an icosahedron with 20 triangular faces which can be subdivided
     * * The parameter `radius` sets the radius size (float) of the icosphere (default 1)
     * * You can set some different icosphere dimensions, for instance to build an ellipsoid, by using the parameters `radiusX`, `radiusY` and `radiusZ` (all by default have the same value than `radius`)
     * * The parameter `subdivisions` sets the number of subdivisions (postive integer, default 4). The more subdivisions, the more faces on the icosphere whatever its size
     * * The parameter `flat` (boolean, default true) gives each side its own normals. Set it to false to get a smooth continuous light reflection on the surface
     * * You can also set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : http://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns a new Mesh
     * @see http://doc.babylonjs.com/how_to/polyhedra_shapes#icosphere
     */
    Mesh.CreateIcoSphere = function (name, options, scene) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    /**
     * Creates a decal mesh.
     * Please consider using the same method from the MeshBuilder class instead.
     * A decal is a mesh usually applied as a model onto the surface of another mesh
     * @param name  defines the name of the mesh
     * @param sourceMesh defines the mesh receiving the decal
     * @param position sets the position of the decal in world coordinates
     * @param normal sets the normal of the mesh where the decal is applied onto in world coordinates
     * @param size sets the decal scaling
     * @param angle sets the angle to rotate the decal
     * @returns a new Mesh
     */
    Mesh.CreateDecal = function (name, sourceMesh, position, normal, size, angle) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("MeshBuilder");
    };
    // Skeletons
    /**
     * Prepare internal position array for software CPU skinning
     * @returns original positions used for CPU skinning. Useful for integrating Morphing with skeletons in same mesh
     */
    Mesh.prototype.setPositionsForCPUSkinning = function () {
        var internalDataInfo = this._internalMeshDataInfo;
        if (!internalDataInfo._sourcePositions) {
            var source = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind);
            if (!source) {
                return internalDataInfo._sourcePositions;
            }
            internalDataInfo._sourcePositions = new Float32Array(source);
            if (!this.isVertexBufferUpdatable(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind)) {
                this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, source, true);
            }
        }
        return internalDataInfo._sourcePositions;
    };
    /**
     * Prepare internal normal array for software CPU skinning
     * @returns original normals used for CPU skinning. Useful for integrating Morphing with skeletons in same mesh.
     */
    Mesh.prototype.setNormalsForCPUSkinning = function () {
        var internalDataInfo = this._internalMeshDataInfo;
        if (!internalDataInfo._sourceNormals) {
            var source = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind);
            if (!source) {
                return internalDataInfo._sourceNormals;
            }
            internalDataInfo._sourceNormals = new Float32Array(source);
            if (!this.isVertexBufferUpdatable(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind)) {
                this.setVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, source, true);
            }
        }
        return internalDataInfo._sourceNormals;
    };
    /**
     * Updates the vertex buffer by applying transformation from the bones
     * @param skeleton defines the skeleton to apply to current mesh
     * @returns the current mesh
     */
    Mesh.prototype.applySkeleton = function (skeleton) {
        if (!this.geometry) {
            return this;
        }
        if (this.geometry._softwareSkinningFrameId == this.getScene().getFrameId()) {
            return this;
        }
        this.geometry._softwareSkinningFrameId = this.getScene().getFrameId();
        if (!this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind)) {
            return this;
        }
        if (!this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind)) {
            return this;
        }
        if (!this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesIndicesKind)) {
            return this;
        }
        if (!this.isVerticesDataPresent(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind)) {
            return this;
        }
        var internalDataInfo = this._internalMeshDataInfo;
        if (!internalDataInfo._sourcePositions) {
            var submeshes = this.subMeshes.slice();
            this.setPositionsForCPUSkinning();
            this.subMeshes = submeshes;
        }
        if (!internalDataInfo._sourceNormals) {
            this.setNormalsForCPUSkinning();
        }
        // positionsData checks for not being Float32Array will only pass at most once
        var positionsData = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind);
        if (!positionsData) {
            return this;
        }
        if (!(positionsData instanceof Float32Array)) {
            positionsData = new Float32Array(positionsData);
        }
        // normalsData checks for not being Float32Array will only pass at most once
        var normalsData = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind);
        if (!normalsData) {
            return this;
        }
        if (!(normalsData instanceof Float32Array)) {
            normalsData = new Float32Array(normalsData);
        }
        var matricesIndicesData = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesIndicesKind);
        var matricesWeightsData = this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsKind);
        if (!matricesWeightsData || !matricesIndicesData) {
            return this;
        }
        var needExtras = this.numBoneInfluencers > 4;
        var matricesIndicesExtraData = needExtras ? this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesIndicesExtraKind) : null;
        var matricesWeightsExtraData = needExtras ? this.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].MatricesWeightsExtraKind) : null;
        var skeletonMatrices = skeleton.getTransformMatrices(this);
        var tempVector3 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero();
        var finalMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"]();
        var tempMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"]();
        var matWeightIdx = 0;
        var inf;
        for (var index = 0; index < positionsData.length; index += 3, matWeightIdx += 4) {
            var weight;
            for (inf = 0; inf < 4; inf++) {
                weight = matricesWeightsData[matWeightIdx + inf];
                if (weight > 0) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[matWeightIdx + inf] * 16), weight, tempMatrix);
                    finalMatrix.addToSelf(tempMatrix);
                }
            }
            if (needExtras) {
                for (inf = 0; inf < 4; inf++) {
                    weight = matricesWeightsExtraData[matWeightIdx + inf];
                    if (weight > 0) {
                        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Matrix"].FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[matWeightIdx + inf] * 16), weight, tempMatrix);
                        finalMatrix.addToSelf(tempMatrix);
                    }
                }
            }
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].TransformCoordinatesFromFloatsToRef(internalDataInfo._sourcePositions[index], internalDataInfo._sourcePositions[index + 1], internalDataInfo._sourcePositions[index + 2], finalMatrix, tempVector3);
            tempVector3.toArray(positionsData, index);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].TransformNormalFromFloatsToRef(internalDataInfo._sourceNormals[index], internalDataInfo._sourceNormals[index + 1], internalDataInfo._sourceNormals[index + 2], finalMatrix, tempVector3);
            tempVector3.toArray(normalsData, index);
            finalMatrix.reset();
        }
        this.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].PositionKind, positionsData);
        this.updateVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_8__["VertexBuffer"].NormalKind, normalsData);
        return this;
    };
    // Tools
    /**
     * Returns an object containing a min and max Vector3 which are the minimum and maximum vectors of each mesh bounding box from the passed array, in the world coordinates
     * @param meshes defines the list of meshes to scan
     * @returns an object `{min:` Vector3`, max:` Vector3`}`
     */
    Mesh.MinMax = function (meshes) {
        var minVector = null;
        var maxVector = null;
        meshes.forEach(function (mesh) {
            var boundingInfo = mesh.getBoundingInfo();
            var boundingBox = boundingInfo.boundingBox;
            if (!minVector || !maxVector) {
                minVector = boundingBox.minimumWorld;
                maxVector = boundingBox.maximumWorld;
            }
            else {
                minVector.minimizeInPlace(boundingBox.minimumWorld);
                maxVector.maximizeInPlace(boundingBox.maximumWorld);
            }
        });
        if (!minVector || !maxVector) {
            return {
                min: _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero(),
                max: _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Zero()
            };
        }
        return {
            min: minVector,
            max: maxVector
        };
    };
    /**
     * Returns the center of the `{min:` Vector3`, max:` Vector3`}` or the center of MinMax vector3 computed from a mesh array
     * @param meshesOrMinMaxVector could be an array of meshes or a `{min:` Vector3`, max:` Vector3`}` object
     * @returns a vector3
     */
    Mesh.Center = function (meshesOrMinMaxVector) {
        var minMaxVector = (meshesOrMinMaxVector instanceof Array) ? Mesh.MinMax(meshesOrMinMaxVector) : meshesOrMinMaxVector;
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"].Center(minMaxVector.min, minMaxVector.max);
    };
    /**
     * Merge the array of meshes into a single mesh for performance reasons.
     * @param meshes defines he vertices source.  They should all be of the same material.  Entries can empty
     * @param disposeSource when true (default), dispose of the vertices from the source meshes
     * @param allow32BitsIndices when the sum of the vertices > 64k, this must be set to true
     * @param meshSubclass when set, vertices inserted into this Mesh.  Meshes can then be merged into a Mesh sub-class.
     * @param subdivideWithSubMeshes when true (false default), subdivide mesh to his subMesh array with meshes source.
     * @param multiMultiMaterials when true (false default), subdivide mesh and accept multiple multi materials, ignores subdivideWithSubMeshes.
     * @returns a new mesh
     */
    Mesh.MergeMeshes = function (meshes, disposeSource, allow32BitsIndices, meshSubclass, subdivideWithSubMeshes, multiMultiMaterials) {
        if (disposeSource === void 0) { disposeSource = true; }
        var index;
        if (!allow32BitsIndices) {
            var totalVertices = 0;
            // Counting vertices
            for (index = 0; index < meshes.length; index++) {
                if (meshes[index]) {
                    totalVertices += meshes[index].getTotalVertices();
                    if (totalVertices >= 65536) {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Warn("Cannot merge meshes because resulting mesh will have more than 65536 vertices. Please use allow32BitsIndices = true to use 32 bits indices");
                        return null;
                    }
                }
            }
        }
        if (multiMultiMaterials) {
            var newMultiMaterial = null;
            var subIndex;
            var matIndex;
            subdivideWithSubMeshes = false;
        }
        var materialArray = new Array();
        var materialIndexArray = new Array();
        // Merge
        var vertexData = null;
        var otherVertexData;
        var indiceArray = new Array();
        var source = null;
        for (index = 0; index < meshes.length; index++) {
            if (meshes[index]) {
                var mesh = meshes[index];
                if (mesh.isAnInstance) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_19__["Logger"].Warn("Cannot merge instance meshes.");
                    return null;
                }
                var wm = mesh.computeWorldMatrix(true);
                otherVertexData = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].ExtractFromMesh(mesh, true, true);
                otherVertexData.transform(wm);
                if (vertexData) {
                    vertexData.merge(otherVertexData, allow32BitsIndices);
                }
                else {
                    vertexData = otherVertexData;
                    source = mesh;
                }
                if (subdivideWithSubMeshes) {
                    indiceArray.push(mesh.getTotalIndices());
                }
                if (multiMultiMaterials) {
                    if (mesh.material) {
                        var material = mesh.material;
                        if (material instanceof _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_15__["MultiMaterial"]) {
                            for (matIndex = 0; matIndex < material.subMaterials.length; matIndex++) {
                                if (materialArray.indexOf(material.subMaterials[matIndex]) < 0) {
                                    materialArray.push(material.subMaterials[matIndex]);
                                }
                            }
                            for (subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                                materialIndexArray.push(materialArray.indexOf(material.subMaterials[mesh.subMeshes[subIndex].materialIndex]));
                                indiceArray.push(mesh.subMeshes[subIndex].indexCount);
                            }
                        }
                        else {
                            if (materialArray.indexOf(material) < 0) {
                                materialArray.push(material);
                            }
                            for (subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                                materialIndexArray.push(materialArray.indexOf(material));
                                indiceArray.push(mesh.subMeshes[subIndex].indexCount);
                            }
                        }
                    }
                    else {
                        for (subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                            materialIndexArray.push(0);
                            indiceArray.push(mesh.subMeshes[subIndex].indexCount);
                        }
                    }
                }
            }
        }
        source = source;
        if (!meshSubclass) {
            meshSubclass = new Mesh(source.name + "_merged", source.getScene());
        }
        vertexData.applyToMesh(meshSubclass);
        // Setting properties
        meshSubclass.checkCollisions = source.checkCollisions;
        // Cleaning
        if (disposeSource) {
            for (index = 0; index < meshes.length; index++) {
                if (meshes[index]) {
                    meshes[index].dispose();
                }
            }
        }
        // Subdivide
        if (subdivideWithSubMeshes || multiMultiMaterials) {
            //-- removal of global submesh
            meshSubclass.releaseSubMeshes();
            index = 0;
            var offset = 0;
            //-- apply subdivision according to index table
            while (index < indiceArray.length) {
                _subMesh__WEBPACK_IMPORTED_MODULE_12__["SubMesh"].CreateFromIndices(0, offset, indiceArray[index], meshSubclass);
                offset += indiceArray[index];
                index++;
            }
        }
        if (multiMultiMaterials) {
            newMultiMaterial = new _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_15__["MultiMaterial"](source.name + "_merged", source.getScene());
            newMultiMaterial.subMaterials = materialArray;
            for (subIndex = 0; subIndex < meshSubclass.subMeshes.length; subIndex++) {
                meshSubclass.subMeshes[subIndex].materialIndex = materialIndexArray[subIndex];
            }
            meshSubclass.material = newMultiMaterial;
        }
        else {
            meshSubclass.material = source.material;
        }
        return meshSubclass;
    };
    /** @hidden */
    Mesh.prototype.addInstance = function (instance) {
        instance._indexInSourceMeshInstanceArray = this.instances.length;
        this.instances.push(instance);
    };
    /** @hidden */
    Mesh.prototype.removeInstance = function (instance) {
        // Remove from mesh
        var index = instance._indexInSourceMeshInstanceArray;
        if (index != -1) {
            if (index !== this.instances.length - 1) {
                var last = this.instances[this.instances.length - 1];
                this.instances[index] = last;
                last._indexInSourceMeshInstanceArray = index;
            }
            instance._indexInSourceMeshInstanceArray = -1;
            this.instances.pop();
        }
    };
    // Consts
    /**
     * Mesh side orientation : usually the external or front surface
     */
    Mesh.FRONTSIDE = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].FRONTSIDE;
    /**
     * Mesh side orientation : usually the internal or back surface
     */
    Mesh.BACKSIDE = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].BACKSIDE;
    /**
     * Mesh side orientation : both internal and external or front and back surfaces
     */
    Mesh.DOUBLESIDE = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].DOUBLESIDE;
    /**
     * Mesh side orientation : by default, `FRONTSIDE`
     */
    Mesh.DEFAULTSIDE = _mesh_vertexData__WEBPACK_IMPORTED_MODULE_9__["VertexData"].DEFAULTSIDE;
    /**
     * Mesh cap setting : no cap
     */
    Mesh.NO_CAP = 0;
    /**
     * Mesh cap setting : one cap at the beginning of the mesh
     */
    Mesh.CAP_START = 1;
    /**
     * Mesh cap setting : one cap at the end of the mesh
     */
    Mesh.CAP_END = 2;
    /**
     * Mesh cap setting : two caps, one at the beginning  and one at the end of the mesh
     */
    Mesh.CAP_ALL = 3;
    /**
     * Mesh pattern setting : no flip or rotate
     */
    Mesh.NO_FLIP = 0;
    /**
     * Mesh pattern setting : flip (reflect in y axis) alternate tiles on each row or column
     */
    Mesh.FLIP_TILE = 1;
    /**
     * Mesh pattern setting : rotate (180degs) alternate tiles on each row or column
     */
    Mesh.ROTATE_TILE = 2;
    /**
     * Mesh pattern setting : flip (reflect in y axis) all tiles on alternate rows
     */
    Mesh.FLIP_ROW = 3;
    /**
     * Mesh pattern setting : rotate (180degs) all tiles on alternate rows
     */
    Mesh.ROTATE_ROW = 4;
    /**
     * Mesh pattern setting : flip and rotate alternate tiles on each row or column
     */
    Mesh.FLIP_N_ROTATE_TILE = 5;
    /**
     * Mesh pattern setting : rotate pattern and rotate
     */
    Mesh.FLIP_N_ROTATE_ROW = 6;
    /**
     * Mesh tile positioning : part tiles same on left/right or top/bottom
     */
    Mesh.CENTER = 0;
    /**
     * Mesh tile positioning : part tiles on left
     */
    Mesh.LEFT = 1;
    /**
     * Mesh tile positioning : part tiles on right
     */
    Mesh.RIGHT = 2;
    /**
     * Mesh tile positioning : part tiles on top
     */
    Mesh.TOP = 3;
    /**
     * Mesh tile positioning : part tiles on bottom
     */
    Mesh.BOTTOM = 4;
    // Statics
    /** @hidden */
    Mesh._GroundMeshParser = function (parsedMesh, scene) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_21__["_DevTools"].WarnImport("GroundMesh");
    };
    return Mesh;
}(_abstractMesh__WEBPACK_IMPORTED_MODULE_11__["AbstractMesh"]));



/***/ }),

/***/ "./Meshes/mesh.vertexData.ts":
/*!***********************************!*\
  !*** ./Meshes/mesh.vertexData.ts ***!
  \***********************************/
/*! exports provided: VertexData */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VertexData", function() { return VertexData; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");




/**
 * This class contains the various kinds of data on every vertex of a mesh used in determining its shape and appearance
 */
var VertexData = /** @class */ (function () {
    function VertexData() {
    }
    /**
     * Uses the passed data array to set the set the values for the specified kind of data
     * @param data a linear array of floating numbers
     * @param kind the type of data that is being set, eg positions, colors etc
     */
    VertexData.prototype.set = function (data, kind) {
        switch (kind) {
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind:
                this.positions = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind:
                this.normals = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind:
                this.tangents = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind:
                this.uvs = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind:
                this.uvs2 = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind:
                this.uvs3 = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind:
                this.uvs4 = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind:
                this.uvs5 = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind:
                this.uvs6 = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind:
                this.colors = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind:
                this.matricesIndices = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind:
                this.matricesWeights = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind:
                this.matricesIndicesExtra = data;
                break;
            case _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind:
                this.matricesWeightsExtra = data;
                break;
        }
    };
    /**
     * Associates the vertexData to the passed Mesh.
     * Sets it as updatable or not (default `false`)
     * @param mesh the mesh the vertexData is applied to
     * @param updatable when used and having the value true allows new data to update the vertexData
     * @returns the VertexData
     */
    VertexData.prototype.applyToMesh = function (mesh, updatable) {
        this._applyTo(mesh, updatable);
        return this;
    };
    /**
     * Associates the vertexData to the passed Geometry.
     * Sets it as updatable or not (default `false`)
     * @param geometry the geometry the vertexData is applied to
     * @param updatable when used and having the value true allows new data to update the vertexData
     * @returns VertexData
     */
    VertexData.prototype.applyToGeometry = function (geometry, updatable) {
        this._applyTo(geometry, updatable);
        return this;
    };
    /**
     * Updates the associated mesh
     * @param mesh the mesh to be updated
     * @param updateExtends when true the mesh BoundingInfo will be renewed when and if position kind is updated, optional with default false
     * @param makeItUnique when true, and when and if position kind is updated, a new global geometry will be  created from these positions and set to the mesh, optional with default false
     * @returns VertexData
     */
    VertexData.prototype.updateMesh = function (mesh) {
        this._update(mesh);
        return this;
    };
    /**
     * Updates the associated geometry
     * @param geometry the geometry to be updated
     * @param updateExtends when true BoundingInfo will be renewed when and if position kind is updated, optional with default false
     * @param makeItUnique when true, and when and if position kind is updated, a new global geometry will be created from these positions and set to the mesh, optional with default false
     * @returns VertexData.
     */
    VertexData.prototype.updateGeometry = function (geometry) {
        this._update(geometry);
        return this;
    };
    VertexData.prototype._applyTo = function (meshOrGeometry, updatable) {
        if (updatable === void 0) { updatable = false; }
        if (this.positions) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, this.positions, updatable);
        }
        if (this.normals) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, this.normals, updatable);
        }
        if (this.tangents) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind, this.tangents, updatable);
        }
        if (this.uvs) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind, this.uvs, updatable);
        }
        if (this.uvs2) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind, this.uvs2, updatable);
        }
        if (this.uvs3) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind, this.uvs3, updatable);
        }
        if (this.uvs4) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind, this.uvs4, updatable);
        }
        if (this.uvs5) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind, this.uvs5, updatable);
        }
        if (this.uvs6) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind, this.uvs6, updatable);
        }
        if (this.colors) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind, this.colors, updatable);
        }
        if (this.matricesIndices) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind, this.matricesIndices, updatable);
        }
        if (this.matricesWeights) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind, this.matricesWeights, updatable);
        }
        if (this.matricesIndicesExtra) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind, this.matricesIndicesExtra, updatable);
        }
        if (this.matricesWeightsExtra) {
            meshOrGeometry.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind, this.matricesWeightsExtra, updatable);
        }
        if (this.indices) {
            meshOrGeometry.setIndices(this.indices, null, updatable);
        }
        else {
            meshOrGeometry.setIndices([], null);
        }
        return this;
    };
    VertexData.prototype._update = function (meshOrGeometry, updateExtends, makeItUnique) {
        if (this.positions) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, this.positions, updateExtends, makeItUnique);
        }
        if (this.normals) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, this.normals, updateExtends, makeItUnique);
        }
        if (this.tangents) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind, this.tangents, updateExtends, makeItUnique);
        }
        if (this.uvs) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind, this.uvs, updateExtends, makeItUnique);
        }
        if (this.uvs2) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind, this.uvs2, updateExtends, makeItUnique);
        }
        if (this.uvs3) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind, this.uvs3, updateExtends, makeItUnique);
        }
        if (this.uvs4) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind, this.uvs4, updateExtends, makeItUnique);
        }
        if (this.uvs5) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind, this.uvs5, updateExtends, makeItUnique);
        }
        if (this.uvs6) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind, this.uvs6, updateExtends, makeItUnique);
        }
        if (this.colors) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind, this.colors, updateExtends, makeItUnique);
        }
        if (this.matricesIndices) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind, this.matricesIndices, updateExtends, makeItUnique);
        }
        if (this.matricesWeights) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind, this.matricesWeights, updateExtends, makeItUnique);
        }
        if (this.matricesIndicesExtra) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind, this.matricesIndicesExtra, updateExtends, makeItUnique);
        }
        if (this.matricesWeightsExtra) {
            meshOrGeometry.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind, this.matricesWeightsExtra, updateExtends, makeItUnique);
        }
        if (this.indices) {
            meshOrGeometry.setIndices(this.indices, null);
        }
        return this;
    };
    /**
     * Transforms each position and each normal of the vertexData according to the passed Matrix
     * @param matrix the transforming matrix
     * @returns the VertexData
     */
    VertexData.prototype.transform = function (matrix) {
        var flip = matrix.m[0] * matrix.m[5] * matrix.m[10] < 0;
        var transformed = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        var index;
        if (this.positions) {
            var position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
            for (index = 0; index < this.positions.length; index += 3) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(this.positions, index, position);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(position, matrix, transformed);
                this.positions[index] = transformed.x;
                this.positions[index + 1] = transformed.y;
                this.positions[index + 2] = transformed.z;
            }
        }
        if (this.normals) {
            var normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
            for (index = 0; index < this.normals.length; index += 3) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArrayToRef(this.normals, index, normal);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormalToRef(normal, matrix, transformed);
                this.normals[index] = transformed.x;
                this.normals[index + 1] = transformed.y;
                this.normals[index + 2] = transformed.z;
            }
        }
        if (this.tangents) {
            var tangent = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"].Zero();
            var tangentTransformed = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"].Zero();
            for (index = 0; index < this.tangents.length; index += 4) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"].FromArrayToRef(this.tangents, index, tangent);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"].TransformNormalToRef(tangent, matrix, tangentTransformed);
                this.tangents[index] = tangentTransformed.x;
                this.tangents[index + 1] = tangentTransformed.y;
                this.tangents[index + 2] = tangentTransformed.z;
                this.tangents[index + 3] = tangentTransformed.w;
            }
        }
        if (flip && this.indices) {
            for (index = 0; index < this.indices.length; index += 3) {
                var tmp = this.indices[index + 1];
                this.indices[index + 1] = this.indices[index + 2];
                this.indices[index + 2] = tmp;
            }
        }
        return this;
    };
    /**
     * Merges the passed VertexData into the current one
     * @param other the VertexData to be merged into the current one
     * @param use32BitsIndices defines a boolean indicating if indices must be store in a 32 bits array
     * @returns the modified VertexData
     */
    VertexData.prototype.merge = function (other, use32BitsIndices) {
        if (use32BitsIndices === void 0) { use32BitsIndices = false; }
        this._validate();
        other._validate();
        if (!this.normals !== !other.normals ||
            !this.tangents !== !other.tangents ||
            !this.uvs !== !other.uvs ||
            !this.uvs2 !== !other.uvs2 ||
            !this.uvs3 !== !other.uvs3 ||
            !this.uvs4 !== !other.uvs4 ||
            !this.uvs5 !== !other.uvs5 ||
            !this.uvs6 !== !other.uvs6 ||
            !this.colors !== !other.colors ||
            !this.matricesIndices !== !other.matricesIndices ||
            !this.matricesWeights !== !other.matricesWeights ||
            !this.matricesIndicesExtra !== !other.matricesIndicesExtra ||
            !this.matricesWeightsExtra !== !other.matricesWeightsExtra) {
            throw new Error("Cannot merge vertex data that do not have the same set of attributes");
        }
        if (other.indices) {
            if (!this.indices) {
                this.indices = [];
            }
            var offset = this.positions ? this.positions.length / 3 : 0;
            var isSrcTypedArray = this.indices.BYTES_PER_ELEMENT !== undefined;
            if (isSrcTypedArray) {
                var len = this.indices.length + other.indices.length;
                var temp = use32BitsIndices || this.indices instanceof Uint32Array ? new Uint32Array(len) : new Uint16Array(len);
                temp.set(this.indices);
                var decal = this.indices.length;
                for (var index = 0; index < other.indices.length; index++) {
                    temp[decal + index] = other.indices[index] + offset;
                }
                this.indices = temp;
            }
            else {
                for (var index = 0; index < other.indices.length; index++) {
                    this.indices.push(other.indices[index] + offset);
                }
            }
        }
        this.positions = this._mergeElement(this.positions, other.positions);
        this.normals = this._mergeElement(this.normals, other.normals);
        this.tangents = this._mergeElement(this.tangents, other.tangents);
        this.uvs = this._mergeElement(this.uvs, other.uvs);
        this.uvs2 = this._mergeElement(this.uvs2, other.uvs2);
        this.uvs3 = this._mergeElement(this.uvs3, other.uvs3);
        this.uvs4 = this._mergeElement(this.uvs4, other.uvs4);
        this.uvs5 = this._mergeElement(this.uvs5, other.uvs5);
        this.uvs6 = this._mergeElement(this.uvs6, other.uvs6);
        this.colors = this._mergeElement(this.colors, other.colors);
        this.matricesIndices = this._mergeElement(this.matricesIndices, other.matricesIndices);
        this.matricesWeights = this._mergeElement(this.matricesWeights, other.matricesWeights);
        this.matricesIndicesExtra = this._mergeElement(this.matricesIndicesExtra, other.matricesIndicesExtra);
        this.matricesWeightsExtra = this._mergeElement(this.matricesWeightsExtra, other.matricesWeightsExtra);
        return this;
    };
    VertexData.prototype._mergeElement = function (source, other) {
        if (!source) {
            return other;
        }
        if (!other) {
            return source;
        }
        var len = other.length + source.length;
        var isSrcTypedArray = source instanceof Float32Array;
        var isOthTypedArray = other instanceof Float32Array;
        // use non-loop method when the source is Float32Array
        if (isSrcTypedArray) {
            var ret32 = new Float32Array(len);
            ret32.set(source);
            ret32.set(other, source.length);
            return ret32;
            // source is number[], when other is also use concat
        }
        else if (!isOthTypedArray) {
            return source.concat(other);
            // source is a number[], but other is a Float32Array, loop required
        }
        else {
            var ret = source.slice(0); // copy source to a separate array
            for (var i = 0, len = other.length; i < len; i++) {
                ret.push(other[i]);
            }
            return ret;
        }
    };
    VertexData.prototype._validate = function () {
        if (!this.positions) {
            throw new Error("Positions are required");
        }
        var getElementCount = function (kind, values) {
            var stride = _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].DeduceStride(kind);
            if ((values.length % stride) !== 0) {
                throw new Error("The " + kind + "s array count must be a multiple of " + stride);
            }
            return values.length / stride;
        };
        var positionsElementCount = getElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, this.positions);
        var validateElementCount = function (kind, values) {
            var elementCount = getElementCount(kind, values);
            if (elementCount !== positionsElementCount) {
                throw new Error("The " + kind + "s element count (" + elementCount + ") does not match the positions count (" + positionsElementCount + ")");
            }
        };
        if (this.normals) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, this.normals);
        }
        if (this.tangents) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind, this.tangents);
        }
        if (this.uvs) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind, this.uvs);
        }
        if (this.uvs2) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind, this.uvs2);
        }
        if (this.uvs3) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind, this.uvs3);
        }
        if (this.uvs4) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind, this.uvs4);
        }
        if (this.uvs5) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind, this.uvs5);
        }
        if (this.uvs6) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind, this.uvs6);
        }
        if (this.colors) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind, this.colors);
        }
        if (this.matricesIndices) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind, this.matricesIndices);
        }
        if (this.matricesWeights) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind, this.matricesWeights);
        }
        if (this.matricesIndicesExtra) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind, this.matricesIndicesExtra);
        }
        if (this.matricesWeightsExtra) {
            validateElementCount(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind, this.matricesWeightsExtra);
        }
    };
    /**
     * Serializes the VertexData
     * @returns a serialized object
     */
    VertexData.prototype.serialize = function () {
        var serializationObject = this.serialize();
        if (this.positions) {
            serializationObject.positions = this.positions;
        }
        if (this.normals) {
            serializationObject.normals = this.normals;
        }
        if (this.tangents) {
            serializationObject.tangents = this.tangents;
        }
        if (this.uvs) {
            serializationObject.uvs = this.uvs;
        }
        if (this.uvs2) {
            serializationObject.uvs2 = this.uvs2;
        }
        if (this.uvs3) {
            serializationObject.uvs3 = this.uvs3;
        }
        if (this.uvs4) {
            serializationObject.uvs4 = this.uvs4;
        }
        if (this.uvs5) {
            serializationObject.uvs5 = this.uvs5;
        }
        if (this.uvs6) {
            serializationObject.uvs6 = this.uvs6;
        }
        if (this.colors) {
            serializationObject.colors = this.colors;
        }
        if (this.matricesIndices) {
            serializationObject.matricesIndices = this.matricesIndices;
            serializationObject.matricesIndices._isExpanded = true;
        }
        if (this.matricesWeights) {
            serializationObject.matricesWeights = this.matricesWeights;
        }
        if (this.matricesIndicesExtra) {
            serializationObject.matricesIndicesExtra = this.matricesIndicesExtra;
            serializationObject.matricesIndicesExtra._isExpanded = true;
        }
        if (this.matricesWeightsExtra) {
            serializationObject.matricesWeightsExtra = this.matricesWeightsExtra;
        }
        serializationObject.indices = this.indices;
        return serializationObject;
    };
    // Statics
    /**
     * Extracts the vertexData from a mesh
     * @param mesh the mesh from which to extract the VertexData
     * @param copyWhenShared defines if the VertexData must be cloned when shared between multiple meshes, optional, default false
     * @param forceCopy indicating that the VertexData must be cloned, optional, default false
     * @returns the object VertexData associated to the passed mesh
     */
    VertexData.ExtractFromMesh = function (mesh, copyWhenShared, forceCopy) {
        return VertexData._ExtractFrom(mesh, copyWhenShared, forceCopy);
    };
    /**
     * Extracts the vertexData from the geometry
     * @param geometry the geometry from which to extract the VertexData
     * @param copyWhenShared defines if the VertexData must be cloned when the geometrty is shared between multiple meshes, optional, default false
     * @param forceCopy indicating that the VertexData must be cloned, optional, default false
     * @returns the object VertexData associated to the passed mesh
     */
    VertexData.ExtractFromGeometry = function (geometry, copyWhenShared, forceCopy) {
        return VertexData._ExtractFrom(geometry, copyWhenShared, forceCopy);
    };
    VertexData._ExtractFrom = function (meshOrGeometry, copyWhenShared, forceCopy) {
        var result = new VertexData();
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind)) {
            result.positions = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind)) {
            result.normals = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind)) {
            result.tangents = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind)) {
            result.uvs = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind)) {
            result.uvs2 = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind)) {
            result.uvs3 = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind)) {
            result.uvs4 = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind)) {
            result.uvs5 = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind)) {
            result.uvs6 = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind)) {
            result.colors = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind)) {
            result.matricesIndices = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind)) {
            result.matricesWeights = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind)) {
            result.matricesIndicesExtra = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind, copyWhenShared, forceCopy);
        }
        if (meshOrGeometry.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind)) {
            result.matricesWeightsExtra = meshOrGeometry.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind, copyWhenShared, forceCopy);
        }
        result.indices = meshOrGeometry.getIndices(copyWhenShared, forceCopy);
        return result;
    };
    /**
     * Creates the VertexData for a Ribbon
     * @param options an object used to set the following optional parameters for the ribbon, required but can be empty
      * * pathArray array of paths, each of which an array of successive Vector3
      * * closeArray creates a seam between the first and the last paths of the pathArray, optional, default false
      * * closePath creates a seam between the first and the last points of each path of the path array, optional, default false
      * * offset a positive integer, only used when pathArray contains a single path (offset = 10 means the point 1 is joined to the point 11), default rounded half size of the pathArray length
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
      * * invertUV swaps in the U and V coordinates when applying a texture, optional, default false
      * * uvs a linear array, of length 2 * number of vertices, of custom UV values, optional
      * * colors a linear array, of length 4 * number of vertices, of custom color values, optional
     * @returns the VertexData of the ribbon
     */
    VertexData.CreateRibbon = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("ribbonBuilder");
    };
    /**
     * Creates the VertexData for a box
     * @param options an object used to set the following optional parameters for the box, required but can be empty
      * * size sets the width, height and depth of the box to the value of size, optional default 1
      * * width sets the width (x direction) of the box, overwrites the width set by size, optional, default size
      * * height sets the height (y direction) of the box, overwrites the height set by size, optional, default size
      * * depth sets the depth (z direction) of the box, overwrites the depth set by size, optional, default size
      * * faceUV an array of 6 Vector4 elements used to set different images to each box side
      * * faceColors an array of 6 Color3 elements used to set different colors to each box side
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the box
     */
    VertexData.CreateBox = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("boxBuilder");
    };
    /**
     * Creates the VertexData for a tiled box
     * @param options an object used to set the following optional parameters for the box, required but can be empty
      * * faceTiles sets the pattern, tile size and number of tiles for a face
      * * faceUV an array of 6 Vector4 elements used to set different images to each box side
      * * faceColors an array of 6 Color3 elements used to set different colors to each box side
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * @returns the VertexData of the box
     */
    VertexData.CreateTiledBox = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("tiledBoxBuilder");
    };
    /**
     * Creates the VertexData for a tiled plane
     * @param options an object used to set the following optional parameters for the box, required but can be empty
      * * pattern a limited pattern arrangement depending on the number
      * * tileSize sets the width, height and depth of the tile to the value of size, optional default 1
      * * tileWidth sets the width (x direction) of the tile, overwrites the width set by size, optional, default size
      * * tileHeight sets the height (y direction) of the tile, overwrites the height set by size, optional, default size
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the tiled plane
     */
    VertexData.CreateTiledPlane = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("tiledPlaneBuilder");
    };
    /**
     * Creates the VertexData for an ellipsoid, defaults to a sphere
     * @param options an object used to set the following optional parameters for the box, required but can be empty
      * * segments sets the number of horizontal strips optional, default 32
      * * diameter sets the axes dimensions, diameterX, diameterY and diameterZ to the value of diameter, optional default 1
      * * diameterX sets the diameterX (x direction) of the ellipsoid, overwrites the diameterX set by diameter, optional, default diameter
      * * diameterY sets the diameterY (y direction) of the ellipsoid, overwrites the diameterY set by diameter, optional, default diameter
      * * diameterZ sets the diameterZ (z direction) of the ellipsoid, overwrites the diameterZ set by diameter, optional, default diameter
      * * arc a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the circumference (latitude) given by the arc value, optional, default 1
      * * slice a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the height (latitude) given by the arc value, optional, default 1
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the ellipsoid
     */
    VertexData.CreateSphere = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("sphereBuilder");
    };
    /**
     * Creates the VertexData for a cylinder, cone or prism
     * @param options an object used to set the following optional parameters for the box, required but can be empty
      * * height sets the height (y direction) of the cylinder, optional, default 2
      * * diameterTop sets the diameter of the top of the cone, overwrites diameter,  optional, default diameter
      * * diameterBottom sets the diameter of the bottom of the cone, overwrites diameter,  optional, default diameter
      * * diameter sets the diameter of the top and bottom of the cone, optional default 1
      * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24
      * * subdivisions` the number of rings along the cylinder height, optional, default 1
      * * arc a number from 0 to 1, to create an unclosed cylinder based on the fraction of the circumference given by the arc value, optional, default 1
      * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
      * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
      * * hasRings when true makes each subdivision independantly treated as a face for faceUV and faceColors, optional, default false
      * * enclose when true closes an open cylinder by adding extra flat faces between the height axis and vertical edges, think cut cake
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the cylinder, cone or prism
     */
    VertexData.CreateCylinder = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("cylinderBuilder");
    };
    /**
     * Creates the VertexData for a torus
     * @param options an object used to set the following optional parameters for the box, required but can be empty
      * * diameter the diameter of the torus, optional default 1
      * * thickness the diameter of the tube forming the torus, optional default 0.5
      * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the torus
     */
    VertexData.CreateTorus = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("torusBuilder");
    };
    /**
     * Creates the VertexData of the LineSystem
     * @param options an object used to set the following optional parameters for the LineSystem, required but can be empty
     *  - lines an array of lines, each line being an array of successive Vector3
     *  - colors an array of line colors, each of the line colors being an array of successive Color4, one per line point
     * @returns the VertexData of the LineSystem
     */
    VertexData.CreateLineSystem = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("linesBuilder");
    };
    /**
     * Create the VertexData for a DashedLines
     * @param options an object used to set the following optional parameters for the DashedLines, required but can be empty
     *  - points an array successive Vector3
     *  - dashSize the size of the dashes relative to the dash number, optional, default 3
     *  - gapSize the size of the gap between two successive dashes relative to the dash number, optional, default 1
     *  - dashNb the intended total number of dashes, optional, default 200
     * @returns the VertexData for the DashedLines
     */
    VertexData.CreateDashedLines = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("linesBuilder");
    };
    /**
     * Creates the VertexData for a Ground
     * @param options an object used to set the following optional parameters for the Ground, required but can be empty
     *  - width the width (x direction) of the ground, optional, default 1
     *  - height the height (z direction) of the ground, optional, default 1
     *  - subdivisions the number of subdivisions per side, optional, default 1
     * @returns the VertexData of the Ground
     */
    VertexData.CreateGround = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("groundBuilder");
    };
    /**
     * Creates the VertexData for a TiledGround by subdividing the ground into tiles
     * @param options an object used to set the following optional parameters for the Ground, required but can be empty
      * * xmin the ground minimum X coordinate, optional, default -1
      * * zmin the ground minimum Z coordinate, optional, default -1
      * * xmax the ground maximum X coordinate, optional, default 1
      * * zmax the ground maximum Z coordinate, optional, default 1
      * * subdivisions a javascript object {w: positive integer, h: positive integer}, `w` and `h` are the numbers of subdivisions on the ground width and height creating 'tiles', default {w: 6, h: 6}
      * * precision a javascript object {w: positive integer, h: positive integer}, `w` and `h` are the numbers of subdivisions on the tile width and height, default {w: 2, h: 2}
     * @returns the VertexData of the TiledGround
     */
    VertexData.CreateTiledGround = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("groundBuilder");
    };
    /**
     * Creates the VertexData of the Ground designed from a heightmap
     * @param options an object used to set the following parameters for the Ground, required and provided by MeshBuilder.CreateGroundFromHeightMap
      * * width the width (x direction) of the ground
      * * height the height (z direction) of the ground
      * * subdivisions the number of subdivisions per side
      * * minHeight the minimum altitude on the ground, optional, default 0
      * * maxHeight the maximum altitude on the ground, optional default 1
      * * colorFilter the filter to apply to the image pixel colors to compute the height, optional Color3, default (0.3, 0.59, 0.11)
      * * buffer the array holding the image color data
      * * bufferWidth the width of image
      * * bufferHeight the height of image
      * * alphaFilter Remove any data where the alpha channel is below this value, defaults 0 (all data visible)
     * @returns the VertexData of the Ground designed from a heightmap
     */
    VertexData.CreateGroundFromHeightMap = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("groundBuilder");
    };
    /**
     * Creates the VertexData for a Plane
     * @param options an object used to set the following optional parameters for the plane, required but can be empty
      * * size sets the width and height of the plane to the value of size, optional default 1
      * * width sets the width (x direction) of the plane, overwrites the width set by size, optional, default size
      * * height sets the height (y direction) of the plane, overwrites the height set by size, optional, default size
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the box
     */
    VertexData.CreatePlane = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("planeBuilder");
    };
    /**
     * Creates the VertexData of the Disc or regular Polygon
     * @param options an object used to set the following optional parameters for the disc, required but can be empty
      * * radius the radius of the disc, optional default 0.5
      * * tessellation the number of polygon sides, optional, default 64
      * * arc a number from 0 to 1, to create an unclosed polygon based on the fraction of the circumference given by the arc value, optional, default 1
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the box
     */
    VertexData.CreateDisc = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("discBuilder");
    };
    /**
     * Creates the VertexData for an irregular Polygon in the XoZ plane using a mesh built by polygonTriangulation.build()
     * All parameters are provided by MeshBuilder.CreatePolygon as needed
     * @param polygon a mesh built from polygonTriangulation.build()
     * @param sideOrientation takes the values Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * @param fUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
     * @param fColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
     * @param frontUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
     * @param backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the Polygon
     */
    VertexData.CreatePolygon = function (polygon, sideOrientation, fUV, fColors, frontUVs, backUVs) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("polygonBuilder");
    };
    /**
     * Creates the VertexData of the IcoSphere
     * @param options an object used to set the following optional parameters for the IcoSphere, required but can be empty
      * * radius the radius of the IcoSphere, optional default 1
      * * radiusX allows stretching in the x direction, optional, default radius
      * * radiusY allows stretching in the y direction, optional, default radius
      * * radiusZ allows stretching in the z direction, optional, default radius
      * * flat when true creates a flat shaded mesh, optional, default true
      * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the IcoSphere
     */
    VertexData.CreateIcoSphere = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("icoSphereBuilder");
    };
    // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
    /**
     * Creates the VertexData for a Polyhedron
     * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty
     * * type provided types are:
     *  * 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
     *  * 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)
     * * size the size of the IcoSphere, optional default 1
     * * sizeX allows stretching in the x direction, optional, default size
     * * sizeY allows stretching in the y direction, optional, default size
     * * sizeZ allows stretching in the z direction, optional, default size
     * * custom a number that overwrites the type to create from an extended set of polyhedron from https://www.babylonjs-playground.com/#21QRSK#15 with minimised editor
     * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
     * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
     * * flat when true creates a flat shaded mesh, optional, default true
     * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4
     * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
     * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the Polyhedron
     */
    VertexData.CreatePolyhedron = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("polyhedronBuilder");
    };
    // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
    /**
     * Creates the VertexData for a TorusKnot
     * @param options an object used to set the following optional parameters for the TorusKnot, required but can be empty
      * * radius the radius of the torus knot, optional, default 2
      * * tube the thickness of the tube, optional, default 0.5
      * * radialSegments the number of sides on each tube segments, optional, default 32
      * * tubularSegments the number of tubes to decompose the knot into, optional, default 32
      * * p the number of windings around the z axis, optional,  default 2
      * * q the number of windings around the x axis, optional,  default 3
      * * sideOrientation optional and takes the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
      * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
      * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
     * @returns the VertexData of the Torus Knot
     */
    VertexData.CreateTorusKnot = function (options) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("torusKnotBuilder");
    };
    // Tools
    /**
     * Compute normals for given positions and indices
     * @param positions an array of vertex positions, [...., x, y, z, ......]
     * @param indices an array of indices in groups of three for each triangular facet, [...., i, j, k, ......]
     * @param normals an array of vertex normals, [...., x, y, z, ......]
     * @param options an object used to set the following optional parameters for the TorusKnot, optional
      * * facetNormals : optional array of facet normals (vector3)
      * * facetPositions : optional array of facet positions (vector3)
      * * facetPartitioning : optional partitioning array. facetPositions is required for facetPartitioning computation
      * * ratio : optional partitioning ratio / bounding box, required for facetPartitioning computation
      * * bInfo : optional bounding info, required for facetPartitioning computation
      * * bbSize : optional bounding box size data, required for facetPartitioning computation
      * * subDiv : optional partitioning data about subdivsions on  each axis (int), required for facetPartitioning computation
      * * useRightHandedSystem: optional boolean to for right handed system computation
      * * depthSort : optional boolean to enable the facet depth sort computation
      * * distanceTo : optional Vector3 to compute the facet depth from this location
      * * depthSortedFacets : optional array of depthSortedFacets to store the facet distances from the reference location
     */
    VertexData.ComputeNormals = function (positions, indices, normals, options) {
        // temporary scalar variables
        var index = 0; // facet index
        var p1p2x = 0.0; // p1p2 vector x coordinate
        var p1p2y = 0.0; // p1p2 vector y coordinate
        var p1p2z = 0.0; // p1p2 vector z coordinate
        var p3p2x = 0.0; // p3p2 vector x coordinate
        var p3p2y = 0.0; // p3p2 vector y coordinate
        var p3p2z = 0.0; // p3p2 vector z coordinate
        var faceNormalx = 0.0; // facet normal x coordinate
        var faceNormaly = 0.0; // facet normal y coordinate
        var faceNormalz = 0.0; // facet normal z coordinate
        var length = 0.0; // facet normal length before normalization
        var v1x = 0; // vector1 x index in the positions array
        var v1y = 0; // vector1 y index in the positions array
        var v1z = 0; // vector1 z index in the positions array
        var v2x = 0; // vector2 x index in the positions array
        var v2y = 0; // vector2 y index in the positions array
        var v2z = 0; // vector2 z index in the positions array
        var v3x = 0; // vector3 x index in the positions array
        var v3y = 0; // vector3 y index in the positions array
        var v3z = 0; // vector3 z index in the positions array
        var computeFacetNormals = false;
        var computeFacetPositions = false;
        var computeFacetPartitioning = false;
        var computeDepthSort = false;
        var faceNormalSign = 1;
        var ratio = 0;
        var distanceTo = null;
        if (options) {
            computeFacetNormals = (options.facetNormals) ? true : false;
            computeFacetPositions = (options.facetPositions) ? true : false;
            computeFacetPartitioning = (options.facetPartitioning) ? true : false;
            faceNormalSign = (options.useRightHandedSystem === true) ? -1 : 1;
            ratio = options.ratio || 0;
            computeDepthSort = (options.depthSort) ? true : false;
            distanceTo = (options.distanceTo);
            if (computeDepthSort) {
                if (distanceTo === undefined) {
                    distanceTo = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                }
                var depthSortedFacets = options.depthSortedFacets;
            }
        }
        // facetPartitioning reinit if needed
        var xSubRatio = 0;
        var ySubRatio = 0;
        var zSubRatio = 0;
        var subSq = 0;
        if (computeFacetPartitioning && options && options.bbSize) {
            var ox = 0; // X partitioning index for facet position
            var oy = 0; // Y partinioning index for facet position
            var oz = 0; // Z partinioning index for facet position
            var b1x = 0; // X partitioning index for facet v1 vertex
            var b1y = 0; // Y partitioning index for facet v1 vertex
            var b1z = 0; // z partitioning index for facet v1 vertex
            var b2x = 0; // X partitioning index for facet v2 vertex
            var b2y = 0; // Y partitioning index for facet v2 vertex
            var b2z = 0; // Z partitioning index for facet v2 vertex
            var b3x = 0; // X partitioning index for facet v3 vertex
            var b3y = 0; // Y partitioning index for facet v3 vertex
            var b3z = 0; // Z partitioning index for facet v3 vertex
            var block_idx_o = 0; // facet barycenter block index
            var block_idx_v1 = 0; // v1 vertex block index
            var block_idx_v2 = 0; // v2 vertex block index
            var block_idx_v3 = 0; // v3 vertex block index
            var bbSizeMax = (options.bbSize.x > options.bbSize.y) ? options.bbSize.x : options.bbSize.y;
            bbSizeMax = (bbSizeMax > options.bbSize.z) ? bbSizeMax : options.bbSize.z;
            xSubRatio = options.subDiv.X * ratio / options.bbSize.x;
            ySubRatio = options.subDiv.Y * ratio / options.bbSize.y;
            zSubRatio = options.subDiv.Z * ratio / options.bbSize.z;
            subSq = options.subDiv.max * options.subDiv.max;
            options.facetPartitioning.length = 0;
        }
        // reset the normals
        for (index = 0; index < positions.length; index++) {
            normals[index] = 0.0;
        }
        // Loop : 1 indice triplet = 1 facet
        var nbFaces = (indices.length / 3) | 0;
        for (index = 0; index < nbFaces; index++) {
            // get the indexes of the coordinates of each vertex of the facet
            v1x = indices[index * 3] * 3;
            v1y = v1x + 1;
            v1z = v1x + 2;
            v2x = indices[index * 3 + 1] * 3;
            v2y = v2x + 1;
            v2z = v2x + 2;
            v3x = indices[index * 3 + 2] * 3;
            v3y = v3x + 1;
            v3z = v3x + 2;
            p1p2x = positions[v1x] - positions[v2x]; // compute two vectors per facet : p1p2 and p3p2
            p1p2y = positions[v1y] - positions[v2y];
            p1p2z = positions[v1z] - positions[v2z];
            p3p2x = positions[v3x] - positions[v2x];
            p3p2y = positions[v3y] - positions[v2y];
            p3p2z = positions[v3z] - positions[v2z];
            // compute the face normal with the cross product
            faceNormalx = faceNormalSign * (p1p2y * p3p2z - p1p2z * p3p2y);
            faceNormaly = faceNormalSign * (p1p2z * p3p2x - p1p2x * p3p2z);
            faceNormalz = faceNormalSign * (p1p2x * p3p2y - p1p2y * p3p2x);
            // normalize this normal and store it in the array facetData
            length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
            length = (length === 0) ? 1.0 : length;
            faceNormalx /= length;
            faceNormaly /= length;
            faceNormalz /= length;
            if (computeFacetNormals && options) {
                options.facetNormals[index].x = faceNormalx;
                options.facetNormals[index].y = faceNormaly;
                options.facetNormals[index].z = faceNormalz;
            }
            if (computeFacetPositions && options) {
                // compute and the facet barycenter coordinates in the array facetPositions
                options.facetPositions[index].x = (positions[v1x] + positions[v2x] + positions[v3x]) / 3.0;
                options.facetPositions[index].y = (positions[v1y] + positions[v2y] + positions[v3y]) / 3.0;
                options.facetPositions[index].z = (positions[v1z] + positions[v2z] + positions[v3z]) / 3.0;
            }
            if (computeFacetPartitioning && options) {
                // store the facet indexes in arrays in the main facetPartitioning array :
                // compute each facet vertex (+ facet barycenter) index in the partiniong array
                ox = Math.floor((options.facetPositions[index].x - options.bInfo.minimum.x * ratio) * xSubRatio);
                oy = Math.floor((options.facetPositions[index].y - options.bInfo.minimum.y * ratio) * ySubRatio);
                oz = Math.floor((options.facetPositions[index].z - options.bInfo.minimum.z * ratio) * zSubRatio);
                b1x = Math.floor((positions[v1x] - options.bInfo.minimum.x * ratio) * xSubRatio);
                b1y = Math.floor((positions[v1y] - options.bInfo.minimum.y * ratio) * ySubRatio);
                b1z = Math.floor((positions[v1z] - options.bInfo.minimum.z * ratio) * zSubRatio);
                b2x = Math.floor((positions[v2x] - options.bInfo.minimum.x * ratio) * xSubRatio);
                b2y = Math.floor((positions[v2y] - options.bInfo.minimum.y * ratio) * ySubRatio);
                b2z = Math.floor((positions[v2z] - options.bInfo.minimum.z * ratio) * zSubRatio);
                b3x = Math.floor((positions[v3x] - options.bInfo.minimum.x * ratio) * xSubRatio);
                b3y = Math.floor((positions[v3y] - options.bInfo.minimum.y * ratio) * ySubRatio);
                b3z = Math.floor((positions[v3z] - options.bInfo.minimum.z * ratio) * zSubRatio);
                block_idx_v1 = b1x + options.subDiv.max * b1y + subSq * b1z;
                block_idx_v2 = b2x + options.subDiv.max * b2y + subSq * b2z;
                block_idx_v3 = b3x + options.subDiv.max * b3y + subSq * b3z;
                block_idx_o = ox + options.subDiv.max * oy + subSq * oz;
                options.facetPartitioning[block_idx_o] = options.facetPartitioning[block_idx_o] ? options.facetPartitioning[block_idx_o] : new Array();
                options.facetPartitioning[block_idx_v1] = options.facetPartitioning[block_idx_v1] ? options.facetPartitioning[block_idx_v1] : new Array();
                options.facetPartitioning[block_idx_v2] = options.facetPartitioning[block_idx_v2] ? options.facetPartitioning[block_idx_v2] : new Array();
                options.facetPartitioning[block_idx_v3] = options.facetPartitioning[block_idx_v3] ? options.facetPartitioning[block_idx_v3] : new Array();
                // push each facet index in each block containing the vertex
                options.facetPartitioning[block_idx_v1].push(index);
                if (block_idx_v2 != block_idx_v1) {
                    options.facetPartitioning[block_idx_v2].push(index);
                }
                if (!(block_idx_v3 == block_idx_v2 || block_idx_v3 == block_idx_v1)) {
                    options.facetPartitioning[block_idx_v3].push(index);
                }
                if (!(block_idx_o == block_idx_v1 || block_idx_o == block_idx_v2 || block_idx_o == block_idx_v3)) {
                    options.facetPartitioning[block_idx_o].push(index);
                }
            }
            if (computeDepthSort && options && options.facetPositions) {
                var dsf = depthSortedFacets[index];
                dsf.ind = index * 3;
                dsf.sqDistance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].DistanceSquared(options.facetPositions[index], distanceTo);
            }
            // compute the normals anyway
            normals[v1x] += faceNormalx; // accumulate all the normals per face
            normals[v1y] += faceNormaly;
            normals[v1z] += faceNormalz;
            normals[v2x] += faceNormalx;
            normals[v2y] += faceNormaly;
            normals[v2z] += faceNormalz;
            normals[v3x] += faceNormalx;
            normals[v3y] += faceNormaly;
            normals[v3z] += faceNormalz;
        }
        // last normalization of each normal
        for (index = 0; index < normals.length / 3; index++) {
            faceNormalx = normals[index * 3];
            faceNormaly = normals[index * 3 + 1];
            faceNormalz = normals[index * 3 + 2];
            length = Math.sqrt(faceNormalx * faceNormalx + faceNormaly * faceNormaly + faceNormalz * faceNormalz);
            length = (length === 0) ? 1.0 : length;
            faceNormalx /= length;
            faceNormaly /= length;
            faceNormalz /= length;
            normals[index * 3] = faceNormalx;
            normals[index * 3 + 1] = faceNormaly;
            normals[index * 3 + 2] = faceNormalz;
        }
    };
    /** @hidden */
    VertexData._ComputeSides = function (sideOrientation, positions, indices, normals, uvs, frontUVs, backUVs) {
        var li = indices.length;
        var ln = normals.length;
        var i;
        var n;
        sideOrientation = sideOrientation || VertexData.DEFAULTSIDE;
        switch (sideOrientation) {
            case VertexData.FRONTSIDE:
                // nothing changed
                break;
            case VertexData.BACKSIDE:
                var tmp;
                // indices
                for (i = 0; i < li; i += 3) {
                    tmp = indices[i];
                    indices[i] = indices[i + 2];
                    indices[i + 2] = tmp;
                }
                // normals
                for (n = 0; n < ln; n++) {
                    normals[n] = -normals[n];
                }
                break;
            case VertexData.DOUBLESIDE:
                // positions
                var lp = positions.length;
                var l = lp / 3;
                for (var p = 0; p < lp; p++) {
                    positions[lp + p] = positions[p];
                }
                // indices
                for (i = 0; i < li; i += 3) {
                    indices[i + li] = indices[i + 2] + l;
                    indices[i + 1 + li] = indices[i + 1] + l;
                    indices[i + 2 + li] = indices[i] + l;
                }
                // normals
                for (n = 0; n < ln; n++) {
                    normals[ln + n] = -normals[n];
                }
                // uvs
                var lu = uvs.length;
                var u = 0;
                for (u = 0; u < lu; u++) {
                    uvs[u + lu] = uvs[u];
                }
                frontUVs = frontUVs ? frontUVs : new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0.0, 0.0, 1.0, 1.0);
                backUVs = backUVs ? backUVs : new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0.0, 0.0, 1.0, 1.0);
                u = 0;
                for (i = 0; i < lu / 2; i++) {
                    uvs[u] = frontUVs.x + (frontUVs.z - frontUVs.x) * uvs[u];
                    uvs[u + 1] = frontUVs.y + (frontUVs.w - frontUVs.y) * uvs[u + 1];
                    uvs[u + lu] = backUVs.x + (backUVs.z - backUVs.x) * uvs[u + lu];
                    uvs[u + lu + 1] = backUVs.y + (backUVs.w - backUVs.y) * uvs[u + lu + 1];
                    u += 2;
                }
                break;
        }
    };
    /**
     * Applies VertexData created from the imported parameters to the geometry
     * @param parsedVertexData the parsed data from an imported file
     * @param geometry the geometry to apply the VertexData to
     */
    VertexData.ImportVertexData = function (parsedVertexData, geometry) {
        var vertexData = new VertexData();
        // positions
        var positions = parsedVertexData.positions;
        if (positions) {
            vertexData.set(positions, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
        }
        // normals
        var normals = parsedVertexData.normals;
        if (normals) {
            vertexData.set(normals, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind);
        }
        // tangents
        var tangents = parsedVertexData.tangents;
        if (tangents) {
            vertexData.set(tangents, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind);
        }
        // uvs
        var uvs = parsedVertexData.uvs;
        if (uvs) {
            vertexData.set(uvs, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind);
        }
        // uv2s
        var uv2s = parsedVertexData.uv2s;
        if (uv2s) {
            vertexData.set(uv2s, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind);
        }
        // uv3s
        var uv3s = parsedVertexData.uv3s;
        if (uv3s) {
            vertexData.set(uv3s, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV3Kind);
        }
        // uv4s
        var uv4s = parsedVertexData.uv4s;
        if (uv4s) {
            vertexData.set(uv4s, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV4Kind);
        }
        // uv5s
        var uv5s = parsedVertexData.uv5s;
        if (uv5s) {
            vertexData.set(uv5s, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV5Kind);
        }
        // uv6s
        var uv6s = parsedVertexData.uv6s;
        if (uv6s) {
            vertexData.set(uv6s, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV6Kind);
        }
        // colors
        var colors = parsedVertexData.colors;
        if (colors) {
            vertexData.set(_Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color4"].CheckColors4(colors, positions.length / 3), _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind);
        }
        // matricesIndices
        var matricesIndices = parsedVertexData.matricesIndices;
        if (matricesIndices) {
            vertexData.set(matricesIndices, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind);
        }
        // matricesWeights
        var matricesWeights = parsedVertexData.matricesWeights;
        if (matricesWeights) {
            vertexData.set(matricesWeights, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind);
        }
        // indices
        var indices = parsedVertexData.indices;
        if (indices) {
            vertexData.indices = indices;
        }
        geometry.setAllVerticesData(vertexData, parsedVertexData.updatable);
    };
    /**
     * Mesh side orientation : usually the external or front surface
     */
    VertexData.FRONTSIDE = 0;
    /**
     * Mesh side orientation : usually the internal or back surface
     */
    VertexData.BACKSIDE = 1;
    /**
     * Mesh side orientation : both internal and external or front and back surfaces
     */
    VertexData.DOUBLESIDE = 2;
    /**
     * Mesh side orientation : by default, `FRONTSIDE`
     */
    VertexData.DEFAULTSIDE = 0;
    return VertexData;
}());



/***/ }),

/***/ "./Meshes/meshBuilder.ts":
/*!*******************************!*\
  !*** ./Meshes/meshBuilder.ts ***!
  \*******************************/
/*! exports provided: MeshBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshBuilder", function() { return MeshBuilder; });
/* harmony import */ var _Builders_ribbonBuilder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Builders/ribbonBuilder */ "./Meshes/Builders/ribbonBuilder.ts");
/* harmony import */ var _Builders_discBuilder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Builders/discBuilder */ "./Meshes/Builders/discBuilder.ts");
/* harmony import */ var _Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Builders_tiledBoxBuilder__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Builders/tiledBoxBuilder */ "./Meshes/Builders/tiledBoxBuilder.ts");
/* harmony import */ var _Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Builders/cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");
/* harmony import */ var _Builders_torusBuilder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Builders/torusBuilder */ "./Meshes/Builders/torusBuilder.ts");
/* harmony import */ var _Builders_torusKnotBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Builders/torusKnotBuilder */ "./Meshes/Builders/torusKnotBuilder.ts");
/* harmony import */ var _Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Builders/linesBuilder */ "./Meshes/Builders/linesBuilder.ts");
/* harmony import */ var _Builders_polygonBuilder__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Builders/polygonBuilder */ "./Meshes/Builders/polygonBuilder.ts");
/* harmony import */ var _Builders_shapeBuilder__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Builders/shapeBuilder */ "./Meshes/Builders/shapeBuilder.ts");
/* harmony import */ var _Builders_latheBuilder__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Builders/latheBuilder */ "./Meshes/Builders/latheBuilder.ts");
/* harmony import */ var _Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Builders/planeBuilder */ "./Meshes/Builders/planeBuilder.ts");
/* harmony import */ var _Builders_tiledPlaneBuilder__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Builders/tiledPlaneBuilder */ "./Meshes/Builders/tiledPlaneBuilder.ts");
/* harmony import */ var _Builders_groundBuilder__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Builders/groundBuilder */ "./Meshes/Builders/groundBuilder.ts");
/* harmony import */ var _Builders_tubeBuilder__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Builders/tubeBuilder */ "./Meshes/Builders/tubeBuilder.ts");
/* harmony import */ var _Builders_polyhedronBuilder__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Builders/polyhedronBuilder */ "./Meshes/Builders/polyhedronBuilder.ts");
/* harmony import */ var _Builders_icoSphereBuilder__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Builders/icoSphereBuilder */ "./Meshes/Builders/icoSphereBuilder.ts");
/* harmony import */ var _Builders_decalBuilder__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Builders/decalBuilder */ "./Meshes/Builders/decalBuilder.ts");



















/**
 * Class containing static functions to help procedurally build meshes
 */
var MeshBuilder = /** @class */ (function () {
    function MeshBuilder() {
    }
    /**
     * Creates a box mesh
     * * The parameter `size` sets the size (float) of each box side (default 1)
     * * You can set some different box dimensions by using the parameters `width`, `height` and `depth` (all by default have the same value of `size`)
     * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of 6 Color3 elements) and `faceUV` (an array of 6 Vector4 elements)
     * * Please read this tutorial : https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @see https://doc.babylonjs.com/how_to/set_shapes#box
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the box mesh
     */
    MeshBuilder.CreateBox = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_2__["BoxBuilder"].CreateBox(name, options, scene);
    };
    /**
     * Creates a tiled box mesh
     * * faceTiles sets the pattern, tile size and number of tiles for a face
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the tiled box mesh
     */
    MeshBuilder.CreateTiledBox = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_tiledBoxBuilder__WEBPACK_IMPORTED_MODULE_3__["TiledBoxBuilder"].CreateTiledBox(name, options, scene);
    };
    /**
     * Creates a sphere mesh
     * * The parameter `diameter` sets the diameter size (float) of the sphere (default 1)
     * * You can set some different sphere dimensions, for instance to build an ellipsoid, by using the parameters `diameterX`, `diameterY` and `diameterZ` (all by default have the same value of `diameter`)
     * * The parameter `segments` sets the sphere number of horizontal stripes (positive integer, default 32)
     * * You can create an unclosed sphere with the parameter `arc` (positive float, default 1), valued between 0 and 1, what is the ratio of the circumference (latitude) : 2 x PI x ratio
     * * You can create an unclosed sphere on its height with the parameter `slice` (positive float, default1), valued between 0 and 1, what is the height ratio (longitude)
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the sphere mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#sphere
     */
    MeshBuilder.CreateSphere = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_4__["SphereBuilder"].CreateSphere(name, options, scene);
    };
    /**
     * Creates a plane polygonal mesh.  By default, this is a disc
     * * The parameter `radius` sets the radius size (float) of the polygon (default 0.5)
     * * The parameter `tessellation` sets the number of polygon sides (positive integer, default 64). So a tessellation valued to 3 will build a triangle, to 4 a square, etc
     * * You can create an unclosed polygon with the parameter `arc` (positive float, default 1), valued between 0 and 1, what is the ratio of the circumference : 2 x PI x ratio
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the plane polygonal mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#disc-or-regular-polygon
     */
    MeshBuilder.CreateDisc = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_discBuilder__WEBPACK_IMPORTED_MODULE_1__["DiscBuilder"].CreateDisc(name, options, scene);
    };
    /**
     * Creates a sphere based upon an icosahedron with 20 triangular faces which can be subdivided
     * * The parameter `radius` sets the radius size (float) of the icosphere (default 1)
     * * You can set some different icosphere dimensions, for instance to build an ellipsoid, by using the parameters `radiusX`, `radiusY` and `radiusZ` (all by default have the same value of `radius`)
     * * The parameter `subdivisions` sets the number of subdivisions (postive integer, default 4). The more subdivisions, the more faces on the icosphere whatever its size
     * * The parameter `flat` (boolean, default true) gives each side its own normals. Set it to false to get a smooth continuous light reflection on the surface
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the icosahedron mesh
     * @see https://doc.babylonjs.com/how_to/polyhedra_shapes#icosphere
     */
    MeshBuilder.CreateIcoSphere = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_icoSphereBuilder__WEBPACK_IMPORTED_MODULE_17__["IcoSphereBuilder"].CreateIcoSphere(name, options, scene);
    };
    /**
     * Creates a ribbon mesh. The ribbon is a parametric shape.  It has no predefined shape. Its final shape will depend on the input parameters
     * * The parameter `pathArray` is a required array of paths, what are each an array of successive Vector3. The pathArray parameter depicts the ribbon geometry
     * * The parameter `closeArray` (boolean, default false) creates a seam between the first and the last paths of the path array
     * * The parameter `closePath` (boolean, default false) creates a seam between the first and the last points of each path of the path array
     * * The parameter `offset` (positive integer, default : rounded half size of the pathArray length), is taken in account only if the `pathArray` is containing a single path
     * * It's the offset to join the points from the same path. Ex : offset = 10 means the point 1 is joined to the point 11
     * * The optional parameter `instance` is an instance of an existing Ribbon object to be updated with the passed `pathArray` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#ribbon
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The parameter `uvs` is an optional flat array of `Vector2` to update/set each ribbon vertex with its own custom UV values instead of the computed ones
     * * The parameters `colors` is an optional flat array of `Color4` to set/update each ribbon vertex with its own custom color values
     * * Note that if you use the parameters `uvs` or `colors`, the passed arrays must be populated with the right number of elements, it is to say the number of ribbon vertices. Remember that if you set `closePath` to `true`, there's one extra vertex per path in the geometry
     * * Moreover, you can use the parameter `color` with `instance` (to update the ribbon), only if you previously used it at creation time
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the ribbon mesh
     * @see https://doc.babylonjs.com/how_to/ribbon_tutorial
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     */
    MeshBuilder.CreateRibbon = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_ribbonBuilder__WEBPACK_IMPORTED_MODULE_0__["RibbonBuilder"].CreateRibbon(name, options, scene);
    };
    /**
     * Creates a cylinder or a cone mesh
     * * The parameter `height` sets the height size (float) of the cylinder/cone (float, default 2).
     * * The parameter `diameter` sets the diameter of the top and bottom cap at once (float, default 1).
     * * The parameters `diameterTop` and `diameterBottom` overwrite the parameter `diameter` and set respectively the top cap and bottom cap diameter (floats, default 1). The parameter "diameterBottom" can't be zero.
     * * The parameter `tessellation` sets the number of cylinder sides (positive integer, default 24). Set it to 3 to get a prism for instance.
     * * The parameter `subdivisions` sets the number of rings along the cylinder height (positive integer, default 1).
     * * The parameter `hasRings` (boolean, default false) makes the subdivisions independent from each other, so they become different faces.
     * * The parameter `enclose`  (boolean, default false) adds two extra faces per subdivision to a sliced cylinder to close it around its height axis.
     * * The parameter `cap` sets the way the cylinder is capped. Possible values : BABYLON.Mesh.NO_CAP, BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL (default).
     * * The parameter `arc` (float, default 1) is the ratio (max 1) to apply to the circumference to slice the cylinder.
     * * You can set different colors and different images to each box side by using the parameters `faceColors` (an array of n Color3 elements) and `faceUV` (an array of n Vector4 elements).
     * * The value of n is the number of cylinder faces. If the cylinder has only 1 subdivisions, n equals : top face + cylinder surface + bottom face = 3
     * * Now, if the cylinder has 5 independent subdivisions (hasRings = true), n equals : top face + 5 stripe surfaces + bottom face = 2 + 5 = 7
     * * Finally, if the cylinder has 5 independent subdivisions and is enclose, n equals : top face + 5 x (stripe surface + 2 closing faces) + bottom face = 2 + 5 * 3 = 17
     * * Each array (color or UVs) is always ordered the same way : the first element is the bottom cap, the last element is the top cap. The other elements are each a ring surface.
     * * If `enclose` is false, a ring surface is one element.
     * * If `enclose` is true, a ring surface is 3 successive elements in the array : the tubular surface, then the two closing faces.
     * * Example how to set colors and textures on a sliced cylinder : https://www.html5gamedevs.com/topic/17945-creating-a-closed-slice-of-a-cylinder/#comment-106379
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the cylinder mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#cylinder-or-cone
     */
    MeshBuilder.CreateCylinder = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_5__["CylinderBuilder"].CreateCylinder(name, options, scene);
    };
    /**
     * Creates a torus mesh
     * * The parameter `diameter` sets the diameter size (float) of the torus (default 1)
     * * The parameter `thickness` sets the diameter size of the tube of the torus (float, default 0.5)
     * * The parameter `tessellation` sets the number of torus sides (postive integer, default 16)
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the torus mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#torus
     */
    MeshBuilder.CreateTorus = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_torusBuilder__WEBPACK_IMPORTED_MODULE_6__["TorusBuilder"].CreateTorus(name, options, scene);
    };
    /**
     * Creates a torus knot mesh
     * * The parameter `radius` sets the global radius size (float) of the torus knot (default 2)
     * * The parameter `radialSegments` sets the number of sides on each tube segments (positive integer, default 32)
     * * The parameter `tubularSegments` sets the number of tubes to decompose the knot into (positive integer, default 32)
     * * The parameters `p` and `q` are the number of windings on each axis (positive integers, default 2 and 3)
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the torus knot mesh
     * @see  https://doc.babylonjs.com/how_to/set_shapes#torus-knot
     */
    MeshBuilder.CreateTorusKnot = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_torusKnotBuilder__WEBPACK_IMPORTED_MODULE_7__["TorusKnotBuilder"].CreateTorusKnot(name, options, scene);
    };
    /**
     * Creates a line system mesh. A line system is a pool of many lines gathered in a single mesh
     * * A line system mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of lines as an input parameter
     * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineSystem to this static function
     * * The parameter `lines` is an array of lines, each line being an array of successive Vector3
     * * The optional parameter `instance` is an instance of an existing LineSystem object to be updated with the passed `lines` parameter
     * * The optional parameter `colors` is an array of line colors, each line colors being an array of successive Color4, one per line point
     * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need the alpha blending (faster)
     * * Updating a simple Line mesh, you just need to update every line in the `lines` array : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#lines-and-dashedlines
     * * When updating an instance, remember that only line point positions can change, not the number of points, neither the number of lines
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#line-system
     * @param name defines the name of the new line system
     * @param options defines the options used to create the line system
     * @param scene defines the hosting scene
     * @returns a new line system mesh
     */
    MeshBuilder.CreateLineSystem = function (name, options, scene) {
        return _Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLineSystem(name, options, scene);
    };
    /**
     * Creates a line mesh
     * A line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter
     * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function
     * * The parameter `points` is an array successive Vector3
     * * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#lines-and-dashedlines
     * * The optional parameter `colors` is an array of successive Color4, one per line point
     * * The optional parameter `useVertexAlpha` is to be set to `false` (default `true`) when you don't need alpha blending (faster)
     * * When updating an instance, remember that only point positions can change, not the number of points
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#lines
     * @param name defines the name of the new line system
     * @param options defines the options used to create the line system
     * @param scene defines the hosting scene
     * @returns a new line mesh
     */
    MeshBuilder.CreateLines = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateLines(name, options, scene);
    };
    /**
     * Creates a dashed line mesh
     * * A dashed line mesh is considered as a parametric shape since it has no predefined original shape. Its shape is determined by the passed array of points as an input parameter
     * * Like every other parametric shape, it is dynamically updatable by passing an existing instance of LineMesh to this static function
     * * The parameter `points` is an array successive Vector3
     * * The parameter `dashNb` is the intended total number of dashes (positive integer, default 200)
     * * The parameter `dashSize` is the size of the dashes relatively the dash number (positive float, default 3)
     * * The parameter `gapSize` is the size of the gap between two successive dashes relatively the dash number (positive float, default 1)
     * * The optional parameter `instance` is an instance of an existing LineMesh object to be updated with the passed `points` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#lines-and-dashedlines
     * * When updating an instance, remember that only point positions can change, not the number of points
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the dashed line mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#dashed-lines
     */
    MeshBuilder.CreateDashedLines = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_8__["LinesBuilder"].CreateDashedLines(name, options, scene);
    };
    /**
     * Creates an extruded shape mesh. The extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.
     * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis.
     * * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.
     * * The parameter `rotation` (float, default 0 radians) is the angle value to rotate the shape each step (each path point), from the former step (so rotation added each step) along the curve.
     * * The parameter `scale` (float, default 1) is the value to scale the shape.
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#extruded-shape
     * * Remember you can only change the shape or path point positions, not their number when updating an extruded shape.
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture.
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the extruded shape mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes
     */
    MeshBuilder.ExtrudeShape = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_shapeBuilder__WEBPACK_IMPORTED_MODULE_10__["ShapeBuilder"].ExtrudeShape(name, options, scene);
    };
    /**
     * Creates an custom extruded shape mesh.
     * The custom extrusion is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters.
     * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be extruded in its local space : the shape must be designed in the xOy plane and will be extruded along the Z axis.
     * * The parameter `path` is a required array of successive Vector3. This is the axis curve the shape is extruded along.
     * * The parameter `rotationFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path and the distance of this point from the begining of the path
     * * It must returns a float value that will be the rotation in radians applied to the shape on each path point.
     * * The parameter `scaleFunction` (JS function) is a custom Javascript function called on each path point. This function is passed the position i of the point in the path and the distance of this point from the begining of the path
     * * It must returns a float value that will be the scale value applied to the shape on each path point
     * * The parameter `ribbonClosePath` (boolean, default false) forces the extrusion underlying ribbon to close all the paths in its `pathArray`
     * * The parameter `ribbonCloseArray` (boolean, default false) forces the extrusion underlying ribbon to close its `pathArray`
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * The optional parameter `instance` is an instance of an existing ExtrudedShape object to be updated with the passed `shape`, `path`, `scale` or `rotation` parameters : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#extruded-shape
     * * Remember you can only change the shape or path point positions, not their number when updating an extruded shape
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the custom extruded shape mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#custom-extruded-shapes
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#extruded-shapes
     */
    MeshBuilder.ExtrudeShapeCustom = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_shapeBuilder__WEBPACK_IMPORTED_MODULE_10__["ShapeBuilder"].ExtrudeShapeCustom(name, options, scene);
    };
    /**
     * Creates lathe mesh.
     * The lathe is a shape with a symetry axis : a 2D model shape is rotated around this axis to design the lathe
     * * The parameter `shape` is a required array of successive Vector3. This array depicts the shape to be rotated in its local space : the shape must be designed in the xOy plane and will be rotated around the Y axis. It's usually a 2D shape, so the Vector3 z coordinates are often set to zero
     * * The parameter `radius` (positive float, default 1) is the radius value of the lathe
     * * The parameter `tessellation` (positive integer, default 64) is the side number of the lathe
     * * The parameter `clip` (positive integer, default 0) is the number of sides to not create without effecting the general shape of the sides
     * * The parameter `arc` (positive float, default 1) is the ratio of the lathe. 0.5 builds for instance half a lathe, so an opened shape
     * * The parameter `closed` (boolean, default true) opens/closes the lathe circumference. This should be set to false when used with the parameter "arc"
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the lathe mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes#lathe
     */
    MeshBuilder.CreateLathe = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_latheBuilder__WEBPACK_IMPORTED_MODULE_11__["LatheBuilder"].CreateLathe(name, options, scene);
    };
    /**
     * Creates a tiled plane mesh
     * * You can set a limited pattern arrangement with the tiles
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the plane mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#plane
     */
    MeshBuilder.CreateTiledPlane = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_tiledPlaneBuilder__WEBPACK_IMPORTED_MODULE_13__["TiledPlaneBuilder"].CreateTiledPlane(name, options, scene);
    };
    /**
     * Creates a plane mesh
     * * The parameter `size` sets the size (float) of both sides of the plane at once (default 1)
     * * You can set some different plane dimensions by using the parameters `width` and `height` (both by default have the same value of `size`)
     * * The parameter `sourcePlane` is a Plane instance. It builds a mesh plane from a Math plane
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the plane mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#plane
     */
    MeshBuilder.CreatePlane = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_12__["PlaneBuilder"].CreatePlane(name, options, scene);
    };
    /**
     * Creates a ground mesh
     * * The parameters `width` and `height` (floats, default 1) set the width and height sizes of the ground
     * * The parameter `subdivisions` (positive integer) sets the number of subdivisions per side
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the ground mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#ground
     */
    MeshBuilder.CreateGround = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_groundBuilder__WEBPACK_IMPORTED_MODULE_14__["GroundBuilder"].CreateGround(name, options, scene);
    };
    /**
     * Creates a tiled ground mesh
     * * The parameters `xmin` and `xmax` (floats, default -1 and 1) set the ground minimum and maximum X coordinates
     * * The parameters `zmin` and `zmax` (floats, default -1 and 1) set the ground minimum and maximum Z coordinates
     * * The parameter `subdivisions` is a javascript object `{w: positive integer, h: positive integer}` (default `{w: 6, h: 6}`). `w` and `h` are the numbers of subdivisions on the ground width and height. Each subdivision is called a tile
     * * The parameter `precision` is a javascript object `{w: positive integer, h: positive integer}` (default `{w: 2, h: 2}`). `w` and `h` are the numbers of subdivisions on the ground width and height of each tile
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the tiled ground mesh
     * @see https://doc.babylonjs.com/how_to/set_shapes#tiled-ground
     */
    MeshBuilder.CreateTiledGround = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_groundBuilder__WEBPACK_IMPORTED_MODULE_14__["GroundBuilder"].CreateTiledGround(name, options, scene);
    };
    /**
     * Creates a ground mesh from a height map
     * * The parameter `url` sets the URL of the height map image resource.
     * * The parameters `width` and `height` (positive floats, default 10) set the ground width and height sizes.
     * * The parameter `subdivisions` (positive integer, default 1) sets the number of subdivision per side.
     * * The parameter `minHeight` (float, default 0) is the minimum altitude on the ground.
     * * The parameter `maxHeight` (float, default 1) is the maximum altitude on the ground.
     * * The parameter `colorFilter` (optional Color3, default (0.3, 0.59, 0.11) ) is the filter to apply to the image pixel colors to compute the height.
     * * The parameter `onReady` is a javascript callback function that will be called  once the mesh is just built (the height map download can last some time).
     * * The parameter `alphaFilter` will filter any data where the alpha channel is below this value, defaults 0 (all data visible)
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created.
     * @param name defines the name of the mesh
     * @param url defines the url to the height map
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the ground mesh
     * @see https://doc.babylonjs.com/babylon101/height_map
     * @see https://doc.babylonjs.com/how_to/set_shapes#ground-from-a-height-map
     */
    MeshBuilder.CreateGroundFromHeightMap = function (name, url, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_groundBuilder__WEBPACK_IMPORTED_MODULE_14__["GroundBuilder"].CreateGroundFromHeightMap(name, url, options, scene);
    };
    /**
     * Creates a polygon mesh
     * The polygon's shape will depend on the input parameters and is constructed parallel to a ground mesh
     * * The parameter `shape` is a required array of successive Vector3 representing the corners of the polygon in th XoZ plane, that is y = 0 for all vectors
     * * You can set the mesh side orientation with the values : Mesh.FRONTSIDE (default), Mesh.BACKSIDE or Mesh.DOUBLESIDE
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4)
     * * Remember you can only change the shape positions, not their number when updating a polygon
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @param earcutInjection can be used to inject your own earcut reference
     * @returns the polygon mesh
     */
    MeshBuilder.CreatePolygon = function (name, options, scene, earcutInjection) {
        if (scene === void 0) { scene = null; }
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        return _Builders_polygonBuilder__WEBPACK_IMPORTED_MODULE_9__["PolygonBuilder"].CreatePolygon(name, options, scene, earcutInjection);
    };
    /**
     * Creates an extruded polygon mesh, with depth in the Y direction.
     * * You can set different colors and different images to the top, bottom and extruded side by using the parameters `faceColors` (an array of 3 Color3 elements) and `faceUV` (an array of 3 Vector4 elements)
     * @see https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @param earcutInjection can be used to inject your own earcut reference
     * @returns the polygon mesh
     */
    MeshBuilder.ExtrudePolygon = function (name, options, scene, earcutInjection) {
        if (scene === void 0) { scene = null; }
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        return _Builders_polygonBuilder__WEBPACK_IMPORTED_MODULE_9__["PolygonBuilder"].ExtrudePolygon(name, options, scene, earcutInjection);
    };
    /**
     * Creates a tube mesh.
     * The tube is a parametric shape. It has no predefined shape. Its final shape will depend on the input parameters
     * * The parameter `path` is a required array of successive Vector3. It is the curve used as the axis of the tube
     * * The parameter `radius` (positive float, default 1) sets the tube radius size
     * * The parameter `tessellation` (positive float, default 64) is the number of sides on the tubular surface
     * * The parameter `radiusFunction` (javascript function, default null) is a vanilla javascript function. If it is not null, it overwrittes the parameter `radius`
     * * This function is called on each point of the tube path and is passed the index `i` of the i-th point and the distance of this point from the first point of the path. It must return a radius value (positive float)
     * * The parameter `arc` (positive float, maximum 1, default 1) is the ratio to apply to the tube circumference : 2 x PI x arc
     * * The parameter `cap` sets the way the extruded shape is capped. Possible values : BABYLON.Mesh.NO_CAP (default), BABYLON.Mesh.CAP_START, BABYLON.Mesh.CAP_END, BABYLON.Mesh.CAP_ALL
     * * The optional parameter `instance` is an instance of an existing Tube object to be updated with the passed `pathArray` parameter : https://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh#tube
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The optional parameter `invertUV` (boolean, default false) swaps in the geometry the U and V coordinates to apply a texture
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the tube mesh
     * @see https://doc.babylonjs.com/how_to/parametric_shapes
     * @see https://doc.babylonjs.com/how_to/set_shapes#tube
     */
    MeshBuilder.CreateTube = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_tubeBuilder__WEBPACK_IMPORTED_MODULE_15__["TubeBuilder"].CreateTube(name, options, scene);
    };
    /**
     * Creates a polyhedron mesh
     * * The parameter `type` (positive integer, max 14, default 0) sets the polyhedron type to build among the 15 embbeded types. Please refer to the type sheet in the tutorial to choose the wanted type
     * * The parameter `size` (positive float, default 1) sets the polygon size
     * * You can overwrite the `size` on each dimension bu using the parameters `sizeX`, `sizeY` or `sizeZ` (positive floats, default to `size` value)
     * * You can build other polyhedron types than the 15 embbeded ones by setting the parameter `custom` (`polyhedronObject`, default null). If you set the parameter `custom`, this overwrittes the parameter `type`
     * * A `polyhedronObject` is a formatted javascript object. You'll find a full file with pre-set polyhedra here : https://github.com/BabylonJS/Extensions/tree/master/Polyhedron
     * * You can set the color and the UV of each side of the polyhedron with the parameters `faceColors` (Color4, default `(1, 1, 1, 1)`) and faceUV (Vector4, default `(0, 0, 1, 1)`)
     * * To understand how to set `faceUV` or `faceColors`, please read this by considering the right number of faces of your polyhedron, instead of only 6 for the box : https://doc.babylonjs.com/how_to/createbox_per_face_textures_and_colors
     * * The parameter `flat` (boolean, default true). If set to false, it gives the polyhedron a single global face, so less vertices and shared normals. In this case, `faceColors` and `faceUV` are ignored
     * * You can also set the mesh side orientation with the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
     * * If you create a double-sided mesh, you can choose what parts of the texture image to crop and stick respectively on the front and the back sides with the parameters `frontUVs` and `backUVs` (Vector4). Detail here : https://doc.babylonjs.com/babylon101/discover_basic_elements#side-orientation
     * * The mesh can be set to updatable with the boolean parameter `updatable` (default false) if its internal geometry is supposed to change once created
     * @param name defines the name of the mesh
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the polyhedron mesh
     * @see https://doc.babylonjs.com/how_to/polyhedra_shapes
     */
    MeshBuilder.CreatePolyhedron = function (name, options, scene) {
        if (scene === void 0) { scene = null; }
        return _Builders_polyhedronBuilder__WEBPACK_IMPORTED_MODULE_16__["PolyhedronBuilder"].CreatePolyhedron(name, options, scene);
    };
    /**
     * Creates a decal mesh.
     * A decal is a mesh usually applied as a model onto the surface of another mesh. So don't forget the parameter `sourceMesh` depicting the decal
     * * The parameter `position` (Vector3, default `(0, 0, 0)`) sets the position of the decal in World coordinates
     * * The parameter `normal` (Vector3, default `Vector3.Up`) sets the normal of the mesh where the decal is applied onto in World coordinates
     * * The parameter `size` (Vector3, default `(1, 1, 1)`) sets the decal scaling
     * * The parameter `angle` (float in radian, default 0) sets the angle to rotate the decal
     * @param name defines the name of the mesh
     * @param sourceMesh defines the mesh where the decal must be applied
     * @param options defines the options used to create the mesh
     * @param scene defines the hosting scene
     * @returns the decal mesh
     * @see https://doc.babylonjs.com/how_to/decals
     */
    MeshBuilder.CreateDecal = function (name, sourceMesh, options) {
        return _Builders_decalBuilder__WEBPACK_IMPORTED_MODULE_18__["DecalBuilder"].CreateDecal(name, sourceMesh, options);
    };
    return MeshBuilder;
}());



/***/ }),

/***/ "./Meshes/meshLODLevel.ts":
/*!********************************!*\
  !*** ./Meshes/meshLODLevel.ts ***!
  \********************************/
/*! exports provided: MeshLODLevel */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshLODLevel", function() { return MeshLODLevel; });
/**
 * Class used to represent a specific level of detail of a mesh
 * @see http://doc.babylonjs.com/how_to/how_to_use_lod
 */
var MeshLODLevel = /** @class */ (function () {
    /**
     * Creates a new LOD level
     * @param distance defines the distance where this level should star being displayed
     * @param mesh defines the mesh to use to render this level
     */
    function MeshLODLevel(
    /** Defines the distance where this level should start being displayed */
    distance,
    /** Defines the mesh to use to render this level */
    mesh) {
        this.distance = distance;
        this.mesh = mesh;
    }
    return MeshLODLevel;
}());



/***/ }),

/***/ "./Meshes/meshSimplification.ts":
/*!**************************************!*\
  !*** ./Meshes/meshSimplification.ts ***!
  \**************************************/
/*! exports provided: SimplificationSettings, SimplificationQueue, SimplificationType */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimplificationSettings", function() { return SimplificationSettings; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimplificationQueue", function() { return SimplificationQueue; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimplificationType", function() { return SimplificationType; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/subMesh */ "./Meshes/subMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");






/**
 * Class used to specify simplification options
 * @see http://doc.babylonjs.com/how_to/in-browser_mesh_simplification
 */
var SimplificationSettings = /** @class */ (function () {
    /**
     * Creates a SimplificationSettings
     * @param quality expected quality
     * @param distance distance when this optimized version should be used
     * @param optimizeMesh already optimized mesh
     */
    function SimplificationSettings(
    /** expected quality */
    quality,
    /** distance when this optimized version should be used */
    distance,
    /** already optimized mesh  */
    optimizeMesh) {
        this.quality = quality;
        this.distance = distance;
        this.optimizeMesh = optimizeMesh;
    }
    return SimplificationSettings;
}());

/**
 * Queue used to order the simplification tasks
 * @see http://doc.babylonjs.com/how_to/in-browser_mesh_simplification
 */
var SimplificationQueue = /** @class */ (function () {
    /**
     * Creates a new queue
     */
    function SimplificationQueue() {
        this.running = false;
        this._simplificationArray = [];
    }
    /**
     * Adds a new simplification task
     * @param task defines a task to add
     */
    SimplificationQueue.prototype.addTask = function (task) {
        this._simplificationArray.push(task);
    };
    /**
     * Execute next task
     */
    SimplificationQueue.prototype.executeNext = function () {
        var task = this._simplificationArray.pop();
        if (task) {
            this.running = true;
            this.runSimplification(task);
        }
        else {
            this.running = false;
        }
    };
    /**
     * Execute a simplification task
     * @param task defines the task to run
     */
    SimplificationQueue.prototype.runSimplification = function (task) {
        var _this = this;
        if (task.parallelProcessing) {
            //parallel simplifier
            task.settings.forEach(function (setting) {
                var simplifier = _this.getSimplifier(task);
                simplifier.simplify(setting, function (newMesh) {
                    task.mesh.addLODLevel(setting.distance, newMesh);
                    newMesh.isVisible = true;
                    //check if it is the last
                    if (setting.quality === task.settings[task.settings.length - 1].quality && task.successCallback) {
                        //all done, run the success callback.
                        task.successCallback();
                    }
                    _this.executeNext();
                });
            });
        }
        else {
            //single simplifier.
            var simplifier = this.getSimplifier(task);
            var runDecimation = function (setting, callback) {
                simplifier.simplify(setting, function (newMesh) {
                    task.mesh.addLODLevel(setting.distance, newMesh);
                    newMesh.isVisible = true;
                    //run the next quality level
                    callback();
                });
            };
            _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].Run(task.settings.length, function (loop) {
                runDecimation(task.settings[loop.index], function () {
                    loop.executeNext();
                });
            }, function () {
                //execution ended, run the success callback.
                if (task.successCallback) {
                    task.successCallback();
                }
                _this.executeNext();
            });
        }
    };
    SimplificationQueue.prototype.getSimplifier = function (task) {
        switch (task.simplificationType) {
            case SimplificationType.QUADRATIC:
            default:
                return new QuadraticErrorSimplification(task.mesh);
        }
    };
    return SimplificationQueue;
}());

/**
 * The implemented types of simplification
 * At the moment only Quadratic Error Decimation is implemented
 * @see http://doc.babylonjs.com/how_to/in-browser_mesh_simplification
 */
var SimplificationType;
(function (SimplificationType) {
    /** Quadratic error decimation */
    SimplificationType[SimplificationType["QUADRATIC"] = 0] = "QUADRATIC";
})(SimplificationType || (SimplificationType = {}));
var DecimationTriangle = /** @class */ (function () {
    function DecimationTriangle(vertices) {
        this.vertices = vertices;
        this.error = new Array(4);
        this.deleted = false;
        this.isDirty = false;
        this.deletePending = false;
        this.borderFactor = 0;
    }
    return DecimationTriangle;
}());
var DecimationVertex = /** @class */ (function () {
    function DecimationVertex(position, id) {
        this.position = position;
        this.id = id;
        this.isBorder = true;
        this.q = new QuadraticMatrix();
        this.triangleCount = 0;
        this.triangleStart = 0;
        this.originalOffsets = [];
    }
    DecimationVertex.prototype.updatePosition = function (newPosition) {
        this.position.copyFrom(newPosition);
    };
    return DecimationVertex;
}());
var QuadraticMatrix = /** @class */ (function () {
    function QuadraticMatrix(data) {
        this.data = new Array(10);
        for (var i = 0; i < 10; ++i) {
            if (data && data[i]) {
                this.data[i] = data[i];
            }
            else {
                this.data[i] = 0;
            }
        }
    }
    QuadraticMatrix.prototype.det = function (a11, a12, a13, a21, a22, a23, a31, a32, a33) {
        var det = this.data[a11] * this.data[a22] * this.data[a33] + this.data[a13] * this.data[a21] * this.data[a32] +
            this.data[a12] * this.data[a23] * this.data[a31] - this.data[a13] * this.data[a22] * this.data[a31] -
            this.data[a11] * this.data[a23] * this.data[a32] - this.data[a12] * this.data[a21] * this.data[a33];
        return det;
    };
    QuadraticMatrix.prototype.addInPlace = function (matrix) {
        for (var i = 0; i < 10; ++i) {
            this.data[i] += matrix.data[i];
        }
    };
    QuadraticMatrix.prototype.addArrayInPlace = function (data) {
        for (var i = 0; i < 10; ++i) {
            this.data[i] += data[i];
        }
    };
    QuadraticMatrix.prototype.add = function (matrix) {
        var m = new QuadraticMatrix();
        for (var i = 0; i < 10; ++i) {
            m.data[i] = this.data[i] + matrix.data[i];
        }
        return m;
    };
    QuadraticMatrix.FromData = function (a, b, c, d) {
        return new QuadraticMatrix(QuadraticMatrix.DataFromNumbers(a, b, c, d));
    };
    //returning an array to avoid garbage collection
    QuadraticMatrix.DataFromNumbers = function (a, b, c, d) {
        return [a * a, a * b, a * c, a * d, b * b, b * c, b * d, c * c, c * d, d * d];
    };
    return QuadraticMatrix;
}());
var Reference = /** @class */ (function () {
    function Reference(vertexId, triangleId) {
        this.vertexId = vertexId;
        this.triangleId = triangleId;
    }
    return Reference;
}());
/**
 * An implementation of the Quadratic Error simplification algorithm.
 * Original paper : http://www1.cs.columbia.edu/~cs4162/html05s/garland97.pdf
 * Ported mostly from QSlim and http://voxels.blogspot.de/2014/05/quadric-mesh-simplification-with-source.html to babylon JS
 * @author RaananW
 * @see http://doc.babylonjs.com/how_to/in-browser_mesh_simplification
 */
var QuadraticErrorSimplification = /** @class */ (function () {
    function QuadraticErrorSimplification(_mesh) {
        this._mesh = _mesh;
        this.syncIterations = 5000;
        this.aggressiveness = 7;
        this.decimationIterations = 100;
        this.boundingBoxEpsilon = _Maths_math_constants__WEBPACK_IMPORTED_MODULE_5__["Epsilon"];
    }
    QuadraticErrorSimplification.prototype.simplify = function (settings, successCallback) {
        var _this = this;
        this.initDecimatedMesh();
        //iterating through the submeshes array, one after the other.
        _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].Run(this._mesh.subMeshes.length, function (loop) {
            _this.initWithMesh(loop.index, function () {
                _this.runDecimation(settings, loop.index, function () {
                    loop.executeNext();
                });
            }, settings.optimizeMesh);
        }, function () {
            setTimeout(function () {
                successCallback(_this._reconstructedMesh);
            }, 0);
        });
    };
    QuadraticErrorSimplification.prototype.runDecimation = function (settings, submeshIndex, successCallback) {
        var _this = this;
        var targetCount = ~~(this.triangles.length * settings.quality);
        var deletedTriangles = 0;
        var triangleCount = this.triangles.length;
        var iterationFunction = function (iteration, callback) {
            setTimeout(function () {
                if (iteration % 5 === 0) {
                    _this.updateMesh(iteration === 0);
                }
                for (var i = 0; i < _this.triangles.length; ++i) {
                    _this.triangles[i].isDirty = false;
                }
                var threshold = 0.000000001 * Math.pow((iteration + 3), _this.aggressiveness);
                var trianglesIterator = function (i) {
                    var tIdx = ~~(((_this.triangles.length / 2) + i) % _this.triangles.length);
                    var t = _this.triangles[tIdx];
                    if (!t) {
                        return;
                    }
                    if (t.error[3] > threshold || t.deleted || t.isDirty) {
                        return;
                    }
                    for (var j = 0; j < 3; ++j) {
                        if (t.error[j] < threshold) {
                            var deleted0 = [];
                            var deleted1 = [];
                            var v0 = t.vertices[j];
                            var v1 = t.vertices[(j + 1) % 3];
                            if (v0.isBorder || v1.isBorder) {
                                continue;
                            }
                            var p = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                            // var n = Vector3.Zero();
                            // var uv = Vector2.Zero();
                            // var color = new Color4(0, 0, 0, 1);
                            _this.calculateError(v0, v1, p);
                            var delTr = new Array();
                            if (_this.isFlipped(v0, v1, p, deleted0, delTr)) {
                                continue;
                            }
                            if (_this.isFlipped(v1, v0, p, deleted1, delTr)) {
                                continue;
                            }
                            if (deleted0.indexOf(true) < 0 || deleted1.indexOf(true) < 0) {
                                continue;
                            }
                            var uniqueArray = new Array();
                            delTr.forEach(function (deletedT) {
                                if (uniqueArray.indexOf(deletedT) === -1) {
                                    deletedT.deletePending = true;
                                    uniqueArray.push(deletedT);
                                }
                            });
                            if (uniqueArray.length % 2 !== 0) {
                                continue;
                            }
                            v0.q = v1.q.add(v0.q);
                            v0.updatePosition(p);
                            var tStart = _this.references.length;
                            deletedTriangles = _this.updateTriangles(v0, v0, deleted0, deletedTriangles);
                            deletedTriangles = _this.updateTriangles(v0, v1, deleted1, deletedTriangles);
                            var tCount = _this.references.length - tStart;
                            if (tCount <= v0.triangleCount) {
                                if (tCount) {
                                    for (var c = 0; c < tCount; c++) {
                                        _this.references[v0.triangleStart + c] = _this.references[tStart + c];
                                    }
                                }
                            }
                            else {
                                v0.triangleStart = tStart;
                            }
                            v0.triangleCount = tCount;
                            break;
                        }
                    }
                };
                _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, trianglesIterator, callback, function () { return (triangleCount - deletedTriangles <= targetCount); });
            }, 0);
        };
        _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].Run(this.decimationIterations, function (loop) {
            if (triangleCount - deletedTriangles <= targetCount) {
                loop.breakLoop();
            }
            else {
                iterationFunction(loop.index, function () {
                    loop.executeNext();
                });
            }
        }, function () {
            setTimeout(function () {
                //reconstruct this part of the mesh
                _this.reconstructMesh(submeshIndex);
                successCallback();
            }, 0);
        });
    };
    QuadraticErrorSimplification.prototype.initWithMesh = function (submeshIndex, callback, optimizeMesh) {
        var _this = this;
        this.vertices = [];
        this.triangles = [];
        var positionData = this._mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
        var indices = this._mesh.getIndices();
        var submesh = this._mesh.subMeshes[submeshIndex];
        var findInVertices = function (positionToSearch) {
            if (optimizeMesh) {
                for (var ii = 0; ii < _this.vertices.length; ++ii) {
                    if (_this.vertices[ii].position.equals(positionToSearch)) {
                        return _this.vertices[ii];
                    }
                }
            }
            return null;
        };
        var vertexReferences = [];
        var vertexInit = function (i) {
            if (!positionData) {
                return;
            }
            var offset = i + submesh.verticesStart;
            var position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(positionData, offset * 3);
            var vertex = findInVertices(position) || new DecimationVertex(position, _this.vertices.length);
            vertex.originalOffsets.push(offset);
            if (vertex.id === _this.vertices.length) {
                _this.vertices.push(vertex);
            }
            vertexReferences.push(vertex.id);
        };
        //var totalVertices = mesh.getTotalVertices();
        var totalVertices = submesh.verticesCount;
        _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].SyncAsyncForLoop(totalVertices, (this.syncIterations / 4) >> 0, vertexInit, function () {
            var indicesInit = function (i) {
                if (!indices) {
                    return;
                }
                var offset = (submesh.indexStart / 3) + i;
                var pos = (offset * 3);
                var i0 = indices[pos + 0];
                var i1 = indices[pos + 1];
                var i2 = indices[pos + 2];
                var v0 = _this.vertices[vertexReferences[i0 - submesh.verticesStart]];
                var v1 = _this.vertices[vertexReferences[i1 - submesh.verticesStart]];
                var v2 = _this.vertices[vertexReferences[i2 - submesh.verticesStart]];
                var triangle = new DecimationTriangle([v0, v1, v2]);
                triangle.originalOffset = pos;
                _this.triangles.push(triangle);
            };
            _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].SyncAsyncForLoop(submesh.indexCount / 3, _this.syncIterations, indicesInit, function () {
                _this.init(callback);
            });
        });
    };
    QuadraticErrorSimplification.prototype.init = function (callback) {
        var _this = this;
        var triangleInit1 = function (i) {
            var t = _this.triangles[i];
            t.normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(t.vertices[1].position.subtract(t.vertices[0].position), t.vertices[2].position.subtract(t.vertices[0].position)).normalize();
            for (var j = 0; j < 3; j++) {
                t.vertices[j].q.addArrayInPlace(QuadraticMatrix.DataFromNumbers(t.normal.x, t.normal.y, t.normal.z, -(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(t.normal, t.vertices[0].position))));
            }
        };
        _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].SyncAsyncForLoop(this.triangles.length, this.syncIterations, triangleInit1, function () {
            var triangleInit2 = function (i) {
                var t = _this.triangles[i];
                for (var j = 0; j < 3; ++j) {
                    t.error[j] = _this.calculateError(t.vertices[j], t.vertices[(j + 1) % 3]);
                }
                t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
            };
            _Misc_tools__WEBPACK_IMPORTED_MODULE_4__["AsyncLoop"].SyncAsyncForLoop(_this.triangles.length, _this.syncIterations, triangleInit2, function () {
                callback();
            });
        });
    };
    QuadraticErrorSimplification.prototype.reconstructMesh = function (submeshIndex) {
        var newTriangles = [];
        var i;
        for (i = 0; i < this.vertices.length; ++i) {
            this.vertices[i].triangleCount = 0;
        }
        var t;
        var j;
        for (i = 0; i < this.triangles.length; ++i) {
            if (!this.triangles[i].deleted) {
                t = this.triangles[i];
                for (j = 0; j < 3; ++j) {
                    t.vertices[j].triangleCount = 1;
                }
                newTriangles.push(t);
            }
        }
        var newPositionData = (this._reconstructedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind) || []);
        var newNormalData = (this._reconstructedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind) || []);
        var newUVsData = (this._reconstructedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind) || []);
        var newColorsData = (this._reconstructedMesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind) || []);
        var normalData = this._mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind);
        var uvs = this._mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind);
        var colorsData = this._mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind);
        var vertexCount = 0;
        for (i = 0; i < this.vertices.length; ++i) {
            var vertex = this.vertices[i];
            vertex.id = vertexCount;
            if (vertex.triangleCount) {
                vertex.originalOffsets.forEach(function (originalOffset) {
                    if (!normalData) {
                        return;
                    }
                    newPositionData.push(vertex.position.x);
                    newPositionData.push(vertex.position.y);
                    newPositionData.push(vertex.position.z);
                    newNormalData.push(normalData[originalOffset * 3]);
                    newNormalData.push(normalData[(originalOffset * 3) + 1]);
                    newNormalData.push(normalData[(originalOffset * 3) + 2]);
                    if (uvs && uvs.length) {
                        newUVsData.push(uvs[(originalOffset * 2)]);
                        newUVsData.push(uvs[(originalOffset * 2) + 1]);
                    }
                    if (colorsData && colorsData.length) {
                        newColorsData.push(colorsData[(originalOffset * 4)]);
                        newColorsData.push(colorsData[(originalOffset * 4) + 1]);
                        newColorsData.push(colorsData[(originalOffset * 4) + 2]);
                        newColorsData.push(colorsData[(originalOffset * 4) + 3]);
                    }
                    ++vertexCount;
                });
            }
        }
        var startingIndex = this._reconstructedMesh.getTotalIndices();
        var startingVertex = this._reconstructedMesh.getTotalVertices();
        var submeshesArray = this._reconstructedMesh.subMeshes;
        this._reconstructedMesh.subMeshes = [];
        var newIndicesArray = this._reconstructedMesh.getIndices(); //[];
        var originalIndices = this._mesh.getIndices();
        for (i = 0; i < newTriangles.length; ++i) {
            t = newTriangles[i]; //now get the new referencing point for each vertex
            [0, 1, 2].forEach(function (idx) {
                var id = originalIndices[t.originalOffset + idx];
                var offset = t.vertices[idx].originalOffsets.indexOf(id);
                if (offset < 0) {
                    offset = 0;
                }
                newIndicesArray.push(t.vertices[idx].id + offset + startingVertex);
            });
        }
        //overwriting the old vertex buffers and indices.
        this._reconstructedMesh.setIndices(newIndicesArray);
        this._reconstructedMesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, newPositionData);
        this._reconstructedMesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, newNormalData);
        if (newUVsData.length > 0) {
            this._reconstructedMesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind, newUVsData);
        }
        if (newColorsData.length > 0) {
            this._reconstructedMesh.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].ColorKind, newColorsData);
        }
        //create submesh
        var originalSubmesh = this._mesh.subMeshes[submeshIndex];
        if (submeshIndex > 0) {
            this._reconstructedMesh.subMeshes = [];
            submeshesArray.forEach(function (submesh) {
                _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_2__["SubMesh"].AddToMesh(submesh.materialIndex, submesh.verticesStart, submesh.verticesCount, /* 0, newPositionData.length/3, */ submesh.indexStart, submesh.indexCount, submesh.getMesh());
            });
            _Meshes_subMesh__WEBPACK_IMPORTED_MODULE_2__["SubMesh"].AddToMesh(originalSubmesh.materialIndex, startingVertex, vertexCount, /* 0, newPositionData.length / 3, */ startingIndex, newTriangles.length * 3, this._reconstructedMesh);
        }
    };
    QuadraticErrorSimplification.prototype.initDecimatedMesh = function () {
        this._reconstructedMesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_3__["Mesh"](this._mesh.name + "Decimated", this._mesh.getScene());
        this._reconstructedMesh.material = this._mesh.material;
        this._reconstructedMesh.parent = this._mesh.parent;
        this._reconstructedMesh.isVisible = false;
        this._reconstructedMesh.renderingGroupId = this._mesh.renderingGroupId;
    };
    QuadraticErrorSimplification.prototype.isFlipped = function (vertex1, vertex2, point, deletedArray, delTr) {
        for (var i = 0; i < vertex1.triangleCount; ++i) {
            var t = this.triangles[this.references[vertex1.triangleStart + i].triangleId];
            if (t.deleted) {
                continue;
            }
            var s = this.references[vertex1.triangleStart + i].vertexId;
            var v1 = t.vertices[(s + 1) % 3];
            var v2 = t.vertices[(s + 2) % 3];
            if ((v1 === vertex2 || v2 === vertex2)) {
                deletedArray[i] = true;
                delTr.push(t);
                continue;
            }
            var d1 = v1.position.subtract(point);
            d1 = d1.normalize();
            var d2 = v2.position.subtract(point);
            d2 = d2.normalize();
            if (Math.abs(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(d1, d2)) > 0.999) {
                return true;
            }
            var normal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(d1, d2).normalize();
            deletedArray[i] = false;
            if (_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(normal, t.normal) < 0.2) {
                return true;
            }
        }
        return false;
    };
    QuadraticErrorSimplification.prototype.updateTriangles = function (origVertex, vertex, deletedArray, deletedTriangles) {
        var newDeleted = deletedTriangles;
        for (var i = 0; i < vertex.triangleCount; ++i) {
            var ref = this.references[vertex.triangleStart + i];
            var t = this.triangles[ref.triangleId];
            if (t.deleted) {
                continue;
            }
            if (deletedArray[i] && t.deletePending) {
                t.deleted = true;
                newDeleted++;
                continue;
            }
            t.vertices[ref.vertexId] = origVertex;
            t.isDirty = true;
            t.error[0] = this.calculateError(t.vertices[0], t.vertices[1]) + (t.borderFactor / 2);
            t.error[1] = this.calculateError(t.vertices[1], t.vertices[2]) + (t.borderFactor / 2);
            t.error[2] = this.calculateError(t.vertices[2], t.vertices[0]) + (t.borderFactor / 2);
            t.error[3] = Math.min(t.error[0], t.error[1], t.error[2]);
            this.references.push(ref);
        }
        return newDeleted;
    };
    QuadraticErrorSimplification.prototype.identifyBorder = function () {
        for (var i = 0; i < this.vertices.length; ++i) {
            var vCount = [];
            var vId = [];
            var v = this.vertices[i];
            var j;
            for (j = 0; j < v.triangleCount; ++j) {
                var triangle = this.triangles[this.references[v.triangleStart + j].triangleId];
                for (var ii = 0; ii < 3; ii++) {
                    var ofs = 0;
                    var vv = triangle.vertices[ii];
                    while (ofs < vCount.length) {
                        if (vId[ofs] === vv.id) {
                            break;
                        }
                        ++ofs;
                    }
                    if (ofs === vCount.length) {
                        vCount.push(1);
                        vId.push(vv.id);
                    }
                    else {
                        vCount[ofs]++;
                    }
                }
            }
            for (j = 0; j < vCount.length; ++j) {
                if (vCount[j] === 1) {
                    this.vertices[vId[j]].isBorder = true;
                }
                else {
                    this.vertices[vId[j]].isBorder = false;
                }
            }
        }
    };
    QuadraticErrorSimplification.prototype.updateMesh = function (identifyBorders) {
        if (identifyBorders === void 0) { identifyBorders = false; }
        var i;
        if (!identifyBorders) {
            var newTrianglesVector = [];
            for (i = 0; i < this.triangles.length; ++i) {
                if (!this.triangles[i].deleted) {
                    newTrianglesVector.push(this.triangles[i]);
                }
            }
            this.triangles = newTrianglesVector;
        }
        for (i = 0; i < this.vertices.length; ++i) {
            this.vertices[i].triangleCount = 0;
            this.vertices[i].triangleStart = 0;
        }
        var t;
        var j;
        var v;
        for (i = 0; i < this.triangles.length; ++i) {
            t = this.triangles[i];
            for (j = 0; j < 3; ++j) {
                v = t.vertices[j];
                v.triangleCount++;
            }
        }
        var tStart = 0;
        for (i = 0; i < this.vertices.length; ++i) {
            this.vertices[i].triangleStart = tStart;
            tStart += this.vertices[i].triangleCount;
            this.vertices[i].triangleCount = 0;
        }
        var newReferences = new Array(this.triangles.length * 3);
        for (i = 0; i < this.triangles.length; ++i) {
            t = this.triangles[i];
            for (j = 0; j < 3; ++j) {
                v = t.vertices[j];
                newReferences[v.triangleStart + v.triangleCount] = new Reference(j, i);
                v.triangleCount++;
            }
        }
        this.references = newReferences;
        if (identifyBorders) {
            this.identifyBorder();
        }
    };
    QuadraticErrorSimplification.prototype.vertexError = function (q, point) {
        var x = point.x;
        var y = point.y;
        var z = point.z;
        return q.data[0] * x * x + 2 * q.data[1] * x * y + 2 * q.data[2] * x * z + 2 * q.data[3] * x + q.data[4] * y * y
            + 2 * q.data[5] * y * z + 2 * q.data[6] * y + q.data[7] * z * z + 2 * q.data[8] * z + q.data[9];
    };
    QuadraticErrorSimplification.prototype.calculateError = function (vertex1, vertex2, pointResult) {
        var q = vertex1.q.add(vertex2.q);
        var border = vertex1.isBorder && vertex2.isBorder;
        var error = 0;
        var qDet = q.det(0, 1, 2, 1, 4, 5, 2, 5, 7);
        if (qDet !== 0 && !border) {
            if (!pointResult) {
                pointResult = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
            }
            pointResult.x = -1 / qDet * (q.det(1, 2, 3, 4, 5, 6, 5, 7, 8));
            pointResult.y = 1 / qDet * (q.det(0, 2, 3, 1, 5, 6, 2, 7, 8));
            pointResult.z = -1 / qDet * (q.det(0, 1, 3, 1, 4, 6, 2, 5, 8));
            error = this.vertexError(q, pointResult);
        }
        else {
            var p3 = (vertex1.position.add(vertex2.position)).divide(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](2, 2, 2));
            //var norm3 = (vertex1.normal.add(vertex2.normal)).divide(new Vector3(2, 2, 2)).normalize();
            var error1 = this.vertexError(q, vertex1.position);
            var error2 = this.vertexError(q, vertex2.position);
            var error3 = this.vertexError(q, p3);
            error = Math.min(error1, error2, error3);
            if (error === error1) {
                if (pointResult) {
                    pointResult.copyFrom(vertex1.position);
                }
            }
            else if (error === error2) {
                if (pointResult) {
                    pointResult.copyFrom(vertex2.position);
                }
            }
            else {
                if (pointResult) {
                    pointResult.copyFrom(p3);
                }
            }
        }
        return error;
    };
    return QuadraticErrorSimplification;
}());


/***/ }),

/***/ "./Meshes/meshSimplificationSceneComponent.ts":
/*!****************************************************!*\
  !*** ./Meshes/meshSimplificationSceneComponent.ts ***!
  \****************************************************/
/*! exports provided: SimplicationQueueSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimplicationQueueSceneComponent", function() { return SimplicationQueueSceneComponent; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _meshSimplification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./meshSimplification */ "./Meshes/meshSimplification.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");




Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype, "simplificationQueue", {
    get: function () {
        if (!this._simplificationQueue) {
            this._simplificationQueue = new _meshSimplification__WEBPACK_IMPORTED_MODULE_2__["SimplificationQueue"]();
            var component = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].NAME_SIMPLIFICATIONQUEUE);
            if (!component) {
                component = new SimplicationQueueSceneComponent(this);
                this._addComponent(component);
            }
        }
        return this._simplificationQueue;
    },
    set: function (value) {
        this._simplificationQueue = value;
    },
    enumerable: true,
    configurable: true
});
_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"].prototype.simplify = function (settings, parallelProcessing, simplificationType, successCallback) {
    if (parallelProcessing === void 0) { parallelProcessing = true; }
    if (simplificationType === void 0) { simplificationType = _meshSimplification__WEBPACK_IMPORTED_MODULE_2__["SimplificationType"].QUADRATIC; }
    this.getScene().simplificationQueue.addTask({
        settings: settings,
        parallelProcessing: parallelProcessing,
        mesh: this,
        simplificationType: simplificationType,
        successCallback: successCallback
    });
    return this;
};
/**
 * Defines the simplification queue scene component responsible to help scheduling the various simplification task
 * created in a scene
 */
var SimplicationQueueSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function SimplicationQueueSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].NAME_SIMPLIFICATIONQUEUE;
        this.scene = scene;
    }
    /**
     * Registers the component in a given scene
     */
    SimplicationQueueSceneComponent.prototype.register = function () {
        this.scene._beforeCameraUpdateStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE, this, this._beforeCameraUpdate);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    SimplicationQueueSceneComponent.prototype.rebuild = function () {
        // Nothing to do for this component
    };
    /**
     * Disposes the component and the associated ressources
     */
    SimplicationQueueSceneComponent.prototype.dispose = function () {
        // Nothing to do for this component
    };
    SimplicationQueueSceneComponent.prototype._beforeCameraUpdate = function () {
        if (this.scene._simplificationQueue && !this.scene._simplificationQueue.running) {
            this.scene._simplificationQueue.executeNext();
        }
    };
    return SimplicationQueueSceneComponent;
}());



/***/ }),

/***/ "./Meshes/polygonMesh.ts":
/*!*******************************!*\
  !*** ./Meshes/polygonMesh.ts ***!
  \*******************************/
/*! exports provided: Polygon, PolygonMeshBuilder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Polygon", function() { return Polygon; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PolygonMeshBuilder", function() { return PolygonMeshBuilder; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Maths_math_path__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Maths/math.path */ "./Maths/math.path.ts");








/**
 * Vector2 wth index property
 */
var IndexedVector2 = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IndexedVector2, _super);
    function IndexedVector2(original,
    /** Index of the vector2 */
    index) {
        var _this = _super.call(this, original.x, original.y) || this;
        _this.index = index;
        return _this;
    }
    return IndexedVector2;
}(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"]));
/**
 * Defines points to create a polygon
 */
var PolygonPoints = /** @class */ (function () {
    function PolygonPoints() {
        this.elements = new Array();
    }
    PolygonPoints.prototype.add = function (originalPoints) {
        var _this = this;
        var result = new Array();
        originalPoints.forEach(function (point) {
            if (result.length === 0 || !point.equalsWithEpsilon(result[0])) {
                var newPoint = new IndexedVector2(point, _this.elements.length);
                result.push(newPoint);
                _this.elements.push(newPoint);
            }
        });
        return result;
    };
    PolygonPoints.prototype.computeBounds = function () {
        var lmin = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](this.elements[0].x, this.elements[0].y);
        var lmax = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](this.elements[0].x, this.elements[0].y);
        this.elements.forEach(function (point) {
            // x
            if (point.x < lmin.x) {
                lmin.x = point.x;
            }
            else if (point.x > lmax.x) {
                lmax.x = point.x;
            }
            // y
            if (point.y < lmin.y) {
                lmin.y = point.y;
            }
            else if (point.y > lmax.y) {
                lmax.y = point.y;
            }
        });
        return {
            min: lmin,
            max: lmax,
            width: lmax.x - lmin.x,
            height: lmax.y - lmin.y
        };
    };
    return PolygonPoints;
}());
/**
 * Polygon
 * @see https://doc.babylonjs.com/how_to/parametric_shapes#non-regular-polygon
 */
var Polygon = /** @class */ (function () {
    function Polygon() {
    }
    /**
     * Creates a rectangle
     * @param xmin bottom X coord
     * @param ymin bottom Y coord
     * @param xmax top X coord
     * @param ymax top Y coord
     * @returns points that make the resulting rectation
     */
    Polygon.Rectangle = function (xmin, ymin, xmax, ymax) {
        return [
            new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](xmin, ymin),
            new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](xmax, ymin),
            new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](xmax, ymax),
            new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](xmin, ymax)
        ];
    };
    /**
     * Creates a circle
     * @param radius radius of circle
     * @param cx scale in x
     * @param cy scale in y
     * @param numberOfSides number of sides that make up the circle
     * @returns points that make the resulting circle
     */
    Polygon.Circle = function (radius, cx, cy, numberOfSides) {
        if (cx === void 0) { cx = 0; }
        if (cy === void 0) { cy = 0; }
        if (numberOfSides === void 0) { numberOfSides = 32; }
        var result = new Array();
        var angle = 0;
        var increment = (Math.PI * 2) / numberOfSides;
        for (var i = 0; i < numberOfSides; i++) {
            result.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](cx + Math.cos(angle) * radius, cy + Math.sin(angle) * radius));
            angle -= increment;
        }
        return result;
    };
    /**
     * Creates a polygon from input string
     * @param input Input polygon data
     * @returns the parsed points
     */
    Polygon.Parse = function (input) {
        var floats = input.split(/[^-+eE\.\d]+/).map(parseFloat).filter(function (val) { return (!isNaN(val)); });
        var i, result = [];
        for (i = 0; i < (floats.length & 0x7FFFFFFE); i += 2) {
            result.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](floats[i], floats[i + 1]));
        }
        return result;
    };
    /**
     * Starts building a polygon from x and y coordinates
     * @param x x coordinate
     * @param y y coordinate
     * @returns the started path2
     */
    Polygon.StartingAt = function (x, y) {
        return _Maths_math_path__WEBPACK_IMPORTED_MODULE_7__["Path2"].StartingAt(x, y);
    };
    return Polygon;
}());

/**
 * Builds a polygon
 * @see https://doc.babylonjs.com/how_to/polygonmeshbuilder
 */
var PolygonMeshBuilder = /** @class */ (function () {
    /**
     * Creates a PolygonMeshBuilder
     * @param name name of the builder
     * @param contours Path of the polygon
     * @param scene scene to add to when creating the mesh
     * @param earcutInjection can be used to inject your own earcut reference
     */
    function PolygonMeshBuilder(name, contours, scene, earcutInjection) {
        if (earcutInjection === void 0) { earcutInjection = earcut; }
        this._points = new PolygonPoints();
        this._outlinepoints = new PolygonPoints();
        this._holes = new Array();
        this._epoints = new Array();
        this._eholes = new Array();
        this.bjsEarcut = earcutInjection;
        this._name = name;
        this._scene = scene || _Engines_engine__WEBPACK_IMPORTED_MODULE_6__["Engine"].LastCreatedScene;
        var points;
        if (contours instanceof _Maths_math_path__WEBPACK_IMPORTED_MODULE_7__["Path2"]) {
            points = contours.getPoints();
        }
        else {
            points = contours;
        }
        this._addToepoint(points);
        this._points.add(points);
        this._outlinepoints.add(points);
        if (typeof this.bjsEarcut === 'undefined') {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Earcut was not found, the polygon will not be built.");
        }
    }
    PolygonMeshBuilder.prototype._addToepoint = function (points) {
        for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {
            var p = points_1[_i];
            this._epoints.push(p.x, p.y);
        }
    };
    /**
     * Adds a whole within the polygon
     * @param hole Array of points defining the hole
     * @returns this
     */
    PolygonMeshBuilder.prototype.addHole = function (hole) {
        this._points.add(hole);
        var holepoints = new PolygonPoints();
        holepoints.add(hole);
        this._holes.push(holepoints);
        this._eholes.push(this._epoints.length / 2);
        this._addToepoint(hole);
        return this;
    };
    /**
     * Creates the polygon
     * @param updatable If the mesh should be updatable
     * @param depth The depth of the mesh created
     * @returns the created mesh
     */
    PolygonMeshBuilder.prototype.build = function (updatable, depth) {
        if (updatable === void 0) { updatable = false; }
        if (depth === void 0) { depth = 0; }
        var result = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"](this._name, this._scene);
        var vertexData = this.buildVertexData(depth);
        result.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, vertexData.positions, updatable);
        result.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind, vertexData.normals, updatable);
        result.setVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind, vertexData.uvs, updatable);
        result.setIndices(vertexData.indices);
        return result;
    };
    /**
     * Creates the polygon
     * @param depth The depth of the mesh created
     * @returns the created VertexData
     */
    PolygonMeshBuilder.prototype.buildVertexData = function (depth) {
        var _this = this;
        if (depth === void 0) { depth = 0; }
        var result = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_5__["VertexData"]();
        var normals = new Array();
        var positions = new Array();
        var uvs = new Array();
        var bounds = this._points.computeBounds();
        this._points.elements.forEach(function (p) {
            normals.push(0, 1.0, 0);
            positions.push(p.x, 0, p.y);
            uvs.push((p.x - bounds.min.x) / bounds.width, (p.y - bounds.min.y) / bounds.height);
        });
        var indices = new Array();
        var res = this.bjsEarcut(this._epoints, this._eholes, 2);
        for (var i = 0; i < res.length; i++) {
            indices.push(res[i]);
        }
        if (depth > 0) {
            var positionscount = (positions.length / 3); //get the current pointcount
            this._points.elements.forEach(function (p) {
                normals.push(0, -1.0, 0);
                positions.push(p.x, -depth, p.y);
                uvs.push(1 - (p.x - bounds.min.x) / bounds.width, 1 - (p.y - bounds.min.y) / bounds.height);
            });
            var totalCount = indices.length;
            for (var i = 0; i < totalCount; i += 3) {
                var i0 = indices[i + 0];
                var i1 = indices[i + 1];
                var i2 = indices[i + 2];
                indices.push(i2 + positionscount);
                indices.push(i1 + positionscount);
                indices.push(i0 + positionscount);
            }
            //Add the sides
            this.addSide(positions, normals, uvs, indices, bounds, this._outlinepoints, depth, false);
            this._holes.forEach(function (hole) {
                _this.addSide(positions, normals, uvs, indices, bounds, hole, depth, true);
            });
        }
        result.indices = indices;
        result.positions = positions;
        result.normals = normals;
        result.uvs = uvs;
        return result;
    };
    /**
     * Adds a side to the polygon
     * @param positions points that make the polygon
     * @param normals normals of the polygon
     * @param uvs uvs of the polygon
     * @param indices indices of the polygon
     * @param bounds bounds of the polygon
     * @param points points of the polygon
     * @param depth depth of the polygon
     * @param flip flip of the polygon
     */
    PolygonMeshBuilder.prototype.addSide = function (positions, normals, uvs, indices, bounds, points, depth, flip) {
        var StartIndex = positions.length / 3;
        var ulength = 0;
        for (var i = 0; i < points.elements.length; i++) {
            var p = points.elements[i];
            var p1;
            if ((i + 1) > points.elements.length - 1) {
                p1 = points.elements[0];
            }
            else {
                p1 = points.elements[i + 1];
            }
            positions.push(p.x, 0, p.y);
            positions.push(p.x, -depth, p.y);
            positions.push(p1.x, 0, p1.y);
            positions.push(p1.x, -depth, p1.y);
            var v1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](p.x, 0, p.y);
            var v2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](p1.x, 0, p1.y);
            var v3 = v2.subtract(v1);
            var v4 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, 1, 0);
            var vn = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Cross(v3, v4);
            vn = vn.normalize();
            uvs.push(ulength / bounds.width, 0);
            uvs.push(ulength / bounds.width, 1);
            ulength += v3.length();
            uvs.push((ulength / bounds.width), 0);
            uvs.push((ulength / bounds.width), 1);
            if (!flip) {
                normals.push(-vn.x, -vn.y, -vn.z);
                normals.push(-vn.x, -vn.y, -vn.z);
                normals.push(-vn.x, -vn.y, -vn.z);
                normals.push(-vn.x, -vn.y, -vn.z);
                indices.push(StartIndex);
                indices.push(StartIndex + 1);
                indices.push(StartIndex + 2);
                indices.push(StartIndex + 1);
                indices.push(StartIndex + 3);
                indices.push(StartIndex + 2);
            }
            else {
                normals.push(vn.x, vn.y, vn.z);
                normals.push(vn.x, vn.y, vn.z);
                normals.push(vn.x, vn.y, vn.z);
                normals.push(vn.x, vn.y, vn.z);
                indices.push(StartIndex);
                indices.push(StartIndex + 2);
                indices.push(StartIndex + 1);
                indices.push(StartIndex + 1);
                indices.push(StartIndex + 2);
                indices.push(StartIndex + 3);
            }
            StartIndex += 4;
        }
    };
    return PolygonMeshBuilder;
}());



/***/ }),

/***/ "./Meshes/subMesh.ts":
/*!***************************!*\
  !*** ./Meshes/subMesh.ts ***!
  \***************************/
/*! exports provided: BaseSubMesh, SubMesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSubMesh", function() { return BaseSubMesh; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubMesh", function() { return SubMesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Collisions_intersectionInfo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Collisions/intersectionInfo */ "./Collisions/intersectionInfo.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Culling/boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Maths_math_functions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.functions */ "./Maths/math.functions.ts");






/**
 * Base class for submeshes
 */
var BaseSubMesh = /** @class */ (function () {
    function BaseSubMesh() {
        /** @hidden */
        this._materialDefines = null;
        /** @hidden */
        this._materialEffect = null;
    }
    Object.defineProperty(BaseSubMesh.prototype, "effect", {
        /**
         * Gets associated effect
         */
        get: function () {
            return this._materialEffect;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets associated effect (effect used to render this submesh)
     * @param effect defines the effect to associate with
     * @param defines defines the set of defines used to compile this effect
     */
    BaseSubMesh.prototype.setEffect = function (effect, defines) {
        if (defines === void 0) { defines = null; }
        if (this._materialEffect === effect) {
            if (!effect) {
                this._materialDefines = null;
            }
            return;
        }
        this._materialDefines = defines;
        this._materialEffect = effect;
    };
    return BaseSubMesh;
}());

/**
 * Defines a subdivision inside a mesh
 */
var SubMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubMesh, _super);
    /**
     * Creates a new submesh
     * @param materialIndex defines the material index to use
     * @param verticesStart defines vertex index start
     * @param verticesCount defines vertices count
     * @param indexStart defines index start
     * @param indexCount defines indices count
     * @param mesh defines the parent mesh
     * @param renderingMesh defines an optional rendering mesh
     * @param createBoundingBox defines if bounding box should be created for this submesh
     */
    function SubMesh(
    /** the material index to use */
    materialIndex,
    /** vertex index start */
    verticesStart,
    /** vertices count */
    verticesCount,
    /** index start */
    indexStart,
    /** indices count */
    indexCount, mesh, renderingMesh, createBoundingBox) {
        if (createBoundingBox === void 0) { createBoundingBox = true; }
        var _this = _super.call(this) || this;
        _this.materialIndex = materialIndex;
        _this.verticesStart = verticesStart;
        _this.verticesCount = verticesCount;
        _this.indexStart = indexStart;
        _this.indexCount = indexCount;
        /** @hidden */
        _this._linesIndexCount = 0;
        _this._linesIndexBuffer = null;
        /** @hidden */
        _this._lastColliderWorldVertices = null;
        /** @hidden */
        _this._lastColliderTransformMatrix = null;
        /** @hidden */
        _this._renderId = 0;
        /** @hidden */
        _this._alphaIndex = 0;
        /** @hidden */
        _this._distanceToCamera = 0;
        _this._currentMaterial = null;
        _this._mesh = mesh;
        _this._renderingMesh = renderingMesh || mesh;
        mesh.subMeshes.push(_this);
        _this._trianglePlanes = [];
        _this._id = mesh.subMeshes.length - 1;
        if (createBoundingBox) {
            _this.refreshBoundingInfo();
            mesh.computeWorldMatrix(true);
        }
        return _this;
    }
    /**
     * Add a new submesh to a mesh
     * @param materialIndex defines the material index to use
     * @param verticesStart defines vertex index start
     * @param verticesCount defines vertices count
     * @param indexStart defines index start
     * @param indexCount defines indices count
     * @param mesh defines the parent mesh
     * @param renderingMesh defines an optional rendering mesh
     * @param createBoundingBox defines if bounding box should be created for this submesh
     * @returns the new submesh
     */
    SubMesh.AddToMesh = function (materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh, renderingMesh, createBoundingBox) {
        if (createBoundingBox === void 0) { createBoundingBox = true; }
        return new SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh, renderingMesh, createBoundingBox);
    };
    Object.defineProperty(SubMesh.prototype, "IsGlobal", {
        /**
         * Returns true if this submesh covers the entire parent mesh
         * @ignorenaming
         */
        get: function () {
            return (this.verticesStart === 0 && this.verticesCount === this._mesh.getTotalVertices());
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the submesh BoudingInfo object
     * @returns current bounding info (or mesh's one if the submesh is global)
     */
    SubMesh.prototype.getBoundingInfo = function () {
        if (this.IsGlobal) {
            return this._mesh.getBoundingInfo();
        }
        return this._boundingInfo;
    };
    /**
     * Sets the submesh BoundingInfo
     * @param boundingInfo defines the new bounding info to use
     * @returns the SubMesh
     */
    SubMesh.prototype.setBoundingInfo = function (boundingInfo) {
        this._boundingInfo = boundingInfo;
        return this;
    };
    /**
     * Returns the mesh of the current submesh
     * @return the parent mesh
     */
    SubMesh.prototype.getMesh = function () {
        return this._mesh;
    };
    /**
     * Returns the rendering mesh of the submesh
     * @returns the rendering mesh (could be different from parent mesh)
     */
    SubMesh.prototype.getRenderingMesh = function () {
        return this._renderingMesh;
    };
    /**
     * Returns the submesh material
     * @returns null or the current material
     */
    SubMesh.prototype.getMaterial = function () {
        var rootMaterial = this._renderingMesh.material;
        if (rootMaterial === null || rootMaterial === undefined) {
            return this._mesh.getScene().defaultMaterial;
        }
        else if (rootMaterial.getSubMaterial) {
            var multiMaterial = rootMaterial;
            var effectiveMaterial = multiMaterial.getSubMaterial(this.materialIndex);
            if (this._currentMaterial !== effectiveMaterial) {
                this._currentMaterial = effectiveMaterial;
                this._materialDefines = null;
            }
            return effectiveMaterial;
        }
        return rootMaterial;
    };
    // Methods
    /**
     * Sets a new updated BoundingInfo object to the submesh
     * @param data defines an optional position array to use to determine the bounding info
     * @returns the SubMesh
     */
    SubMesh.prototype.refreshBoundingInfo = function (data) {
        if (data === void 0) { data = null; }
        this._lastColliderWorldVertices = null;
        if (this.IsGlobal || !this._renderingMesh || !this._renderingMesh.geometry) {
            return this;
        }
        if (!data) {
            data = this._renderingMesh.getVerticesData(_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
        }
        if (!data) {
            this._boundingInfo = this._mesh.getBoundingInfo();
            return this;
        }
        var indices = this._renderingMesh.getIndices();
        var extend;
        //is this the only submesh?
        if (this.indexStart === 0 && this.indexCount === indices.length) {
            var boundingInfo = this._renderingMesh.getBoundingInfo();
            //the rendering mesh's bounding info can be used, it is the standard submesh for all indices.
            extend = { minimum: boundingInfo.minimum.clone(), maximum: boundingInfo.maximum.clone() };
        }
        else {
            extend = Object(_Maths_math_functions__WEBPACK_IMPORTED_MODULE_5__["extractMinAndMaxIndexed"])(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
        }
        if (this._boundingInfo) {
            this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
        }
        else {
            this._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_3__["BoundingInfo"](extend.minimum, extend.maximum);
        }
        return this;
    };
    /** @hidden */
    SubMesh.prototype._checkCollision = function (collider) {
        var boundingInfo = this.getBoundingInfo();
        return boundingInfo._checkCollision(collider);
    };
    /**
     * Updates the submesh BoundingInfo
     * @param world defines the world matrix to use to update the bounding info
     * @returns the submesh
     */
    SubMesh.prototype.updateBoundingInfo = function (world) {
        var boundingInfo = this.getBoundingInfo();
        if (!boundingInfo) {
            this.refreshBoundingInfo();
            boundingInfo = this.getBoundingInfo();
        }
        boundingInfo.update(world);
        return this;
    };
    /**
     * True is the submesh bounding box intersects the frustum defined by the passed array of planes.
     * @param frustumPlanes defines the frustum planes
     * @returns true if the submesh is intersecting with the frustum
     */
    SubMesh.prototype.isInFrustum = function (frustumPlanes) {
        var boundingInfo = this.getBoundingInfo();
        if (!boundingInfo) {
            return false;
        }
        return boundingInfo.isInFrustum(frustumPlanes, this._mesh.cullingStrategy);
    };
    /**
     * True is the submesh bounding box is completely inside the frustum defined by the passed array of planes
     * @param frustumPlanes defines the frustum planes
     * @returns true if the submesh is inside the frustum
     */
    SubMesh.prototype.isCompletelyInFrustum = function (frustumPlanes) {
        var boundingInfo = this.getBoundingInfo();
        if (!boundingInfo) {
            return false;
        }
        return boundingInfo.isCompletelyInFrustum(frustumPlanes);
    };
    /**
     * Renders the submesh
     * @param enableAlphaMode defines if alpha needs to be used
     * @returns the submesh
     */
    SubMesh.prototype.render = function (enableAlphaMode) {
        this._renderingMesh.render(this, enableAlphaMode);
        return this;
    };
    /**
     * @hidden
     */
    SubMesh.prototype._getLinesIndexBuffer = function (indices, engine) {
        if (!this._linesIndexBuffer) {
            var linesIndices = [];
            for (var index = this.indexStart; index < this.indexStart + this.indexCount; index += 3) {
                linesIndices.push(indices[index], indices[index + 1], indices[index + 1], indices[index + 2], indices[index + 2], indices[index]);
            }
            this._linesIndexBuffer = engine.createIndexBuffer(linesIndices);
            this._linesIndexCount = linesIndices.length;
        }
        return this._linesIndexBuffer;
    };
    /**
     * Checks if the submesh intersects with a ray
     * @param ray defines the ray to test
     * @returns true is the passed ray intersects the submesh bounding box
     */
    SubMesh.prototype.canIntersects = function (ray) {
        var boundingInfo = this.getBoundingInfo();
        if (!boundingInfo) {
            return false;
        }
        return ray.intersectsBox(boundingInfo.boundingBox);
    };
    /**
     * Intersects current submesh with a ray
     * @param ray defines the ray to test
     * @param positions defines mesh's positions array
     * @param indices defines mesh's indices array
     * @param fastCheck defines if only bounding info should be used
     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
     * @returns intersection info or null if no intersection
     */
    SubMesh.prototype.intersects = function (ray, positions, indices, fastCheck, trianglePredicate) {
        var material = this.getMaterial();
        if (!material) {
            return null;
        }
        switch (material.fillMode) {
            case _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_PointListDrawMode:
            case _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_LineListDrawMode:
            case _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_LineLoopDrawMode:
            case _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_LineStripDrawMode:
            case _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_TriangleFanDrawMode:
            case _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].MATERIAL_TriangleStripDrawMode:
                return null;
        }
        // LineMesh first as it's also a Mesh...
        if (this._mesh.getClassName() === "InstancedLinesMesh" || this._mesh.getClassName() === "LinesMesh") {
            // Check if mesh is unindexed
            if (!indices.length) {
                return this._intersectUnIndexedLines(ray, positions, indices, this._mesh.intersectionThreshold, fastCheck);
            }
            return this._intersectLines(ray, positions, indices, this._mesh.intersectionThreshold, fastCheck);
        }
        else {
            // Check if mesh is unindexed
            if (!indices.length && this._mesh._unIndexed) {
                return this._intersectUnIndexedTriangles(ray, positions, indices, fastCheck, trianglePredicate);
            }
            return this._intersectTriangles(ray, positions, indices, fastCheck, trianglePredicate);
        }
    };
    /** @hidden */
    SubMesh.prototype._intersectLines = function (ray, positions, indices, intersectionThreshold, fastCheck) {
        var intersectInfo = null;
        // Line test
        for (var index = this.indexStart; index < this.indexStart + this.indexCount; index += 2) {
            var p0 = positions[indices[index]];
            var p1 = positions[indices[index + 1]];
            var length = ray.intersectionSegment(p0, p1, intersectionThreshold);
            if (length < 0) {
                continue;
            }
            if (fastCheck || !intersectInfo || length < intersectInfo.distance) {
                intersectInfo = new _Collisions_intersectionInfo__WEBPACK_IMPORTED_MODULE_2__["IntersectionInfo"](null, null, length);
                intersectInfo.faceId = index / 2;
                if (fastCheck) {
                    break;
                }
            }
        }
        return intersectInfo;
    };
    /** @hidden */
    SubMesh.prototype._intersectUnIndexedLines = function (ray, positions, indices, intersectionThreshold, fastCheck) {
        var intersectInfo = null;
        // Line test
        for (var index = this.verticesStart; index < this.verticesStart + this.verticesCount; index += 2) {
            var p0 = positions[index];
            var p1 = positions[index + 1];
            var length = ray.intersectionSegment(p0, p1, intersectionThreshold);
            if (length < 0) {
                continue;
            }
            if (fastCheck || !intersectInfo || length < intersectInfo.distance) {
                intersectInfo = new _Collisions_intersectionInfo__WEBPACK_IMPORTED_MODULE_2__["IntersectionInfo"](null, null, length);
                intersectInfo.faceId = index / 2;
                if (fastCheck) {
                    break;
                }
            }
        }
        return intersectInfo;
    };
    /** @hidden */
    SubMesh.prototype._intersectTriangles = function (ray, positions, indices, fastCheck, trianglePredicate) {
        var intersectInfo = null;
        // Triangles test
        for (var index = this.indexStart; index < this.indexStart + this.indexCount; index += 3) {
            var p0 = positions[indices[index]];
            var p1 = positions[indices[index + 1]];
            var p2 = positions[indices[index + 2]];
            if (trianglePredicate && !trianglePredicate(p0, p1, p2, ray)) {
                continue;
            }
            var currentIntersectInfo = ray.intersectsTriangle(p0, p1, p2);
            if (currentIntersectInfo) {
                if (currentIntersectInfo.distance < 0) {
                    continue;
                }
                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {
                    intersectInfo = currentIntersectInfo;
                    intersectInfo.faceId = index / 3;
                    if (fastCheck) {
                        break;
                    }
                }
            }
        }
        return intersectInfo;
    };
    /** @hidden */
    SubMesh.prototype._intersectUnIndexedTriangles = function (ray, positions, indices, fastCheck, trianglePredicate) {
        var intersectInfo = null;
        // Triangles test
        for (var index = this.verticesStart; index < this.verticesStart + this.verticesCount; index += 3) {
            var p0 = positions[index];
            var p1 = positions[index + 1];
            var p2 = positions[index + 2];
            if (trianglePredicate && !trianglePredicate(p0, p1, p2, ray)) {
                continue;
            }
            var currentIntersectInfo = ray.intersectsTriangle(p0, p1, p2);
            if (currentIntersectInfo) {
                if (currentIntersectInfo.distance < 0) {
                    continue;
                }
                if (fastCheck || !intersectInfo || currentIntersectInfo.distance < intersectInfo.distance) {
                    intersectInfo = currentIntersectInfo;
                    intersectInfo.faceId = index / 3;
                    if (fastCheck) {
                        break;
                    }
                }
            }
        }
        return intersectInfo;
    };
    /** @hidden */
    SubMesh.prototype._rebuild = function () {
        if (this._linesIndexBuffer) {
            this._linesIndexBuffer = null;
        }
    };
    // Clone
    /**
     * Creates a new submesh from the passed mesh
     * @param newMesh defines the new hosting mesh
     * @param newRenderingMesh defines an optional rendering mesh
     * @returns the new submesh
     */
    SubMesh.prototype.clone = function (newMesh, newRenderingMesh) {
        var result = new SubMesh(this.materialIndex, this.verticesStart, this.verticesCount, this.indexStart, this.indexCount, newMesh, newRenderingMesh, false);
        if (!this.IsGlobal) {
            var boundingInfo = this.getBoundingInfo();
            if (!boundingInfo) {
                return result;
            }
            result._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_3__["BoundingInfo"](boundingInfo.minimum, boundingInfo.maximum);
        }
        return result;
    };
    // Dispose
    /**
     * Release associated resources
     */
    SubMesh.prototype.dispose = function () {
        if (this._linesIndexBuffer) {
            this._mesh.getScene().getEngine()._releaseBuffer(this._linesIndexBuffer);
            this._linesIndexBuffer = null;
        }
        // Remove from mesh
        var index = this._mesh.subMeshes.indexOf(this);
        this._mesh.subMeshes.splice(index, 1);
    };
    /**
     * Gets the class name
     * @returns the string "SubMesh".
     */
    SubMesh.prototype.getClassName = function () {
        return "SubMesh";
    };
    // Statics
    /**
     * Creates a new submesh from indices data
     * @param materialIndex the index of the main mesh material
     * @param startIndex the index where to start the copy in the mesh indices array
     * @param indexCount the number of indices to copy then from the startIndex
     * @param mesh the main mesh to create the submesh from
     * @param renderingMesh the optional rendering mesh
     * @returns a new submesh
     */
    SubMesh.CreateFromIndices = function (materialIndex, startIndex, indexCount, mesh, renderingMesh) {
        var minVertexIndex = Number.MAX_VALUE;
        var maxVertexIndex = -Number.MAX_VALUE;
        var whatWillRender = (renderingMesh || mesh);
        var indices = whatWillRender.getIndices();
        for (var index = startIndex; index < startIndex + indexCount; index++) {
            var vertexIndex = indices[index];
            if (vertexIndex < minVertexIndex) {
                minVertexIndex = vertexIndex;
            }
            if (vertexIndex > maxVertexIndex) {
                maxVertexIndex = vertexIndex;
            }
        }
        return new SubMesh(materialIndex, minVertexIndex, maxVertexIndex - minVertexIndex + 1, startIndex, indexCount, mesh, renderingMesh);
    };
    return SubMesh;
}(BaseSubMesh));



/***/ }),

/***/ "./Meshes/trailMesh.ts":
/*!*****************************!*\
  !*** ./Meshes/trailMesh.ts ***!
  \*****************************/
/*! exports provided: TrailMesh */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrailMesh", function() { return TrailMesh; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");





/**
 * Class used to create a trail following a mesh
 */
var TrailMesh = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TrailMesh, _super);
    /**
     * @constructor
     * @param name The value used by scene.getMeshByName() to do a lookup.
     * @param generator The mesh to generate a trail.
     * @param scene The scene to add this mesh to.
     * @param diameter Diameter of trailing mesh. Default is 1.
     * @param length Length of trailing mesh. Default is 60.
     * @param autoStart Automatically start trailing mesh. Default true.
     */
    function TrailMesh(name, generator, scene, diameter, length, autoStart) {
        if (diameter === void 0) { diameter = 1; }
        if (length === void 0) { length = 60; }
        if (autoStart === void 0) { autoStart = true; }
        var _this = _super.call(this, name, scene) || this;
        _this._sectionPolygonPointsCount = 4;
        _this._running = false;
        _this._autoStart = autoStart;
        _this._generator = generator;
        _this._diameter = diameter;
        _this._length = length;
        _this._sectionVectors = [];
        _this._sectionNormalVectors = [];
        for (var i = 0; i < _this._sectionPolygonPointsCount; i++) {
            _this._sectionVectors[i] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
            _this._sectionNormalVectors[i] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        }
        _this._createMesh();
        return _this;
    }
    /**
     * "TrailMesh"
     * @returns "TrailMesh"
     */
    TrailMesh.prototype.getClassName = function () {
        return "TrailMesh";
    };
    TrailMesh.prototype._createMesh = function () {
        var data = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_4__["VertexData"]();
        var positions = [];
        var normals = [];
        var indices = [];
        var meshCenter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        if (this._generator._boundingInfo) {
            meshCenter = this._generator._boundingInfo.boundingBox.centerWorld;
        }
        var alpha = 2 * Math.PI / this._sectionPolygonPointsCount;
        for (var i = 0; i < this._sectionPolygonPointsCount; i++) {
            positions.push(meshCenter.x + Math.cos(i * alpha) * this._diameter, meshCenter.y + Math.sin(i * alpha) * this._diameter, meshCenter.z);
        }
        for (var i = 1; i <= this._length; i++) {
            for (var j = 0; j < this._sectionPolygonPointsCount; j++) {
                positions.push(meshCenter.x + Math.cos(j * alpha) * this._diameter, meshCenter.y + Math.sin(j * alpha) * this._diameter, meshCenter.z);
            }
            var l = positions.length / 3 - 2 * this._sectionPolygonPointsCount;
            for (var j = 0; j < this._sectionPolygonPointsCount - 1; j++) {
                indices.push(l + j, l + j + this._sectionPolygonPointsCount, l + j + this._sectionPolygonPointsCount + 1);
                indices.push(l + j, l + j + this._sectionPolygonPointsCount + 1, l + j + 1);
            }
            indices.push(l + this._sectionPolygonPointsCount - 1, l + this._sectionPolygonPointsCount - 1 + this._sectionPolygonPointsCount, l + this._sectionPolygonPointsCount);
            indices.push(l + this._sectionPolygonPointsCount - 1, l + this._sectionPolygonPointsCount, l);
        }
        _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_4__["VertexData"].ComputeNormals(positions, indices, normals);
        data.positions = positions;
        data.normals = normals;
        data.indices = indices;
        data.applyToMesh(this, true);
        if (this._autoStart) {
            this.start();
        }
    };
    /**
     * Start trailing mesh.
     */
    TrailMesh.prototype.start = function () {
        var _this = this;
        if (!this._running) {
            this._running = true;
            this._beforeRenderObserver = this.getScene().onBeforeRenderObservable.add(function () {
                _this.update();
            });
        }
    };
    /**
     * Stop trailing mesh.
     */
    TrailMesh.prototype.stop = function () {
        if (this._beforeRenderObserver && this._running) {
            this._running = false;
            this.getScene().onBeforeRenderObservable.remove(this._beforeRenderObserver);
        }
    };
    /**
     * Update trailing mesh geometry.
     */
    TrailMesh.prototype.update = function () {
        var positions = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind);
        var normals = this.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind);
        var wm = this._generator.getWorldMatrix();
        if (positions && normals) {
            for (var i = 3 * this._sectionPolygonPointsCount; i < positions.length; i++) {
                positions[i - 3 * this._sectionPolygonPointsCount] = positions[i] - normals[i] / this._length * this._diameter;
            }
            for (var i = 3 * this._sectionPolygonPointsCount; i < normals.length; i++) {
                normals[i - 3 * this._sectionPolygonPointsCount] = normals[i];
            }
            var l = positions.length - 3 * this._sectionPolygonPointsCount;
            var alpha = 2 * Math.PI / this._sectionPolygonPointsCount;
            for (var i = 0; i < this._sectionPolygonPointsCount; i++) {
                this._sectionVectors[i].copyFromFloats(Math.cos(i * alpha) * this._diameter, Math.sin(i * alpha) * this._diameter, 0);
                this._sectionNormalVectors[i].copyFromFloats(Math.cos(i * alpha), Math.sin(i * alpha), 0);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformCoordinatesToRef(this._sectionVectors[i], wm, this._sectionVectors[i]);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].TransformNormalToRef(this._sectionNormalVectors[i], wm, this._sectionNormalVectors[i]);
            }
            for (var i = 0; i < this._sectionPolygonPointsCount; i++) {
                positions[l + 3 * i] = this._sectionVectors[i].x;
                positions[l + 3 * i + 1] = this._sectionVectors[i].y;
                positions[l + 3 * i + 2] = this._sectionVectors[i].z;
                normals[l + 3 * i] = this._sectionNormalVectors[i].x;
                normals[l + 3 * i + 1] = this._sectionNormalVectors[i].y;
                normals[l + 3 * i + 2] = this._sectionNormalVectors[i].z;
            }
            this.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind, positions, true, false);
            this.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind, normals, true, false);
        }
    };
    /**
     * Returns a new TrailMesh object.
     * @param name is a string, the name given to the new mesh
     * @param newGenerator use new generator object for cloned trail mesh
     * @returns a new mesh
     */
    TrailMesh.prototype.clone = function (name, newGenerator) {
        if (name === void 0) { name = ""; }
        return new TrailMesh(name, (newGenerator === undefined ? this._generator : newGenerator), this.getScene(), this._diameter, this._length, this._autoStart);
    };
    /**
     * Serializes this trail mesh
     * @param serializationObject object to write serialization to
     */
    TrailMesh.prototype.serialize = function (serializationObject) {
        _super.prototype.serialize.call(this, serializationObject);
    };
    /**
     * Parses a serialized trail mesh
     * @param parsedMesh the serialized mesh
     * @param scene the scene to create the trail mesh in
     * @returns the created trail mesh
     */
    TrailMesh.Parse = function (parsedMesh, scene) {
        return new TrailMesh(parsedMesh.name, parsedMesh._generator, scene, parsedMesh._diameter, parsedMesh._length, parsedMesh._autoStart);
    };
    return TrailMesh;
}(_Meshes_mesh__WEBPACK_IMPORTED_MODULE_1__["Mesh"]));



/***/ }),

/***/ "./Meshes/transformNode.ts":
/*!*********************************!*\
  !*** ./Meshes/transformNode.ts ***!
  \*********************************/
/*! exports provided: TransformNode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TransformNode", function() { return TransformNode; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../node */ "./node.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");






/**
 * A TransformNode is an object that is not rendered but can be used as a center of transformation. This can decrease memory usage and increase rendering speed compared to using an empty mesh as a parent and is less complicated than using a pivot matrix.
 * @see https://doc.babylonjs.com/how_to/transformnode
 */
var TransformNode = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TransformNode, _super);
    function TransformNode(name, scene, isPure) {
        if (scene === void 0) { scene = null; }
        if (isPure === void 0) { isPure = true; }
        var _this = _super.call(this, name, scene) || this;
        _this._forward = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 1);
        _this._forwardInverted = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, -1);
        _this._up = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 1, 0);
        _this._right = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1, 0, 0);
        _this._rightInverted = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](-1, 0, 0);
        // Properties
        _this._position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._rotationQuaternion = null;
        _this._scaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].One();
        _this._isDirty = false;
        _this._transformToBoneReferal = null;
        _this._isAbsoluteSynced = false;
        _this._billboardMode = TransformNode.BILLBOARDMODE_NONE;
        _this._preserveParentRotationForBillboard = false;
        /**
         * Multiplication factor on scale x/y/z when computing the world matrix. Eg. for a 1x1x1 cube setting this to 2 will make it a 2x2x2 cube
         */
        _this.scalingDeterminant = 1;
        _this._infiniteDistance = false;
        /**
         * Gets or sets a boolean indicating that non uniform scaling (when at least one component is different from others) should be ignored.
         * By default the system will update normals to compensate
         */
        _this.ignoreNonUniformScaling = false;
        /**
         * Gets or sets a boolean indicating that even if rotationQuaternion is defined, you can keep updating rotation property and Babylon.js will just mix both
         */
        _this.reIntegrateRotationIntoRotationQuaternion = false;
        // Cache
        /** @hidden */
        _this._poseMatrix = null;
        /** @hidden */
        _this._localMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Zero();
        _this._usePivotMatrix = false;
        _this._absolutePosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._absoluteScaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._absoluteRotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].Identity();
        _this._pivotMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
        _this._postMultiplyPivotMatrix = false;
        _this._isWorldMatrixFrozen = false;
        /** @hidden */
        _this._indexInSceneTransformNodesArray = -1;
        /**
        * An event triggered after the world matrix is updated
        */
        _this.onAfterWorldMatrixUpdateObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this._nonUniformScaling = false;
        if (isPure) {
            _this.getScene().addTransformNode(_this);
        }
        return _this;
    }
    Object.defineProperty(TransformNode.prototype, "billboardMode", {
        /**
        * Gets or sets the billboard mode. Default is 0.
        *
        * | Value | Type | Description |
        * | --- | --- | --- |
        * | 0 | BILLBOARDMODE_NONE |  |
        * | 1 | BILLBOARDMODE_X |  |
        * | 2 | BILLBOARDMODE_Y |  |
        * | 4 | BILLBOARDMODE_Z |  |
        * | 7 | BILLBOARDMODE_ALL |  |
        *
        */
        get: function () {
            return this._billboardMode;
        },
        set: function (value) {
            if (this._billboardMode === value) {
                return;
            }
            this._billboardMode = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "preserveParentRotationForBillboard", {
        /**
         * Gets or sets a boolean indicating that parent rotation should be preserved when using billboards.
         * This could be useful for glTF objects where parent rotation helps converting from right handed to left handed
         */
        get: function () {
            return this._preserveParentRotationForBillboard;
        },
        set: function (value) {
            if (value === this._preserveParentRotationForBillboard) {
                return;
            }
            this._preserveParentRotationForBillboard = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "infiniteDistance", {
        /**
         * Gets or sets the distance of the object to max, often used by skybox
         */
        get: function () {
            return this._infiniteDistance;
        },
        set: function (value) {
            if (this._infiniteDistance === value) {
                return;
            }
            this._infiniteDistance = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets a string identifying the name of the class
     * @returns "TransformNode" string
     */
    TransformNode.prototype.getClassName = function () {
        return "TransformNode";
    };
    Object.defineProperty(TransformNode.prototype, "position", {
        /**
          * Gets or set the node position (default is (0.0, 0.0, 0.0))
          */
        get: function () {
            return this._position;
        },
        set: function (newPosition) {
            this._position = newPosition;
            this._isDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "rotation", {
        /**
          * Gets or sets the rotation property : a Vector3 defining the rotation value in radians around each local axis X, Y, Z  (default is (0.0, 0.0, 0.0)).
          * If rotation quaternion is set, this Vector3 will be ignored and copy from the quaternion
          */
        get: function () {
            return this._rotation;
        },
        set: function (newRotation) {
            this._rotation = newRotation;
            this._rotationQuaternion = null;
            this._isDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "scaling", {
        /**
         * Gets or sets the scaling property : a Vector3 defining the node scaling along each local axis X, Y, Z (default is (0.0, 0.0, 0.0)).
         */
        get: function () {
            return this._scaling;
        },
        set: function (newScaling) {
            this._scaling = newScaling;
            this._isDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "rotationQuaternion", {
        /**
         * Gets or sets the rotation Quaternion property : this a Quaternion object defining the node rotation by using a unit quaternion (undefined by default, but can be null).
         * If set, only the rotationQuaternion is then used to compute the node rotation (ie. node.rotation will be ignored)
         */
        get: function () {
            return this._rotationQuaternion;
        },
        set: function (quaternion) {
            this._rotationQuaternion = quaternion;
            //reset the rotation vector.
            if (quaternion) {
                this._rotation.setAll(0.0);
            }
            this._isDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "forward", {
        /**
         * The forward direction of that transform in world space.
         */
        get: function () {
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Normalize(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(this.getScene().useRightHandedSystem ? this._forwardInverted : this._forward, this.getWorldMatrix()));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "up", {
        /**
         * The up direction of that transform in world space.
         */
        get: function () {
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Normalize(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(this._up, this.getWorldMatrix()));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "right", {
        /**
         * The right direction of that transform in world space.
         */
        get: function () {
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Normalize(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(this.getScene().useRightHandedSystem ? this._rightInverted : this._right, this.getWorldMatrix()));
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Copies the parameter passed Matrix into the mesh Pose matrix.
     * @param matrix the matrix to copy the pose from
     * @returns this TransformNode.
     */
    TransformNode.prototype.updatePoseMatrix = function (matrix) {
        if (!this._poseMatrix) {
            this._poseMatrix = matrix.clone();
            return this;
        }
        this._poseMatrix.copyFrom(matrix);
        return this;
    };
    /**
     * Returns the mesh Pose matrix.
     * @returns the pose matrix
     */
    TransformNode.prototype.getPoseMatrix = function () {
        if (!this._poseMatrix) {
            this._poseMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
        }
        return this._poseMatrix;
    };
    /** @hidden */
    TransformNode.prototype._isSynchronized = function () {
        var cache = this._cache;
        if (this.billboardMode !== cache.billboardMode || this.billboardMode !== TransformNode.BILLBOARDMODE_NONE) {
            return false;
        }
        if (cache.pivotMatrixUpdated) {
            return false;
        }
        if (this.infiniteDistance) {
            return false;
        }
        if (!cache.position.equals(this._position)) {
            return false;
        }
        if (this._rotationQuaternion) {
            if (!cache.rotationQuaternion.equals(this._rotationQuaternion)) {
                return false;
            }
        }
        else if (!cache.rotation.equals(this._rotation)) {
            return false;
        }
        if (!cache.scaling.equals(this._scaling)) {
            return false;
        }
        return true;
    };
    /** @hidden */
    TransformNode.prototype._initCache = function () {
        _super.prototype._initCache.call(this);
        var cache = this._cache;
        cache.localMatrixUpdated = false;
        cache.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        cache.scaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        cache.rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        cache.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"](0, 0, 0, 0);
        cache.billboardMode = -1;
        cache.infiniteDistance = false;
    };
    /**
    * Flag the transform node as dirty (Forcing it to update everything)
    * @param property if set to "rotation" the objects rotationQuaternion will be set to null
    * @returns this transform node
    */
    TransformNode.prototype.markAsDirty = function (property) {
        this._currentRenderId = Number.MAX_VALUE;
        this._isDirty = true;
        return this;
    };
    Object.defineProperty(TransformNode.prototype, "absolutePosition", {
        /**
         * Returns the current mesh absolute position.
         * Returns a Vector3.
         */
        get: function () {
            return this._absolutePosition;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "absoluteScaling", {
        /**
         * Returns the current mesh absolute scaling.
         * Returns a Vector3.
         */
        get: function () {
            this._syncAbsoluteScalingAndRotation();
            return this._absoluteScaling;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(TransformNode.prototype, "absoluteRotationQuaternion", {
        /**
         * Returns the current mesh absolute rotation.
         * Returns a Quaternion.
         */
        get: function () {
            this._syncAbsoluteScalingAndRotation();
            return this._absoluteRotationQuaternion;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets a new matrix to apply before all other transformation
     * @param matrix defines the transform matrix
     * @returns the current TransformNode
     */
    TransformNode.prototype.setPreTransformMatrix = function (matrix) {
        return this.setPivotMatrix(matrix, false);
    };
    /**
     * Sets a new pivot matrix to the current node
     * @param matrix defines the new pivot matrix to use
     * @param postMultiplyPivotMatrix defines if the pivot matrix must be cancelled in the world matrix. When this parameter is set to true (default), the inverse of the pivot matrix is also applied at the end to cancel the transformation effect
     * @returns the current TransformNode
    */
    TransformNode.prototype.setPivotMatrix = function (matrix, postMultiplyPivotMatrix) {
        if (postMultiplyPivotMatrix === void 0) { postMultiplyPivotMatrix = true; }
        this._pivotMatrix.copyFrom(matrix);
        this._usePivotMatrix = !this._pivotMatrix.isIdentity();
        this._cache.pivotMatrixUpdated = true;
        this._postMultiplyPivotMatrix = postMultiplyPivotMatrix;
        if (this._postMultiplyPivotMatrix) {
            if (!this._pivotMatrixInverse) {
                this._pivotMatrixInverse = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Invert(this._pivotMatrix);
            }
            else {
                this._pivotMatrix.invertToRef(this._pivotMatrixInverse);
            }
        }
        return this;
    };
    /**
     * Returns the mesh pivot matrix.
     * Default : Identity.
     * @returns the matrix
     */
    TransformNode.prototype.getPivotMatrix = function () {
        return this._pivotMatrix;
    };
    /**
     * Instantiate (when possible) or clone that node with its hierarchy
     * @param newParent defines the new parent to use for the instance (or clone)
     * @returns an instance (or a clone) of the current node with its hiearchy
     */
    TransformNode.prototype.instantiateHierarychy = function (newParent) {
        if (newParent === void 0) { newParent = null; }
        var clone = this.clone("Clone of " + (this.name || this.id), newParent || this.parent, true);
        for (var _i = 0, _a = this.getChildTransformNodes(true); _i < _a.length; _i++) {
            var child = _a[_i];
            child.instantiateHierarychy(clone);
        }
        return clone;
    };
    /**
     * Prevents the World matrix to be computed any longer
     * @param newWorldMatrix defines an optional matrix to use as world matrix
     * @returns the TransformNode.
     */
    TransformNode.prototype.freezeWorldMatrix = function (newWorldMatrix) {
        if (newWorldMatrix === void 0) { newWorldMatrix = null; }
        if (newWorldMatrix) {
            this._worldMatrix = this._worldMatrix;
        }
        else {
            this._isWorldMatrixFrozen = false; // no guarantee world is not already frozen, switch off temporarily
            this.computeWorldMatrix(true);
        }
        this._isWorldMatrixFrozen = true;
        return this;
    };
    /**
     * Allows back the World matrix computation.
     * @returns the TransformNode.
     */
    TransformNode.prototype.unfreezeWorldMatrix = function () {
        this._isWorldMatrixFrozen = false;
        this.computeWorldMatrix(true);
        return this;
    };
    Object.defineProperty(TransformNode.prototype, "isWorldMatrixFrozen", {
        /**
         * True if the World matrix has been frozen.
         */
        get: function () {
            return this._isWorldMatrixFrozen;
        },
        enumerable: true,
        configurable: true
    });
    /**
    * Retuns the mesh absolute position in the World.
    * @returns a Vector3.
    */
    TransformNode.prototype.getAbsolutePosition = function () {
        this.computeWorldMatrix();
        return this._absolutePosition;
    };
    /**
     * Sets the mesh absolute position in the World from a Vector3 or an Array(3).
     * @param absolutePosition the absolute position to set
     * @returns the TransformNode.
     */
    TransformNode.prototype.setAbsolutePosition = function (absolutePosition) {
        if (!absolutePosition) {
            return this;
        }
        var absolutePositionX;
        var absolutePositionY;
        var absolutePositionZ;
        if (absolutePosition.x === undefined) {
            if (arguments.length < 3) {
                return this;
            }
            absolutePositionX = arguments[0];
            absolutePositionY = arguments[1];
            absolutePositionZ = arguments[2];
        }
        else {
            absolutePositionX = absolutePosition.x;
            absolutePositionY = absolutePosition.y;
            absolutePositionZ = absolutePosition.z;
        }
        if (this.parent) {
            var invertParentWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
            this.parent.getWorldMatrix().invertToRef(invertParentWorldMatrix);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesFromFloatsToRef(absolutePositionX, absolutePositionY, absolutePositionZ, invertParentWorldMatrix, this.position);
        }
        else {
            this.position.x = absolutePositionX;
            this.position.y = absolutePositionY;
            this.position.z = absolutePositionZ;
        }
        return this;
    };
    /**
     * Sets the mesh position in its local space.
     * @param vector3 the position to set in localspace
     * @returns the TransformNode.
     */
    TransformNode.prototype.setPositionWithLocalVector = function (vector3) {
        this.computeWorldMatrix();
        this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(vector3, this._localMatrix);
        return this;
    };
    /**
     * Returns the mesh position in the local space from the current World matrix values.
     * @returns a new Vector3.
     */
    TransformNode.prototype.getPositionExpressedInLocalSpace = function () {
        this.computeWorldMatrix();
        var invLocalWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
        this._localMatrix.invertToRef(invLocalWorldMatrix);
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(this.position, invLocalWorldMatrix);
    };
    /**
     * Translates the mesh along the passed Vector3 in its local space.
     * @param vector3 the distance to translate in localspace
     * @returns the TransformNode.
     */
    TransformNode.prototype.locallyTranslate = function (vector3) {
        this.computeWorldMatrix(true);
        this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinates(vector3, this._localMatrix);
        return this;
    };
    /**
     * Orients a mesh towards a target point. Mesh must be drawn facing user.
     * @param targetPoint the position (must be in same space as current mesh) to look at
     * @param yawCor optional yaw (y-axis) correction in radians
     * @param pitchCor optional pitch (x-axis) correction in radians
     * @param rollCor optional roll (z-axis) correction in radians
     * @param space the choosen space of the target
     * @returns the TransformNode.
     */
    TransformNode.prototype.lookAt = function (targetPoint, yawCor, pitchCor, rollCor, space) {
        if (yawCor === void 0) { yawCor = 0; }
        if (pitchCor === void 0) { pitchCor = 0; }
        if (rollCor === void 0) { rollCor = 0; }
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].LOCAL; }
        var dv = TransformNode._lookAtVectorCache;
        var pos = space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].LOCAL ? this.position : this.getAbsolutePosition();
        targetPoint.subtractToRef(pos, dv);
        this.setDirection(dv, yawCor, pitchCor, rollCor);
        // Correct for parent's rotation offset
        if (space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].WORLD && this.parent) {
            if (this.rotationQuaternion) {
                // Get local rotation matrix of the looking object
                var rotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
                this.rotationQuaternion.toRotationMatrix(rotationMatrix);
                // Offset rotation by parent's inverted rotation matrix to correct in world space
                var parentRotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1];
                this.parent.getWorldMatrix().getRotationMatrixToRef(parentRotationMatrix);
                parentRotationMatrix.invert();
                rotationMatrix.multiplyToRef(parentRotationMatrix, rotationMatrix);
                this.rotationQuaternion.fromRotationMatrix(rotationMatrix);
            }
            else {
                // Get local rotation matrix of the looking object
                var quaternionRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[0];
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].FromEulerVectorToRef(this.rotation, quaternionRotation);
                var rotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
                quaternionRotation.toRotationMatrix(rotationMatrix);
                // Offset rotation by parent's inverted rotation matrix to correct in world space
                var parentRotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1];
                this.parent.getWorldMatrix().getRotationMatrixToRef(parentRotationMatrix);
                parentRotationMatrix.invert();
                rotationMatrix.multiplyToRef(parentRotationMatrix, rotationMatrix);
                quaternionRotation.fromRotationMatrix(rotationMatrix);
                quaternionRotation.toEulerAnglesToRef(this.rotation);
            }
        }
        return this;
    };
    /**
      * Returns a new Vector3 that is the localAxis, expressed in the mesh local space, rotated like the mesh.
      * This Vector3 is expressed in the World space.
      * @param localAxis axis to rotate
      * @returns a new Vector3 that is the localAxis, expressed in the mesh local space, rotated like the mesh.
      */
    TransformNode.prototype.getDirection = function (localAxis) {
        var result = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this.getDirectionToRef(localAxis, result);
        return result;
    };
    /**
     * Sets the Vector3 "result" as the rotated Vector3 "localAxis" in the same rotation than the mesh.
     * localAxis is expressed in the mesh local space.
     * result is computed in the Wordl space from the mesh World matrix.
     * @param localAxis axis to rotate
     * @param result the resulting transformnode
     * @returns this TransformNode.
     */
    TransformNode.prototype.getDirectionToRef = function (localAxis, result) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormalToRef(localAxis, this.getWorldMatrix(), result);
        return this;
    };
    /**
     * Sets this transform node rotation to the given local axis.
     * @param localAxis the axis in local space
     * @param yawCor optional yaw (y-axis) correction in radians
     * @param pitchCor optional pitch (x-axis) correction in radians
     * @param rollCor optional roll (z-axis) correction in radians
     * @returns this TransformNode
     */
    TransformNode.prototype.setDirection = function (localAxis, yawCor, pitchCor, rollCor) {
        if (yawCor === void 0) { yawCor = 0; }
        if (pitchCor === void 0) { pitchCor = 0; }
        if (rollCor === void 0) { rollCor = 0; }
        var yaw = -Math.atan2(localAxis.z, localAxis.x) + Math.PI / 2;
        var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
        var pitch = -Math.atan2(localAxis.y, len);
        if (this.rotationQuaternion) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(yaw + yawCor, pitch + pitchCor, rollCor, this.rotationQuaternion);
        }
        else {
            this.rotation.x = pitch + pitchCor;
            this.rotation.y = yaw + yawCor;
            this.rotation.z = rollCor;
        }
        return this;
    };
    /**
     * Sets a new pivot point to the current node
     * @param point defines the new pivot point to use
     * @param space defines if the point is in world or local space (local by default)
     * @returns the current TransformNode
    */
    TransformNode.prototype.setPivotPoint = function (point, space) {
        if (space === void 0) { space = _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].LOCAL; }
        if (this.getScene().getRenderId() == 0) {
            this.computeWorldMatrix(true);
        }
        var wm = this.getWorldMatrix();
        if (space == _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].WORLD) {
            var tmat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
            wm.invertToRef(tmat);
            point = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinates(point, tmat);
        }
        return this.setPivotMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Translation(-point.x, -point.y, -point.z), true);
    };
    /**
     * Returns a new Vector3 set with the mesh pivot point coordinates in the local space.
     * @returns the pivot point
     */
    TransformNode.prototype.getPivotPoint = function () {
        var point = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this.getPivotPointToRef(point);
        return point;
    };
    /**
     * Sets the passed Vector3 "result" with the coordinates of the mesh pivot point in the local space.
     * @param result the vector3 to store the result
     * @returns this TransformNode.
     */
    TransformNode.prototype.getPivotPointToRef = function (result) {
        result.x = -this._pivotMatrix.m[12];
        result.y = -this._pivotMatrix.m[13];
        result.z = -this._pivotMatrix.m[14];
        return this;
    };
    /**
     * Returns a new Vector3 set with the mesh pivot point World coordinates.
     * @returns a new Vector3 set with the mesh pivot point World coordinates.
     */
    TransformNode.prototype.getAbsolutePivotPoint = function () {
        var point = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this.getAbsolutePivotPointToRef(point);
        return point;
    };
    /**
     * Sets the Vector3 "result" coordinates with the mesh pivot point World coordinates.
     * @param result vector3 to store the result
     * @returns this TransformNode.
     */
    TransformNode.prototype.getAbsolutePivotPointToRef = function (result) {
        result.x = this._pivotMatrix.m[12];
        result.y = this._pivotMatrix.m[13];
        result.z = this._pivotMatrix.m[14];
        this.getPivotPointToRef(result);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(result, this.getWorldMatrix(), result);
        return this;
    };
    /**
     * Defines the passed node as the parent of the current node.
     * The node will remain exactly where it is and its position / rotation will be updated accordingly
     * @see https://doc.babylonjs.com/how_to/parenting
     * @param node the node ot set as the parent
     * @returns this TransformNode.
     */
    TransformNode.prototype.setParent = function (node) {
        if (!node && !this.parent) {
            return this;
        }
        var quatRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[0];
        var position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
        var scale = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
        if (!node) {
            this.computeWorldMatrix(true);
            this.getWorldMatrix().decompose(scale, quatRotation, position);
        }
        else {
            var diffMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
            var invParentMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1];
            this.computeWorldMatrix(true);
            node.computeWorldMatrix(true);
            node.getWorldMatrix().invertToRef(invParentMatrix);
            this.getWorldMatrix().multiplyToRef(invParentMatrix, diffMatrix);
            diffMatrix.decompose(scale, quatRotation, position);
        }
        if (this.rotationQuaternion) {
            this.rotationQuaternion.copyFrom(quatRotation);
        }
        else {
            quatRotation.toEulerAnglesToRef(this.rotation);
        }
        this.scaling.copyFrom(scale);
        this.position.copyFrom(position);
        this.parent = node;
        return this;
    };
    Object.defineProperty(TransformNode.prototype, "nonUniformScaling", {
        /**
         * True if the scaling property of this object is non uniform eg. (1,2,1)
         */
        get: function () {
            return this._nonUniformScaling;
        },
        enumerable: true,
        configurable: true
    });
    /** @hidden */
    TransformNode.prototype._updateNonUniformScalingState = function (value) {
        if (this._nonUniformScaling === value) {
            return false;
        }
        this._nonUniformScaling = value;
        return true;
    };
    /**
     * Attach the current TransformNode to another TransformNode associated with a bone
     * @param bone Bone affecting the TransformNode
     * @param affectedTransformNode TransformNode associated with the bone
     * @returns this object
     */
    TransformNode.prototype.attachToBone = function (bone, affectedTransformNode) {
        this._transformToBoneReferal = affectedTransformNode;
        this.parent = bone;
        if (bone.getWorldMatrix().determinant() < 0) {
            this.scalingDeterminant *= -1;
        }
        return this;
    };
    /**
     * Detach the transform node if its associated with a bone
     * @returns this object
     */
    TransformNode.prototype.detachFromBone = function () {
        if (!this.parent) {
            return this;
        }
        if (this.parent.getWorldMatrix().determinant() < 0) {
            this.scalingDeterminant *= -1;
        }
        this._transformToBoneReferal = null;
        this.parent = null;
        return this;
    };
    /**
     * Rotates the mesh around the axis vector for the passed angle (amount) expressed in radians, in the given space.
     * space (default LOCAL) can be either Space.LOCAL, either Space.WORLD.
     * Note that the property `rotationQuaternion` is then automatically updated and the property `rotation` is set to (0,0,0) and no longer used.
     * The passed axis is also normalized.
     * @param axis the axis to rotate around
     * @param amount the amount to rotate in radians
     * @param space Space to rotate in (Default: local)
     * @returns the TransformNode.
     */
    TransformNode.prototype.rotate = function (axis, amount, space) {
        axis.normalize();
        if (!this.rotationQuaternion) {
            this.rotationQuaternion = this.rotation.toQuaternion();
            this.rotation.setAll(0);
        }
        var rotationQuaternion;
        if (!space || space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].LOCAL) {
            rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationAxisToRef(axis, amount, TransformNode._rotationAxisCache);
            this.rotationQuaternion.multiplyToRef(rotationQuaternion, this.rotationQuaternion);
        }
        else {
            if (this.parent) {
                var invertParentWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
                this.parent.getWorldMatrix().invertToRef(invertParentWorldMatrix);
                axis = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformNormal(axis, invertParentWorldMatrix);
            }
            rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationAxisToRef(axis, amount, TransformNode._rotationAxisCache);
            rotationQuaternion.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);
        }
        return this;
    };
    /**
     * Rotates the mesh around the axis vector for the passed angle (amount) expressed in radians, in world space.
     * Note that the property `rotationQuaternion` is then automatically updated and the property `rotation` is set to (0,0,0) and no longer used.
     * The passed axis is also normalized. .
     * Method is based on http://www.euclideanspace.com/maths/geometry/affine/aroundPoint/index.htm
     * @param point the point to rotate around
     * @param axis the axis to rotate around
     * @param amount the amount to rotate in radians
     * @returns the TransformNode
     */
    TransformNode.prototype.rotateAround = function (point, axis, amount) {
        axis.normalize();
        if (!this.rotationQuaternion) {
            this.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
            this.rotation.setAll(0);
        }
        var tmpVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
        var finalScale = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
        var finalTranslation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[2];
        var finalRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[0];
        var translationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]; // T
        var translationMatrixInv = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1]; // T'
        var rotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[2]; // R
        var finalMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[3]; // T' x R x T
        point.subtractToRef(this.position, tmpVector);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].TranslationToRef(tmpVector.x, tmpVector.y, tmpVector.z, translationMatrix); // T
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].TranslationToRef(-tmpVector.x, -tmpVector.y, -tmpVector.z, translationMatrixInv); // T'
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationAxisToRef(axis, amount, rotationMatrix); // R
        translationMatrixInv.multiplyToRef(rotationMatrix, finalMatrix); // T' x R
        finalMatrix.multiplyToRef(translationMatrix, finalMatrix); // T' x R x T
        finalMatrix.decompose(finalScale, finalRotation, finalTranslation);
        this.position.addInPlace(finalTranslation);
        finalRotation.multiplyToRef(this.rotationQuaternion, this.rotationQuaternion);
        return this;
    };
    /**
     * Translates the mesh along the axis vector for the passed distance in the given space.
     * space (default LOCAL) can be either Space.LOCAL, either Space.WORLD.
     * @param axis the axis to translate in
     * @param distance the distance to translate
     * @param space Space to rotate in (Default: local)
     * @returns the TransformNode.
     */
    TransformNode.prototype.translate = function (axis, distance, space) {
        var displacementVector = axis.scale(distance);
        if (!space || space === _Maths_math_axis__WEBPACK_IMPORTED_MODULE_5__["Space"].LOCAL) {
            var tempV3 = this.getPositionExpressedInLocalSpace().add(displacementVector);
            this.setPositionWithLocalVector(tempV3);
        }
        else {
            this.setAbsolutePosition(this.getAbsolutePosition().add(displacementVector));
        }
        return this;
    };
    /**
     * Adds a rotation step to the mesh current rotation.
     * x, y, z are Euler angles expressed in radians.
     * This methods updates the current mesh rotation, either mesh.rotation, either mesh.rotationQuaternion if it's set.
     * This means this rotation is made in the mesh local space only.
     * It's useful to set a custom rotation order different from the BJS standard one YXZ.
     * Example : this rotates the mesh first around its local X axis, then around its local Z axis, finally around its local Y axis.
     * ```javascript
     * mesh.addRotation(x1, 0, 0).addRotation(0, 0, z2).addRotation(0, 0, y3);
     * ```
     * Note that `addRotation()` accumulates the passed rotation values to the current ones and computes the .rotation or .rotationQuaternion updated values.
     * Under the hood, only quaternions are used. So it's a little faster is you use .rotationQuaternion because it doesn't need to translate them back to Euler angles.
     * @param x Rotation to add
     * @param y Rotation to add
     * @param z Rotation to add
     * @returns the TransformNode.
     */
    TransformNode.prototype.addRotation = function (x, y, z) {
        var rotationQuaternion;
        if (this.rotationQuaternion) {
            rotationQuaternion = this.rotationQuaternion;
        }
        else {
            rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[1];
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, rotationQuaternion);
        }
        var accumulation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[0];
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(y, x, z, accumulation);
        rotationQuaternion.multiplyInPlace(accumulation);
        if (!this.rotationQuaternion) {
            rotationQuaternion.toEulerAnglesToRef(this.rotation);
        }
        return this;
    };
    /**
     * @hidden
     */
    TransformNode.prototype._getEffectiveParent = function () {
        return this.parent;
    };
    /**
     * Computes the world matrix of the node
     * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
     * @returns the world matrix
     */
    TransformNode.prototype.computeWorldMatrix = function (force) {
        if (this._isWorldMatrixFrozen && !this._isDirty) {
            return this._worldMatrix;
        }
        var currentRenderId = this.getScene().getRenderId();
        if (!this._isDirty && !force && this.isSynchronized()) {
            this._currentRenderId = currentRenderId;
            return this._worldMatrix;
        }
        var camera = this.getScene().activeCamera;
        var useBillboardPosition = (this._billboardMode & TransformNode.BILLBOARDMODE_USE_POSITION) !== 0;
        var useBillboardPath = this._billboardMode !== TransformNode.BILLBOARDMODE_NONE && !this.preserveParentRotationForBillboard;
        // Billboarding based on camera position
        if (useBillboardPath && camera && useBillboardPosition) {
            this.lookAt(camera.position);
            if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {
                this.rotation.x = 0;
            }
            if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {
                this.rotation.y = 0;
            }
            if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {
                this.rotation.z = 0;
            }
        }
        this._updateCache();
        var cache = this._cache;
        cache.pivotMatrixUpdated = false;
        cache.billboardMode = this.billboardMode;
        cache.infiniteDistance = this.infiniteDistance;
        this._currentRenderId = currentRenderId;
        this._childUpdateId++;
        this._isDirty = false;
        var parent = this._getEffectiveParent();
        // Scaling
        var scaling = cache.scaling;
        var translation = cache.position;
        // Translation
        if (this._infiniteDistance) {
            if (!this.parent && camera) {
                var cameraWorldMatrix = camera.getWorldMatrix();
                var cameraGlobalPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](cameraWorldMatrix.m[12], cameraWorldMatrix.m[13], cameraWorldMatrix.m[14]);
                translation.copyFromFloats(this._position.x + cameraGlobalPosition.x, this._position.y + cameraGlobalPosition.y, this._position.z + cameraGlobalPosition.z);
            }
            else {
                translation.copyFrom(this._position);
            }
        }
        else {
            translation.copyFrom(this._position);
        }
        // Scaling
        scaling.copyFromFloats(this._scaling.x * this.scalingDeterminant, this._scaling.y * this.scalingDeterminant, this._scaling.z * this.scalingDeterminant);
        // Rotation
        var rotation = cache.rotationQuaternion;
        if (this._rotationQuaternion) {
            if (this.reIntegrateRotationIntoRotationQuaternion) {
                var len = this.rotation.lengthSquared();
                if (len) {
                    this._rotationQuaternion.multiplyInPlace(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRoll(this._rotation.y, this._rotation.x, this._rotation.z));
                    this._rotation.copyFromFloats(0, 0, 0);
                }
            }
            rotation.copyFrom(this._rotationQuaternion);
        }
        else {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"].RotationYawPitchRollToRef(this._rotation.y, this._rotation.x, this._rotation.z, rotation);
            cache.rotation.copyFrom(this._rotation);
        }
        // Compose
        if (this._usePivotMatrix) {
            var scaleMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1];
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].ScalingToRef(scaling.x, scaling.y, scaling.z, scaleMatrix);
            // Rotation
            var rotationMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0];
            rotation.toRotationMatrix(rotationMatrix);
            // Composing transformations
            this._pivotMatrix.multiplyToRef(scaleMatrix, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[4]);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[4].multiplyToRef(rotationMatrix, this._localMatrix);
            // Post multiply inverse of pivotMatrix
            if (this._postMultiplyPivotMatrix) {
                this._localMatrix.multiplyToRef(this._pivotMatrixInverse, this._localMatrix);
            }
            this._localMatrix.addTranslationFromFloats(translation.x, translation.y, translation.z);
        }
        else {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].ComposeToRef(scaling, rotation, translation, this._localMatrix);
        }
        // Parent
        if (parent && parent.getWorldMatrix) {
            if (force) {
                parent.computeWorldMatrix();
            }
            if (useBillboardPath) {
                if (this._transformToBoneReferal) {
                    parent.getWorldMatrix().multiplyToRef(this._transformToBoneReferal.getWorldMatrix(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[7]);
                }
                else {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[7].copyFrom(parent.getWorldMatrix());
                }
                // Extract scaling and translation from parent
                var translation_1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[5];
                var scale = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[6];
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[7].decompose(scale, undefined, translation_1);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].ScalingToRef(scale.x, scale.y, scale.z, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[7]);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[7].setTranslation(translation_1);
                this._localMatrix.multiplyToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[7], this._worldMatrix);
            }
            else {
                if (this._transformToBoneReferal) {
                    this._localMatrix.multiplyToRef(parent.getWorldMatrix(), _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[6]);
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[6].multiplyToRef(this._transformToBoneReferal.getWorldMatrix(), this._worldMatrix);
                }
                else {
                    this._localMatrix.multiplyToRef(parent.getWorldMatrix(), this._worldMatrix);
                }
            }
            this._markSyncedWithParent();
        }
        else {
            this._worldMatrix.copyFrom(this._localMatrix);
        }
        // Billboarding based on camera orientation (testing PG:http://www.babylonjs-playground.com/#UJEIL#13)
        if (useBillboardPath && camera && this.billboardMode && !useBillboardPosition) {
            var storedTranslation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
            this._worldMatrix.getTranslationToRef(storedTranslation); // Save translation
            // Cancel camera rotation
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1].copyFrom(camera.getViewMatrix());
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1].setTranslationFromFloats(0, 0, 0);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[1].invertToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
            if ((this.billboardMode & TransformNode.BILLBOARDMODE_ALL) !== TransformNode.BILLBOARDMODE_ALL) {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0].decompose(undefined, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[0], undefined);
                var eulerAngles = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Quaternion[0].toEulerAnglesToRef(eulerAngles);
                if ((this.billboardMode & TransformNode.BILLBOARDMODE_X) !== TransformNode.BILLBOARDMODE_X) {
                    eulerAngles.x = 0;
                }
                if ((this.billboardMode & TransformNode.BILLBOARDMODE_Y) !== TransformNode.BILLBOARDMODE_Y) {
                    eulerAngles.y = 0;
                }
                if ((this.billboardMode & TransformNode.BILLBOARDMODE_Z) !== TransformNode.BILLBOARDMODE_Z) {
                    eulerAngles.z = 0;
                }
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].RotationYawPitchRollToRef(eulerAngles.y, eulerAngles.x, eulerAngles.z, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
            }
            this._worldMatrix.setTranslationFromFloats(0, 0, 0);
            this._worldMatrix.multiplyToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0], this._worldMatrix);
            // Restore translation
            this._worldMatrix.setTranslation(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0]);
        }
        // Normal matrix
        if (!this.ignoreNonUniformScaling) {
            if (this._scaling.isNonUniform) {
                this._updateNonUniformScalingState(true);
            }
            else if (parent && parent._nonUniformScaling) {
                this._updateNonUniformScalingState(parent._nonUniformScaling);
            }
            else {
                this._updateNonUniformScalingState(false);
            }
        }
        else {
            this._updateNonUniformScalingState(false);
        }
        this._afterComputeWorldMatrix();
        // Absolute position
        this._absolutePosition.copyFromFloats(this._worldMatrix.m[12], this._worldMatrix.m[13], this._worldMatrix.m[14]);
        this._isAbsoluteSynced = false;
        // Callbacks
        this.onAfterWorldMatrixUpdateObservable.notifyObservers(this);
        if (!this._poseMatrix) {
            this._poseMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Invert(this._worldMatrix);
        }
        // Cache the determinant
        this._worldMatrixDeterminantIsDirty = true;
        return this._worldMatrix;
    };
    TransformNode.prototype._afterComputeWorldMatrix = function () {
    };
    /**
    * If you'd like to be called back after the mesh position, rotation or scaling has been updated.
    * @param func callback function to add
    *
    * @returns the TransformNode.
    */
    TransformNode.prototype.registerAfterWorldMatrixUpdate = function (func) {
        this.onAfterWorldMatrixUpdateObservable.add(func);
        return this;
    };
    /**
     * Removes a registered callback function.
     * @param func callback function to remove
     * @returns the TransformNode.
     */
    TransformNode.prototype.unregisterAfterWorldMatrixUpdate = function (func) {
        this.onAfterWorldMatrixUpdateObservable.removeCallback(func);
        return this;
    };
    /**
     * Gets the position of the current mesh in camera space
     * @param camera defines the camera to use
     * @returns a position
     */
    TransformNode.prototype.getPositionInCameraSpace = function (camera) {
        if (camera === void 0) { camera = null; }
        if (!camera) {
            camera = this.getScene().activeCamera;
        }
        return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinates(this.absolutePosition, camera.getViewMatrix());
    };
    /**
     * Returns the distance from the mesh to the active camera
     * @param camera defines the camera to use
     * @returns the distance
     */
    TransformNode.prototype.getDistanceToCamera = function (camera) {
        if (camera === void 0) { camera = null; }
        if (!camera) {
            camera = this.getScene().activeCamera;
        }
        return this.absolutePosition.subtract(camera.globalPosition).length();
    };
    /**
     * Clone the current transform node
     * @param name Name of the new clone
     * @param newParent New parent for the clone
     * @param doNotCloneChildren Do not clone children hierarchy
     * @returns the new transform node
     */
    TransformNode.prototype.clone = function (name, newParent, doNotCloneChildren) {
        var _this = this;
        var result = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Clone(function () { return new TransformNode(name, _this.getScene()); }, this);
        result.name = name;
        result.id = name;
        if (newParent) {
            result.parent = newParent;
        }
        if (!doNotCloneChildren) {
            // Children
            var directDescendants = this.getDescendants(true);
            for (var index = 0; index < directDescendants.length; index++) {
                var child = directDescendants[index];
                if (child.clone) {
                    child.clone(name + "." + child.name, result);
                }
            }
        }
        return result;
    };
    /**
     * Serializes the objects information.
     * @param currentSerializationObject defines the object to serialize in
     * @returns the serialized object
     */
    TransformNode.prototype.serialize = function (currentSerializationObject) {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this, currentSerializationObject);
        serializationObject.type = this.getClassName();
        // Parent
        if (this.parent) {
            serializationObject.parentId = this.parent.id;
        }
        serializationObject.localMatrix = this.getPivotMatrix().asArray();
        serializationObject.isEnabled = this.isEnabled();
        // Parent
        if (this.parent) {
            serializationObject.parentId = this.parent.id;
        }
        return serializationObject;
    };
    // Statics
    /**
     * Returns a new TransformNode object parsed from the source provided.
     * @param parsedTransformNode is the source.
     * @param scene the scne the object belongs to
     * @param rootUrl is a string, it's the root URL to prefix the `delayLoadingFile` property with
     * @returns a new TransformNode object parsed from the source provided.
     */
    TransformNode.Parse = function (parsedTransformNode, scene, rootUrl) {
        var transformNode = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new TransformNode(parsedTransformNode.name, scene); }, parsedTransformNode, scene, rootUrl);
        if (parsedTransformNode.localMatrix) {
            transformNode.setPreTransformMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromArray(parsedTransformNode.localMatrix));
        }
        else if (parsedTransformNode.pivotMatrix) {
            transformNode.setPivotMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromArray(parsedTransformNode.pivotMatrix));
        }
        transformNode.setEnabled(parsedTransformNode.isEnabled);
        // Parent
        if (parsedTransformNode.parentId) {
            transformNode._waitingParentId = parsedTransformNode.parentId;
        }
        return transformNode;
    };
    /**
     * Get all child-transformNodes of this node
     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
     * @returns an array of TransformNode
     */
    TransformNode.prototype.getChildTransformNodes = function (directDescendantsOnly, predicate) {
        var results = [];
        this._getDescendants(results, directDescendantsOnly, function (node) {
            return ((!predicate || predicate(node)) && (node instanceof TransformNode));
        });
        return results;
    };
    /**
     * Releases resources associated with this transform node.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    TransformNode.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        // Animations
        this.getScene().stopAnimation(this);
        // Remove from scene
        this.getScene().removeTransformNode(this);
        this.onAfterWorldMatrixUpdateObservable.clear();
        if (doNotRecurse) {
            var transformNodes = this.getChildTransformNodes(true);
            for (var _i = 0, transformNodes_1 = transformNodes; _i < transformNodes_1.length; _i++) {
                var transformNode = transformNodes_1[_i];
                transformNode.parent = null;
                transformNode.computeWorldMatrix(true);
            }
        }
        _super.prototype.dispose.call(this, doNotRecurse, disposeMaterialAndTextures);
    };
    /**
     * Uniformly scales the mesh to fit inside of a unit cube (1 X 1 X 1 units)
     * @param includeDescendants Use the hierarchy's bounding box instead of the mesh's bounding box. Default is false
     * @param ignoreRotation ignore rotation when computing the scale (ie. object will be axis aligned). Default is false
     * @param predicate predicate that is passed in to getHierarchyBoundingVectors when selecting which object should be included when scaling
     * @returns the current mesh
     */
    TransformNode.prototype.normalizeToUnitCube = function (includeDescendants, ignoreRotation, predicate) {
        if (includeDescendants === void 0) { includeDescendants = true; }
        if (ignoreRotation === void 0) { ignoreRotation = false; }
        var storedRotation = null;
        var storedRotationQuaternion = null;
        if (ignoreRotation) {
            if (this.rotationQuaternion) {
                storedRotationQuaternion = this.rotationQuaternion.clone();
                this.rotationQuaternion.copyFromFloats(0, 0, 0, 1);
            }
            else if (this.rotation) {
                storedRotation = this.rotation.clone();
                this.rotation.copyFromFloats(0, 0, 0);
            }
        }
        var boundingVectors = this.getHierarchyBoundingVectors(includeDescendants, predicate);
        var sizeVec = boundingVectors.max.subtract(boundingVectors.min);
        var maxDimension = Math.max(sizeVec.x, sizeVec.y, sizeVec.z);
        if (maxDimension === 0) {
            return this;
        }
        var scale = 1 / maxDimension;
        this.scaling.scaleInPlace(scale);
        if (ignoreRotation) {
            if (this.rotationQuaternion && storedRotationQuaternion) {
                this.rotationQuaternion.copyFrom(storedRotationQuaternion);
            }
            else if (this.rotation && storedRotation) {
                this.rotation.copyFrom(storedRotation);
            }
        }
        return this;
    };
    TransformNode.prototype._syncAbsoluteScalingAndRotation = function () {
        if (!this._isAbsoluteSynced) {
            this._worldMatrix.decompose(this._absoluteScaling, this._absoluteRotationQuaternion);
            this._isAbsoluteSynced = true;
        }
    };
    // Statics
    /**
     * Object will not rotate to face the camera
     */
    TransformNode.BILLBOARDMODE_NONE = 0;
    /**
     * Object will rotate to face the camera but only on the x axis
     */
    TransformNode.BILLBOARDMODE_X = 1;
    /**
     * Object will rotate to face the camera but only on the y axis
     */
    TransformNode.BILLBOARDMODE_Y = 2;
    /**
     * Object will rotate to face the camera but only on the z axis
     */
    TransformNode.BILLBOARDMODE_Z = 4;
    /**
     * Object will rotate to face the camera
     */
    TransformNode.BILLBOARDMODE_ALL = 7;
    /**
     * Object will rotate to face the camera's position instead of orientation
     */
    TransformNode.BILLBOARDMODE_USE_POSITION = 128;
    TransformNode._lookAtVectorCache = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0, 0, 0);
    TransformNode._rotationAxisCache = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])("position")
    ], TransformNode.prototype, "_position", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])("rotation")
    ], TransformNode.prototype, "_rotation", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsQuaternion"])("rotationQuaternion")
    ], TransformNode.prototype, "_rotationQuaternion", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])("scaling")
    ], TransformNode.prototype, "_scaling", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("billboardMode")
    ], TransformNode.prototype, "_billboardMode", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], TransformNode.prototype, "scalingDeterminant", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])("infiniteDistance")
    ], TransformNode.prototype, "_infiniteDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], TransformNode.prototype, "ignoreNonUniformScaling", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], TransformNode.prototype, "reIntegrateRotationIntoRotationQuaternion", void 0);
    return TransformNode;
}(_node__WEBPACK_IMPORTED_MODULE_4__["Node"]));



/***/ }),

/***/ "./Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts":
/*!***************************************************************!*\
  !*** ./Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts ***!
  \***************************************************************/
/*! exports provided: CubeMapToSphericalPolynomialTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeMapToSphericalPolynomialTools", function() { return CubeMapToSphericalPolynomialTools; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/sphericalPolynomial */ "./Maths/sphericalPolynomial.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Maths/math.constants */ "./Maths/math.constants.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Maths/math.color */ "./Maths/math.color.ts");






var FileFaceOrientation = /** @class */ (function () {
    function FileFaceOrientation(name, worldAxisForNormal, worldAxisForFileX, worldAxisForFileY) {
        this.name = name;
        this.worldAxisForNormal = worldAxisForNormal;
        this.worldAxisForFileX = worldAxisForFileX;
        this.worldAxisForFileY = worldAxisForFileY;
    }
    return FileFaceOrientation;
}());
/**
 * Helper class dealing with the extraction of spherical polynomial dataArray
 * from a cube map.
 */
var CubeMapToSphericalPolynomialTools = /** @class */ (function () {
    function CubeMapToSphericalPolynomialTools() {
    }
    /**
     * Converts a texture to the according Spherical Polynomial data.
     * This extracts the first 3 orders only as they are the only one used in the lighting.
     *
     * @param texture The texture to extract the information from.
     * @return The Spherical Polynomial data.
     */
    CubeMapToSphericalPolynomialTools.ConvertCubeMapTextureToSphericalPolynomial = function (texture) {
        if (!texture.isCube) {
            // Only supports cube Textures currently.
            return null;
        }
        var size = texture.getSize().width;
        var right = texture.readPixels(0);
        var left = texture.readPixels(1);
        var up;
        var down;
        if (texture.isRenderTarget) {
            up = texture.readPixels(3);
            down = texture.readPixels(2);
        }
        else {
            up = texture.readPixels(2);
            down = texture.readPixels(3);
        }
        var front = texture.readPixels(4);
        var back = texture.readPixels(5);
        var gammaSpace = texture.gammaSpace;
        // Always read as RGBA.
        var format = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA;
        var type = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        if (texture.textureType && texture.textureType !== _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT) {
            type = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_FLOAT;
        }
        var cubeInfo = {
            size: size,
            right: right,
            left: left,
            up: up,
            down: down,
            front: front,
            back: back,
            format: format,
            type: type,
            gammaSpace: gammaSpace,
        };
        return this.ConvertCubeMapToSphericalPolynomial(cubeInfo);
    };
    /**
     * Converts a cubemap to the according Spherical Polynomial data.
     * This extracts the first 3 orders only as they are the only one used in the lighting.
     *
     * @param cubeInfo The Cube map to extract the information from.
     * @return The Spherical Polynomial data.
     */
    CubeMapToSphericalPolynomialTools.ConvertCubeMapToSphericalPolynomial = function (cubeInfo) {
        var sphericalHarmonics = new _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_2__["SphericalHarmonics"]();
        var totalSolidAngle = 0.0;
        // The (u,v) range is [-1,+1], so the distance between each texel is 2/Size.
        var du = 2.0 / cubeInfo.size;
        var dv = du;
        // The (u,v) of the first texel is half a texel from the corner (-1,-1).
        var minUV = du * 0.5 - 1.0;
        for (var faceIndex = 0; faceIndex < 6; faceIndex++) {
            var fileFace = this.FileFaces[faceIndex];
            var dataArray = cubeInfo[fileFace.name];
            var v = minUV;
            // TODO: we could perform the summation directly into a SphericalPolynomial (SP), which is more efficient than SphericalHarmonic (SH).
            // This is possible because during the summation we do not need the SH-specific properties, e.g. orthogonality.
            // Because SP is still linear, so summation is fine in that basis.
            var stride = cubeInfo.format === _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTUREFORMAT_RGBA ? 4 : 3;
            for (var y = 0; y < cubeInfo.size; y++) {
                var u = minUV;
                for (var x = 0; x < cubeInfo.size; x++) {
                    // World direction (not normalised)
                    var worldDirection = fileFace.worldAxisForFileX.scale(u).add(fileFace.worldAxisForFileY.scale(v)).add(fileFace.worldAxisForNormal);
                    worldDirection.normalize();
                    var deltaSolidAngle = Math.pow(1.0 + u * u + v * v, -3.0 / 2.0);
                    var r = dataArray[(y * cubeInfo.size * stride) + (x * stride) + 0];
                    var g = dataArray[(y * cubeInfo.size * stride) + (x * stride) + 1];
                    var b = dataArray[(y * cubeInfo.size * stride) + (x * stride) + 2];
                    // Prevent NaN harmonics with extreme HDRI data.
                    if (isNaN(r)) {
                        r = 0;
                    }
                    if (isNaN(g)) {
                        g = 0;
                    }
                    if (isNaN(b)) {
                        b = 0;
                    }
                    // Handle Integer types.
                    if (cubeInfo.type === _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT) {
                        r /= 255;
                        g /= 255;
                        b /= 255;
                    }
                    // Handle Gamma space textures.
                    if (cubeInfo.gammaSpace) {
                        r = Math.pow(_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__["Scalar"].Clamp(r), _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["ToLinearSpace"]);
                        g = Math.pow(_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__["Scalar"].Clamp(g), _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["ToLinearSpace"]);
                        b = Math.pow(_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__["Scalar"].Clamp(b), _Maths_math_constants__WEBPACK_IMPORTED_MODULE_4__["ToLinearSpace"]);
                    }
                    // Prevent to explode in case of really high dynamic ranges.
                    // sh 3 would not be enough to accurately represent it.
                    var max = 4096;
                    r = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__["Scalar"].Clamp(r, 0, max);
                    g = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__["Scalar"].Clamp(g, 0, max);
                    b = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_1__["Scalar"].Clamp(b, 0, max);
                    var color = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_5__["Color3"](r, g, b);
                    sphericalHarmonics.addLight(worldDirection, color, deltaSolidAngle);
                    totalSolidAngle += deltaSolidAngle;
                    u += du;
                }
                v += dv;
            }
        }
        // Solid angle for entire sphere is 4*pi
        var sphereSolidAngle = 4.0 * Math.PI;
        // Adjust the solid angle to allow for how many faces we processed.
        var facesProcessed = 6.0;
        var expectedSolidAngle = sphereSolidAngle * facesProcessed / 6.0;
        // Adjust the harmonics so that the accumulated solid angle matches the expected solid angle.
        // This is needed because the numerical integration over the cube uses a
        // small angle approximation of solid angle for each texel (see deltaSolidAngle),
        // and also to compensate for accumulative error due to float precision in the summation.
        var correctionFactor = expectedSolidAngle / totalSolidAngle;
        sphericalHarmonics.scaleInPlace(correctionFactor);
        sphericalHarmonics.convertIncidentRadianceToIrradiance();
        sphericalHarmonics.convertIrradianceToLambertianRadiance();
        return _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_2__["SphericalPolynomial"].FromHarmonics(sphericalHarmonics);
    };
    CubeMapToSphericalPolynomialTools.FileFaces = [
        new FileFaceOrientation("right", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, -1), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0)),
        new FileFaceOrientation("left", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 1), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0)),
        new FileFaceOrientation("up", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 1)),
        new FileFaceOrientation("down", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, -1)),
        new FileFaceOrientation("front", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 1), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0)),
        new FileFaceOrientation("back", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, -1), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1, 0, 0), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -1, 0)) // -Z bottom
    ];
    return CubeMapToSphericalPolynomialTools;
}());



/***/ }),

/***/ "./Misc/HighDynamicRange/hdr.ts":
/*!**************************************!*\
  !*** ./Misc/HighDynamicRange/hdr.ts ***!
  \**************************************/
/*! exports provided: HDRTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HDRTools", function() { return HDRTools; });
/* harmony import */ var _panoramaToCubemap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./panoramaToCubemap */ "./Misc/HighDynamicRange/panoramaToCubemap.ts");

/**
 * This groups tools to convert HDR texture to native colors array.
 */
var HDRTools = /** @class */ (function () {
    function HDRTools() {
    }
    HDRTools.Ldexp = function (mantissa, exponent) {
        if (exponent > 1023) {
            return mantissa * Math.pow(2, 1023) * Math.pow(2, exponent - 1023);
        }
        if (exponent < -1074) {
            return mantissa * Math.pow(2, -1074) * Math.pow(2, exponent + 1074);
        }
        return mantissa * Math.pow(2, exponent);
    };
    HDRTools.Rgbe2float = function (float32array, red, green, blue, exponent, index) {
        if (exponent > 0) { /*nonzero pixel*/
            exponent = this.Ldexp(1.0, exponent - (128 + 8));
            float32array[index + 0] = red * exponent;
            float32array[index + 1] = green * exponent;
            float32array[index + 2] = blue * exponent;
        }
        else {
            float32array[index + 0] = 0;
            float32array[index + 1] = 0;
            float32array[index + 2] = 0;
        }
    };
    HDRTools.readStringLine = function (uint8array, startIndex) {
        var line = "";
        var character = "";
        for (var i = startIndex; i < uint8array.length - startIndex; i++) {
            character = String.fromCharCode(uint8array[i]);
            if (character == "\n") {
                break;
            }
            line += character;
        }
        return line;
    };
    /**
     * Reads header information from an RGBE texture stored in a native array.
     * More information on this format are available here:
     * https://en.wikipedia.org/wiki/RGBE_image_format
     *
     * @param uint8array The binary file stored in  native array.
     * @return The header information.
     */
    HDRTools.RGBE_ReadHeader = function (uint8array) {
        var height = 0;
        var width = 0;
        var line = this.readStringLine(uint8array, 0);
        if (line[0] != '#' || line[1] != '?') {
            throw "Bad HDR Format.";
        }
        var endOfHeader = false;
        var findFormat = false;
        var lineIndex = 0;
        do {
            lineIndex += (line.length + 1);
            line = this.readStringLine(uint8array, lineIndex);
            if (line == "FORMAT=32-bit_rle_rgbe") {
                findFormat = true;
            }
            else if (line.length == 0) {
                endOfHeader = true;
            }
        } while (!endOfHeader);
        if (!findFormat) {
            throw "HDR Bad header format, unsupported FORMAT";
        }
        lineIndex += (line.length + 1);
        line = this.readStringLine(uint8array, lineIndex);
        var sizeRegexp = /^\-Y (.*) \+X (.*)$/g;
        var match = sizeRegexp.exec(line);
        // TODO. Support +Y and -X if needed.
        if (!match || match.length < 3) {
            throw "HDR Bad header format, no size";
        }
        width = parseInt(match[2]);
        height = parseInt(match[1]);
        if (width < 8 || width > 0x7fff) {
            throw "HDR Bad header format, unsupported size";
        }
        lineIndex += (line.length + 1);
        return {
            height: height,
            width: width,
            dataPosition: lineIndex
        };
    };
    /**
     * Returns the cubemap information (each faces texture data) extracted from an RGBE texture.
     * This RGBE texture needs to store the information as a panorama.
     *
     * More information on this format are available here:
     * https://en.wikipedia.org/wiki/RGBE_image_format
     *
     * @param buffer The binary file stored in an array buffer.
     * @param size The expected size of the extracted cubemap.
     * @return The Cube Map information.
     */
    HDRTools.GetCubeMapTextureData = function (buffer, size) {
        var uint8array = new Uint8Array(buffer);
        var hdrInfo = this.RGBE_ReadHeader(uint8array);
        var data = this.RGBE_ReadPixels_RLE(uint8array, hdrInfo);
        var cubeMapData = _panoramaToCubemap__WEBPACK_IMPORTED_MODULE_0__["PanoramaToCubeMapTools"].ConvertPanoramaToCubemap(data, hdrInfo.width, hdrInfo.height, size);
        return cubeMapData;
    };
    /**
     * Returns the pixels data extracted from an RGBE texture.
     * This pixels will be stored left to right up to down in the R G B order in one array.
     *
     * More information on this format are available here:
     * https://en.wikipedia.org/wiki/RGBE_image_format
     *
     * @param uint8array The binary file stored in an array buffer.
     * @param hdrInfo The header information of the file.
     * @return The pixels data in RGB right to left up to down order.
     */
    HDRTools.RGBE_ReadPixels = function (uint8array, hdrInfo) {
        // Keep for multi format supports.
        return this.RGBE_ReadPixels_RLE(uint8array, hdrInfo);
    };
    HDRTools.RGBE_ReadPixels_RLE = function (uint8array, hdrInfo) {
        var num_scanlines = hdrInfo.height;
        var scanline_width = hdrInfo.width;
        var a, b, c, d, count;
        var dataIndex = hdrInfo.dataPosition;
        var index = 0, endIndex = 0, i = 0;
        var scanLineArrayBuffer = new ArrayBuffer(scanline_width * 4); // four channel R G B E
        var scanLineArray = new Uint8Array(scanLineArrayBuffer);
        // 3 channels of 4 bytes per pixel in float.
        var resultBuffer = new ArrayBuffer(hdrInfo.width * hdrInfo.height * 4 * 3);
        var resultArray = new Float32Array(resultBuffer);
        // read in each successive scanline
        while (num_scanlines > 0) {
            a = uint8array[dataIndex++];
            b = uint8array[dataIndex++];
            c = uint8array[dataIndex++];
            d = uint8array[dataIndex++];
            if (a != 2 || b != 2 || (c & 0x80)) {
                // this file is not run length encoded
                throw "HDR Bad header format, not RLE";
            }
            if (((c << 8) | d) != scanline_width) {
                throw "HDR Bad header format, wrong scan line width";
            }
            index = 0;
            // read each of the four channels for the scanline into the buffer
            for (i = 0; i < 4; i++) {
                endIndex = (i + 1) * scanline_width;
                while (index < endIndex) {
                    a = uint8array[dataIndex++];
                    b = uint8array[dataIndex++];
                    if (a > 128) {
                        // a run of the same value
                        count = a - 128;
                        if ((count == 0) || (count > endIndex - index)) {
                            throw "HDR Bad Format, bad scanline data (run)";
                        }
                        while (count-- > 0) {
                            scanLineArray[index++] = b;
                        }
                    }
                    else {
                        // a non-run
                        count = a;
                        if ((count == 0) || (count > endIndex - index)) {
                            throw "HDR Bad Format, bad scanline data (non-run)";
                        }
                        scanLineArray[index++] = b;
                        if (--count > 0) {
                            for (var j = 0; j < count; j++) {
                                scanLineArray[index++] = uint8array[dataIndex++];
                            }
                        }
                    }
                }
            }
            // now convert data from buffer into floats
            for (i = 0; i < scanline_width; i++) {
                a = scanLineArray[i];
                b = scanLineArray[i + scanline_width];
                c = scanLineArray[i + 2 * scanline_width];
                d = scanLineArray[i + 3 * scanline_width];
                this.Rgbe2float(resultArray, a, b, c, d, (hdrInfo.height - num_scanlines) * scanline_width * 3 + i * 3);
            }
            num_scanlines--;
        }
        return resultArray;
    };
    return HDRTools;
}());



/***/ }),

/***/ "./Misc/HighDynamicRange/index.ts":
/*!****************************************!*\
  !*** ./Misc/HighDynamicRange/index.ts ***!
  \****************************************/
/*! exports provided: CubeMapToSphericalPolynomialTools, HDRTools, PanoramaToCubeMapTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./cubemapToSphericalPolynomial */ "./Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeMapToSphericalPolynomialTools", function() { return _cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_0__["CubeMapToSphericalPolynomialTools"]; });

/* harmony import */ var _hdr__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./hdr */ "./Misc/HighDynamicRange/hdr.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRTools", function() { return _hdr__WEBPACK_IMPORTED_MODULE_1__["HDRTools"]; });

/* harmony import */ var _panoramaToCubemap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./panoramaToCubemap */ "./Misc/HighDynamicRange/panoramaToCubemap.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PanoramaToCubeMapTools", function() { return _panoramaToCubemap__WEBPACK_IMPORTED_MODULE_2__["PanoramaToCubeMapTools"]; });






/***/ }),

/***/ "./Misc/HighDynamicRange/panoramaToCubemap.ts":
/*!****************************************************!*\
  !*** ./Misc/HighDynamicRange/panoramaToCubemap.ts ***!
  \****************************************************/
/*! exports provided: PanoramaToCubeMapTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PanoramaToCubeMapTools", function() { return PanoramaToCubeMapTools; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Engines/constants */ "./Engines/constants.ts");


/**
 * Helper class useful to convert panorama picture to their cubemap representation in 6 faces.
 */
var PanoramaToCubeMapTools = /** @class */ (function () {
    function PanoramaToCubeMapTools() {
    }
    /**
     * Converts a panorma stored in RGB right to left up to down format into a cubemap (6 faces).
     *
     * @param float32Array The source data.
     * @param inputWidth The width of the input panorama.
     * @param inputHeight The height of the input panorama.
     * @param size The willing size of the generated cubemap (each faces will be size * size pixels)
     * @return The cubemap data
     */
    PanoramaToCubeMapTools.ConvertPanoramaToCubemap = function (float32Array, inputWidth, inputHeight, size) {
        if (!float32Array) {
            throw "ConvertPanoramaToCubemap: input cannot be null";
        }
        if (float32Array.length != inputWidth * inputHeight * 3) {
            throw "ConvertPanoramaToCubemap: input size is wrong";
        }
        var textureFront = this.CreateCubemapTexture(size, this.FACE_FRONT, float32Array, inputWidth, inputHeight);
        var textureBack = this.CreateCubemapTexture(size, this.FACE_BACK, float32Array, inputWidth, inputHeight);
        var textureLeft = this.CreateCubemapTexture(size, this.FACE_LEFT, float32Array, inputWidth, inputHeight);
        var textureRight = this.CreateCubemapTexture(size, this.FACE_RIGHT, float32Array, inputWidth, inputHeight);
        var textureUp = this.CreateCubemapTexture(size, this.FACE_UP, float32Array, inputWidth, inputHeight);
        var textureDown = this.CreateCubemapTexture(size, this.FACE_DOWN, float32Array, inputWidth, inputHeight);
        return {
            front: textureFront,
            back: textureBack,
            left: textureLeft,
            right: textureRight,
            up: textureUp,
            down: textureDown,
            size: size,
            type: _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].TEXTURETYPE_FLOAT,
            format: _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].TEXTUREFORMAT_RGB,
            gammaSpace: false,
        };
    };
    PanoramaToCubeMapTools.CreateCubemapTexture = function (texSize, faceData, float32Array, inputWidth, inputHeight) {
        var buffer = new ArrayBuffer(texSize * texSize * 4 * 3);
        var textureArray = new Float32Array(buffer);
        var rotDX1 = faceData[1].subtract(faceData[0]).scale(1 / texSize);
        var rotDX2 = faceData[3].subtract(faceData[2]).scale(1 / texSize);
        var dy = 1 / texSize;
        var fy = 0;
        for (var y = 0; y < texSize; y++) {
            var xv1 = faceData[0];
            var xv2 = faceData[2];
            for (var x = 0; x < texSize; x++) {
                var v = xv2.subtract(xv1).scale(fy).add(xv1);
                v.normalize();
                var color = this.CalcProjectionSpherical(v, float32Array, inputWidth, inputHeight);
                // 3 channels per pixels
                textureArray[y * texSize * 3 + (x * 3) + 0] = color.r;
                textureArray[y * texSize * 3 + (x * 3) + 1] = color.g;
                textureArray[y * texSize * 3 + (x * 3) + 2] = color.b;
                xv1 = xv1.add(rotDX1);
                xv2 = xv2.add(rotDX2);
            }
            fy += dy;
        }
        return textureArray;
    };
    PanoramaToCubeMapTools.CalcProjectionSpherical = function (vDir, float32Array, inputWidth, inputHeight) {
        var theta = Math.atan2(vDir.z, vDir.x);
        var phi = Math.acos(vDir.y);
        while (theta < -Math.PI) {
            theta += 2 * Math.PI;
        }
        while (theta > Math.PI) {
            theta -= 2 * Math.PI;
        }
        var dx = theta / Math.PI;
        var dy = phi / Math.PI;
        // recenter.
        dx = dx * 0.5 + 0.5;
        var px = Math.round(dx * inputWidth);
        if (px < 0) {
            px = 0;
        }
        else if (px >= inputWidth) {
            px = inputWidth - 1;
        }
        var py = Math.round(dy * inputHeight);
        if (py < 0) {
            py = 0;
        }
        else if (py >= inputHeight) {
            py = inputHeight - 1;
        }
        var inputY = (inputHeight - py - 1);
        var r = float32Array[inputY * inputWidth * 3 + (px * 3) + 0];
        var g = float32Array[inputY * inputWidth * 3 + (px * 3) + 1];
        var b = float32Array[inputY * inputWidth * 3 + (px * 3) + 2];
        return {
            r: r,
            g: g,
            b: b
        };
    };
    PanoramaToCubeMapTools.FACE_FRONT = [
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, -1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, -1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, 1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 1.0, -1.0)
    ];
    PanoramaToCubeMapTools.FACE_BACK = [
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, -1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, -1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, 1.0, 1.0)
    ];
    PanoramaToCubeMapTools.FACE_RIGHT = [
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, -1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, -1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 1.0, 1.0)
    ];
    PanoramaToCubeMapTools.FACE_LEFT = [
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, -1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, -1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, 1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, 1.0, -1.0)
    ];
    PanoramaToCubeMapTools.FACE_DOWN = [
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, 1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, 1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, 1.0, 1.0)
    ];
    PanoramaToCubeMapTools.FACE_UP = [
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, -1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, -1.0, 1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-1.0, -1.0, -1.0),
        new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1.0, -1.0, -1.0)
    ];
    return PanoramaToCubeMapTools;
}());



/***/ }),

/***/ "./Misc/andOrNotEvaluator.ts":
/*!***********************************!*\
  !*** ./Misc/andOrNotEvaluator.ts ***!
  \***********************************/
/*! exports provided: AndOrNotEvaluator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AndOrNotEvaluator", function() { return AndOrNotEvaluator; });
/**
 * Class used to evalaute queries containing `and` and `or` operators
 */
var AndOrNotEvaluator = /** @class */ (function () {
    function AndOrNotEvaluator() {
    }
    /**
     * Evaluate a query
     * @param query defines the query to evaluate
     * @param evaluateCallback defines the callback used to filter result
     * @returns true if the query matches
     */
    AndOrNotEvaluator.Eval = function (query, evaluateCallback) {
        if (!query.match(/\([^\(\)]*\)/g)) {
            query = AndOrNotEvaluator._HandleParenthesisContent(query, evaluateCallback);
        }
        else {
            query = query.replace(/\([^\(\)]*\)/g, function (r) {
                // remove parenthesis
                r = r.slice(1, r.length - 1);
                return AndOrNotEvaluator._HandleParenthesisContent(r, evaluateCallback);
            });
        }
        if (query === "true") {
            return true;
        }
        if (query === "false") {
            return false;
        }
        return AndOrNotEvaluator.Eval(query, evaluateCallback);
    };
    AndOrNotEvaluator._HandleParenthesisContent = function (parenthesisContent, evaluateCallback) {
        evaluateCallback = evaluateCallback || (function (r) {
            return r === "true" ? true : false;
        });
        var result;
        var or = parenthesisContent.split("||");
        for (var i in or) {
            if (or.hasOwnProperty(i)) {
                var ori = AndOrNotEvaluator._SimplifyNegation(or[i].trim());
                var and = ori.split("&&");
                if (and.length > 1) {
                    for (var j = 0; j < and.length; ++j) {
                        var andj = AndOrNotEvaluator._SimplifyNegation(and[j].trim());
                        if (andj !== "true" && andj !== "false") {
                            if (andj[0] === "!") {
                                result = !evaluateCallback(andj.substring(1));
                            }
                            else {
                                result = evaluateCallback(andj);
                            }
                        }
                        else {
                            result = andj === "true" ? true : false;
                        }
                        if (!result) { // no need to continue since 'false && ... && ...' will always return false
                            ori = "false";
                            break;
                        }
                    }
                }
                if (result || ori === "true") { // no need to continue since 'true || ... || ...' will always return true
                    result = true;
                    break;
                }
                // result equals false (or undefined)
                if (ori !== "true" && ori !== "false") {
                    if (ori[0] === "!") {
                        result = !evaluateCallback(ori.substring(1));
                    }
                    else {
                        result = evaluateCallback(ori);
                    }
                }
                else {
                    result = ori === "true" ? true : false;
                }
            }
        }
        // the whole parenthesis scope is replaced by 'true' or 'false'
        return result ? "true" : "false";
    };
    AndOrNotEvaluator._SimplifyNegation = function (booleanString) {
        booleanString = booleanString.replace(/^[\s!]+/, function (r) {
            // remove whitespaces
            r = r.replace(/[\s]/g, function () { return ""; });
            return r.length % 2 ? "!" : "";
        });
        booleanString = booleanString.trim();
        if (booleanString === "!true") {
            booleanString = "false";
        }
        else if (booleanString === "!false") {
            booleanString = "true";
        }
        return booleanString;
    };
    return AndOrNotEvaluator;
}());



/***/ }),

/***/ "./Misc/arrayTools.ts":
/*!****************************!*\
  !*** ./Misc/arrayTools.ts ***!
  \****************************/
/*! exports provided: ArrayTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ArrayTools", function() { return ArrayTools; });
/**
 * Class containing a set of static utilities functions for arrays.
 */
var ArrayTools = /** @class */ (function () {
    function ArrayTools() {
    }
    /**
     * Returns an array of the given size filled with element built from the given constructor and the paramters
     * @param size the number of element to construct and put in the array
     * @param itemBuilder a callback responsible for creating new instance of item. Called once per array entry.
     * @returns a new array filled with new objects
     */
    ArrayTools.BuildArray = function (size, itemBuilder) {
        var a = [];
        for (var i = 0; i < size; ++i) {
            a.push(itemBuilder());
        }
        return a;
    };
    return ArrayTools;
}());



/***/ }),

/***/ "./Misc/assetsManager.ts":
/*!*******************************!*\
  !*** ./Misc/assetsManager.ts ***!
  \*******************************/
/*! exports provided: AssetTaskState, AbstractAssetTask, AssetsProgressEvent, MeshAssetTask, TextFileAssetTask, BinaryFileAssetTask, ImageAssetTask, TextureAssetTask, CubeTextureAssetTask, HDRCubeTextureAssetTask, EquiRectangularCubeTextureAssetTask, AssetsManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AssetTaskState", function() { return AssetTaskState; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractAssetTask", function() { return AbstractAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AssetsProgressEvent", function() { return AssetsProgressEvent; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshAssetTask", function() { return MeshAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextFileAssetTask", function() { return TextFileAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BinaryFileAssetTask", function() { return BinaryFileAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageAssetTask", function() { return ImageAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextureAssetTask", function() { return TextureAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CubeTextureAssetTask", function() { return CubeTextureAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTextureAssetTask", function() { return HDRCubeTextureAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTextureAssetTask", function() { return EquiRectangularCubeTextureAssetTask; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AssetsManager", function() { return AssetsManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./tools */ "./Misc/tools.ts");
/* harmony import */ var _observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./observable */ "./Misc/observable.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Textures/cubeTexture */ "./Materials/Textures/cubeTexture.ts");
/* harmony import */ var _Materials_Textures_hdrCubeTexture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/Textures/hdrCubeTexture */ "./Materials/Textures/hdrCubeTexture.ts");
/* harmony import */ var _Materials_Textures_equiRectangularCubeTexture__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/Textures/equiRectangularCubeTexture */ "./Materials/Textures/equiRectangularCubeTexture.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");









/**
 * Defines the list of states available for a task inside a AssetsManager
 */
var AssetTaskState;
(function (AssetTaskState) {
    /**
     * Initialization
     */
    AssetTaskState[AssetTaskState["INIT"] = 0] = "INIT";
    /**
     * Running
     */
    AssetTaskState[AssetTaskState["RUNNING"] = 1] = "RUNNING";
    /**
     * Done
     */
    AssetTaskState[AssetTaskState["DONE"] = 2] = "DONE";
    /**
     * Error
     */
    AssetTaskState[AssetTaskState["ERROR"] = 3] = "ERROR";
})(AssetTaskState || (AssetTaskState = {}));
/**
 * Define an abstract asset task used with a AssetsManager class to load assets into a scene
 */
var AbstractAssetTask = /** @class */ (function () {
    /**
     * Creates a new AssetsManager
     * @param name defines the name of the task
     */
    function AbstractAssetTask(
    /**
     * Task name
     */ name) {
        this.name = name;
        this._isCompleted = false;
        this._taskState = AssetTaskState.INIT;
    }
    Object.defineProperty(AbstractAssetTask.prototype, "isCompleted", {
        /**
         * Get if the task is completed
         */
        get: function () {
            return this._isCompleted;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractAssetTask.prototype, "taskState", {
        /**
         * Gets the current state of the task
         */
        get: function () {
            return this._taskState;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(AbstractAssetTask.prototype, "errorObject", {
        /**
         * Gets the current error object (if task is in error)
         */
        get: function () {
            return this._errorObject;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Internal only
     * @hidden
     */
    AbstractAssetTask.prototype._setErrorObject = function (message, exception) {
        if (this._errorObject) {
            return;
        }
        this._errorObject = {
            message: message,
            exception: exception
        };
    };
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    AbstractAssetTask.prototype.run = function (scene, onSuccess, onError) {
        var _this = this;
        this._taskState = AssetTaskState.RUNNING;
        this.runTask(scene, function () {
            _this.onDoneCallback(onSuccess, onError);
        }, function (msg, exception) {
            _this.onErrorCallback(onError, msg, exception);
        });
    };
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    AbstractAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        throw new Error("runTask is not implemented");
    };
    /**
     * Reset will set the task state back to INIT, so the next load call of the assets manager will execute this task again.
     * This can be used with failed tasks that have the reason for failure fixed.
     */
    AbstractAssetTask.prototype.reset = function () {
        this._taskState = AssetTaskState.INIT;
    };
    AbstractAssetTask.prototype.onErrorCallback = function (onError, message, exception) {
        this._taskState = AssetTaskState.ERROR;
        this._errorObject = {
            message: message,
            exception: exception
        };
        if (this.onError) {
            this.onError(this, message, exception);
        }
        onError();
    };
    AbstractAssetTask.prototype.onDoneCallback = function (onSuccess, onError) {
        try {
            this._taskState = AssetTaskState.DONE;
            this._isCompleted = true;
            if (this.onSuccess) {
                this.onSuccess(this);
            }
            onSuccess();
        }
        catch (e) {
            this.onErrorCallback(onError, "Task is done, error executing success callback(s)", e);
        }
    };
    return AbstractAssetTask;
}());

/**
 * Class used to share progress information about assets loading
 */
var AssetsProgressEvent = /** @class */ (function () {
    /**
     * Creates a AssetsProgressEvent
     * @param remainingCount defines the number of remaining tasks to process
     * @param totalCount defines the total number of tasks
     * @param task defines the task that was just processed
     */
    function AssetsProgressEvent(remainingCount, totalCount, task) {
        this.remainingCount = remainingCount;
        this.totalCount = totalCount;
        this.task = task;
    }
    return AssetsProgressEvent;
}());

/**
 * Define a task used by AssetsManager to load meshes
 */
var MeshAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MeshAssetTask, _super);
    /**
     * Creates a new MeshAssetTask
     * @param name defines the name of the task
     * @param meshesNames defines the list of mesh's names you want to load
     * @param rootUrl defines the root url to use as a base to load your meshes and associated resources
     * @param sceneFilename defines the filename of the scene to load from
     */
    function MeshAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the list of mesh's names you want to load
     */
    meshesNames,
    /**
     * Defines the root url to use as a base to load your meshes and associated resources
     */
    rootUrl,
    /**
     * Defines the filename of the scene to load from
     */
    sceneFilename) {
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.meshesNames = meshesNames;
        _this.rootUrl = rootUrl;
        _this.sceneFilename = sceneFilename;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    MeshAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var _this = this;
        _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_1__["SceneLoader"].ImportMesh(this.meshesNames, this.rootUrl, this.sceneFilename, scene, function (meshes, particleSystems, skeletons, animationGroups) {
            _this.loadedMeshes = meshes;
            _this.loadedParticleSystems = particleSystems;
            _this.loadedSkeletons = skeletons;
            _this.loadedAnimationGroups = animationGroups;
            onSuccess();
        }, null, function (scene, message, exception) {
            onError(message, exception);
        });
    };
    return MeshAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load text content
 */
var TextFileAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TextFileAssetTask, _super);
    /**
     * Creates a new TextFileAssetTask object
     * @param name defines the name of the task
     * @param url defines the location of the file to load
     */
    function TextFileAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the file to load
     */
    url) {
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    TextFileAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var _this = this;
        scene._loadFile(this.url, function (data) {
            _this.text = data;
            onSuccess();
        }, undefined, false, false, function (request, exception) {
            if (request) {
                onError(request.status + " " + request.statusText, exception);
            }
        });
    };
    return TextFileAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load binary data
 */
var BinaryFileAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BinaryFileAssetTask, _super);
    /**
     * Creates a new BinaryFileAssetTask object
     * @param name defines the name of the new task
     * @param url defines the location of the file to load
     */
    function BinaryFileAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the file to load
     */
    url) {
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    BinaryFileAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var _this = this;
        scene._loadFile(this.url, function (data) {
            _this.data = data;
            onSuccess();
        }, undefined, true, true, function (request, exception) {
            if (request) {
                onError(request.status + " " + request.statusText, exception);
            }
        });
    };
    return BinaryFileAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load images
 */
var ImageAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ImageAssetTask, _super);
    /**
     * Creates a new ImageAssetTask
     * @param name defines the name of the task
     * @param url defines the location of the image to load
     */
    function ImageAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the image to load
     */
    url) {
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    ImageAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var _this = this;
        var img = new Image();
        _tools__WEBPACK_IMPORTED_MODULE_2__["Tools"].SetCorsBehavior(this.url, img);
        img.onload = function () {
            _this.image = img;
            onSuccess();
        };
        img.onerror = function (err) {
            onError("Error loading image", err);
        };
        img.src = this.url;
    };
    return ImageAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load 2D textures
 */
var TextureAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TextureAssetTask, _super);
    /**
     * Creates a new TextureAssetTask object
     * @param name defines the name of the task
     * @param url defines the location of the file to load
     * @param noMipmap defines if mipmap should not be generated (default is false)
     * @param invertY defines if texture must be inverted on Y axis (default is false)
     * @param samplingMode defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
     */
    function TextureAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the file to load
     */
    url,
    /**
     * Defines if mipmap should not be generated (default is false)
     */
    noMipmap,
    /**
     * Defines if texture must be inverted on Y axis (default is false)
     */
    invertY,
    /**
     * Defines the sampling mode to use (default is Texture.TRILINEAR_SAMPLINGMODE)
     */
    samplingMode) {
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE; }
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        _this.noMipmap = noMipmap;
        _this.invertY = invertY;
        _this.samplingMode = samplingMode;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    TextureAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var onload = function () {
            onSuccess();
        };
        var onerror = function (message, exception) {
            onError(message, exception);
        };
        this.texture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"](this.url, scene, this.noMipmap, this.invertY, this.samplingMode, onload, onerror);
    };
    return TextureAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load cube textures
 */
var CubeTextureAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CubeTextureAssetTask, _super);
    /**
     * Creates a new CubeTextureAssetTask
     * @param name defines the name of the task
     * @param url defines the location of the files to load (You have to specify the folder where the files are + filename with no extension)
     * @param extensions defines the extensions to use to load files (["_px", "_py", "_pz", "_nx", "_ny", "_nz"] by default)
     * @param noMipmap defines if mipmaps should not be generated (default is false)
     * @param files defines the explicit list of files (undefined by default)
     */
    function CubeTextureAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the files to load (You have to specify the folder where the files are + filename with no extension)
     */
    url,
    /**
     * Defines the extensions to use to load files (["_px", "_py", "_pz", "_nx", "_ny", "_nz"] by default)
     */
    extensions,
    /**
     * Defines if mipmaps should not be generated (default is false)
     */
    noMipmap,
    /**
     * Defines the explicit list of files (undefined by default)
     */
    files) {
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        _this.extensions = extensions;
        _this.noMipmap = noMipmap;
        _this.files = files;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    CubeTextureAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var onload = function () {
            onSuccess();
        };
        var onerror = function (message, exception) {
            onError(message, exception);
        };
        this.texture = new _Materials_Textures_cubeTexture__WEBPACK_IMPORTED_MODULE_5__["CubeTexture"](this.url, scene, this.extensions, this.noMipmap, this.files, onload, onerror);
    };
    return CubeTextureAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load HDR cube textures
 */
var HDRCubeTextureAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HDRCubeTextureAssetTask, _super);
    /**
     * Creates a new HDRCubeTextureAssetTask object
     * @param name defines the name of the task
     * @param url defines the location of the file to load
     * @param size defines the desired size (the more it increases the longer the generation will be) If the size is omitted this implies you are using a preprocessed cubemap.
     * @param noMipmap defines if mipmaps should not be generated (default is false)
     * @param generateHarmonics specifies whether you want to extract the polynomial harmonics during the generation process (default is true)
     * @param gammaSpace specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)
     * @param reserved Internal use only
     */
    function HDRCubeTextureAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the file to load
     */
    url,
    /**
     * Defines the desired size (the more it increases the longer the generation will be)
     */
    size,
    /**
     * Defines if mipmaps should not be generated (default is false)
     */
    noMipmap,
    /**
     * Specifies whether you want to extract the polynomial harmonics during the generation process (default is true)
     */
    generateHarmonics,
    /**
     * Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)
     */
    gammaSpace,
    /**
     * Internal Use Only
     */
    reserved) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (generateHarmonics === void 0) { generateHarmonics = true; }
        if (gammaSpace === void 0) { gammaSpace = false; }
        if (reserved === void 0) { reserved = false; }
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        _this.size = size;
        _this.noMipmap = noMipmap;
        _this.generateHarmonics = generateHarmonics;
        _this.gammaSpace = gammaSpace;
        _this.reserved = reserved;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    HDRCubeTextureAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var onload = function () {
            onSuccess();
        };
        var onerror = function (message, exception) {
            onError(message, exception);
        };
        this.texture = new _Materials_Textures_hdrCubeTexture__WEBPACK_IMPORTED_MODULE_6__["HDRCubeTexture"](this.url, scene, this.size, this.noMipmap, this.generateHarmonics, this.gammaSpace, this.reserved, onload, onerror);
    };
    return HDRCubeTextureAssetTask;
}(AbstractAssetTask));

/**
 * Define a task used by AssetsManager to load Equirectangular cube textures
 */
var EquiRectangularCubeTextureAssetTask = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](EquiRectangularCubeTextureAssetTask, _super);
    /**
     * Creates a new EquiRectangularCubeTextureAssetTask object
     * @param name defines the name of the task
     * @param url defines the location of the file to load
     * @param size defines the desired size (the more it increases the longer the generation will be)
     * If the size is omitted this implies you are using a preprocessed cubemap.
     * @param noMipmap defines if mipmaps should not be generated (default is false)
     * @param gammaSpace specifies if the texture will be used in gamma or linear space
     * (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space)
     * (default is true)
     */
    function EquiRectangularCubeTextureAssetTask(
    /**
     * Defines the name of the task
     */
    name,
    /**
     * Defines the location of the file to load
     */
    url,
    /**
     * Defines the desired size (the more it increases the longer the generation will be)
     */
    size,
    /**
     * Defines if mipmaps should not be generated (default is false)
     */
    noMipmap,
    /**
     * Specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space,
     * but the standard material would require them in Gamma space) (default is true)
     */
    gammaSpace) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (gammaSpace === void 0) { gammaSpace = true; }
        var _this = _super.call(this, name) || this;
        _this.name = name;
        _this.url = url;
        _this.size = size;
        _this.noMipmap = noMipmap;
        _this.gammaSpace = gammaSpace;
        return _this;
    }
    /**
     * Execute the current task
     * @param scene defines the scene where you want your assets to be loaded
     * @param onSuccess is a callback called when the task is successfully executed
     * @param onError is a callback called if an error occurs
     */
    EquiRectangularCubeTextureAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
        var onload = function () {
            onSuccess();
        };
        var onerror = function (message, exception) {
            onError(message, exception);
        };
        this.texture = new _Materials_Textures_equiRectangularCubeTexture__WEBPACK_IMPORTED_MODULE_7__["EquiRectangularCubeTexture"](this.url, scene, this.size, this.noMipmap, this.gammaSpace, onload, onerror);
    };
    return EquiRectangularCubeTextureAssetTask;
}(AbstractAssetTask));

/**
 * This class can be used to easily import assets into a scene
 * @see http://doc.babylonjs.com/how_to/how_to_use_assetsmanager
 */
var AssetsManager = /** @class */ (function () {
    /**
     * Creates a new AssetsManager
     * @param scene defines the scene to work on
     */
    function AssetsManager(scene) {
        this._isLoading = false;
        this._tasks = new Array();
        this._waitingTasksCount = 0;
        this._totalTasksCount = 0;
        /**
         * Observable called when all tasks are processed
         */
        this.onTaskSuccessObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Observable called when a task had an error
         */
        this.onTaskErrorObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Observable called when all tasks were executed
         */
        this.onTasksDoneObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Observable called when a task is done (whatever the result is)
         */
        this.onProgressObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Gets or sets a boolean defining if the AssetsManager should use the default loading screen
         * @see http://doc.babylonjs.com/how_to/creating_a_custom_loading_screen
         */
        this.useDefaultLoadingScreen = true;
        /**
         * Gets or sets a boolean defining if the AssetsManager should automatically hide the loading screen
         * when all assets have been downloaded.
         * If set to false, you need to manually call in hideLoadingUI() once your scene is ready.
         */
        this.autoHideLoadingUI = true;
        this._scene = scene;
    }
    /**
     * Add a MeshAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param meshesNames defines the name of meshes to load
     * @param rootUrl defines the root url to use to locate files
     * @param sceneFilename defines the filename of the scene file
     * @returns a new MeshAssetTask object
     */
    AssetsManager.prototype.addMeshTask = function (taskName, meshesNames, rootUrl, sceneFilename) {
        var task = new MeshAssetTask(taskName, meshesNames, rootUrl, sceneFilename);
        this._tasks.push(task);
        return task;
    };
    /**
     * Add a TextFileAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @returns a new TextFileAssetTask object
     */
    AssetsManager.prototype.addTextFileTask = function (taskName, url) {
        var task = new TextFileAssetTask(taskName, url);
        this._tasks.push(task);
        return task;
    };
    /**
     * Add a BinaryFileAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @returns a new BinaryFileAssetTask object
     */
    AssetsManager.prototype.addBinaryFileTask = function (taskName, url) {
        var task = new BinaryFileAssetTask(taskName, url);
        this._tasks.push(task);
        return task;
    };
    /**
     * Add a ImageAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @returns a new ImageAssetTask object
     */
    AssetsManager.prototype.addImageTask = function (taskName, url) {
        var task = new ImageAssetTask(taskName, url);
        this._tasks.push(task);
        return task;
    };
    /**
     * Add a TextureAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @param noMipmap defines if the texture must not receive mipmaps (false by default)
     * @param invertY defines if you want to invert Y axis of the loaded texture (false by default)
     * @param samplingMode defines the sampling mode to use (Texture.TRILINEAR_SAMPLINGMODE by default)
     * @returns a new TextureAssetTask object
     */
    AssetsManager.prototype.addTextureTask = function (taskName, url, noMipmap, invertY, samplingMode) {
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE; }
        var task = new TextureAssetTask(taskName, url, noMipmap, invertY, samplingMode);
        this._tasks.push(task);
        return task;
    };
    /**
     * Add a CubeTextureAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @param extensions defines the extension to use to load the cube map (can be null)
     * @param noMipmap defines if the texture must not receive mipmaps (false by default)
     * @param files defines the list of files to load (can be null)
     * @returns a new CubeTextureAssetTask object
     */
    AssetsManager.prototype.addCubeTextureTask = function (taskName, url, extensions, noMipmap, files) {
        var task = new CubeTextureAssetTask(taskName, url, extensions, noMipmap, files);
        this._tasks.push(task);
        return task;
    };
    /**
     *
     * Add a HDRCubeTextureAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @param size defines the size you want for the cubemap (can be null)
     * @param noMipmap defines if the texture must not receive mipmaps (false by default)
     * @param generateHarmonics defines if you want to automatically generate (true by default)
     * @param gammaSpace specifies if the texture will be use in gamma or linear space (the PBR material requires those texture in linear space, but the standard material would require them in Gamma space) (default is false)
     * @param reserved Internal use only
     * @returns a new HDRCubeTextureAssetTask object
     */
    AssetsManager.prototype.addHDRCubeTextureTask = function (taskName, url, size, noMipmap, generateHarmonics, gammaSpace, reserved) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (generateHarmonics === void 0) { generateHarmonics = true; }
        if (gammaSpace === void 0) { gammaSpace = false; }
        if (reserved === void 0) { reserved = false; }
        var task = new HDRCubeTextureAssetTask(taskName, url, size, noMipmap, generateHarmonics, gammaSpace, reserved);
        this._tasks.push(task);
        return task;
    };
    /**
     *
     * Add a EquiRectangularCubeTextureAssetTask to the list of active tasks
     * @param taskName defines the name of the new task
     * @param url defines the url of the file to load
     * @param size defines the size you want for the cubemap (can be null)
     * @param noMipmap defines if the texture must not receive mipmaps (false by default)
     * @param gammaSpace Specifies if the texture will be used in gamma or linear space
     * (the PBR material requires those textures in linear space, but the standard material would require them in Gamma space)
     * @returns a new EquiRectangularCubeTextureAssetTask object
     */
    AssetsManager.prototype.addEquiRectangularCubeTextureAssetTask = function (taskName, url, size, noMipmap, gammaSpace) {
        if (noMipmap === void 0) { noMipmap = false; }
        if (gammaSpace === void 0) { gammaSpace = true; }
        var task = new EquiRectangularCubeTextureAssetTask(taskName, url, size, noMipmap, gammaSpace);
        this._tasks.push(task);
        return task;
    };
    /**
     * Remove a task from the assets manager.
     * @param task the task to remove
     */
    AssetsManager.prototype.removeTask = function (task) {
        var index = this._tasks.indexOf(task);
        if (index > -1) {
            this._tasks.splice(index, 1);
        }
    };
    AssetsManager.prototype._decreaseWaitingTasksCount = function (task) {
        this._waitingTasksCount--;
        try {
            if (this.onProgress) {
                this.onProgress(this._waitingTasksCount, this._totalTasksCount, task);
            }
            this.onProgressObservable.notifyObservers(new AssetsProgressEvent(this._waitingTasksCount, this._totalTasksCount, task));
        }
        catch (e) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_8__["Logger"].Error("Error running progress callbacks.");
            console.log(e);
        }
        if (this._waitingTasksCount === 0) {
            try {
                if (this.onFinish) {
                    this.onFinish(this._tasks);
                }
                // Let's remove successfull tasks
                var currentTasks = this._tasks.slice();
                for (var _i = 0, currentTasks_1 = currentTasks; _i < currentTasks_1.length; _i++) {
                    var task = currentTasks_1[_i];
                    if (task.taskState === AssetTaskState.DONE) {
                        var index = this._tasks.indexOf(task);
                        if (index > -1) {
                            this._tasks.splice(index, 1);
                        }
                    }
                }
                this.onTasksDoneObservable.notifyObservers(this._tasks);
            }
            catch (e) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_8__["Logger"].Error("Error running tasks-done callbacks.");
                console.log(e);
            }
            this._isLoading = false;
            if (this.autoHideLoadingUI) {
                this._scene.getEngine().hideLoadingUI();
            }
        }
    };
    AssetsManager.prototype._runTask = function (task) {
        var _this = this;
        var done = function () {
            try {
                if (_this.onTaskSuccess) {
                    _this.onTaskSuccess(task);
                }
                _this.onTaskSuccessObservable.notifyObservers(task);
                _this._decreaseWaitingTasksCount(task);
            }
            catch (e) {
                error("Error executing task success callbacks", e);
            }
        };
        var error = function (message, exception) {
            task._setErrorObject(message, exception);
            if (_this.onTaskError) {
                _this.onTaskError(task);
            }
            _this.onTaskErrorObservable.notifyObservers(task);
            _this._decreaseWaitingTasksCount(task);
        };
        task.run(this._scene, done, error);
    };
    /**
     * Reset the AssetsManager and remove all tasks
     * @return the current instance of the AssetsManager
     */
    AssetsManager.prototype.reset = function () {
        this._isLoading = false;
        this._tasks = new Array();
        return this;
    };
    /**
     * Start the loading process
     * @return the current instance of the AssetsManager
     */
    AssetsManager.prototype.load = function () {
        if (this._isLoading) {
            return this;
        }
        this._isLoading = true;
        this._waitingTasksCount = this._tasks.length;
        this._totalTasksCount = this._tasks.length;
        if (this._waitingTasksCount === 0) {
            this._isLoading = false;
            if (this.onFinish) {
                this.onFinish(this._tasks);
            }
            this.onTasksDoneObservable.notifyObservers(this._tasks);
            return this;
        }
        if (this.useDefaultLoadingScreen) {
            this._scene.getEngine().displayLoadingUI();
        }
        for (var index = 0; index < this._tasks.length; index++) {
            var task = this._tasks[index];
            if (task.taskState === AssetTaskState.INIT) {
                this._runTask(task);
            }
        }
        return this;
    };
    /**
     * Start the loading process as an async operation
     * @return a promise returning the list of failed tasks
     */
    AssetsManager.prototype.loadAsync = function () {
        var _this = this;
        return new Promise(function (resolve, reject) {
            if (_this._isLoading) {
                resolve();
                return;
            }
            _this.onTasksDoneObservable.addOnce(function (remainingTasks) {
                if (remainingTasks && remainingTasks.length) {
                    reject(remainingTasks);
                }
                else {
                    resolve();
                }
            });
            _this.load();
        });
    };
    return AssetsManager;
}());



/***/ }),

/***/ "./Misc/basis.ts":
/*!***********************!*\
  !*** ./Misc/basis.ts ***!
  \***********************/
/*! exports provided: BasisTranscodeConfiguration, BasisTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BasisTranscodeConfiguration", function() { return BasisTranscodeConfiguration; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BasisTools", function() { return BasisTools; });
/* harmony import */ var _tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tools */ "./Misc/tools.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");





/**
 * Info about the .basis files
 */
var BasisFileInfo = /** @class */ (function () {
    function BasisFileInfo() {
    }
    return BasisFileInfo;
}());
/**
 * Result of transcoding a basis file
 */
var TranscodeResult = /** @class */ (function () {
    function TranscodeResult() {
    }
    return TranscodeResult;
}());
/**
 * Configuration options for the Basis transcoder
 */
var BasisTranscodeConfiguration = /** @class */ (function () {
    function BasisTranscodeConfiguration() {
    }
    return BasisTranscodeConfiguration;
}());

/**
 * @hidden
 * Enum of basis transcoder formats
 */
var BASIS_FORMATS;
(function (BASIS_FORMATS) {
    BASIS_FORMATS[BASIS_FORMATS["cTFETC1"] = 0] = "cTFETC1";
    BASIS_FORMATS[BASIS_FORMATS["cTFBC1"] = 1] = "cTFBC1";
    BASIS_FORMATS[BASIS_FORMATS["cTFBC4"] = 2] = "cTFBC4";
    BASIS_FORMATS[BASIS_FORMATS["cTFPVRTC1_4_OPAQUE_ONLY"] = 3] = "cTFPVRTC1_4_OPAQUE_ONLY";
    BASIS_FORMATS[BASIS_FORMATS["cTFBC7_M6_OPAQUE_ONLY"] = 4] = "cTFBC7_M6_OPAQUE_ONLY";
    BASIS_FORMATS[BASIS_FORMATS["cTFETC2"] = 5] = "cTFETC2";
    BASIS_FORMATS[BASIS_FORMATS["cTFBC3"] = 6] = "cTFBC3";
    BASIS_FORMATS[BASIS_FORMATS["cTFBC5"] = 7] = "cTFBC5";
})(BASIS_FORMATS || (BASIS_FORMATS = {}));
/**
 * Used to load .Basis files
 * See https://github.com/BinomialLLC/basis_universal/tree/master/webgl
 */
var BasisTools = /** @class */ (function () {
    function BasisTools() {
    }
    /**
     * Get the internal format to be passed to texImage2D corresponding to the .basis format value
     * @param basisFormat format chosen from GetSupportedTranscodeFormat
     * @returns internal format corresponding to the Basis format
     */
    BasisTools.GetInternalFormatFromBasisFormat = function (basisFormat) {
        // Corrisponding internal formats
        var COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
        var COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
        var RGB_ETC1_Format = 36196;
        if (basisFormat === BASIS_FORMATS.cTFETC1) {
            return RGB_ETC1_Format;
        }
        else if (basisFormat === BASIS_FORMATS.cTFBC1) {
            return COMPRESSED_RGB_S3TC_DXT1_EXT;
        }
        else if (basisFormat === BASIS_FORMATS.cTFBC3) {
            return COMPRESSED_RGBA_S3TC_DXT5_EXT;
        }
        else {
            throw "The chosen Basis transcoder format is not currently supported";
        }
    };
    BasisTools._CreateWorkerAsync = function () {
        var _this = this;
        if (!this._WorkerPromise) {
            this._WorkerPromise = new Promise(function (res) {
                if (_this._Worker) {
                    res(_this._Worker);
                }
                else {
                    _tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].LoadFileAsync(BasisTools.WasmModuleURL).then(function (wasmBinary) {
                        var workerBlobUrl = URL.createObjectURL(new Blob(["(" + workerFunc + ")()"], { type: "application/javascript" }));
                        _this._Worker = new Worker(workerBlobUrl);
                        var initHandler = function (msg) {
                            if (msg.data.action === "init") {
                                _this._Worker.removeEventListener("message", initHandler);
                                res(_this._Worker);
                            }
                        };
                        _this._Worker.addEventListener("message", initHandler);
                        _this._Worker.postMessage({ action: "init", url: BasisTools.JSModuleURL, wasmBinary: wasmBinary });
                    });
                }
            });
        }
        return this._WorkerPromise;
    };
    /**
     * Transcodes a loaded image file to compressed pixel data
     * @param imageData image data to transcode
     * @param config configuration options for the transcoding
     * @returns a promise resulting in the transcoded image
     */
    BasisTools.TranscodeAsync = function (imageData, config) {
        var _this = this;
        return new Promise(function (res, rej) {
            _this._CreateWorkerAsync().then(function () {
                var actionId = _this._actionId++;
                var messageHandler = function (msg) {
                    if (msg.data.action === "transcode" && msg.data.id === actionId) {
                        _this._Worker.removeEventListener("message", messageHandler);
                        if (!msg.data.success) {
                            rej("Transcode is not supported on this device");
                        }
                        else {
                            res(msg.data);
                        }
                    }
                };
                _this._Worker.addEventListener("message", messageHandler);
                _this._Worker.postMessage({ action: "transcode", id: actionId, imageData: imageData, config: config, ignoreSupportedFormats: _this._IgnoreSupportedFormats }, [imageData]);
            });
        });
    };
    /**
     * Loads a texture from the transcode result
     * @param texture texture load to
     * @param transcodeResult the result of transcoding the basis file to load from
     */
    BasisTools.LoadTextureFromTranscodeResult = function (texture, transcodeResult) {
        var _loop_1 = function () {
            rootImage = transcodeResult.fileInfo.images[i].levels[0];
            texture._invertVScale = texture.invertY;
            if (transcodeResult.format === -1) {
                // No compatable compressed format found, fallback to RGB
                texture.type = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTURETYPE_UNSIGNED_SHORT_5_6_5;
                texture.format = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTUREFORMAT_RGB;
                if (texture.getEngine().webGLVersion < 2 && (_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Log2(rootImage.width) % 1 !== 0 || _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Log2(rootImage.height) % 1 !== 0)) {
                    // Create non power of two texture
                    var source_1 = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"](texture.getEngine(), _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_2__["InternalTexture"].DATASOURCE_TEMP);
                    texture._invertVScale = texture.invertY;
                    source_1.type = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTURETYPE_UNSIGNED_SHORT_5_6_5;
                    source_1.format = _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTUREFORMAT_RGB;
                    // Fallback requires aligned width/height
                    source_1.width = (rootImage.width + 3) & ~3;
                    source_1.height = (rootImage.height + 3) & ~3;
                    texture.getEngine()._bindTextureDirectly(source_1.getEngine()._gl.TEXTURE_2D, source_1, true);
                    texture.getEngine()._uploadDataToTextureDirectly(source_1, rootImage.transcodedPixels, i, 0, _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTUREFORMAT_RGB, true);
                    // Resize to power of two
                    source_1.getEngine()._rescaleTexture(source_1, texture, texture.getEngine().scenes[0], source_1.getEngine()._getInternalFormat(_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTUREFORMAT_RGB), function () {
                        source_1.getEngine()._releaseTexture(source_1);
                        source_1.getEngine()._bindTextureDirectly(source_1.getEngine()._gl.TEXTURE_2D, texture, true);
                    });
                }
                else {
                    // Fallback is already inverted
                    texture._invertVScale = !texture.invertY;
                    // Upload directly
                    texture.width = (rootImage.width + 3) & ~3;
                    texture.height = (rootImage.height + 3) & ~3;
                    texture.getEngine()._uploadDataToTextureDirectly(texture, rootImage.transcodedPixels, i, 0, _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTUREFORMAT_RGB, true);
                }
            }
            else {
                texture.width = rootImage.width;
                texture.height = rootImage.height;
                // Upload all mip levels in the file
                transcodeResult.fileInfo.images[i].levels.forEach(function (level, index) {
                    texture.getEngine()._uploadCompressedDataToTextureDirectly(texture, BasisTools.GetInternalFormatFromBasisFormat(transcodeResult.format), level.width, level.height, level.transcodedPixels, i, index);
                });
                if (texture.getEngine().webGLVersion < 2 && (_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Log2(texture.width) % 1 !== 0 || _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Log2(texture.height) % 1 !== 0)) {
                    _tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].Warn("Loaded .basis texture width and height are not a power of two. Texture wrapping will be set to Texture.CLAMP_ADDRESSMODE as other modes are not supported with non power of two dimensions in webGL 1.");
                    texture._cachedWrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].CLAMP_ADDRESSMODE;
                    texture._cachedWrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].CLAMP_ADDRESSMODE;
                }
            }
        };
        var rootImage;
        for (var i = 0; i < transcodeResult.fileInfo.images.length; i++) {
            _loop_1();
        }
    };
    BasisTools._IgnoreSupportedFormats = false;
    /**
     * URL to use when loading the basis transcoder
     */
    BasisTools.JSModuleURL = "https://preview.babylonjs.com/basisTranscoder/basis_transcoder.js";
    /**
     * URL to use when loading the wasm module for the transcoder
     */
    BasisTools.WasmModuleURL = "https://preview.babylonjs.com/basisTranscoder/basis_transcoder.wasm";
    BasisTools._WorkerPromise = null;
    BasisTools._Worker = null;
    BasisTools._actionId = 0;
    return BasisTools;
}());

function workerFunc() {
    var _BASIS_FORMAT = {
        cTFETC1: 0,
        cTFBC1: 1,
        cTFBC4: 2,
        cTFPVRTC1_4_OPAQUE_ONLY: 3,
        cTFBC7_M6_OPAQUE_ONLY: 4,
        cTFETC2: 5,
        cTFBC3: 6,
        cTFBC5: 7,
    };
    var transcoderModulePromise = null;
    onmessage = function (event) {
        if (event.data.action === "init") {
            // Load the transcoder if it hasn't been yet
            if (!transcoderModulePromise) {
                // Override wasm binary
                Module = { wasmBinary: (event.data.wasmBinary) };
                importScripts(event.data.url);
                transcoderModulePromise = new Promise(function (res) {
                    Module.onRuntimeInitialized = function () {
                        Module.initializeBasis();
                        res();
                    };
                });
            }
            transcoderModulePromise.then(function () {
                postMessage({ action: "init" });
            });
        }
        else if (event.data.action === "transcode") {
            // Transcode the basis image and return the resulting pixels
            var config = event.data.config;
            var imgData = event.data.imageData;
            var loadedFile = new Module.BasisFile(new Uint8Array(imgData));
            var fileInfo = GetFileInfo(loadedFile);
            var format = event.data.ignoreSupportedFormats ? null : GetSupportedTranscodeFormat(event.data.config, fileInfo);
            var needsConversion = false;
            if (format === null) {
                needsConversion = true;
                format = fileInfo.hasAlpha ? _BASIS_FORMAT.cTFBC3 : _BASIS_FORMAT.cTFBC1;
            }
            // Begin transcode
            var success = true;
            if (!loadedFile.startTranscoding()) {
                success = false;
            }
            var buffers = [];
            for (var imageIndex = 0; imageIndex < fileInfo.images.length; imageIndex++) {
                if (!success) {
                    break;
                }
                var image = fileInfo.images[imageIndex];
                if (config.loadSingleImage === undefined || config.loadSingleImage === imageIndex) {
                    var mipCount = image.levels.length;
                    if (config.loadMipmapLevels === false) {
                        mipCount = 1;
                    }
                    for (var levelIndex = 0; levelIndex < mipCount; levelIndex++) {
                        var levelInfo = image.levels[levelIndex];
                        var pixels = TranscodeLevel(loadedFile, imageIndex, levelIndex, format, needsConversion);
                        if (!pixels) {
                            success = false;
                            break;
                        }
                        levelInfo.transcodedPixels = pixels;
                        buffers.push(levelInfo.transcodedPixels.buffer);
                    }
                }
            }
            // Close file
            loadedFile.close();
            loadedFile.delete();
            if (needsConversion) {
                format = -1;
            }
            if (!success) {
                postMessage({ action: "transcode", success: success, id: event.data.id });
            }
            else {
                postMessage({ action: "transcode", success: success, id: event.data.id, fileInfo: fileInfo, format: format }, buffers);
            }
        }
    };
    /**
     * Detects the supported transcode format for the file
     * @param config transcode config
     * @param fileInfo info about the file
     * @returns the chosed format or null if none are supported
     */
    function GetSupportedTranscodeFormat(config, fileInfo) {
        var format = null;
        if (config.supportedCompressionFormats) {
            if (config.supportedCompressionFormats.etc1) {
                format = _BASIS_FORMAT.cTFETC1;
            }
            else if (config.supportedCompressionFormats.s3tc) {
                format = fileInfo.hasAlpha ? _BASIS_FORMAT.cTFBC3 : _BASIS_FORMAT.cTFBC1;
            }
            else if (config.supportedCompressionFormats.pvrtc) {
                // TODO uncomment this after pvrtc bug is fixed is basis transcoder
                // See discussion here: https://github.com/mrdoob/three.js/issues/16524#issuecomment-498929924
                // format = _BASIS_FORMAT.cTFPVRTC1_4_OPAQUE_ONLY;
            }
            else if (config.supportedCompressionFormats.etc2) {
                format = _BASIS_FORMAT.cTFETC2;
            }
        }
        return format;
    }
    /**
     * Retreives information about the basis file eg. dimensions
     * @param basisFile the basis file to get the info from
     * @returns information about the basis file
     */
    function GetFileInfo(basisFile) {
        var hasAlpha = basisFile.getHasAlpha();
        var imageCount = basisFile.getNumImages();
        var images = [];
        for (var i = 0; i < imageCount; i++) {
            var imageInfo = {
                levels: []
            };
            var levelCount = basisFile.getNumLevels(i);
            for (var level = 0; level < levelCount; level++) {
                var levelInfo = {
                    width: basisFile.getImageWidth(i, level),
                    height: basisFile.getImageHeight(i, level)
                };
                imageInfo.levels.push(levelInfo);
            }
            images.push(imageInfo);
        }
        var info = { hasAlpha: hasAlpha, images: images };
        return info;
    }
    function TranscodeLevel(loadedFile, imageIndex, levelIndex, format, convertToRgb565) {
        var dstSize = loadedFile.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);
        var dst = new Uint8Array(dstSize);
        if (!loadedFile.transcodeImage(dst, imageIndex, levelIndex, format, 1, 0)) {
            return null;
        }
        // If no supported format is found, load as dxt and convert to rgb565
        if (convertToRgb565) {
            var alignedWidth = (loadedFile.getImageWidth(imageIndex, levelIndex) + 3) & ~3;
            var alignedHeight = (loadedFile.getImageHeight(imageIndex, levelIndex) + 3) & ~3;
            dst = ConvertDxtToRgb565(dst, 0, alignedWidth, alignedHeight);
        }
        return dst;
    }
    /**
     * From https://github.com/BinomialLLC/basis_universal/blob/master/webgl/texture/dxt-to-rgb565.js
     * An unoptimized version of dxtToRgb565.  Also, the floating
     * point math used to compute the colors actually results in
     * slightly different colors compared to hardware DXT decoders.
     * @param src dxt src pixels
     * @param srcByteOffset offset for the start of src
     * @param  width aligned width of the image
     * @param  height aligned height of the image
     * @return the converted pixels
     */
    function ConvertDxtToRgb565(src, srcByteOffset, width, height) {
        var c = new Uint16Array(4);
        var dst = new Uint16Array(width * height);
        var blockWidth = width / 4;
        var blockHeight = height / 4;
        for (var blockY = 0; blockY < blockHeight; blockY++) {
            for (var blockX = 0; blockX < blockWidth; blockX++) {
                var i = srcByteOffset + 8 * (blockY * blockWidth + blockX);
                c[0] = src[i] | (src[i + 1] << 8);
                c[1] = src[i + 2] | (src[i + 3] << 8);
                c[2] = (2 * (c[0] & 0x1f) + 1 * (c[1] & 0x1f)) / 3
                    | (((2 * (c[0] & 0x7e0) + 1 * (c[1] & 0x7e0)) / 3) & 0x7e0)
                    | (((2 * (c[0] & 0xf800) + 1 * (c[1] & 0xf800)) / 3) & 0xf800);
                c[3] = (2 * (c[1] & 0x1f) + 1 * (c[0] & 0x1f)) / 3
                    | (((2 * (c[1] & 0x7e0) + 1 * (c[0] & 0x7e0)) / 3) & 0x7e0)
                    | (((2 * (c[1] & 0xf800) + 1 * (c[0] & 0xf800)) / 3) & 0xf800);
                for (var row = 0; row < 4; row++) {
                    var m = src[i + 4 + row];
                    var dstI = (blockY * 4 + row) * width + blockX * 4;
                    dst[dstI++] = c[m & 0x3];
                    dst[dstI++] = c[(m >> 2) & 0x3];
                    dst[dstI++] = c[(m >> 4) & 0x3];
                    dst[dstI++] = c[(m >> 6) & 0x3];
                }
            }
        }
        return dst;
    }
}


/***/ }),

/***/ "./Misc/brdfTextureTools.ts":
/*!**********************************!*\
  !*** ./Misc/brdfTextureTools.ts ***!
  \**********************************/
/*! exports provided: BRDFTextureTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BRDFTextureTools", function() { return BRDFTextureTools; });
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _rgbdTextureTools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./rgbdTextureTools */ "./Misc/rgbdTextureTools.ts");


/**
 * Class used to host texture specific utilities
 */
var BRDFTextureTools = /** @class */ (function () {
    function BRDFTextureTools() {
    }
    /**
     * Gets a default environment BRDF for MS-BRDF Height Correlated BRDF
     * @param scene defines the hosting scene
     * @returns the environment BRDF texture
     */
    BRDFTextureTools.GetEnvironmentBRDFTexture = function (scene) {
        if (!scene.environmentBRDFTexture) {
            // Forces Delayed Texture Loading to prevent undefined error whilst setting RGBD values.
            var useDelayedTextureLoading = scene.useDelayedTextureLoading;
            scene.useDelayedTextureLoading = false;
            var texture = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].CreateFromBase64String(this._environmentBRDFBase64Texture, "EnvironmentBRDFTexture", scene, true, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].BILINEAR_SAMPLINGMODE);
            texture.isRGBD = true;
            texture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].CLAMP_ADDRESSMODE;
            texture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].CLAMP_ADDRESSMODE;
            scene.environmentBRDFTexture = texture;
            scene.useDelayedTextureLoading = useDelayedTextureLoading;
            _rgbdTextureTools__WEBPACK_IMPORTED_MODULE_1__["RGBDTextureTools"].ExpandRGBDTexture(texture);
        }
        return scene.environmentBRDFTexture;
    };
    BRDFTextureTools._environmentBRDFBase64Texture = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAgAElEQVR42u29yY5tWXIlZnbuiSaTbZFUkZRKrCKhElASQA0EoQABgn6hJvoXzfUP+gP9hWb6Bg00IgRoQJaKqUxmZmTEe8/v0uB2u7Fm2T7HIyIrnz88uPvt3f2a2WrMbOvf/u3PvvzP/sUf/N6//i8vf/lv/3v5H//d//Sb//Uq/5u8yf8hV/m/5Cp/L1f5hVzlG7nKJ7mKyJuIXN/hPwqXI/g++zq6rPI5u8z+WqfLre+zy7PrVv9L8brsMiGvk8XLmM/sdfHXal4e3ad6GXPdyu2ij8u/+uv/5cuf/OSLfdtEfvUr+dnf/d0X//t3H/7bf/hP//N/928h/0Yg/4VA/kogfyGQP5Wr/IFAvhbIlwK5CGQTPP+9z5uPeePJSW+yo2+s/GtN30Rnv1E+f5zxof9R/lSXv/nr//mrr3+i+5dfyX7ZZQP07Tffys//8R/l/9TtX7790T/7r/8G8pdy+/8XAvnnAvkzgfwzgfyxQP5AIL8vkJ8K5KsmMVzu1U7p5PA5AXxOAJ8TwPf7sX/51ZeXfcemqnp9w/W77/S7X/6T/vzf/7383RWCX3/z05/9i3/13/0PX//eX/2FyP8tIv+PiPy9iPy/IvIzEfm5iPxCRH4lIt/c/393//9BRD6KyKf7f488fP74/PH544dJAF9cLl98IZfLBZtuqterXr/7Dt9982v95S9+Lv+gF/3i7Spv/8lf/vnf/vGf/dF/JfKnIvLnIvLvReQ/NEngn0TklyLy6/v/34jIt00iGJOBlxAsdvv54/PH5493SQCXy9t2ueh2ueimKorrFbjq9eNH+fDtb+TXv/ol/vHyhX4Fxfbx7euPf/Lnf/PfiPyeiPyhiPxxkwB+fk8AvxzQgJcIrGTwFsiAEXH4/PH54/PHUgLY7whgu2C7bLqpQgHB2xvePn6SDx8+6G9+84384vKF/IPu8iVU9Y/+7C/+jWxffiHytYj8VER+X0T+oEEBvxqQwCMJeIngo5EI3goIwVMIPn98/vj8ESaAbbtu2ybbvl8u2ybbdtluSECA65u8ffqIDx8+6G++/VZ/efkV/sO261dQXP7wT/7kX8vl8qXIFyLylbySwe/dE0CLAr65B/9vGn0gQwRMMqgmhM/J4fPH548eAezbZd/lsm3YtssNAYiqiogAAkCvb5/k46cP8u2HD/rrb7+R/2/b9Wu9yJe//8d/9Ney6S5yEZFdRL68/38khG/uKOCnAwoYkcCoEXwkEgGDDq7CeQfyOTl8/vhd1QCum26ybZtu2yabbrKpQvXue1yvuF6v+vbpTT5+/CDffviAX1++1V9sO77WXb/66R/+4V/dgkbllQi+aBLBV/dE8LWRALwkYCWCNyMZXElkwLTMeMkga/P4/PH547ccAVwuctkvdxSw6bbdtYDbTfSZBN7e8PHTR/3u4wf55vKd/nL7DX6mu3791U9//5+/gkNFZGuSgZUQvnKowKgLWLTAQgRtEniTuEfwaELw0MJvf3LQzynud+53uG+X6y3gN9kul+2y6XVT1U27JCDAFVc8ksAn/e7jR/nN5YP+avtWfq6Xy9f7Vz/9w1dgRYngiyYhfNkkgzYBWHTg44AEMmqQUYQKOmDaiCIa8TmsfmzB+DnZDQjgcpGLbti2y3bZHjRAdRMVvb/dcYU8kcDbPQlsH/CrbddfbF98+RPZfvLFnAQeieCRDC5DMvju/vmD4JkEvjRQgKULeGggowdHkAHTYxihg89vu88I5UeGAPSOAFTlrgPopiqbKPSmCKreUoAAkCcSePukHz590m8vH+WbD9/JP335k6/+tA86KxFchv8jMvhiogE4JQm8XhfKqOAqx5qRPyeGzx8/cgSwbXcUoLJtim27C4Oi93+4v6VxQwKAvl2v+Hj9pB8+fZJvt4/yzfbF9lPdv/wJnsE2BogmyeCRED40tGFvksIXiSbgiYSRRpDNDZ6BDI6ghM+J4fPHeyKAO+zX7cb9t4tedMMNAQju5V+f1uAtBSiu1zsduMrHy5t8ePsk3376KN98sX/xE5FPAnm7/782o0DiUINXMkCXCB7/P94/e87AWUmARQWVvgMuKej9t1RLBp+Tw+ePgwngsutFFdu26WXbbl+rSvdfbnqAiuA23QcBgCugV1zl7e1NPm5v+LC96XfbJ/1W9y++fgXjA3bDYXV+MuhRwSPwL3JLMFYC+HS/LU8HYrGwIhwyNOF12SvgM4SgztdifP85MXz+KGsA2C6X7aJ6bXSAOwrY5OYIqGy3d5uq4P5GhABXuV6veLvRAf10fZMPb2/y3b7vX7+g+9v98/WOBq7GG7RNAlYy+Dgkhhb+Xxp0sE8IAC4SGAP/TbgVJK/PoJPBnAiwPKxsXfbbnRg+i3s/JAK4Q/4b9NfLtomBAqCickMBjy7BuywAUVyv8na94tMjCVzf9KNcLl/0SeA6oAEYb1i9g+FtSALb/bKL8/+t+wxXFMyswqiHoK4ToIgKqslgpg1qUC0QoYbvJZg/B/q5v4szHmPX7YEAsD0CX25OwEUVm9xag1+agKg+nxQArnKjAtDr9U0+Xd/k4/UqH7bL5YsewrcBBiMJZPRAp6TwQgWfjM9vgRbgUYGL8AvLWH2gqhesCokeUmCSwPsnhs8fP2YNYMO2XeSmAWxy2VQaXeDmDIhApf33rD4PTUCuV+DtCn27XuXT5ir8VmCJ2G5BpBM8/r/dEcJb8/0lEQMtJHA5TAlqNuLRhJChhEpSqFabH3di+G1AGj+W1/dyAR4IYJNNnuLf6+tWC9CHHiAtFhAIFLjK2/Uqn65X+SS67aK+3QeTDoy/IG2ogQ7fb/dAtz5vBgrYGqrwNtCHsVfgIvwK07OTQBURVNCBFpKCOjqCHn5L/67TgTN+fpySAC56nwSUi256kXsSuFGAVyLoUIDo8/Pz7fdoErr/v17lk162HbgHvFpIYDfoAJJfW4sGPjkU4VNAF8ZEcLmLhdc7kljdY1y1Dq9yLiI4IiRqcLujb138KIPn80ejATwRwIbtBvn1cqv+2J78/5EI5N4cJA8qIPcmwRsKAHDF9WYP6mV7VmrgLuTpxYTcMEW0LAmoQxFsuvAI8tv/a/C5fV2ZMMiKg++FCM7RDPRu8ebWY7VG6VJi+Bzk35MI2LsAckMAgwvQ0gC5DQjd3ABg2HQLAPpEAlZ1Bu7VV7MGHDFRAbo3VKsTbAY9sPWC/uvx86gBbDK3D1eEQS8pbAeSgSwmhepnJb6uBv/o/PzHLzxWA/X7TH77De5j6AGQi6o0CUGfCOD2X7cXAlCFQABtEsGLDtxuOyQB2UTQBKZe5GUPXgkUYCUAbZJRhBDeuq8xBf+bgwbehDm+BFQi2IJksOocvA8ysIMfxluVcRsY/eB3JzH8GFDAXQO48X/dcIf9jyDHptIigDsFkEe066tBSETQUYF7ElDdYEBytN4+rk9UcBPfrKaZqFHWcw3i4J8/X4ev2//bSXqAhwTay6OEIPLD2Ipt8OtAGzxkwLw9WVFRjTc/qC6H3+YK/b1oAA0KuOizHfieCLaHHiAb5NYTIC9EMEbZrVEQt1xwhVy1UfBh8PUOquMizwaap3tQXfY5B//tea/NZdfhsvbz+PURQTDSGWB87VX/7WSd4KxjUqrIgE0IUkoKGnhIvwvawpGf6eECXJ7tv4qbA7DJgwpsKthEmmYgfaAAffYF3HLxo0vwNjJ0SwRWMG4db4eh1gPNm18vQ+us/0eGmxDemu/fnM/X4evq/8342ksGHgLY5LyT/zg0wM8lcMjgGFXwqIOVFJBQw99eCvF9oZL9Mfl3QwAvIXDsBRC9R+fz8x0FPBLB0xJEpwUobrfAkARgIAF41h3wQgP6QAmX5E/7eI43IxGwwf/moIkRyWRJQIPgt9CA9b39nzt4bYUWjAlCjWDPgv8IEjgLJfzuaAsrv9VdVG4OwOXW/fdoA35qAdL0BDwvf6AAUVHd8LIEu94A3K+Q+2YxaB84MOH62P//qoo38fCRDERE2zf0JfmDa+MieElAjcDPKz+mRKCOtdgGtXaBjgNJ4H2owSpNeAW/rRH4CaHSpMwnBYYycjgSJwfie9CR6mPu20Uv8kABF206AvXlBMiIBPSlB9wjBW1fwEuSb94296VCqgMaGCt/G1BbExi3IG+r3a3J6P48Gv/J0YmEYoiGY7V/SxwFCwGoE/xa0AJ0CEiV9QPCJb1OJ5F1VTjEY2/MO9AEJvj1BJTQpqLfTlGwjABuzT962e4IoKnyrdh3+/6mzDVJ4PHOxj0JqGKoy20+wBMN6D1gLWi9NQHfVP5MEEPzjGYy8BMAOnTAJgEr8HUIejRo5xrA5xkR5AngmiSHs+zDDAmMgWzTg55GSJEmHE8IvWPAoYTfhWak/Wn/bQ0CGLSAjv83SUEfKp5q24LXuQICpzrjrgWoza8xVE00CQCORdhMJuTUT/rjuls0gO4Iby8BIEgK6gS7BsGuTtDrScH/fR68biUHNVGBnxjeNyHEvQe/ve3LZQqgG3rof6cEclsNflG9J4KtaQ8WHcVBHS1BtHE4QP9OBMS98mpbKTeDW7dJwRsnHpMBTFJpV4I+b0kY/NqInVFSyBLANbnMSgBM8F+Fqfxq/h657/Up+GaBnwV9hRqc9bZ/vA6vu+T9E8KPJWns94UfTeCj2QXwCHS9dNL8Xf3Ho/rfewSeFODGDV69AU0y6NFAE1DP3qK++rdB7/1HRxf86gT376zOr99T/h/ioBiXWQkgQgVeIrCC/WomhDmQK+hASI2ARQZKooHMLdCJwGEBBXC3+uERwg+VOHZ9ioAt9H80AI06wGgJ3nQA3BoCut6AhxYwgcPOFnxuFnrphk+NIKIGrWPQtgz3b0i7Y6D5rs1GKqTop0nQX52vmQC4BkjA+r4a7Kx9WLENGeegkhSETBCrNXIMdi/444Rw1n6E96ry7OPuj8UfLxtQ78NA2iSBbg7gIiIbdDLsb5agPhLC3RkYKv8NDbS2YGsatNRAG2oQwf9ZIOydgy1MAzBkAw8UwEEIDzSAqdPQ6za0PkeJAMH3Z0wXniUSZoHvBXU2mcjQgv56TedIKglCpIoQfgwCIjOytd8WgN0bfxoR8Fn9Gx0Aj5Zgq0lIZbsH/ibSJoFnS+C98g9ooHEELI3gliy25yONIiE6pb0NfBlyNEYyENoodkKwgl6I6s8kARgJ4ZoEfuYWHLEJa0LhSBXm7kImGeSfVdoJ1DO2G7WXsehAptupSOoyrCSF904k+6vt98X/ZcM98Hsd4JYIXhQAIg3/f9AAUYhsLQKAtkHVBnzjCKhOoYl2ym+iBtvzDzQ2DLXJ4PUmbJHAVnBQX4jkxfvHhNDqAdHXGQJgv0aSDGItgOseHIU+K9hXnIJzkoGlEKzNHagTdJ6VWEUH4iCKH4fd2AwDPaYBm4Wgng4gQ9V/CoGiuNmD04AQtNGMGzSAAQ2I2pzfogY9LRh7BrbOh4+D30sAencljFu2CUFrwY8UAWRfWwGvVOVfbx2uIILM0pwDv082dUTw8hYs8L+uIWiHGpWgClnAa1lMPJogovvvbePPs/q3Xr++kgCsfgB5oQF9WYKPJqEn6G+OE3i5AqouF59FQOmahQC8rlPLj38kg1c2f30vw+XaoIX24/pMGIgSBoZqoH3wo0sIIGlA9PWcCPrAtpPB8eBf6x1o6cHra+2+tpIFP4PgBfxZtZUJfo4qxELT948D9ucK8Mt9+ccjIQw6QJcEbrD/1g340ATuDgDkFfx6twSf1f9xvuBECYxq/7ythQQGm+5JDx6Brw4CkMGT3wgscCUoQ4sU2t6DR2ciBjTgtcpenQoZVX9NuL4Owc+dVaDursYVkVALX+shjSBKBuvCYDUZjE5BdNkxdHAUBexyHwB6NP7Iyw7sxUDViwge1t+mz8B/LAvVx/c3PeBBCToB8IUGOgqA3iV4yUg6UAOxaUFHDx6CYS8SorMOue0CCJGAf5YfRhoAI+A1CvwxqNkAY5yAIx2EQmkFfeWOXi+nEdSQQA0ZHMEItiagJArQxDXIrj8nCfQi4HZPAttrIahso9oPQ/2/JwV5JQU8zw+7I4D7/sBn4EO6rjw0FR+i3Z9fHtahzsFvJgM0X+tmVH5vaYiNDGAigewAz+gyNLThnjCURQFR1b9d3lZvnVqmj9mEPDKIUIC4KCCjBXywS4N+otp/Hk3QVthOkwEKlV9PQwXjT7s/zwF4Qf9toAAzFdjuaEB6S7D1//U5FIQu2MevO0rQQH8ZmoXE6B/IkgE60XCjVoq8gt2iCG0S8L5GdxkM1cGsfsCMArSCAnrr7dzAZxCEEpepvB8tqHJ/q+bmJGGts/AcAXFOMMeTwC7Pw0B6CtCtA2vWgonqBQJFSwH0JQK29OB2kvgj2HHXAoyeAIsCQO0kMNECAhFMqCBf8mElAkyBbX1tJQP2RJ/ha0gpAfS9l+/5n00CkrQpq0MZbOdAuxmMvHswog62jZj7BnYQe19b14kxNq2D/ehX/p68HEcF+x3yP7z/V/A/q/5DA3i5A/dzA5pdgbKp3v3/wQF4Bb70WkCTHGRAA6+KL0bFl6FJaFw0ImZwm6igSwbbwPn9RMBWf3sN2JgA/BVh/Rg0kQBgePf6HglAHLFQwqQQOwDjbdVxNZjR4iM6Qa3WxwvNxh0JFb3g/WzFQQS8b/ttKcDWoABtUMAd8j9hf0MB2uDXhzX4CHj03L9DBU3Qjz0C0l4mLSLQPicOOwZoVCB6P6dA7nDbGkVuxcNr8PU2JQO4wX5trEqmccZaHU4q8oCDFOpzAnOwqyMIMktNNNAHouDGxO37DgArQZzlmp/14W1QlqHTMaIIx7SCx0+5yza7AKJ3IXBrNAHVDcMZAU/BT/vgv/ULPOA+XiLggAREDF2g0ci6xNDRglegd7P7TWWH5oJfayliEg7bScQRBVgI4Ookg/F6rvpLWP29swREqA3CaG8/FpKqS8DTAV4TiBqIqtxfzaQRLys5I0XEFIFrPbZRQb+16Fgi2LvJv8EFUPW1gGfQv1T/F/d/HBnccP7rAwnIIyHI4ArgWeGbU4eHy6Tx/EeTZIb5bo/BsMBjmjBE08f/RB0PHYBd9eVRAGY7cHRwiBf8WeCPHY1bgBTa9xKTELzEkQX9CPtl0gJiqsAmCT7I8xbjivh3JGFI+D2nBcSJQJ8agDX+O9iBL7UfG4bzAkcaICrbtYHz1ycSmGmAjJfL3CMgT3tQpmrfB7gxSzC1DnvdhQMieG47u75+kTouKNkM8c/+vq/Q7ZYjO/hhVvRq8F/9gGfhP8aqE9EIdR6LTwJ1h0BItyDqB8iFwuNqASscRnYioxOg9ApvnYA35f8e9Ohbfe8J4rknoFkO0lmA2gmAG0YK0DkB4ieEjiLoMD8wBzom27ANZkzIoU8EMHk/uo1mzeVoEoRWKn8L/62EYAX/lsB7D/LXg74uAMr9oGivJ0CNJCGD6i9DhZdQF+gtOp4S+NODRzsDVbhdgv4BqTMNyIL9SCKwL9/FGPp5oQKxIf8A/UX6r231H7YIqLML0Ae2GtrADOvRQH5b/MPE9dt9BGLNG8jVTAQvIaK5TtvvvWQgDvyXIClUA78S9Nfg7VtIBlO7cbsEYkQDMot+ygQ7QwmOawTHnAM2XUSnJvPIYRYMmYPS+sv3J+cfP3d04JYIXsF/EwMbBKB9Q9AY+BiSwFj9mzrSXmcJhFPVHySTbgHJCPvRQ/z7G/SVUETsg0ZF+i3CRoCjhf7y1A9mOiDD7TwdwEoEXjLwAv+avLE2B7Jnb+OqDpBoAchoQJskxKnss0vu7Q2YhcDv4ySeLOg9GsCKiUIihP7yfW7zbTsBh0TQfN0iAWn9f72Z56/Ax9P7j5OAH/Qvv3/QxKfk0DgDuP+R3USg3bzBC7bO/QT9Eeh9QvDPG7glBQzJwK740lAFFgFk8P88CqDGAa223YckWYhr+c0BPdwetl2ocnsfzePAWcVnnAIp6gDVhDLyfV4nqFEDPxHsbWD3k4BDkN+pARqKMLYBPzYEvxp9xmCHQQdgWH/9EtH2TIFpu3AH/cdGydv1j0TQbRrq+D/mLcX3ZACZ15bF378CG0My6Kq/zoGOQwhASDFwFbxyNGBuSxbCEhQ/uEPe/6gAERWQObCVVfjPpQX+rexxYhYFxIkgpgX7Y/vPs+Pvxf9vwt8kAs7i32t3QCP+3SPaTwIytQXP38u0PESm+YER+o9B3vr8mETAUfDrEkPI80ck0FZ0dXh9U+HRbhey0cAc2H7A4y4egoD6y8JfkBiigLdFP8v2W00E8deT2IeAKujZ/QAVKpAtKI20gLWksHedfgPcb+0+NEHefd9vB9rayi8h7J91gBbaw20MsnWAF5xHkyDUCOoXp+yrOwwxcKj0aL6fFppaaKDv6OpHR5sgx5BAlK/+fYhuP1D196o8e7lFBaKqv5YIMnFQpd0FGVR35RJCnCDaABaXBtgbiSwtICMtalKC+1JQ6bx/PLcDPQL91QFodQNKpwOgF/9eqcBxBBqRcKAAVk+ArQOMx1RYGgB6naDhlK+uQQwJYx4meQbxtNnYQwMjt/d4f3M9ZE4UOld1LAh99fbfzOxiEkKFCkTJIUIMUeVnJ/9sDt8/e1NEJOi9oVHDGYhgnSLss9DX2IAqw1zALUncKcDr0FB5NP+0cBQNrEezDiyiADPkt9qGpwoPdL0AGPx/NOKeyf3b9WJNdfcFv6bKd2cLMJVfJ6Y3B6wB9WFUfWWEwKMfGiQL+3bz9XGQz2EHKhF41GCtZyDi/gUCsNhYoAr3UNJ58YidHKqnMb/6AB5J4N73/4L+t7mAkeeP3P+1LNSB/l0SkMEd8DcEuUlguEw6t2AU/PCE/q++Akw6QFf1u6SBrj1ZnnhG50AfkoGIdf7gJv1KcSfgzWWkQ9U33Z3tHXYASKJ9e/YhU90rvD+q9Ej69/wxYJVs506Eg/r3DkMDzEdDBRGgcZay49XihLA30P+l8N+hf1f57/0AoxbQbwYaan/rBMirE9Dk+sBzTkC8JNDEUlv5McB8PP19Y01Gayep+hC/2zvQ/2HGLAurowsNGlA1cnqGGzeH5weiYLZm7h3QQC4O2tXdhvMMk1ZS5ebpgI8eMrPvPGkwaxayk8Yc6PMOBPEdC1XZ+2UfbfOPtxLMQQAG9BcZFoF0gp/RKjxe7+oAw9T7ZPWhgedodgz0gf5KBtrtIZhQAZpAV1Bi36w6t98qVfH7hqGI318lLCjLCUFlxRHwqYEH9a2qb4XjWvDT7kBwfbZA5P0+PNuRuW1yf4yNQH3zzwv6b70QOJ0G9OT/dhoYRUGT15uQH/71MjQLtQlxfDuiCXrtM+SkA+icQdH6sU/xz7Ze7FlubV4TpoTQ2osdpaEjtqADmEU7OkBEFoLeC3IWFFeswJXKXzkboNL+wzcFHU8hTGKIboO7CLi1/P+5F+gydQhuvRbwEgxvtACmANikhLTbj0gCYk8KdlYgmj+4Ymaod7TwahwadICuX0Cm2fE5iNHPK0x/CDV66Kyg1MnqjNFBnhBoLQCgUULfaVe5nq/6EQWY67bXCszUb+7232fVPz51iGB12owK9peyP1T4raMFF/OEYJP792mgXYfZ04GHMAhBkCSmSj+dKqRPgVFGHbpLEGMiGFeQWfSgrY52VxaeDUPSNJI0P7NoisG729HHl78z6hxfs9rV3m4JjgM/lsui2qmThjCfDFSb+I9vwUqG5wwL55U7C+6ot8B+7N2o6r3q37T9trfpjgmTvv7PSQATLLeRAOZhIJHBQfDQQJPBdUwEbVW3+L08EcEE/9G4ANrCeWcnPKRHDupbNynMx5AA9IRYLmrc/YLSiD5EaEBS/s/TgnU9ILcH19n+CpHwegLejx7Mn/d25fdN+e9U/1vgb7bqf08MOtf8EXxaoh+GY8L6gDfhvs4i6HQ7seYI2sv1GchdMsBIG3xlvxcCRzdgCPTn+6q/TW00VE8Q9FaFv+R2VlOM1vm/hhjhDCdgNflVKME5B47I9xT8z0YgPAJ8myb/LqHy36j/Mwqw9AALxuO1JVjiuQAYLcFzIhiEPe05fk8tRjGw7yWQbsfuLAT2VqOId1osnr0F49VM8INACPHDoBz4B5mqqSnUgyh3ArjXxfQH5BbgUS8gP7aU+w0zHD9GGD0CGHf+P1p/DeivlhU4BbxR9a2kYFR58YaDZCUR2P0DMmgED2eg77puegy6PgDphEB0CwlG/i9d+/Hs34pBEQrBn0W51mqGnJAk3ACCHeiqkQ1XFQA5AlKH7Lk8yJKWY3/nym14h2C3JvxeMwD9ZVMz0BPMi1n1RbKl1cYhIVblF3G0ATsRiCMUvoK9//OgcwYMoe+ZKOLlC6/Xk50br9NFz9fanqA8UIYSpCwlBO4kHc4WLLBfBHVaKwKgLQjmP4Un61Vq+3s7Bsyi0WztmLjJwJwFeE0I2vD/1Q6MVwefxfUf32skCPbCnxQqf+QMPEUDHZ7vGeyj020JgkPXXwsldA7SYR1RE3h94NvNtugswcgxXEkIcBPCGZ1rmrgDC0A4K88nm2fn/eTnpQtWyZfybRoK8Dro4zYDIMGsf7saTBzvX0SMbkAD6o9CYbsfMK38cJKD9l2FJt9/VGs0h5Gib33pxMKWNsigFUh3G2un+/N1WUglI/EEx8fq27vUNnwsiOoKecL7kQS8VnWAGCFUgn6dBtQhv40CmIYggwK0uwDHRGAuBXVdfwzHUjZzATLMAoyJ4FmBhzaWBlrHld9CCWpPHRqofBqMReMGTJ78q9rDes1Tv7/0m0v0AFHXNR6P6g30SHivin7V1BOhh3iWPwvps/yE836L2XiwnUT8x2iHgfqhnwn667QHEE8oLQjEvtEW7GYBZDrDVkwNIO4G5GiBDf9fGoFM6n+vbEtzXwP6u9AduaWnGYSLAlVdl/AU+ikrSeEIKgwdaZ4AACAASURBVKj4/wtgHcHtdO2nWKcBkPfxcvnNQvsj2Me9f02r76T8q0IBn9OLKfz1HX8yVXQYGoAB/2UeBQ5/5kCL6+H/OGGoRnLSwdd3oH8r7KkGTbgIxEwVWvnF8KOpHnyzfF9Jod5Px+IF1h8owyitDw/XEgRb5bPqbt1uvn7qBIQ16vtS/u+DP3cR7CH0WWJgd5mTJKYgNzoGjQrfvu99NDBC+bnyW1x/qhTatv2OaMKgJWPvv5kwnMgxHYGFRtJW8VMl3uP+MgoqSZyWFKr7+KIDw1d6+IiOgZI4+d5iYL3imzbgyO+tph9t2oSBxOM3ugHtPoFZ1LM0hF4kXNEBssvVgPdjdXZWK7uKvyS3q1Xb1WQwtVDqSUggq+Vw3t56JA2cz7PXOwGNW1ecwxPhfe3QEUsDsFaAz8jg0nf+iZMAHNg/XSazDuC18Iq1HBRrOsAQ8NLB+16g614jmuSgs3bROxE55D+WDDQNA4ivdMJ9M1b309UqknaDU8ObV9/PwmMPATvTMAxpABLBzugUtV9bLdhNDQA+7B9tQJ06/7QNDHGSwtgZOCIA47InIoDdROQGtt0U1HI3GaoUnCnC/rzBMQJteN17+VaAzYNA7e+PFqHQUyXPUYB7iQYa5ZFjq1Zqpx8Uqu/XT7+6BWC1Xaj0GlBIwMoHu7UzcI/6/Acb8KIq+hzmGWmAYnADrIpvKP7TZeLaf0LAeQkGgebbq9FToI44p654F47tekKkI0L5PQNZPsDwPBpy/ni+wKMN76Vav4+2cFZFf8+JwAraMt0DFB7beA/u4Zz/a+RXx0M/ct4/jwaNAS8G17eSwmta0Fhx0VRxJkHMivso+onMXr+YwdWKbgioy1jp4x4AzIKg5lEA7wvHEYCRmdx11TAuT6lDLVl4KvXkAET9P4RT8H2u+lg9EPQIpw+/NpJ7RwE8HaDv/Mu4f3OdNkq/EfAiEiOANjEALvcWL9gfFV4NZbgbQc6qPky4Pm35QZxtH1f4j+P/jXuaYPcWwIEH/fmEPBoAO4m4LGxV3txOQqDU+dXgey+UwSzuqP++uImO/u/6ogCb7wTc1n61sL+vZi87rxnrNas+giTg6QLzaUCjIp6JfhwtGI7AjBBB9JjDY4ePYVR6ZPgN4owVv6Q2N5hhVHwNeYrM+w6dN6K1sMHZm/Ce7bHe3dzKr1xw1w4JrSQMZtgnoQHlr18fzunAszD4qurNUg/TDqzx/lfCaO6t4tACMUQ6P6htWjDPC1hCoZ8kpODzJ70MUR9AODcgwyqyPhmE+wfHYB/hvSqt6qeXUShhXH+d9SR8DzrDaZZdpSp/HxqLMQuATgDU/qDPRgOIeT8cvz/h/XC6BtE7ACLOWPE0KIS4UUjmZaJ2grBphiWgT41BUVWZfP3AnEIT6OrfoF122l2rMycBoU5i/OXoUZ4/aglsXwLzHNU++FVF3qikOj5HXm2PBitT1WuvJRAB+6O//W0/PY8vQH5IrAsMs/WuVmAdHBrQgrbOxJShXwRSsu08h8JMBpo0+aDTALwV4tbswgzHrftG/dJKIAQb5h9KCssWIMeto+GYqG12/HWGjx8kzqNJaa0noMWOr2KwW01AMwJoNvhMQda2/RKQP/3ecABM3g9uD6BY68Ntz9+nDOMb5iV+hIE+dP/Zs/wwJhJ9mgBnohBuStABUXjugF3hkXF9ZZJAjefKdHZCc389LoStKvIl7QIEb1d9RyciQgFDI9Cjyccc/23Aam7/PZJBhgDgin5CtQvbCzX8ip9YgIFtOAt+w0owp/hOiCWgEGbVHuYjRigPGR/YOnEoqPDoV5z5YqB3mRq2ox5ICmSSgAP1Ne+XV2NE+/vuFbCTRADxtS70VRBCjgBk2OyDUQiUgfl77b7DwaHm2rAZ7osRSOOUoHgKfNBSLI767+oDYrfwZvqChSpGfj3pFwZFsCJg2jeIQQBUiyI4WgD68ww4qO8khuWkkIuDrxWv2nv+UTBpJYiPd0KemTA8qqFiuUF1jWS3BoG6pADJq751JqBI0wvAVPyMQvjcX1zbELltKK+zBiXRFiRxG+b7q3M9xuLdzR8g0gCGNzSM5gNYfqGO9CBT8OHct6oB3KsSDBisUnwsFuISQaRHxDSv0vptt2oeLHMERfRn/FG/Cx01EpgIQG8LP+/i37PKw53xn6sYCM4/JwSRrCnIeB1ZkLsawDhaPKv/njU3wnZ/dBdGE8+YTHSG8+ofGgIjsC19YnwdM/KAnTSsqj6ig7uGgIPw3nYFzhhIIvriAxFP9CQd4HSlnzgxONIdrE7A8ZDPx9fjib8ifgegNIliRgdx95+E1T7+3nQVNNhEzDgGA3T2rEDLduwtPpuuouPcs8swwXFjdTaMKt+jA5gUAQPcf95KJQxYU0cYxEDvsBSmYuukp7AwnqniC9Afa5z8vboI68ImT0t26CvwBzSggkj447r9IojvCn7U92J/Hw0QSdwZKNNjxPCfSxRqnATkdwpOwh88oc4J8KTSm/wdbZjrc+4iFP8YO0/5JJDCfaijK5xVXevqfg6zGRrQf83chvX4aRfAE//6vv5+6490U4ADdO7QgM/5bcHP/n4OtCQhBEFeDWSvos8DPq8/IwzLzjpa8/U6MMSkBklDm8e0mn3QIY7XG1Om8wzN48y7HwhOK3P0/ZwUQHHv4psbdoVeb9VlAjChBCdtDDpOKTh9ZfcagOYq31RFjN4/gwBYzp8lAwYNwBELhZoxECeZxMlAzWGdCRV0fQWGHo8+8Kx+AAxnCIzowAxy9KvNepWfsfp4RR9kUrD88CPVTuXRybhqqTHcnxEGndsgub1Gdug8yz9fHt3Hpl57x/mfCOC29FOSQ7/noAZR5W3Ob24UMpuPYAYiQrQgk1gnFoUIKr4vKFpV15pHUJO3Y5rfH3UFHU4bGkU+NKJ9f2hJyOMxDBDpjAgwiYqvk5TqNl9EH2Arb6fA3yaA4cBtPWewhkEcIQJBlGzYp6zRmr1v+e3Fv27xpzvyI44NGDkCIi7CGNV9Dw0M8NtHC2vUwHINumCGNG8erxOwtQINsW88Tlwdoc+F85nI559ngEDpt2F/Uu3hiXYrkN/pBFS26hYDAkFgErMK67y9mGBA3L5ore5izf8b3n805MOq/t7XU4WHv1DUF/5gugCSOAIW/59uMwl6CHWAib8bvfxWl9/rBGEMTTwDfG+ezEYG4yk6FvRPuPwE+wvc39IRjENWM+/cm5b0W4Pf4WuKUnw/vD6eDbB1ETs5vl77Dhnm/51g6wPWwQAqxnivgQaeS3gy/u/1H4hpTPrIgHAN0mSgXUX13YP5PMIuQAfBr/f70cdeE+QoCX3i8nFMLcAjInBoAIYqt1LhC1WdtvmSab28AYffaeivCB+ohdYQgfUa/WS4ToMsNLHLc9nnvPZLwn1/EefPVf+U/xvnCVSEQEkEQEnEQJO7S7RvYDxNeNYKrG7DKMhtsQ8cMmhgPKKKj+F7CiHYFR5KIIPxOmg5IVAtu3ACQSPh7CzUQOgAej5CWEkIe3vgxz0ROGO//qYfz/dnLT+ZxDr4QW0eNCJBorCFOVC312Ec2TiY5Bk0cAaQmiA1VH1MOwDHQ0kHdEDDf+2UTWhS4Z8diQMicLx8MLBfverLcP/jQzF0P8EJj5+NGK9RCz755S6F/f1+X/gxeP+Wsedv+vF8/54aSPJYFjIQd624MDz/UDLQnr8HU3ztKHRf8Qeno1vyAQJBaLcMtTV3cvgP56COCqd/QP9xLgBkH4BxO13n4hNUDtACC6G1S3zqooZ6Ba4lp/zcAFb7iERKQwQcF39IFJjdXECGADw0IE4gg674pYAnk4HoHPx54tD5daO5vxrugSkMjgiiqc7TVKAT6AT8R4ckbHEQCYR/IZBxJgA+XZjsR7vaoRpIxWqeqfXuGC2CxwudicwePEB1kNkaZCuwyF0DuKv/4sz9mzP/Qxdg3BDkBTMC8Q+loD6UGBzx0Kz6eAX/KArOQTlPHFoI4vVtf4rNuLrca9edRn4xBP7k8w+9AgZCgBfEUZWfEs8iFNZ3UO7TqmkjCO/rWdgco/yIqHcQWaC2EGTzgz5y/iXQAvyx3riyxxV/JeBriaGB9OrTA5g9/eokM+37GszqfA/UZk9iW5UnCtBqBl3XoNN6Ag/+zy6A5evPAp+TIFDn15gQw9rjrOzFX0s2JBVAxa/nP1a6AsNWYGjPNGPLTQgBsNUFvOA3Ht9o/rGDN0tWOCcxJGp+f7++kkP7PxcGv1+GjkaLt/fawpwwerQxBJNW4b+PJsYEgiAYYdEAGIlDNaAbRkIgK3ut0jKByp+8yz23X6GttmBmjwDvChgiYLP5V/zhH6/110sGcKo5CkggCngxnIPoPja0j2B+1BRkiYJiviaLJqghDI63G2nAgAxMCuDdnoD0wIQm+urMB3VuAwbBrFGgGgnhAFqg9+ujKsLxB3qGCQNEEtPinIQlAj4WgIw7/iXc9V/x/yUWFs2KH504bAh4aYWf4TrTLGTy9YbftyLeVOWNfYNyt/ji29mQnqMAltU3ioTtbX343yv/1u0YPUBz6zB702tQucnX0gWaFh6DgPdmhXaapGotw0SFz1qDiTMdd8h45HfcqCPRUhA3+NmKz1l9teCPaMd4urGaewRitNBDdahR5c3AfQmDCFT9vmtQEwqAYXX4XI2n23Z9B/Yb1FL+LWox6wHGbZSo6FR1LzyG+3hriSZvWT6jfXhl2cmQZJDrAbuYAqAHo1GA/EOgD8eGcU7A8eDvH4fQBuAhBL/Zp/vamPTrRENDGLTV/7E1WEPLDlP/PwzU4YhusIMUgfIPAr6Dhv5R4y2r8ldFwiFoYHnmr8TAHbhRQSZOctH598ZYhqt6wP7q/ouqe77RJxvzFYaji/z4vna4v5cUMDXqDAJ5ytktqtBDckyjvJg04hl16LB0xFfyMfD77PZjErGQRRjYIfSvoAXntks0ok8MsUC4KARWnYPlJBeIgLeFrUgDOHYCag0/XNAbWgRwQuLAsaQwIhC1g7+jCNKuT38JfnYSyTi+QQEwwHeT4/dWHYxJPxfOj5oAnRQqgU3YgGZSOaDyK3n/qkDYBKptzR3oD6B4fyRKjp2AzSl80YR/3P+/1vBjX18Jbu+YsrMRgbqPP8zrDLTAaupphfeZtyPs9BPztpLSBZjowF3woYRwBwOWaqbev15b7X4RWsiqYiY6ZkFEIoUwUA2OrkeEQE8HYNyD/rl3m88jCGgO/nPW3xy8x4Q/HBcM1dYg5q8N+B/SBSYhtD0EY1PRGLDoKIBHF3yLz4H/gSYQJRETgqeB2d4vC8L2NVnQn4PoVJJAcP0inahAfdXVI8CFszjRagCTtRdV7Sr895NBpRKXIT64RMFw/iw5eChhEvmmyUIH+k+Qu3cLzOAN6ILlFvgWnx3YWFDz0f38ze9GlfP6UQ3ojEY0gtqRIEbA5/WgQFhsEuIeL75uTzvqHktAWfj/OD6sQXssROcGiRgFn0QVkld7OznMDT7CJKzhMIqxW9B+LCOQdH4uyxIcE49VTSeLj0wKjzcp2oDXQA8YoDEGBLMW0BJw+eAxXejPV/IXd59/tp5rVyYXDw5BlRetSpQAcvgfOwVM8ObzBq/AQ2wX4lwkQV3vNhYFfn2LFgaoDU1ogqsfqGkJYmrj9Tr22KQwBLzbLuzDeA9yzyJjVRfwegWq0H+FThDPA6ZhZwX2M2Kh4waovCzAWJTzD/qY00c+6PM8coz08VNqglzx54LfHuTJK7z2rwX35ABLg1DzsZ7Qv7l/f2yXDlbf4C/irg0MJ0aCuD0wP74MrxfdFlX7tq+vtRdCpvt599EG9Yz3V+P+Oj/n4zLruZHcJ7oMt/MNp9eD6HEeFb6/TMfbWo85Pb79HJo8t3371/PuIAZqMvjPC34nVV6ZB4hEuA7AzA5cfU0y2n6ux89D/35/n2/vWY5Bf0qwf3tPLISO1Tap9qzFB6eap/beqI94NCCbGwgqOItY3CGl446CaQ8i2Q9g0AvmgJOnBoAA0gu17tsKtKS7D4udgCYERy2QIceCX/P7mBW+g/7D9S6Mn50CS0eAoQPDcBjopIA5+EcxEjLweRjXq0UbLIjcBxsGx2IZvlf0ATjz/6qypAmY7bhrk4ahsIis6ccXKHdueAfUgk+RWPCLh42c6zEeKyJpRTdRAOqBbl/Wq/uT+q+Fx3FoTIuCzc6+hN8j4veGjuAnhSE5gKnco3A3XwYlq2sq+lmP4yEOpqEoG0M+mGDYuYT0pKCFHgLHKt3T7T9p8GcWH+n1UwGa8X6kQt2x4CeqPexegT6o/Z4Cr313PHdgrsS2ZReLfpKIf+IMFnmVmwxQ9AhithYT73+p2s+JIVfrjwiHnpAZrSsr9CMstQXP1+1+510N/q8E/YoekMN9OMFvi5LvkRDsy9rgFCOoPdpgaQIWBZjf5KCSQszZJ1ivTvLokpen6tsJAVND0NFqb6GUGg2Im4Dyx9Pn7/0dm4pADAslJzTv+dKNrAPQ0wyySm7bj1RQgbAXsRa4R+mBJzpaQmHLmy0BLoL+Nh2ZRca8uUc6P37k97n451fvTieAE8BdZ2ItqFEK6oOJIYPsiU4woo140Oh+H/UC++gatHYcOFT+2y3AYvD1rM/fpxdUcsAi70c0OxAEP45X/hymE9XeoC0zfYhbcqfbhs09HpwnKMDR6g0mmYyKth/UcLl9ITGQ8N1S6s+gA1HvQCc2pluPvN2Br8SyZyfyxPP/VhCi1L1HWX2CQCuAE8TIq/sBYdANZmTIwqq0sb0HIzhhugBeUpBZLFyA8y+EErsBUYDZHYN9QAAooQwOws+uQlhdESSSqk5Qsh8LSYI6LDS1AbmOvLlRBqQIeITvM36+TP63VfE5hFClCTr9zEyVFwS3STQBy66DMHB+PJWIrfgGnYBx2dTboPa2X49GaBVlePA7CFx4iaGi4ns0aLVjMGvtPTDtmO4XEE8E5Kb/8qYai+NHl60LgAICcUCoJPVeiYG6Pxw/X9VFNVbFn9FNPzXoIRDTyzcpREYB5Fm1EQQn3KRi9wKApR8Tz48SwxnV3qM0q7ZhpdKvr0zfY+gO4oQf+EGPFYW/Xf5hwWsUgxiBbShGoGIx+D2eH1h2EeR3UQMH4zMaUKr4033nzkSkfQADelFbLOQCalxdxvN8mInhPas9bxtGJw29Fx3Y8429MAS0fL33Oeo7qFZeiToCC3B/VSNYuU0fgDnkhxGgMFdxiYEY7MYel+OHPH30IMeVFK1C79l+QdXVpFqHlMAXEf3EYDyfkkGdNvJ8f3RAXU0jpgM7jMNA5yCrtfzOicKG/M9bgEkEjqqPPDEcDfqVwGZv6zcO9avDfOhf4OmLFd9OLBHHdxp51HvOBlnAoQksYjASA1xnIhPsapTCPjbsGB2YevpPpgM73EYeSYIftgPgte6CWesVBB9QEgfnWYMgoeC8ql69bWoRIqYHvSIv/u26bj/jdqZ9KSGk74JRo6QS9PuTiSHm6Z62kLUGH0UO4rwWrhtRETkR4iKRdI8giJ2D2nUCMjsA0TXiVDb98NAf/rCMlajA9wesWHZrAe1dlwRyVI2jx4KkyUHSx7YDe6YD4tOC6XW01puEdAJwaEJzf1uATHi6ZlSCpBQscsh6C1xRcWEG4bCFeKcAVhVlDu54JQIkTT21hptIT/Afk0kMcS9BKfjBJozcDXCrtgbWXxbMAw3INQIxtQJPAGwXmYaBbYh4SCsuKwLOAQ5awKskCMmRg8P3xwlBfbosQaDqyZqBkyQe1CLQACoTgN4qbyHsPwkTiF2pYaj6MAXBmUosQHnUEYCsBL3MW39SNKMJ5PfoBsT33DVJCEbFnBCMOkHfvj6Xq8uw+dgRIhGgAiUqf5QgKDFyhe8nnYrlqn9sG1GoAfirubygX4H+8IM1CmQrMFAJ5ExzKIp54nPoVU2Auh6eBShDlTV4u5c4HE/fVvjFrsII0Ik6QX+Iq68jB19ziLoKC27FYe0gC+j1RSS+BgB7AvAM3m8HLdy5fV60C8RMVuhD1ieQB32MCCq0QPJuvuw5IHF/geMKwOPdpmsxBwVEfGEOgeincJqNmuSFIPhPq/xM81CWIIi+gCFBqDX3QPYd2OcCRo6GZBoA3AM+00aesAOQ7/2Pe/vBCXoguD4OBD1WfPwClzcui12AuH+gC0gEwW72KfjBCQRBr05D0IQc7N8PzOCMehPWK384MPVDJQim7yDdoiRTItzzFV/ZOX9sYFetP0fsQzb6O7wOoFjxk89YoQXv+BmSN+yYHYO+BsDRAXHhuJXsEFbdIEGZQWUkNVNzGA9NZUVBIQL7jASR0AclE4Pb7JN3BO72mG92+o8UG3nybj+mASh0FsLKn9GPxDrEcS2Au35BzHO1BksriIJdpqWjKR1wlpR4fN977rZqI+XbYjYDgVDpcYQalOYKMiuQbB3G6Pu/HlMbi9a0EMkksXtjvvXTfgMKAEZRN/i/O7yD8Da2S2Bdh3ICWfp8yuMkYl5a4df4vVWt4UF0yyqEnaT6swYyWB8/j111Y1ERS9oB0SLMtBGDEBD1PEHwtdjUEAHnqmoHU4wCDAoAS+lHwtu9eQLUAgmxVvAuMB9cELMV3m8EUtcBYYI9nkNIEEJYrQeUHfnzzRyC39j8CgSkir/E0P2odnAmAqDnDIhqrtV9BDNS2POjv/0pwKr6z1h/PMz3uf9ykFYq9TtoAXSwpz0HljdvBCVAPY6t7osv6gFhMpkX13rcfXQMIpuTsfTibkfOPRAC2meLRipI4mDPwMD5x+v3+Ey+qEfACwoUEkKQSMZxYJDz9R68PyP43yvo2aYf881rNQbZgRU/jp80QnW/hdXqJxMvCFxXQSNHpE8QiF4XI+wFfQcw7VL2Md7RRajsKgh2D+6SLAKPF356+/7yXYBTUgFy/38StUjFHweD+iiHh8/LV/i/TSvGk4L5x7F6AsIKbgb4C0YjgdGRIToGUx7cgS3JKP8pRcgak95BJGQbjaJdBYQ1qHYnYHL8F45QgHx2gLMQ2cDxBD/4SeR0LSDi5XzPQNjM4ySE/HGG6g+ugltLNSARn281BPtNO72eJLjdX4ITSEgpQvJYFEUg24f1qAYQNQdxx6Q/RcB85j9f+03zf2QV33IDPHegNgPABTfqFR8cZK9TA7/ll0EQbUUHW8Gr1d+MSadia+LRHwhunv87yWoJ3h/pRDwJAbDNQQFd2P2mH4kP/wDT/ZeN3CK3+ZjvgVpw4r20AMafb58j4N1UMknuj6iCx883PU9g2VHVH5JX2eEcPghSgRBCKPzK0Q3fknwPN0Hk0CyC0zBkz//7duEetgFjVtypASDI4CsknYJgYDhqsBxxy29+eyxrAZX75EEf8f+CkOcijMDDHx4ASYGGu8WHgPwpHJc0qOG8FgFTuVk0cRZVePFwHEIUEu8xSHoL5qWg4I7/HgOKXe2dcnu2SSdCGIDTA+AcxY1zYL6Q6AAFu+/1GvjKPSeEoJV3NiM4Dz9C6oWkEav+NWjPWXNOIkKgNTi2I8LeBgaZHJxqrC4oNXoB9pzzMws/OW3ghSyQJgjbygOVEDhoj4nHLld8HPD6UUMFVLIgKrTL7cFoBRLQgEdXIseZ2/HhFPKbk4d5tYWwwR0nIFQSD2P5gQhs6meVfB+Bkyz2fOIvX/zxqsSODuAGIOLtPNnmIPCrv6Kqvgz3q4tCwNl9lWYfnsdHj2HTgQw5IBHwULmfSu1jEV3gDFSxTBmqSEVqiYK2IkWcRiAkwV/cyW9YhqHXDw9dkNQAcO6HFNJT7oChfrPUYc3KY17zAd+evAwF2w5SCKLV4EuCEKsKfjBVWHu9Q9Arh4CoBqEMWYBsNX7YgKP/69uC3M7/mOOz232QT+ox4iCyJGEFP4oBHd+GVvXBwX35nqp7qeIbV6L6tdZub3ueJ+gBIKgC6S5gOQFxDoGr+Bv2nzqbknd7ph/EmXzO0o+kZdc/wqvQkAOUffVMzKtYgx5Vob1/+HAfCdzHSiXHenX35/2JTr3KZ9Ruj2lYiMhLIFoNyMq9hFroeYMTE0bSLbhb4l3YlFPa6hMd2jk8dmrDgdQCnC4/+ANFlYTB6ATlx2GDGXP1rvL+SnWHw+cJes5/rRWt4H2pw9GklD4uSMpwasIQiaYR92gIyFX5S8dtRZt/nCAH48VXW3hRE/HKOsGquj8EM85Q9cfeAV4XwNGAlmIFIwPYrfLKuxV476RRetzcdeAsRSZhiHizCKEIOHn3EMOWy5X4uIJnXX6sFiBFLaBm/THOQAkVJK9j6TKwiSDTBWpwHkSPQJX7U959uAkoaTUuug6oQCBz1Zlxm0OJSIoIw04M+7zCGuYiznCfHww9AN6Ir+HXA7lfn2oBSJ2FOOh8SzINfmcAyITq8JX/sOMPx6A9LeYtVfwgCBZhdu25OB9/XmWWNPUEPD5dUuJ68wd1AqD2+w1PI9KxE9BW5t3z/igdYGWiL7L+wPv9jgVY8f0ZcbCKCuLAHN+c5wa69Zpr0J9t2KnpAGzyiAIPiFalJ8/xXrrA6Y+/8NoDnWCPNwFJzf5DpVkHte8hx76P+HU1+HEytEeSEIzAsu5r6wPJGu6oLz8VrKofXLce+ywIHhNa/Dmw8LrptWXZ4NKZm4pr/QQ7Qk8ehMrPtAF7PQCD309QgRgRZMKgAbFREAfBBXNalbHA9cEHMo4IgIUuPjjBWEUFEQpYTkhVO43eRiynJw9Jjj8TOUIlJExK+0wA4gWgQvcFBHAc7P4/u78/Ff4CC5ATB3P3oUwFClYgcALcxzp/B9Ez4DUV8RjBbsCBrMH4dLNwIDaCGhA6o3pXksdBvYBsktrXDgNJKAFy1Z+ZGIy5NXgXoBT8a3ZgVSPIUAMV6DjLxhsV8wX4n4ibbONObHNyCr8Z4FinNFjg8ziiF5zSV8A99u7Zdf5OisvVaAAAG3VJREFU/kIPAJLWX3hUIFD6o7MD4WkHIMXBk4IftSrPNBJVk0OoC7ice8HGS8XBKDoz/YFBLaQi392lGpCMJfhD9xVkx5Xbj73P9V4m1j0v73x9FjDDPlYvATkgFAVWcdNvJBamliOjAwRV0EpeRymAe717kMYRyy/j5FwFBX0fP7Dyx8gq8wn2ZXi8GfGYR+lFcGJSxa3Y84WgzBHetlU4cvKY44Ps4iP9fsgsPGEhQTAcHqwwGCj61SoPexKwasXFqtxq8qhD9SixoBBYcJEDNzmIoi3J7QkoJActVHocTVpPBCDhElAvMDK1PT/Sq3DwB/ygmyB9GNhYDH4so4Foy48kkPtZfZEv1PQTxYpyX0EI3Bu+/5krcN8fgwVdwWu2JNVNWAk+PcOOPMNdGFyAZ5Aj6gicgzNfwuHZg0HrLxBWfjSRl88fVCo/apX/IBrIvf65ZxtEoK9Bec4KZIPLe76osQns46NwW0pUPCPAyMc4A/KXOwZzFLGbAqD5xhhbgBcWfoJBAlarcCSQgdQJ+Movnih4gjZQTw51rz588y/ZgxVUEAQ8soCfX8OR26JwujCLGFAMsOjnwGrlPuQw9D/PPv8BYVR7pG/eeFtQpsLzR2KFI8SwKj9KlX++HeLOPuSBKrKeHBi7L4b+Kx184+ptAp4Trcscv69oARVYzWgaK01H1X0K3zNSmARKtxXYHvwJuT+8gLGGWgpHcWOmBeljFB2Ckg6wiAYOqfxEK3GMCAj6kIiTWdCBCXhkjUKMgJcLk271N9uLSbtvvK0S69OXAvoA5z94VsFubbmZvx4QAnXgBnJxENyQjy38wef81uPhxMpPJIQzr5ckuUTKe0wZyN57iFTWga8GvCwlh5UqvYgmaNV9XSxEVWs40kkosFwA70RgNOu8mLZfR6wDiwRa35y7j08NksqPQhcfkRBK/J8R75Iz+9C8gJpqzwiIeZII3QnYOkJWbVEI5jNuA+o2BwK82ifwnpSgHwaC+GNAdmW2VXfC+vPu6wR6lBj84C9WfvivZyUhZMJlJhjSukDlFJ3g4AvGJfC1iEpQJ/CaEd7G9wds7p71+odruKrHip/C7RdsxeVjzIxhoNkFGOW/+sk/YVAGtltfzZAIfzix8gcHhZCXpcGN2u69qWqD9OlRFAy7x2fQBhHUiETB+DocqvArYt98f+AEAXApsEmEcNLC0t2uPHCqPQIXwHYDfI4/9+8LMpchqr5HK39MJSrBXwnutNqjovjHFdq+fcHLp7YLR4mGgduW5hFpAXUoL4cTTuW5HJSkB5PC0S7A+8c+837DyoM1J9iv/po/o3BunlDqPjOSO/YbLFd+FGy9sxKFeT8b+nLNPrkAyD53FtT27yUS32yqUaEGTMBiASGcZ0FmK8nWxbvjC1q6WQC4VdWdAcBY8eFoAzIrC0b7Wt8wlPcIdE1FhUWeKU1Igv8Q/0dl4k/NnYSxdlDon8diUDeuQB4c8XVzcahRgyyZmNC+LAgeCfSVALde8/t1DCYawNoePGT83wlOpFUdOZKwxn89OsMEf0X8CxJCBN/dwKbFwkSMgx0ACJJDJD4iC1JEYh6XcEqVHpx4+J4I4UiAl26r5x64sttvSlAn3LBuQCz6edU8C+J5epBrC4YP52EFDgHrCw1B0eU9bOaTgh3wmYvQV3Oqqcf53XnVNXUBELX1xtSgFrirlII5d3HFulxBCNEfZx0h7K2f34XwdHpuYQcguN189Ow/nPXclaUcqMH5leCXjKOjbv3F0a7i2ZaRHmBe5zwnhA9S736ZC8AH8LHkg/T5znYgmES1dtuzGo92qwHIquiWX+4KgVLd8utv9Ml1BQNhEJW/FOgweiTguCUoQHkEwYhjfQIgm8eAzPKzHqAG5xGiiPyxeGRRaYetUpDVpHVC1T9bHGyaknb/TQTnuG7rDYwYCUT7/cMjtILzA+Go/FPw581F/mWeTkDuBsBCAK8ki+A29nMzPn4Rzjv6QV7xWW4fzQFUxb9jQQ1qc28kMi4mDl1NBr4usIsz5ltZqNm7AeJXfuTHd7nioLEyPBISU+8/tP1AC4Il/n+YGmjg2NiBRdl6yCw//zG5ph7bqaBuz8B4VMU/TqSsNPbwCeZA1cdxyG9SgKzRZPL+GXFOiH1/SFZ9wX8M3zUgvH8a4rMBjZj/h1W9MrwTiN6MlsCKiI4gycBzgV/xUaQGjGDHwHiYi0VIzeEAasCpNuL76AC7BIEl7i4AIxnAfoMxk35eJbZ68wWEUChs8IPz/EEE9BkUoNA4RCWSLJkY1h0Y/dG9bVCtUVPe7QRhtStXG4nOECDfUxc4Uw/Ik8JkA9o9+a83IrfHH11EdFUWc4phNgVFWkPsIHBnCvCCYBSgqEN9qtoXuwHhByYoJJA7BxIkkRwpDGgAHo+vQ3ZGOwCFJCJKUAx4MBpFZWvReeLgtBBkDDQu2OJxXa7SE/P4ZiUPHABjY1DsFIhPAaygWewiXK72hHjow/k8gCL6gKES8qcDZ7A+EhYlWCPGCX1wXIwzkQEKt8cP6iqkC0FEhFj/ZYtvXCtwuBLcDT5wXN+9H6ZEIkTwV/x/s78fXFX3siWHEKrC3tw7EFZ31Ll7ttknQyEMGgAqCaVe1bGk8r8nFWCQQR0h7CY0dsU/mIeIuA1AGCo02Q0YVXxub36sG1Qgfo0CBBUXxap+ECFEycQVyViBEBFPt14TK9rZHB9EwMG7DPXOv0OVHkdtx7OSCXfb3av4CFZGTwQBwT7/hKPHE4PzpJ4L4+FM9r1n8B+B+9R9I4Fu9brYUZgCunZWNxdQgIs8mASBQ4F8hJpEiaf4GPihk8FdAxin/kybjZjTj+mAQy6ihZ9whDvHAWB6BKrBXQr+5SBfqPaINwiz12UIwoTmbPACZY/fshBBBKNlW8ZCHwH/cVKSOZMm4Mxk4OwE9JeB+EFkn1IzcPQoiSB4vGgNeJSoik1A7m0TCmE/HrggB+/1M12C1Z18ACGoIeH1pH2IhAqFWgBq+kDFEWAvA3X8tpW0cnSD5WAOriOHhnYraF1eLTkS8P/QsHUBdtMPnOrMaANJE9AZiaKWII5Ue/8PTHn/UcCSTgIF2xN4zdmAQYIAKeBFl6FiO0aKfq5jcImHfPwTxcEdRmD3LcFoAva1Hdjm9UgGggI9YOoPkOBYLsT8HlG3nucMDGkOOJ8CkNOELdSO7D5qqAeJYBb2GpABgRi2gxLITgrOQ9C937HgB+0i7MeRx3gfPWCXLtgbLJAu/gCFBPzRX8eADJqCvA3FViC/BlOQC4LZyrBq8BdQAOUKoKjqR7v7EFfVFMojPgEoSlJesNIePyLHwW9NRgq7E6HvUN8A0yj0wyWDHRZ3J2A1jHdMyu3hCGwSDwdRir7h9VP7AKLgPoMCgKziOFLtrUm8aIFHlgxYfz8WBYUU55iAXauo+evJaIK/NTgRJM9sUcZRzcCnMdNKMJc7usnAyrpxHYkTRHK+n1HxS01LheAHqRWwKIDqLvQC0+PupHZgBawfVGsiniTVHwZHRqbUI/D4Cd+ftgyLAR1ehkIiqaKFw7MJEwUIuK5zsu4svoFYCFKgBJZACBuppOId2RDkPZas8H9kULcA9a0KTCQDGtpnzT+RMJiOGseHl4BQ1C29AWUXIIf/OIwwqoNEK3SCuA7FRiBrE9B4/PcrGJ1OQNj83F4Xbol/TgVHfMiIZLAdcaVkgh8sLrd+liNQH/FqsNTfj15m1J0X+ffZuq/gTY7QnvIfJz6UzBJLs83ItQpt3RfZz5iuGfNPajpngUm0R8DoA5jDlzsOTAwZjzsC3Jjxg7H914PjlcskGdghgx9HG4OOQH34uwQyzz61/0qiYNQjXxECuWYbGM/DrjtPH/Mw/K+gBLLSA+cEfPr4MroArzcDuybbr8Zc72i2UnzeHnTgzD4Ug78SzIvCoARVOQxaFFR3TzWnkkHUVFShEuqKxZnKz4p4YYcf8ZhYhuu8wFgSHcuuwCJagI4bgchJQK/qe9c/RT6nGcg6KGREJpb+MI0EY/b0jcsni3AJBeCQNsBOFVYoApcM2Aom4VFgIRdHpeIG8D3YaxBD+qCiQ+rBOSVnci8hzkAG1t/pgHA4uwDzmu8xFKkkkIqCfkIRs204r/hiDgutoAAcowBMZ9+KS0CcXVBOHCvJw2jMQSJyeoeExF2DuTuRcuWAo9sefyUQ6/oBaIjPtiRH1KvQKvygAHb171d+vc4GRMDPoxN/kL5pwlVh1mBQ1quQJAJ5j0TgOAis+h8d3mnC8xTKE34+8sDNjyVXE6nFMN+H39TQDmocHScENvN74LoGScGU4f7g6IG3n3C3qnG6JBS+Z5tHOOzRYQx+u7MZmAl0OSsRLAS/VIKfRAWU92+12aaVPksGDBWQuCMvgNy2M2Mt8EwqbjosZAec5xLEAmXmcFTHiOWARWglpNpjdEtBQRxJJU5VL5/7F1X86XntXgUK4q+KggsUoIIK8oA+kgy4+zLaACqQGTVOX6MBWdehL6BxHn+tlyBMDGAqufd7WOX5WTJwKYDfXJJP2GXDPk7Tj5Ed7BOG7DMFaBRAJgI/+H2Ngeb2SKb0zkoGlQBHkefDr7xMA5HZeJPtKIzyApI9gmnPgf1c3mulfhe0gFekDCdNFnrOwi4Gs6eTACNjB+Uegcgojog4V25P8bctRYY6RL8AJklE9ACFAGZdBEahd4d4CmghFhbzcwaXYH5qTlS6DY+KfNH5Avzjo2JJ0poDkSCMxLn73H/eB+ifvgvyIFCWAji7BWC8hd0qj0FziMdrS70BlVbgamIgcmotGZDNPwm0L9l5iHv7WRoAFx57ScFS2r2iwot8oKu8l+TOCOg2mZ2nFdjTgOFQENzKkJ8OjEnsE8f6AzyXwT6MNF3RDRnuj0Lwo6wTlBMDIyqaz6G+RiLJMg/KUrQV/rh9uH0tWduwoxmky0kSMQ+rnXxZsGadgnxfgk1pCnsIsGYltvfdzTOBIclIsN8MLAGcz5gBwj94AE8DuC9Molip/JGwB57nRyJiyD3pyk6q5ij+3TzRLohcqyqCEQBTepF15+WVmW8SEr5jMUUkx3oMIsrH3ndwAQganKzyMpOJNxMQooGBYwcByw7axIhgPRGEr6GSGJhkAELoQ1YRg+dPeD5IIRDIqq5PA2Jh0Rq0YcS8XBi0ghGRFpCtWTdum5+yLOsQf2EuYY8AfnbQZDgCjHxBSKwTGpt8QCIDVH3/4H5OwEvldhliINwAFLsEyyIfGKV+vm3eEehVqKTdNxtDiPoLHCRiuwTJxCECxMDqDjTvZ63KaPKvRgV2i/F3ohm88V8LN8hgJcXD5pVGIPPNn9EBqSQC0I4AMxBUcQNCkarkFgSn/oCs9GCVep4eUG5BRAOcQOCWlGSc3If0IFqRfURQGRrKewPKEJ9sLnIowKCcw+f48N6UHjqYtgInaCCkBbPSj8VEkCr2g8U43wY1xX/BNkwreQrzg+oaJghOCGTU8RBxuIp6VFOGoEXgEsBLIgV6gBgxoLSI5CgiYNT+GBHsU01GthrceiMUtv9KgAYktgVNeGrBbtiOQVi9x8WjiAW7UNUnm4Vet7WtsFgDCDYEwQ/EVL1PnQf/xCDLTowTh4c4HPRDoQaiwhKIAae4B7xgCBydI/CDPOrevK0FR4p6w3VfoXgQiB3T1N8Y1PCD0X19JqcHGfzB5WkQE4p/kdeXBcEVUXEIFqSij82lMyrWq/7c+LFHA7z5/dwOHHg8s/Y8C2CmhbmALtare+4UWLfb25BmXABKABTniC8gRAP2yvDAiUAsElnrxFzITQa/sAFecAOY7zPV/8jMQHSbWAiUPGkQNABhw85xrSCv+mMSzFR8+7mjw01A8f4F8S/td4jnDHYxpT8/OEyV3gz2+GTfdAeAszswfJNGlQhEIjB0Bls0BKn4Iw7WKu9f1gmSagmvqleEwJwnZwjO7npz1HdCJ1hS/mlBcRXyF3i/M7NxqJFoeH27z7nnJaBmpUZKHsTbGUc1ALEoIGsGYl9ixS50gjAT/VhB8IzvGTrBVfWEz1MzAkRFTtecW731VdjNQPukVdhdn0Y8d/a7WYH6i/TBPBzUFwAlHwtGHOQISrgb1AMUgDETTA3+THAdeRJhg59V/Ektofa9I8wxVICkC7QQSAd2O3cftzPzdMK6aA4iZI4ILfYRbb9RgqICt2AxVnYZ4kkBvHOBxT/zN9ybHx/f5Ql2fkGCX6ANm6F8WCfqAS+Eq5AGcHJd2IFHagTMHAAj+mWBnDXuc81CjhsAi5dL2K8QCYI1aJ/PJtSSxEFXASv7C2I3ZB9/a0j/7nDn/j1pHsz9Jr8fNpxPBUAUUYD4wz5GBlmyAiORjtAIGDFwzSUwqiNZ1d1tPiB7/Q9VeI9KeJU16/knkEeQJEALjY4rkp74fCZiMDSA/PgvT/aT2gYgp5E/P29AKBQAo6TRth5T4VesQFb0i4K7RA2MZpgyFXCEQHCOixuYMPgy2L7+45ezSSKt2oUkURlpXkEMOLSiXPuDQZjk63N5bmzOSxQdLHX7AhwUEA0BAeQPJIQzkAuFlOK/GtyLdiGDKEBdllQ7YouxV2Xdwza9So4Kp5Z0yAgUhTlJgFzSFrznIHYIwKcCu2/L3LsCg6UI1b1/CA+ApIV5/32HqOIjdQusE4azip5Wc1b0q/QGIAlaWEJbXP3r/L+AEipw/+BtkQVY9fIM2i/ZhgVEgJO6DZ1ksVtlYdoQAPhVO0oKmYBmnAYco4DRCRB3TwCziptaE0auER9/VzRqKNOEYINOQg2m1l9GpGNQAhh1v6UmxNQh2M4+LmlUzll0OTjYQOaGlZAEMCrdhmBphaMBwBADrSQQc3//He8KgFETT7p6BHnjj2X9EXsDjrgBS6ihoAmcSQVYmE4JgYWFpp1waAQRoqDzxDhU+HxSnZHz/9JEY6Y5MJA+cwoWrt99+U3Mc/9g/NQTFaigAEtwB1yBzwzucZSX7RZEILhR1d5GDCsBLVUdIQvsldZfEJt5i/MHx2hGJZFkVVyK242iFeh58oBUFqIQbkfp2DV2X0CkAYgv1sU+P+I/HmBu8nErugdRnUWhfp+A/ddlbEH3uQlBsNobUEMHasK1HOYn8BEEvCUaiuigXRIKj+sGOPA4KAWz9/s7WxcgB4+a6/fI2osEwv4yOENAiPf+wQhbc/5f0gGisWuQaRFmGoIqguARWsBQgTTocDLMT5OJUQnhqdCEig+/EShKSEgTVV0MBMnz04BcshPnLk/+OaV0/dwKzB4QUt1NB6uTDfGOP+cNm9mEsBAFiM7AQh9AKVEU75vy68jeOxrUC4mDEuYO0oLqoSdHaEF2eXYYSm0V+oEOwpLmYFOF3Z4CmAeBTIGueiIw2xoKPzDBJVBXQ5g5O8/twwA+QguIjJt3+g0NQEcDfUXgO5gsqlTBLkQLdl86K3CWneitQ8sg/5oWAUJP2C3V3RoEyji5n4b9lB4t9pz2CA+cAFn1Z9I/uzYsU/ELtEBOCHYQQqGcFejV+yeuRJX31zsKV5IGjway9z6PLDxKwNEPsBuOEiqw57jGgOtZ1Y++T50AuMFl7hPIbhskiOwsATtRoc7rS7dXrpcgrMCGJca6ELJo+Y0be0BW5ZKGcFz4y8W9BduwcDnK9iO5fagsKpp9ANnvDPxeP8THNyIVFo1AMas8Qk5v2Ytm0LCCYAXqn+wQsPTBh/5Bcnne14Os3uCQt28vsK1WUESJFviBgAW//3u9PLxusXchcCR2WsNzv/ImvgZzzkUByDUAIrjTvmSHAowpJBQE4SUlxMxnARlQbIqkArVAJ6pBBvELCCKlkyCDAP45BYfEPfcUpfMch3Vn4bheYK4E66BxAxHSVd5INgEPgU/NBCDfNQ8Ho1CoINAPQAW/QT8OCIZlNFCB84XhoDChFByHGjx35v9BLgyhmojqHYb5QYXnuAecvua0hZe6BV9f7v4ibvgvamrmAc1TmaEir0LQ9h97eYAYVoM/nWA60i8Q3Ifezha9BqaaL3zvqd6IAuwwLSCCuCLuJWch4h30giPtyiAphKEBcCu9BV5wwzkMxID8rhMwdwMhcSFgrBT3RUTQboAUg3+p+Qe1IGarOioVnazmefV3lHpwA0AcLWCahUiXwePHWJsP+GH1gnp/we5KfOhJAbsj0H/BIEb04TbrTPsAyb2LLu93KwfCvn5PLAwrOXAa72eEQRo1CNdw5IprsAZ3hApy9zlcITG2vpCihsRSYxNS+J4vdBZ6B52eqRcQ/QXmSjAWSfa/5GA5qEg4iJFtm624AqXLrSA2gx8p1Mdqcghv41S0lSp/xAYs9gakQc4Ie2RTUYwYgt748mV+FU1Xgp14eW3XYZ6cdqGTNHwHICTwEeTPl0jEZwIgP9gDEaogeg5IHWCF+1eoAhvEKPB/EAeTRsM/pSAP5wjWEUMM1/NJRhwJbpJSgK7S7zF3EOsI5jBQBK9DV80Z8Y0COzvmWzJXgDl40KEC6cqvqgi4OB5cpgLFYK/1CvDiItXqC6/S87wfAUfPtxqfGNzlYaOjlf1IsHPPvffHgDAoEeEST4ZLZUd/RSo91/BjXY5ggWgQ4In3fyj4mUqPrInHOCLKO3wUwRsfyXpt1nEIRLrqcWeTuk7bigsbid1zD4iDRQtnIdQsyIXnFCn1I9D7ADgxEhOvR5AJosoUbu1FkJyYCi9OhQERoIx+4AX/YqUXQhtYEwKN4Cy1HntLMmtaAQpqfrT/UCoLSxeswjA5UWPPi0mjajUWxMTdVusNvt/ChMdmILK5IRMFu90BMEzFYHdg2GAgeYVHMMJIBTA7EFTx/5fpgTFXz9w/en0ZjD8kCDoKPNGwlB01BmoWQbh+AxR689mBponGJOr9OwmMu3dtJ/ylW1Tik4ElUPmR9RqII+pVhD9ychABMQ51gOIZg+/G+5mGIzLB1JJC5WhzYjhJ7IWmLDpA8jzsAafUPkB2WnFBF4iSxkq1ty7f25rv/+EQLOxs2oUdTSA9HIR9swdBlCcFe9owPC3XWDDC0ISVzsEVbSCF/sWdA5Fu4HJqankp2SeQCYYrImNalfmhpVxYrGkUS4LeSUjg8dD7+D7w/ybIfy7vlB9/HJ978zr7/45Qgajzj+4EjIK/ULHPRAOlKr/aG0AFcqCyu0GcW45Igh6JMJmhA49/U+cEssHNJhtXDC1MOya3j/sAiAGcrEtqtgjBD6wEzSDc7D8o6C8rIqAZyPk+NQoNLAZ1hR64Yl1FBY648smUYKnSg1Xwk/0DyRyArByMUobyByhCcPnOaPyoegREFS4jNfYAw+IHCjdC1J2WDZBke/OyN85J24WiXwDYPoJyYuCD238ulvuzwt6KgHf0shWKsqCFFGjB/w8HU8eeTED9wAAAAABJRU5ErkJggg==";
    return BRDFTextureTools;
}());



/***/ }),

/***/ "./Misc/dds.ts":
/*!*********************!*\
  !*** ./Misc/dds.ts ***!
  \*********************/
/*! exports provided: DDSTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DDSTools", function() { return DDSTools; });
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/sphericalPolynomial */ "./Maths/sphericalPolynomial.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Misc/HighDynamicRange/cubemapToSphericalPolynomial */ "./Misc/HighDynamicRange/cubemapToSphericalPolynomial.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Engines_Extensions_engine_cubeTexture__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Engines/Extensions/engine.cubeTexture */ "./Engines/Extensions/engine.cubeTexture.ts");









// Based on demo done by Brandon Jones - http://media.tojicode.com/webgl-samples/dds.html
// All values and structures referenced from:
// http://msdn.microsoft.com/en-us/library/bb943991.aspx/
var DDS_MAGIC = 0x20534444;
var
//DDSD_CAPS = 0x1,
//DDSD_HEIGHT = 0x2,
//DDSD_WIDTH = 0x4,
//DDSD_PITCH = 0x8,
//DDSD_PIXELFORMAT = 0x1000,
DDSD_MIPMAPCOUNT = 0x20000;
//DDSD_LINEARSIZE = 0x80000,
//DDSD_DEPTH = 0x800000;
// var DDSCAPS_COMPLEX = 0x8,
//     DDSCAPS_MIPMAP = 0x400000,
//     DDSCAPS_TEXTURE = 0x1000;
var DDSCAPS2_CUBEMAP = 0x200;
// DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
// DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
// DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
// DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
// DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
// DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
// DDSCAPS2_VOLUME = 0x200000;
var
//DDPF_ALPHAPIXELS = 0x1,
//DDPF_ALPHA = 0x2,
DDPF_FOURCC = 0x4, DDPF_RGB = 0x40,
//DDPF_YUV = 0x200,
DDPF_LUMINANCE = 0x20000;
function FourCCToInt32(value) {
    return value.charCodeAt(0) +
        (value.charCodeAt(1) << 8) +
        (value.charCodeAt(2) << 16) +
        (value.charCodeAt(3) << 24);
}
function Int32ToFourCC(value) {
    return String.fromCharCode(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, (value >> 24) & 0xff);
}
var FOURCC_DXT1 = FourCCToInt32("DXT1");
var FOURCC_DXT3 = FourCCToInt32("DXT3");
var FOURCC_DXT5 = FourCCToInt32("DXT5");
var FOURCC_DX10 = FourCCToInt32("DX10");
var FOURCC_D3DFMT_R16G16B16A16F = 113;
var FOURCC_D3DFMT_R32G32B32A32F = 116;
var DXGI_FORMAT_R32G32B32A32_FLOAT = 2;
var DXGI_FORMAT_R16G16B16A16_FLOAT = 10;
var DXGI_FORMAT_B8G8R8X8_UNORM = 88;
var headerLengthInt = 31; // The header length in 32 bit ints
// Offsets into the header array
var off_magic = 0;
var off_size = 1;
var off_flags = 2;
var off_height = 3;
var off_width = 4;
var off_mipmapCount = 7;
var off_pfFlags = 20;
var off_pfFourCC = 21;
var off_RGBbpp = 22;
var off_RMask = 23;
var off_GMask = 24;
var off_BMask = 25;
var off_AMask = 26;
// var off_caps1 = 27;
var off_caps2 = 28;
// var off_caps3 = 29;
// var off_caps4 = 30;
var off_dxgiFormat = 32;
/**
 * Class used to provide DDS decompression tools
 */
var DDSTools = /** @class */ (function () {
    function DDSTools() {
    }
    /**
     * Gets DDS information from an array buffer
     * @param arrayBuffer defines the array buffer to read data from
     * @returns the DDS information
     */
    DDSTools.GetDDSInfo = function (arrayBuffer) {
        var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
        var extendedHeader = new Int32Array(arrayBuffer, 0, headerLengthInt + 4);
        var mipmapCount = 1;
        if (header[off_flags] & DDSD_MIPMAPCOUNT) {
            mipmapCount = Math.max(1, header[off_mipmapCount]);
        }
        var fourCC = header[off_pfFourCC];
        var dxgiFormat = (fourCC === FOURCC_DX10) ? extendedHeader[off_dxgiFormat] : 0;
        var textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        switch (fourCC) {
            case FOURCC_D3DFMT_R16G16B16A16F:
                textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_HALF_FLOAT;
                break;
            case FOURCC_D3DFMT_R32G32B32A32F:
                textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT;
                break;
            case FOURCC_DX10:
                if (dxgiFormat === DXGI_FORMAT_R16G16B16A16_FLOAT) {
                    textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_HALF_FLOAT;
                    break;
                }
                if (dxgiFormat === DXGI_FORMAT_R32G32B32A32_FLOAT) {
                    textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT;
                    break;
                }
        }
        return {
            width: header[off_width],
            height: header[off_height],
            mipmapCount: mipmapCount,
            isFourCC: (header[off_pfFlags] & DDPF_FOURCC) === DDPF_FOURCC,
            isRGB: (header[off_pfFlags] & DDPF_RGB) === DDPF_RGB,
            isLuminance: (header[off_pfFlags] & DDPF_LUMINANCE) === DDPF_LUMINANCE,
            isCube: (header[off_caps2] & DDSCAPS2_CUBEMAP) === DDSCAPS2_CUBEMAP,
            isCompressed: (fourCC === FOURCC_DXT1 || fourCC === FOURCC_DXT3 || fourCC === FOURCC_DXT5),
            dxgiFormat: dxgiFormat,
            textureType: textureType
        };
    };
    DDSTools._ToHalfFloat = function (value) {
        if (!DDSTools._FloatView) {
            DDSTools._FloatView = new Float32Array(1);
            DDSTools._Int32View = new Int32Array(DDSTools._FloatView.buffer);
        }
        DDSTools._FloatView[0] = value;
        var x = DDSTools._Int32View[0];
        var bits = (x >> 16) & 0x8000; /* Get the sign */
        var m = (x >> 12) & 0x07ff; /* Keep one extra bit for rounding */
        var e = (x >> 23) & 0xff; /* Using int is faster here */
        /* If zero, or denormal, or exponent underflows too much for a denormal
        * half, return signed zero. */
        if (e < 103) {
            return bits;
        }
        /* If NaN, return NaN. If Inf or exponent overflow, return Inf. */
        if (e > 142) {
            bits |= 0x7c00;
            /* If exponent was 0xff and one mantissa bit was set, it means NaN,
            * not Inf, so make sure we set one mantissa bit too. */
            bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff);
            return bits;
        }
        /* If exponent underflows but not too much, return a denormal */
        if (e < 113) {
            m |= 0x0800;
            /* Extra rounding may overflow and set mantissa to 0 and exponent
            * to 1, which is OK. */
            bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
            return bits;
        }
        bits |= ((e - 112) << 10) | (m >> 1);
        bits += m & 1;
        return bits;
    };
    DDSTools._FromHalfFloat = function (value) {
        var s = (value & 0x8000) >> 15;
        var e = (value & 0x7C00) >> 10;
        var f = value & 0x03FF;
        if (e === 0) {
            return (s ? -1 : 1) * Math.pow(2, -14) * (f / Math.pow(2, 10));
        }
        else if (e == 0x1F) {
            return f ? NaN : ((s ? -1 : 1) * Infinity);
        }
        return (s ? -1 : 1) * Math.pow(2, e - 15) * (1 + (f / Math.pow(2, 10)));
    };
    DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, lod) {
        var destArray = new Float32Array(dataLength);
        var srcData = new Uint16Array(arrayBuffer, dataOffset);
        var index = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var srcPos = (x + y * width) * 4;
                destArray[index] = DDSTools._FromHalfFloat(srcData[srcPos]);
                destArray[index + 1] = DDSTools._FromHalfFloat(srcData[srcPos + 1]);
                destArray[index + 2] = DDSTools._FromHalfFloat(srcData[srcPos + 2]);
                if (DDSTools.StoreLODInAlphaChannel) {
                    destArray[index + 3] = lod;
                }
                else {
                    destArray[index + 3] = DDSTools._FromHalfFloat(srcData[srcPos + 3]);
                }
                index += 4;
            }
        }
        return destArray;
    };
    DDSTools._GetHalfFloatRGBAArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, lod) {
        if (DDSTools.StoreLODInAlphaChannel) {
            var destArray = new Uint16Array(dataLength);
            var srcData = new Uint16Array(arrayBuffer, dataOffset);
            var index = 0;
            for (var y = 0; y < height; y++) {
                for (var x = 0; x < width; x++) {
                    var srcPos = (x + y * width) * 4;
                    destArray[index] = srcData[srcPos];
                    destArray[index + 1] = srcData[srcPos + 1];
                    destArray[index + 2] = srcData[srcPos + 2];
                    destArray[index + 3] = DDSTools._ToHalfFloat(lod);
                    index += 4;
                }
            }
            return destArray;
        }
        return new Uint16Array(arrayBuffer, dataOffset, dataLength);
    };
    DDSTools._GetFloatRGBAArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, lod) {
        if (DDSTools.StoreLODInAlphaChannel) {
            var destArray = new Float32Array(dataLength);
            var srcData = new Float32Array(arrayBuffer, dataOffset);
            var index = 0;
            for (var y = 0; y < height; y++) {
                for (var x = 0; x < width; x++) {
                    var srcPos = (x + y * width) * 4;
                    destArray[index] = srcData[srcPos];
                    destArray[index + 1] = srcData[srcPos + 1];
                    destArray[index + 2] = srcData[srcPos + 2];
                    destArray[index + 3] = lod;
                    index += 4;
                }
            }
            return destArray;
        }
        return new Float32Array(arrayBuffer, dataOffset, dataLength);
    };
    DDSTools._GetFloatAsUIntRGBAArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, lod) {
        var destArray = new Uint8Array(dataLength);
        var srcData = new Float32Array(arrayBuffer, dataOffset);
        var index = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var srcPos = (x + y * width) * 4;
                destArray[index] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(srcData[srcPos]) * 255;
                destArray[index + 1] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(srcData[srcPos + 1]) * 255;
                destArray[index + 2] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(srcData[srcPos + 2]) * 255;
                if (DDSTools.StoreLODInAlphaChannel) {
                    destArray[index + 3] = lod;
                }
                else {
                    destArray[index + 3] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(srcData[srcPos + 3]) * 255;
                }
                index += 4;
            }
        }
        return destArray;
    };
    DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, lod) {
        var destArray = new Uint8Array(dataLength);
        var srcData = new Uint16Array(arrayBuffer, dataOffset);
        var index = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var srcPos = (x + y * width) * 4;
                destArray[index] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(DDSTools._FromHalfFloat(srcData[srcPos])) * 255;
                destArray[index + 1] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(DDSTools._FromHalfFloat(srcData[srcPos + 1])) * 255;
                destArray[index + 2] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(DDSTools._FromHalfFloat(srcData[srcPos + 2])) * 255;
                if (DDSTools.StoreLODInAlphaChannel) {
                    destArray[index + 3] = lod;
                }
                else {
                    destArray[index + 3] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Clamp(DDSTools._FromHalfFloat(srcData[srcPos + 3])) * 255;
                }
                index += 4;
            }
        }
        return destArray;
    };
    DDSTools._GetRGBAArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, rOffset, gOffset, bOffset, aOffset) {
        var byteArray = new Uint8Array(dataLength);
        var srcData = new Uint8Array(arrayBuffer, dataOffset);
        var index = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var srcPos = (x + y * width) * 4;
                byteArray[index] = srcData[srcPos + rOffset];
                byteArray[index + 1] = srcData[srcPos + gOffset];
                byteArray[index + 2] = srcData[srcPos + bOffset];
                byteArray[index + 3] = srcData[srcPos + aOffset];
                index += 4;
            }
        }
        return byteArray;
    };
    DDSTools._ExtractLongWordOrder = function (value) {
        if (value === 0 || value === 255 || value === -16777216) {
            return 0;
        }
        return 1 + DDSTools._ExtractLongWordOrder(value >> 8);
    };
    DDSTools._GetRGBArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer, rOffset, gOffset, bOffset) {
        var byteArray = new Uint8Array(dataLength);
        var srcData = new Uint8Array(arrayBuffer, dataOffset);
        var index = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var srcPos = (x + y * width) * 3;
                byteArray[index] = srcData[srcPos + rOffset];
                byteArray[index + 1] = srcData[srcPos + gOffset];
                byteArray[index + 2] = srcData[srcPos + bOffset];
                index += 3;
            }
        }
        return byteArray;
    };
    DDSTools._GetLuminanceArrayBuffer = function (width, height, dataOffset, dataLength, arrayBuffer) {
        var byteArray = new Uint8Array(dataLength);
        var srcData = new Uint8Array(arrayBuffer, dataOffset);
        var index = 0;
        for (var y = 0; y < height; y++) {
            for (var x = 0; x < width; x++) {
                var srcPos = (x + y * width);
                byteArray[index] = srcData[srcPos];
                index++;
            }
        }
        return byteArray;
    };
    /**
     * Uploads DDS Levels to a Babylon Texture
     * @hidden
     */
    DDSTools.UploadDDSLevels = function (engine, texture, arrayBuffer, info, loadMipmaps, faces, lodIndex, currentFace) {
        if (lodIndex === void 0) { lodIndex = -1; }
        var sphericalPolynomialFaces = null;
        if (info.sphericalPolynomial) {
            sphericalPolynomialFaces = new Array();
        }
        var ext = engine.getCaps().s3tc;
        var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
        var fourCC, width, height, dataLength = 0, dataOffset;
        var byteArray, mipmapCount, mip;
        var internalCompressedFormat = 0;
        var blockBytes = 1;
        if (header[off_magic] !== DDS_MAGIC) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_5__["Logger"].Error("Invalid magic number in DDS header");
            return;
        }
        if (!info.isFourCC && !info.isRGB && !info.isLuminance) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_5__["Logger"].Error("Unsupported format, must contain a FourCC, RGB or LUMINANCE code");
            return;
        }
        if (info.isCompressed && !ext) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_5__["Logger"].Error("Compressed textures are not supported on this platform.");
            return;
        }
        var bpp = header[off_RGBbpp];
        dataOffset = header[off_size] + 4;
        var computeFormats = false;
        if (info.isFourCC) {
            fourCC = header[off_pfFourCC];
            switch (fourCC) {
                case FOURCC_DXT1:
                    blockBytes = 8;
                    internalCompressedFormat = ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
                    break;
                case FOURCC_DXT3:
                    blockBytes = 16;
                    internalCompressedFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT;
                    break;
                case FOURCC_DXT5:
                    blockBytes = 16;
                    internalCompressedFormat = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
                    break;
                case FOURCC_D3DFMT_R16G16B16A16F:
                    computeFormats = true;
                    break;
                case FOURCC_D3DFMT_R32G32B32A32F:
                    computeFormats = true;
                    break;
                case FOURCC_DX10:
                    // There is an additionnal header so dataOffset need to be changed
                    dataOffset += 5 * 4; // 5 uints
                    var supported = false;
                    switch (info.dxgiFormat) {
                        case DXGI_FORMAT_R16G16B16A16_FLOAT:
                        case DXGI_FORMAT_R32G32B32A32_FLOAT:
                            computeFormats = true;
                            supported = true;
                            break;
                        case DXGI_FORMAT_B8G8R8X8_UNORM:
                            info.isRGB = true;
                            info.isFourCC = false;
                            bpp = 32;
                            supported = true;
                            break;
                    }
                    if (supported) {
                        break;
                    }
                default:
                    console.error("Unsupported FourCC code:", Int32ToFourCC(fourCC));
                    return;
            }
        }
        var rOffset = DDSTools._ExtractLongWordOrder(header[off_RMask]);
        var gOffset = DDSTools._ExtractLongWordOrder(header[off_GMask]);
        var bOffset = DDSTools._ExtractLongWordOrder(header[off_BMask]);
        var aOffset = DDSTools._ExtractLongWordOrder(header[off_AMask]);
        if (computeFormats) {
            internalCompressedFormat = engine._getRGBABufferInternalSizedFormat(info.textureType);
        }
        mipmapCount = 1;
        if (header[off_flags] & DDSD_MIPMAPCOUNT && loadMipmaps !== false) {
            mipmapCount = Math.max(1, header[off_mipmapCount]);
        }
        var startFace = currentFace || 0;
        for (var face = startFace; face < faces; face++) {
            width = header[off_width];
            height = header[off_height];
            for (mip = 0; mip < mipmapCount; ++mip) {
                if (lodIndex === -1 || lodIndex === mip) {
                    // In case of fixed LOD, if the lod has just been uploaded, early exit.
                    var i = (lodIndex === -1) ? mip : 0;
                    if (!info.isCompressed && info.isFourCC) {
                        texture.format = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_RGBA;
                        dataLength = width * height * 4;
                        var floatArray = null;
                        if (engine._badOS || engine._badDesktopOS || (!engine.getCaps().textureHalfFloat && !engine.getCaps().textureFloat)) { // Required because iOS has many issues with float and half float generation
                            if (bpp === 128) {
                                floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                if (sphericalPolynomialFaces && i == 0) {
                                    sphericalPolynomialFaces.push(DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i));
                                }
                            }
                            else if (bpp === 64) {
                                floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                if (sphericalPolynomialFaces && i == 0) {
                                    sphericalPolynomialFaces.push(DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i));
                                }
                            }
                            texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT;
                        }
                        else {
                            if (bpp === 128) {
                                texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT;
                                floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                if (sphericalPolynomialFaces && i == 0) {
                                    sphericalPolynomialFaces.push(floatArray);
                                }
                            }
                            else if (bpp === 64 && !engine.getCaps().textureHalfFloat) {
                                texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT;
                                floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                if (sphericalPolynomialFaces && i == 0) {
                                    sphericalPolynomialFaces.push(floatArray);
                                }
                            }
                            else { // 64
                                texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_HALF_FLOAT;
                                floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
                                if (sphericalPolynomialFaces && i == 0) {
                                    sphericalPolynomialFaces.push(DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i));
                                }
                            }
                        }
                        if (floatArray) {
                            engine._uploadDataToTextureDirectly(texture, floatArray, face, i);
                        }
                    }
                    else if (info.isRGB) {
                        texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT;
                        if (bpp === 24) {
                            texture.format = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_RGB;
                            dataLength = width * height * 3;
                            byteArray = DDSTools._GetRGBArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, rOffset, gOffset, bOffset);
                            engine._uploadDataToTextureDirectly(texture, byteArray, face, i);
                        }
                        else { // 32
                            texture.format = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_RGBA;
                            dataLength = width * height * 4;
                            byteArray = DDSTools._GetRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, rOffset, gOffset, bOffset, aOffset);
                            engine._uploadDataToTextureDirectly(texture, byteArray, face, i);
                        }
                    }
                    else if (info.isLuminance) {
                        var unpackAlignment = engine._getUnpackAlignement();
                        var unpaddedRowSize = width;
                        var paddedRowSize = Math.floor((width + unpackAlignment - 1) / unpackAlignment) * unpackAlignment;
                        dataLength = paddedRowSize * (height - 1) + unpaddedRowSize;
                        byteArray = DDSTools._GetLuminanceArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer);
                        texture.format = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_LUMINANCE;
                        texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT;
                        engine._uploadDataToTextureDirectly(texture, byteArray, face, i);
                    }
                    else {
                        dataLength = Math.max(4, width) / 4 * Math.max(4, height) / 4 * blockBytes;
                        byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
                        texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT;
                        engine._uploadCompressedDataToTextureDirectly(texture, internalCompressedFormat, width, height, byteArray, face, i);
                    }
                }
                dataOffset += bpp ? (width * height * (bpp / 8)) : dataLength;
                width *= 0.5;
                height *= 0.5;
                width = Math.max(1.0, width);
                height = Math.max(1.0, height);
            }
            if (currentFace !== undefined) {
                // Loading a single face
                break;
            }
        }
        if (sphericalPolynomialFaces && sphericalPolynomialFaces.length > 0) {
            info.sphericalPolynomial = _Misc_HighDynamicRange_cubemapToSphericalPolynomial__WEBPACK_IMPORTED_MODULE_6__["CubeMapToSphericalPolynomialTools"].ConvertCubeMapToSphericalPolynomial({
                size: header[off_width],
                right: sphericalPolynomialFaces[0],
                left: sphericalPolynomialFaces[1],
                up: sphericalPolynomialFaces[2],
                down: sphericalPolynomialFaces[3],
                front: sphericalPolynomialFaces[4],
                back: sphericalPolynomialFaces[5],
                format: _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTUREFORMAT_RGBA,
                type: _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT,
                gammaSpace: false,
            });
        }
        else {
            info.sphericalPolynomial = undefined;
        }
    };
    /**
     * Gets or sets a boolean indicating that LOD info is stored in alpha channel (false by default)
     */
    DDSTools.StoreLODInAlphaChannel = false;
    return DDSTools;
}());

/**
 * Create a cube texture from prefiltered data (ie. the mipmaps contain ready to use data for PBR reflection)
 * @param rootUrl defines the url where the file to load is located
 * @param scene defines the current scene
 * @param lodScale defines scale to apply to the mip map selection
 * @param lodOffset defines offset to apply to the mip map selection
 * @param onLoad defines an optional callback raised when the texture is loaded
 * @param onError defines an optional callback raised if there is an issue to load the texture
 * @param format defines the format of the data
 * @param forcedExtension defines the extension to use to pick the right loader
 * @param createPolynomials defines wheter or not to create polynomails harmonics for the texture
 * @returns the cube texture as an InternalTexture
 */
_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].prototype.createPrefilteredCubeTexture = function (rootUrl, scene, lodScale, lodOffset, onLoad, onError, format, forcedExtension, createPolynomials) {
    var _this = this;
    if (onLoad === void 0) { onLoad = null; }
    if (onError === void 0) { onError = null; }
    if (forcedExtension === void 0) { forcedExtension = null; }
    if (createPolynomials === void 0) { createPolynomials = true; }
    var callback = function (loadData) {
        if (!loadData) {
            if (onLoad) {
                onLoad(null);
            }
            return;
        }
        var texture = loadData.texture;
        if (!createPolynomials) {
            texture._sphericalPolynomial = new _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_1__["SphericalPolynomial"]();
        }
        else if (loadData.info.sphericalPolynomial) {
            texture._sphericalPolynomial = loadData.info.sphericalPolynomial;
        }
        texture._dataSource = _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"].DATASOURCE_CUBEPREFILTERED;
        if (_this.getCaps().textureLOD) {
            // Do not add extra process if texture lod is supported.
            if (onLoad) {
                onLoad(texture);
            }
            return;
        }
        var mipSlices = 3;
        var gl = _this._gl;
        var width = loadData.width;
        if (!width) {
            return;
        }
        var textures = [];
        for (var i = 0; i < mipSlices; i++) {
            //compute LOD from even spacing in smoothness (matching shader calculation)
            var smoothness = i / (mipSlices - 1);
            var roughness = 1 - smoothness;
            var minLODIndex = lodOffset; // roughness = 0
            var maxLODIndex = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Log2(width) * lodScale + lodOffset; // roughness = 1
            var lodIndex = minLODIndex + (maxLODIndex - minLODIndex) * roughness;
            var mipmapIndex = Math.round(Math.min(Math.max(lodIndex, 0), maxLODIndex));
            var glTextureFromLod = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"](_this, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"].DATASOURCE_TEMP);
            glTextureFromLod.type = texture.type;
            glTextureFromLod.format = texture.format;
            glTextureFromLod.width = Math.pow(2, Math.max(_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_0__["Scalar"].Log2(width) - mipmapIndex, 0));
            glTextureFromLod.height = glTextureFromLod.width;
            glTextureFromLod.isCube = true;
            _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, glTextureFromLod, true);
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
            if (loadData.isDDS) {
                var info = loadData.info;
                var data = loadData.data;
                _this._unpackFlipY(info.isCompressed);
                DDSTools.UploadDDSLevels(_this, glTextureFromLod, data, info, true, 6, mipmapIndex);
            }
            else {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_5__["Logger"].Warn("DDS is the only prefiltered cube map supported so far.");
            }
            _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
            // Wrap in a base texture for easy binding.
            var lodTexture = new _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_7__["BaseTexture"](scene);
            lodTexture.isCube = true;
            lodTexture._texture = glTextureFromLod;
            glTextureFromLod.isReady = true;
            textures.push(lodTexture);
        }
        texture._lodTextureHigh = textures[2];
        texture._lodTextureMid = textures[1];
        texture._lodTextureLow = textures[0];
        if (onLoad) {
            onLoad(texture);
        }
    };
    return this.createCubeTexture(rootUrl, scene, null, false, callback, onError, format, forcedExtension, createPolynomials, lodScale, lodOffset);
};


/***/ }),

/***/ "./Misc/decorators.ts":
/*!****************************!*\
  !*** ./Misc/decorators.ts ***!
  \****************************/
/*! exports provided: expandToProperty, serialize, serializeAsTexture, serializeAsColor3, serializeAsFresnelParameters, serializeAsVector2, serializeAsVector3, serializeAsMeshReference, serializeAsColorCurves, serializeAsColor4, serializeAsImageProcessingConfiguration, serializeAsQuaternion, serializeAsMatrix, serializeAsCameraReference, SerializationHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expandToProperty", function() { return expandToProperty; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serialize", function() { return serialize; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsTexture", function() { return serializeAsTexture; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor3", function() { return serializeAsColor3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsFresnelParameters", function() { return serializeAsFresnelParameters; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector2", function() { return serializeAsVector2; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector3", function() { return serializeAsVector3; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsMeshReference", function() { return serializeAsMeshReference; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsColorCurves", function() { return serializeAsColorCurves; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor4", function() { return serializeAsColor4; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsImageProcessingConfiguration", function() { return serializeAsImageProcessingConfiguration; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsQuaternion", function() { return serializeAsQuaternion; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsMatrix", function() { return serializeAsMatrix; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serializeAsCameraReference", function() { return serializeAsCameraReference; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SerializationHelper", function() { return SerializationHelper; });
/* harmony import */ var _Misc_tags__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tags */ "./Misc/tags.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _devTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");




var __decoratorInitialStore = {};
var __mergedStore = {};
var _copySource = function (creationFunction, source, instanciate) {
    var destination = creationFunction();
    // Tags
    if (_Misc_tags__WEBPACK_IMPORTED_MODULE_0__["Tags"]) {
        _Misc_tags__WEBPACK_IMPORTED_MODULE_0__["Tags"].AddTagsTo(destination, source.tags);
    }
    var classStore = getMergedStore(destination);
    // Properties
    for (var property in classStore) {
        var propertyDescriptor = classStore[property];
        var sourceProperty = source[property];
        var propertyType = propertyDescriptor.type;
        if (sourceProperty !== undefined && sourceProperty !== null && property !== "uniqueId") {
            switch (propertyType) {
                case 0: // Value
                case 6: // Mesh reference
                case 11: // Camera reference
                    destination[property] = sourceProperty;
                    break;
                case 1: // Texture
                    destination[property] = (instanciate || sourceProperty.isRenderTarget) ? sourceProperty : sourceProperty.clone();
                    break;
                case 2: // Color3
                case 3: // FresnelParameters
                case 4: // Vector2
                case 5: // Vector3
                case 7: // Color Curves
                case 10: // Quaternion
                case 12: // Matrix
                    destination[property] = instanciate ? sourceProperty : sourceProperty.clone();
                    break;
            }
        }
    }
    return destination;
};
function getDirectStore(target) {
    var classKey = target.getClassName();
    if (!__decoratorInitialStore[classKey]) {
        __decoratorInitialStore[classKey] = {};
    }
    return __decoratorInitialStore[classKey];
}
/**
 * Return the list of properties flagged as serializable
 * @param target: host object
 */
function getMergedStore(target) {
    var classKey = target.getClassName();
    if (__mergedStore[classKey]) {
        return __mergedStore[classKey];
    }
    __mergedStore[classKey] = {};
    var store = __mergedStore[classKey];
    var currentTarget = target;
    var currentKey = classKey;
    while (currentKey) {
        var initialStore = __decoratorInitialStore[currentKey];
        for (var property in initialStore) {
            store[property] = initialStore[property];
        }
        var parent_1 = void 0;
        var done = false;
        do {
            parent_1 = Object.getPrototypeOf(currentTarget);
            if (!parent_1.getClassName) {
                done = true;
                break;
            }
            if (parent_1.getClassName() !== currentKey) {
                break;
            }
            currentTarget = parent_1;
        } while (parent_1);
        if (done) {
            break;
        }
        currentKey = parent_1.getClassName();
        currentTarget = parent_1;
    }
    return store;
}
function generateSerializableMember(type, sourceName) {
    return function (target, propertyKey) {
        var classStore = getDirectStore(target);
        if (!classStore[propertyKey]) {
            classStore[propertyKey] = { type: type, sourceName: sourceName };
        }
    };
}
function generateExpandMember(setCallback, targetKey) {
    if (targetKey === void 0) { targetKey = null; }
    return function (target, propertyKey) {
        var key = targetKey || ("_" + propertyKey);
        Object.defineProperty(target, propertyKey, {
            get: function () {
                return this[key];
            },
            set: function (value) {
                if (this[key] === value) {
                    return;
                }
                this[key] = value;
                target[setCallback].apply(this);
            },
            enumerable: true,
            configurable: true
        });
    };
}
function expandToProperty(callback, targetKey) {
    if (targetKey === void 0) { targetKey = null; }
    return generateExpandMember(callback, targetKey);
}
function serialize(sourceName) {
    return generateSerializableMember(0, sourceName); // value member
}
function serializeAsTexture(sourceName) {
    return generateSerializableMember(1, sourceName); // texture member
}
function serializeAsColor3(sourceName) {
    return generateSerializableMember(2, sourceName); // color3 member
}
function serializeAsFresnelParameters(sourceName) {
    return generateSerializableMember(3, sourceName); // fresnel parameters member
}
function serializeAsVector2(sourceName) {
    return generateSerializableMember(4, sourceName); // vector2 member
}
function serializeAsVector3(sourceName) {
    return generateSerializableMember(5, sourceName); // vector3 member
}
function serializeAsMeshReference(sourceName) {
    return generateSerializableMember(6, sourceName); // mesh reference member
}
function serializeAsColorCurves(sourceName) {
    return generateSerializableMember(7, sourceName); // color curves
}
function serializeAsColor4(sourceName) {
    return generateSerializableMember(8, sourceName); // color 4
}
function serializeAsImageProcessingConfiguration(sourceName) {
    return generateSerializableMember(9, sourceName); // image processing
}
function serializeAsQuaternion(sourceName) {
    return generateSerializableMember(10, sourceName); // quaternion member
}
function serializeAsMatrix(sourceName) {
    return generateSerializableMember(12, sourceName); // matrix member
}
/**
 * Decorator used to define property that can be serialized as reference to a camera
 * @param sourceName defines the name of the property to decorate
 */
function serializeAsCameraReference(sourceName) {
    return generateSerializableMember(11, sourceName); // camera reference member
}
/**
 * Class used to help serialization objects
 */
var SerializationHelper = /** @class */ (function () {
    function SerializationHelper() {
    }
    /**
     * Appends the serialized animations from the source animations
     * @param source Source containing the animations
     * @param destination Target to store the animations
     */
    SerializationHelper.AppendSerializedAnimations = function (source, destination) {
        if (source.animations) {
            destination.animations = [];
            for (var animationIndex = 0; animationIndex < source.animations.length; animationIndex++) {
                var animation = source.animations[animationIndex];
                destination.animations.push(animation.serialize());
            }
        }
    };
    /**
     * Static function used to serialized a specific entity
     * @param entity defines the entity to serialize
     * @param serializationObject defines the optional target obecjt where serialization data will be stored
     * @returns a JSON compatible object representing the serialization of the entity
     */
    SerializationHelper.Serialize = function (entity, serializationObject) {
        if (!serializationObject) {
            serializationObject = {};
        }
        // Tags
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_0__["Tags"]) {
            serializationObject.tags = _Misc_tags__WEBPACK_IMPORTED_MODULE_0__["Tags"].GetTags(entity);
        }
        var serializedProperties = getMergedStore(entity);
        // Properties
        for (var property in serializedProperties) {
            var propertyDescriptor = serializedProperties[property];
            var targetPropertyName = propertyDescriptor.sourceName || property;
            var propertyType = propertyDescriptor.type;
            var sourceProperty = entity[property];
            if (sourceProperty !== undefined && sourceProperty !== null) {
                switch (propertyType) {
                    case 0: // Value
                        serializationObject[targetPropertyName] = sourceProperty;
                        break;
                    case 1: // Texture
                        serializationObject[targetPropertyName] = sourceProperty.serialize();
                        break;
                    case 2: // Color3
                        serializationObject[targetPropertyName] = sourceProperty.asArray();
                        break;
                    case 3: // FresnelParameters
                        serializationObject[targetPropertyName] = sourceProperty.serialize();
                        break;
                    case 4: // Vector2
                        serializationObject[targetPropertyName] = sourceProperty.asArray();
                        break;
                    case 5: // Vector3
                        serializationObject[targetPropertyName] = sourceProperty.asArray();
                        break;
                    case 6: // Mesh reference
                        serializationObject[targetPropertyName] = sourceProperty.id;
                        break;
                    case 7: // Color Curves
                        serializationObject[targetPropertyName] = sourceProperty.serialize();
                        break;
                    case 8: // Color 4
                        serializationObject[targetPropertyName] = sourceProperty.asArray();
                        break;
                    case 9: // Image Processing
                        serializationObject[targetPropertyName] = sourceProperty.serialize();
                        break;
                    case 10: // Quaternion
                        serializationObject[targetPropertyName] = sourceProperty.asArray();
                        break;
                    case 11: // Camera reference
                        serializationObject[targetPropertyName] = sourceProperty.id;
                    case 12: // Matrix
                        serializationObject[targetPropertyName] = sourceProperty.asArray();
                        break;
                }
            }
        }
        return serializationObject;
    };
    /**
     * Creates a new entity from a serialization data object
     * @param creationFunction defines a function used to instanciated the new entity
     * @param source defines the source serialization data
     * @param scene defines the hosting scene
     * @param rootUrl defines the root url for resources
     * @returns a new entity
     */
    SerializationHelper.Parse = function (creationFunction, source, scene, rootUrl) {
        if (rootUrl === void 0) { rootUrl = null; }
        var destination = creationFunction();
        if (!rootUrl) {
            rootUrl = "";
        }
        // Tags
        if (_Misc_tags__WEBPACK_IMPORTED_MODULE_0__["Tags"]) {
            _Misc_tags__WEBPACK_IMPORTED_MODULE_0__["Tags"].AddTagsTo(destination, source.tags);
        }
        var classStore = getMergedStore(destination);
        // Properties
        for (var property in classStore) {
            var propertyDescriptor = classStore[property];
            var sourceProperty = source[propertyDescriptor.sourceName || property];
            var propertyType = propertyDescriptor.type;
            if (sourceProperty !== undefined && sourceProperty !== null) {
                var dest = destination;
                switch (propertyType) {
                    case 0: // Value
                        dest[property] = sourceProperty;
                        break;
                    case 1: // Texture
                        if (scene) {
                            dest[property] = SerializationHelper._TextureParser(sourceProperty, scene, rootUrl);
                        }
                        break;
                    case 2: // Color3
                        dest[property] = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color3"].FromArray(sourceProperty);
                        break;
                    case 3: // FresnelParameters
                        dest[property] = SerializationHelper._FresnelParametersParser(sourceProperty);
                        break;
                    case 4: // Vector2
                        dest[property] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"].FromArray(sourceProperty);
                        break;
                    case 5: // Vector3
                        dest[property] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(sourceProperty);
                        break;
                    case 6: // Mesh reference
                        if (scene) {
                            dest[property] = scene.getLastMeshByID(sourceProperty);
                        }
                        break;
                    case 7: // Color Curves
                        dest[property] = SerializationHelper._ColorCurvesParser(sourceProperty);
                        break;
                    case 8: // Color 4
                        dest[property] = _Maths_math_color__WEBPACK_IMPORTED_MODULE_3__["Color4"].FromArray(sourceProperty);
                        break;
                    case 9: // Image Processing
                        dest[property] = SerializationHelper._ImageProcessingConfigurationParser(sourceProperty);
                        break;
                    case 10: // Quaternion
                        dest[property] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].FromArray(sourceProperty);
                        break;
                    case 11: // Camera reference
                        if (scene) {
                            dest[property] = scene.getCameraByID(sourceProperty);
                        }
                    case 12: // Matrix
                        dest[property] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].FromArray(sourceProperty);
                        break;
                }
            }
        }
        return destination;
    };
    /**
     * Clones an object
     * @param creationFunction defines the function used to instanciate the new object
     * @param source defines the source object
     * @returns the cloned object
     */
    SerializationHelper.Clone = function (creationFunction, source) {
        return _copySource(creationFunction, source, false);
    };
    /**
     * Instanciates a new object based on a source one (some data will be shared between both object)
     * @param creationFunction defines the function used to instanciate the new object
     * @param source defines the source object
     * @returns the new object
     */
    SerializationHelper.Instanciate = function (creationFunction, source) {
        return _copySource(creationFunction, source, true);
    };
    /** @hidden */
    SerializationHelper._ImageProcessingConfigurationParser = function (sourceProperty) {
        throw _devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("ImageProcessingConfiguration");
    };
    /** @hidden */
    SerializationHelper._FresnelParametersParser = function (sourceProperty) {
        throw _devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("FresnelParameters");
    };
    /** @hidden */
    SerializationHelper._ColorCurvesParser = function (sourceProperty) {
        throw _devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("ColorCurves");
    };
    /** @hidden */
    SerializationHelper._TextureParser = function (sourceProperty, scene, rootUrl) {
        throw _devTools__WEBPACK_IMPORTED_MODULE_2__["_DevTools"].WarnImport("Texture");
    };
    return SerializationHelper;
}());



/***/ }),

/***/ "./Misc/deepCopier.ts":
/*!****************************!*\
  !*** ./Misc/deepCopier.ts ***!
  \****************************/
/*! exports provided: DeepCopier */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DeepCopier", function() { return DeepCopier; });
var cloneValue = function (source, destinationObject) {
    if (!source) {
        return null;
    }
    if (source.getClassName && source.getClassName() === "Mesh") {
        return null;
    }
    if (source.getClassName && source.getClassName() === "SubMesh") {
        return source.clone(destinationObject);
    }
    else if (source.clone) {
        return source.clone();
    }
    return null;
};
/**
 * Class containing a set of static utilities functions for deep copy.
 */
var DeepCopier = /** @class */ (function () {
    function DeepCopier() {
    }
    /**
     * Tries to copy an object by duplicating every property
     * @param source defines the source object
     * @param destination defines the target object
     * @param doNotCopyList defines a list of properties to avoid
     * @param mustCopyList defines a list of properties to copy (even if they start with _)
     */
    DeepCopier.DeepCopy = function (source, destination, doNotCopyList, mustCopyList) {
        for (var prop in source) {
            if (prop[0] === "_" && (!mustCopyList || mustCopyList.indexOf(prop) === -1)) {
                continue;
            }
            if (doNotCopyList && doNotCopyList.indexOf(prop) !== -1) {
                continue;
            }
            var sourceValue = source[prop];
            var typeOfSourceValue = typeof sourceValue;
            if (typeOfSourceValue === "function") {
                continue;
            }
            try {
                if (typeOfSourceValue === "object") {
                    if (sourceValue instanceof Array) {
                        destination[prop] = [];
                        if (sourceValue.length > 0) {
                            if (typeof sourceValue[0] == "object") {
                                for (var index = 0; index < sourceValue.length; index++) {
                                    var clonedValue = cloneValue(sourceValue[index], destination);
                                    if (destination[prop].indexOf(clonedValue) === -1) { // Test if auto inject was not done
                                        destination[prop].push(clonedValue);
                                    }
                                }
                            }
                            else {
                                destination[prop] = sourceValue.slice(0);
                            }
                        }
                    }
                    else {
                        destination[prop] = cloneValue(sourceValue, destination);
                    }
                }
                else {
                    destination[prop] = sourceValue;
                }
            }
            catch (e) {
                // Just ignore error (it could be because of a read-only property)
            }
        }
    };
    return DeepCopier;
}());



/***/ }),

/***/ "./Misc/deferred.ts":
/*!**************************!*\
  !*** ./Misc/deferred.ts ***!
  \**************************/
/*! exports provided: Deferred */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Deferred", function() { return Deferred; });
/**
 * Wrapper class for promise with external resolve and reject.
 */
var Deferred = /** @class */ (function () {
    /**
     * Constructor for this deferred object.
     */
    function Deferred() {
        var _this = this;
        this.promise = new Promise(function (resolve, reject) {
            _this._resolve = resolve;
            _this._reject = reject;
        });
    }
    Object.defineProperty(Deferred.prototype, "resolve", {
        /**
         * The resolve method of the promise associated with this deferred object.
         */
        get: function () {
            return this._resolve;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Deferred.prototype, "reject", {
        /**
         * The reject method of the promise associated with this deferred object.
         */
        get: function () {
            return this._reject;
        },
        enumerable: true,
        configurable: true
    });
    return Deferred;
}());



/***/ }),

/***/ "./Misc/devTools.ts":
/*!**************************!*\
  !*** ./Misc/devTools.ts ***!
  \**************************/
/*! exports provided: _DevTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_DevTools", function() { return _DevTools; });
/** @hidden */
var _DevTools = /** @class */ (function () {
    function _DevTools() {
    }
    _DevTools.WarnImport = function (name) {
        return name + " needs to be imported before as it contains a side-effect required by your code.";
    };
    return _DevTools;
}());



/***/ }),

/***/ "./Misc/domManagement.ts":
/*!*******************************!*\
  !*** ./Misc/domManagement.ts ***!
  \*******************************/
/*! exports provided: DomManagement */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DomManagement", function() { return DomManagement; });
/**
 * Sets of helpers dealing with the DOM and some of the recurrent functions needed in
 * Babylon.js
 */
var DomManagement = /** @class */ (function () {
    function DomManagement() {
    }
    /**
     * Checks if the window object exists
     * @returns true if the window object exists
     */
    DomManagement.IsWindowObjectExist = function () {
        return (typeof window) !== "undefined";
    };
    /**
     * Checks if the navigator object exists
     * @returns true if the navigator object exists
     */
    DomManagement.IsNavigatorAvailable = function () {
        return (typeof navigator) !== "undefined";
    };
    /**
     * Extracts text content from a DOM element hierarchy
     * @param element defines the root element
     * @returns a string
     */
    DomManagement.GetDOMTextContent = function (element) {
        var result = "";
        var child = element.firstChild;
        while (child) {
            if (child.nodeType === 3) {
                result += child.textContent;
            }
            child = (child.nextSibling);
        }
        return result;
    };
    return DomManagement;
}());



/***/ }),

/***/ "./Misc/environmentTextureTools.ts":
/*!*****************************************!*\
  !*** ./Misc/environmentTextureTools.ts ***!
  \*****************************************/
/*! exports provided: EnvironmentTextureTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EnvironmentTextureTools", function() { return EnvironmentTextureTools; });
/* harmony import */ var _tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/sphericalPolynomial */ "./Maths/sphericalPolynomial.ts");
/* harmony import */ var _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/internalTexture */ "./Materials/Textures/internalTexture.ts");
/* harmony import */ var _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/Textures/baseTexture */ "./Materials/Textures/baseTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_Extensions_engine_renderTarget__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Engines/Extensions/engine.renderTarget */ "./Engines/Extensions/engine.renderTarget.ts");
/* harmony import */ var _Shaders_rgbdEncode_fragment__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Shaders/rgbdEncode.fragment */ "./Shaders/rgbdEncode.fragment.ts");
/* harmony import */ var _Shaders_rgbdDecode_fragment__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Shaders/rgbdDecode.fragment */ "./Shaders/rgbdDecode.fragment.ts");













/**
 * Sets of helpers addressing the serialization and deserialization of environment texture
 * stored in a BabylonJS env file.
 * Those files are usually stored as .env files.
 */
var EnvironmentTextureTools = /** @class */ (function () {
    function EnvironmentTextureTools() {
    }
    /**
     * Gets the environment info from an env file.
     * @param data The array buffer containing the .env bytes.
     * @returns the environment file info (the json header) if successfully parsed.
     */
    EnvironmentTextureTools.GetEnvInfo = function (data) {
        var dataView = new DataView(data);
        var pos = 0;
        for (var i = 0; i < EnvironmentTextureTools._MagicBytes.length; i++) {
            if (dataView.getUint8(pos++) !== EnvironmentTextureTools._MagicBytes[i]) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Error('Not a babylon environment map');
                return null;
            }
        }
        // Read json manifest - collect characters up to null terminator
        var manifestString = '';
        var charCode = 0x00;
        while ((charCode = dataView.getUint8(pos++))) {
            manifestString += String.fromCharCode(charCode);
        }
        var manifest = JSON.parse(manifestString);
        if (manifest.specular) {
            // Extend the header with the position of the payload.
            manifest.specular.specularDataPosition = pos;
            // Fallback to 0.8 exactly if lodGenerationScale is not defined for backward compatibility.
            manifest.specular.lodGenerationScale = manifest.specular.lodGenerationScale || 0.8;
        }
        return manifest;
    };
    /**
     * Creates an environment texture from a loaded cube texture.
     * @param texture defines the cube texture to convert in env file
     * @return a promise containing the environment data if succesfull.
     */
    EnvironmentTextureTools.CreateEnvTextureAsync = function (texture) {
        var _this = this;
        var internalTexture = texture.getInternalTexture();
        if (!internalTexture) {
            return Promise.reject("The cube texture is invalid.");
        }
        if (!texture._prefiltered) {
            return Promise.reject("The cube texture is invalid (not prefiltered).");
        }
        var engine = internalTexture.getEngine();
        if (engine && engine.premultipliedAlpha) {
            return Promise.reject("Env texture can only be created when the engine is created with the premultipliedAlpha option set to false.");
        }
        if (texture.textureType === _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_INT) {
            return Promise.reject("The cube texture should allow HDR (Full Float or Half Float).");
        }
        var canvas = engine.getRenderingCanvas();
        if (!canvas) {
            return Promise.reject("Env texture can only be created when the engine is associated to a canvas.");
        }
        var textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_FLOAT;
        if (!engine.getCaps().textureFloatRender) {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_HALF_FLOAT;
            if (!engine.getCaps().textureHalfFloatRender) {
                return Promise.reject("Env texture can only be created when the browser supports half float or full float rendering.");
            }
        }
        var cubeWidth = internalTexture.width;
        var hostingScene = new _scene__WEBPACK_IMPORTED_MODULE_7__["Scene"](engine);
        var specularTextures = {};
        var promises = [];
        // Read and collect all mipmaps data from the cube.
        var mipmapsCount = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Log2(internalTexture.width);
        mipmapsCount = Math.round(mipmapsCount);
        var _loop_1 = function (i) {
            var faceWidth = Math.pow(2, mipmapsCount - i);
            var _loop_2 = function (face) {
                var data = texture.readPixels(face, i);
                // Creates a temp texture with the face data.
                var tempTexture = engine.createRawTexture(data, faceWidth, faceWidth, _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, null, textureType);
                // And rgbdEncode them.
                var promise = new Promise(function (resolve, reject) {
                    var rgbdPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_8__["PostProcess"]("rgbdEncode", "rgbdEncode", null, null, 1, null, _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, engine, false, undefined, _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_INT, undefined, null, false);
                    rgbdPostProcess.getEffect().executeWhenCompiled(function () {
                        rgbdPostProcess.onApply = function (effect) {
                            effect._bindTexture("textureSampler", tempTexture);
                        };
                        // As the process needs to happen on the main canvas, keep track of the current size
                        var currentW = engine.getRenderWidth();
                        var currentH = engine.getRenderHeight();
                        // Set the desired size for the texture
                        engine.setSize(faceWidth, faceWidth);
                        hostingScene.postProcessManager.directRender([rgbdPostProcess], null);
                        // Reading datas from WebGL
                        _tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].ToBlob(canvas, function (blob) {
                            var fileReader = new FileReader();
                            fileReader.onload = function (event) {
                                var arrayBuffer = event.target.result;
                                specularTextures[i * 6 + face] = arrayBuffer;
                                resolve();
                            };
                            fileReader.readAsArrayBuffer(blob);
                        });
                        // Reapply the previous canvas size
                        engine.setSize(currentW, currentH);
                    });
                });
                promises.push(promise);
            };
            // All faces of the cube.
            for (var face = 0; face < 6; face++) {
                _loop_2(face);
            }
        };
        for (var i = 0; i <= mipmapsCount; i++) {
            _loop_1(i);
        }
        // Once all the textures haves been collected as RGBD stored in PNGs
        return Promise.all(promises).then(function () {
            // We can delete the hosting scene keeping track of all the creation objects
            hostingScene.dispose();
            // Creates the json header for the env texture
            var info = {
                version: 1,
                width: cubeWidth,
                irradiance: _this._CreateEnvTextureIrradiance(texture),
                specular: {
                    mipmaps: [],
                    lodGenerationScale: texture.lodGenerationScale
                }
            };
            // Sets the specular image data information
            var position = 0;
            for (var i = 0; i <= mipmapsCount; i++) {
                for (var face = 0; face < 6; face++) {
                    var byteLength = specularTextures[i * 6 + face].byteLength;
                    info.specular.mipmaps.push({
                        length: byteLength,
                        position: position
                    });
                    position += byteLength;
                }
            }
            // Encode the JSON as an array buffer
            var infoString = JSON.stringify(info);
            var infoBuffer = new ArrayBuffer(infoString.length + 1);
            var infoView = new Uint8Array(infoBuffer); // Limited to ascii subset matching unicode.
            for (var i = 0, strLen = infoString.length; i < strLen; i++) {
                infoView[i] = infoString.charCodeAt(i);
            }
            // Ends up with a null terminator for easier parsing
            infoView[infoString.length] = 0x00;
            // Computes the final required size and creates the storage
            var totalSize = EnvironmentTextureTools._MagicBytes.length + position + infoBuffer.byteLength;
            var finalBuffer = new ArrayBuffer(totalSize);
            var finalBufferView = new Uint8Array(finalBuffer);
            var dataView = new DataView(finalBuffer);
            // Copy the magic bytes identifying the file in
            var pos = 0;
            for (var i = 0; i < EnvironmentTextureTools._MagicBytes.length; i++) {
                dataView.setUint8(pos++, EnvironmentTextureTools._MagicBytes[i]);
            }
            // Add the json info
            finalBufferView.set(new Uint8Array(infoBuffer), pos);
            pos += infoBuffer.byteLength;
            // Finally inserts the texture data
            for (var i = 0; i <= mipmapsCount; i++) {
                for (var face = 0; face < 6; face++) {
                    var dataBuffer = specularTextures[i * 6 + face];
                    finalBufferView.set(new Uint8Array(dataBuffer), pos);
                    pos += dataBuffer.byteLength;
                }
            }
            // Voila
            return finalBuffer;
        });
    };
    /**
     * Creates a JSON representation of the spherical data.
     * @param texture defines the texture containing the polynomials
     * @return the JSON representation of the spherical info
     */
    EnvironmentTextureTools._CreateEnvTextureIrradiance = function (texture) {
        var polynmials = texture.sphericalPolynomial;
        if (polynmials == null) {
            return null;
        }
        return {
            x: [polynmials.x.x, polynmials.x.y, polynmials.x.z],
            y: [polynmials.y.x, polynmials.y.y, polynmials.y.z],
            z: [polynmials.z.x, polynmials.z.y, polynmials.z.z],
            xx: [polynmials.xx.x, polynmials.xx.y, polynmials.xx.z],
            yy: [polynmials.yy.x, polynmials.yy.y, polynmials.yy.z],
            zz: [polynmials.zz.x, polynmials.zz.y, polynmials.zz.z],
            yz: [polynmials.yz.x, polynmials.yz.y, polynmials.yz.z],
            zx: [polynmials.zx.x, polynmials.zx.y, polynmials.zx.z],
            xy: [polynmials.xy.x, polynmials.xy.y, polynmials.xy.z]
        };
    };
    /**
     * Creates the ArrayBufferViews used for initializing environment texture image data.
     * @param arrayBuffer the underlying ArrayBuffer to which the views refer
     * @param info parameters that determine what views will be created for accessing the underlying buffer
     * @return the views described by info providing access to the underlying buffer
     */
    EnvironmentTextureTools.CreateImageDataArrayBufferViews = function (arrayBuffer, info) {
        if (info.version !== 1) {
            throw new Error("Unsupported babylon environment map version \"" + info.version + "\"");
        }
        var specularInfo = info.specular;
        // Double checks the enclosed info
        var mipmapsCount = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Log2(info.width);
        mipmapsCount = Math.round(mipmapsCount) + 1;
        if (specularInfo.mipmaps.length !== 6 * mipmapsCount) {
            throw new Error("Unsupported specular mipmaps number \"" + specularInfo.mipmaps.length + "\"");
        }
        var imageData = new Array(mipmapsCount);
        for (var i = 0; i < mipmapsCount; i++) {
            imageData[i] = new Array(6);
            for (var face = 0; face < 6; face++) {
                var imageInfo = specularInfo.mipmaps[i * 6 + face];
                imageData[i][face] = new Uint8Array(arrayBuffer, specularInfo.specularDataPosition + imageInfo.position, imageInfo.length);
            }
        }
        return imageData;
    };
    /**
     * Uploads the texture info contained in the env file to the GPU.
     * @param texture defines the internal texture to upload to
     * @param arrayBuffer defines the buffer cotaining the data to load
     * @param info defines the texture info retrieved through the GetEnvInfo method
     * @returns a promise
     */
    EnvironmentTextureTools.UploadEnvLevelsAsync = function (texture, arrayBuffer, info) {
        if (info.version !== 1) {
            throw new Error("Unsupported babylon environment map version \"" + info.version + "\"");
        }
        var specularInfo = info.specular;
        if (!specularInfo) {
            // Nothing else parsed so far
            return Promise.resolve();
        }
        texture._lodGenerationScale = specularInfo.lodGenerationScale;
        var imageData = EnvironmentTextureTools.CreateImageDataArrayBufferViews(arrayBuffer, info);
        return EnvironmentTextureTools.UploadLevelsAsync(texture, imageData);
    };
    /**
     * Uploads the levels of image data to the GPU.
     * @param texture defines the internal texture to upload to
     * @param imageData defines the array buffer views of image data [mipmap][face]
     * @returns a promise
     */
    EnvironmentTextureTools.UploadLevelsAsync = function (texture, imageData) {
        if (!_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].IsExponentOfTwo(texture.width)) {
            throw new Error("Texture size must be a power of two");
        }
        var mipmapsCount = Math.round(_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Log2(texture.width)) + 1;
        // Gets everything ready.
        var engine = texture.getEngine();
        var expandTexture = false;
        var generateNonLODTextures = false;
        var rgbdPostProcess = null;
        var cubeRtt = null;
        var lodTextures = null;
        var caps = engine.getCaps();
        texture.format = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA;
        texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        texture.generateMipMaps = true;
        engine.updateTextureSamplingMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE, texture);
        // Add extra process if texture lod is not supported
        if (!caps.textureLOD) {
            expandTexture = false;
            generateNonLODTextures = true;
            lodTextures = {};
        }
        // in webgl 1 there are no ways to either render or copy lod level information for float textures.
        else if (engine.webGLVersion < 2) {
            expandTexture = false;
        }
        // If half float available we can uncompress the texture
        else if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
            expandTexture = true;
            texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_HALF_FLOAT;
        }
        // If full float available we can uncompress the texture
        else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {
            expandTexture = true;
            texture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_FLOAT;
        }
        // Expand the texture if possible
        if (expandTexture) {
            // Simply run through the decode PP
            rgbdPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_8__["PostProcess"]("rgbdDecode", "rgbdDecode", null, null, 1, null, _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE, engine, false, undefined, texture.type, undefined, null, false);
            texture._isRGBD = false;
            texture.invertY = false;
            cubeRtt = engine.createRenderTargetCubeTexture(texture.width, {
                generateDepthBuffer: false,
                generateMipMaps: true,
                generateStencilBuffer: false,
                samplingMode: _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE,
                type: texture.type,
                format: _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA
            });
        }
        else {
            texture._isRGBD = true;
            texture.invertY = true;
            // In case of missing support, applies the same patch than DDS files.
            if (generateNonLODTextures) {
                var mipSlices = 3;
                var scale = texture._lodGenerationScale;
                var offset = texture._lodGenerationOffset;
                for (var i = 0; i < mipSlices; i++) {
                    //compute LOD from even spacing in smoothness (matching shader calculation)
                    var smoothness = i / (mipSlices - 1);
                    var roughness = 1 - smoothness;
                    var minLODIndex = offset; // roughness = 0
                    var maxLODIndex = (mipmapsCount - 1) * scale + offset; // roughness = 1 (mipmaps start from 0)
                    var lodIndex = minLODIndex + (maxLODIndex - minLODIndex) * roughness;
                    var mipmapIndex = Math.round(Math.min(Math.max(lodIndex, 0), maxLODIndex));
                    var glTextureFromLod = new _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"](engine, _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"].DATASOURCE_TEMP);
                    glTextureFromLod.isCube = true;
                    glTextureFromLod.invertY = true;
                    glTextureFromLod.generateMipMaps = false;
                    engine.updateTextureSamplingMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_LINEAR_LINEAR, glTextureFromLod);
                    // Wrap in a base texture for easy binding.
                    var lodTexture = new _Materials_Textures_baseTexture__WEBPACK_IMPORTED_MODULE_5__["BaseTexture"](null);
                    lodTexture.isCube = true;
                    lodTexture._texture = glTextureFromLod;
                    lodTextures[mipmapIndex] = lodTexture;
                    switch (i) {
                        case 0:
                            texture._lodTextureLow = lodTexture;
                            break;
                        case 1:
                            texture._lodTextureMid = lodTexture;
                            break;
                        case 2:
                            texture._lodTextureHigh = lodTexture;
                            break;
                    }
                }
            }
        }
        var promises = [];
        var _loop_3 = function (i) {
            var _loop_4 = function (face) {
                // Constructs an image element from image data
                var bytes = imageData[i][face];
                var blob = new Blob([bytes], { type: 'image/png' });
                var url = URL.createObjectURL(blob);
                var image = new Image();
                image.src = url;
                // Enqueue promise to upload to the texture.
                var promise = new Promise(function (resolve, reject) {
                    image.onload = function () {
                        if (expandTexture) {
                            var tempTexture_1 = engine.createTexture(null, true, true, null, _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, null, function (message) {
                                reject(message);
                            }, image);
                            rgbdPostProcess.getEffect().executeWhenCompiled(function () {
                                // Uncompress the data to a RTT
                                rgbdPostProcess.onApply = function (effect) {
                                    effect._bindTexture("textureSampler", tempTexture_1);
                                    effect.setFloat2("scale", 1, 1);
                                };
                                engine.scenes[0].postProcessManager.directRender([rgbdPostProcess], cubeRtt, true, face, i);
                                // Cleanup
                                engine.restoreDefaultFramebuffer();
                                tempTexture_1.dispose();
                                window.URL.revokeObjectURL(url);
                                resolve();
                            });
                        }
                        else {
                            engine._uploadImageToTexture(texture, image, face, i);
                            // Upload the face to the non lod texture support
                            if (generateNonLODTextures) {
                                var lodTexture = lodTextures[i];
                                if (lodTexture) {
                                    engine._uploadImageToTexture(lodTexture._texture, image, face, 0);
                                }
                            }
                            resolve();
                        }
                    };
                    image.onerror = function (error) {
                        reject(error);
                    };
                });
                promises.push(promise);
            };
            // All faces
            for (var face = 0; face < 6; face++) {
                _loop_4(face);
            }
        };
        // All mipmaps up to provided number of images
        for (var i = 0; i < imageData.length; i++) {
            _loop_3(i);
        }
        // Fill remaining mipmaps with black textures.
        if (imageData.length < mipmapsCount) {
            var data = void 0;
            var size = Math.pow(2, mipmapsCount - 1 - imageData.length);
            var dataLength = size * size * 4;
            switch (texture.type) {
                case _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_INT: {
                    data = new Uint8Array(dataLength);
                    break;
                }
                case _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_HALF_FLOAT: {
                    data = new Uint16Array(dataLength);
                    break;
                }
                case _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_FLOAT: {
                    data = new Float32Array(dataLength);
                    break;
                }
            }
            for (var i = imageData.length; i < mipmapsCount; i++) {
                for (var face = 0; face < 6; face++) {
                    engine._uploadArrayBufferViewToTexture(texture, data, face, i);
                }
            }
        }
        // Once all done, finishes the cleanup and return
        return Promise.all(promises).then(function () {
            // Release temp RTT.
            if (cubeRtt) {
                engine._releaseFramebufferObjects(cubeRtt);
                engine._releaseTexture(texture);
                cubeRtt._swapAndDie(texture);
            }
            // Release temp Post Process.
            if (rgbdPostProcess) {
                rgbdPostProcess.dispose();
            }
            // Flag internal texture as ready in case they are in use.
            if (generateNonLODTextures) {
                if (texture._lodTextureHigh && texture._lodTextureHigh._texture) {
                    texture._lodTextureHigh._texture.isReady = true;
                }
                if (texture._lodTextureMid && texture._lodTextureMid._texture) {
                    texture._lodTextureMid._texture.isReady = true;
                }
                if (texture._lodTextureLow && texture._lodTextureLow._texture) {
                    texture._lodTextureLow._texture.isReady = true;
                }
            }
        });
    };
    /**
     * Uploads spherical polynomials information to the texture.
     * @param texture defines the texture we are trying to upload the information to
     * @param info defines the environment texture info retrieved through the GetEnvInfo method
     */
    EnvironmentTextureTools.UploadEnvSpherical = function (texture, info) {
        if (info.version !== 1) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_9__["Logger"].Warn('Unsupported babylon environment map version "' + info.version + '"');
        }
        var irradianceInfo = info.irradiance;
        if (!irradianceInfo) {
            return;
        }
        var sp = new _Maths_sphericalPolynomial__WEBPACK_IMPORTED_MODULE_3__["SphericalPolynomial"]();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.x, 0, sp.x);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.y, 0, sp.y);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.z, 0, sp.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.xx, 0, sp.xx);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.yy, 0, sp.yy);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.zz, 0, sp.zz);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.yz, 0, sp.yz);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.zx, 0, sp.zx);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(irradianceInfo.xy, 0, sp.xy);
        texture._sphericalPolynomial = sp;
    };
    /** @hidden */
    EnvironmentTextureTools._UpdateRGBDAsync = function (internalTexture, data, sphericalPolynomial, lodScale, lodOffset) {
        internalTexture._dataSource = _Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"].DATASOURCE_CUBERAW_RGBD;
        internalTexture._bufferViewArrayArray = data;
        internalTexture._lodGenerationScale = lodScale;
        internalTexture._lodGenerationOffset = lodOffset;
        internalTexture._sphericalPolynomial = sphericalPolynomial;
        return EnvironmentTextureTools.UploadLevelsAsync(internalTexture, data).then(function () {
            internalTexture.isReady = true;
        });
    };
    /**
     * Magic number identifying the env file.
     */
    EnvironmentTextureTools._MagicBytes = [0x86, 0x16, 0x87, 0x96, 0xf6, 0xd6, 0x96, 0x36];
    return EnvironmentTextureTools;
}());

// References the dependencies.
_Materials_Textures_internalTexture__WEBPACK_IMPORTED_MODULE_4__["InternalTexture"]._UpdateRGBDAsync = EnvironmentTextureTools._UpdateRGBDAsync;


/***/ }),

/***/ "./Misc/fileTools.ts":
/*!***************************!*\
  !*** ./Misc/fileTools.ts ***!
  \***************************/
/*! exports provided: FileTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FileTools", function() { return FileTools; });
/* harmony import */ var _webRequest__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./webRequest */ "./Misc/webRequest.ts");
/* harmony import */ var _loadFileError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./loadFileError */ "./Misc/loadFileError.ts");
/* harmony import */ var _domManagement__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./domManagement */ "./Misc/domManagement.ts");
/* harmony import */ var _observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./observable */ "./Misc/observable.ts");
/* harmony import */ var _filesInputStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./filesInputStore */ "./Misc/filesInputStore.ts");
/* harmony import */ var _retryStrategy__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./retryStrategy */ "./Misc/retryStrategy.ts");






/**
 * @hidden
 */
var FileTools = /** @class */ (function () {
    function FileTools() {
    }
    /**
     * Removes unwanted characters from an url
     * @param url defines the url to clean
     * @returns the cleaned url
     */
    FileTools._CleanUrl = function (url) {
        url = url.replace(/#/mg, "%23");
        return url;
    };
    /**
     * Sets the cors behavior on a dom element. This will add the required Tools.CorsBehavior to the element.
     * @param url define the url we are trying
     * @param element define the dom element where to configure the cors policy
     */
    FileTools.SetCorsBehavior = function (url, element) {
        if (url && url.indexOf("data:") === 0) {
            return;
        }
        if (this.CorsBehavior) {
            if (typeof (this.CorsBehavior) === 'string' || this.CorsBehavior instanceof String) {
                element.crossOrigin = this.CorsBehavior;
            }
            else {
                var result = this.CorsBehavior(url);
                if (result) {
                    element.crossOrigin = result;
                }
            }
        }
    };
    /**
     * Loads an image as an HTMLImageElement.
     * @param input url string, ArrayBuffer, or Blob to load
     * @param onLoad callback called when the image successfully loads
     * @param onError callback called when the image fails to load
     * @param offlineProvider offline provider for caching
     * @returns the HTMLImageElement of the loaded image
     */
    FileTools.LoadImage = function (input, onLoad, onError, offlineProvider) {
        var url;
        var usingObjectURL = false;
        if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {
            url = URL.createObjectURL(new Blob([input]));
            usingObjectURL = true;
        }
        else if (input instanceof Blob) {
            url = URL.createObjectURL(input);
            usingObjectURL = true;
        }
        else {
            url = this._CleanUrl(input);
            url = this.PreprocessUrl(input);
        }
        var img = new Image();
        this.SetCorsBehavior(url, img);
        var loadHandler = function () {
            img.removeEventListener("load", loadHandler);
            img.removeEventListener("error", errorHandler);
            onLoad(img);
            // Must revoke the URL after calling onLoad to avoid security exceptions in
            // certain scenarios (e.g. when hosted in vscode).
            if (usingObjectURL && img.src) {
                URL.revokeObjectURL(img.src);
            }
        };
        var errorHandler = function (err) {
            img.removeEventListener("load", loadHandler);
            img.removeEventListener("error", errorHandler);
            if (onError) {
                onError("Error while trying to load image: " + input, err);
            }
            if (usingObjectURL && img.src) {
                URL.revokeObjectURL(img.src);
            }
        };
        img.addEventListener("load", loadHandler);
        img.addEventListener("error", errorHandler);
        var noOfflineSupport = function () {
            img.src = url;
        };
        var loadFromOfflineSupport = function () {
            if (offlineProvider) {
                offlineProvider.loadImage(url, img);
            }
        };
        if (url.substr(0, 5) !== "data:" && offlineProvider && offlineProvider.enableTexturesOffline) {
            offlineProvider.open(loadFromOfflineSupport, noOfflineSupport);
        }
        else {
            if (url.indexOf("file:") !== -1) {
                var textureName = decodeURIComponent(url.substring(5).toLowerCase());
                if (_filesInputStore__WEBPACK_IMPORTED_MODULE_4__["FilesInputStore"].FilesToLoad[textureName]) {
                    try {
                        var blobURL;
                        try {
                            blobURL = URL.createObjectURL(_filesInputStore__WEBPACK_IMPORTED_MODULE_4__["FilesInputStore"].FilesToLoad[textureName]);
                        }
                        catch (ex) {
                            // Chrome doesn't support oneTimeOnly parameter
                            blobURL = URL.createObjectURL(_filesInputStore__WEBPACK_IMPORTED_MODULE_4__["FilesInputStore"].FilesToLoad[textureName]);
                        }
                        img.src = blobURL;
                        usingObjectURL = true;
                    }
                    catch (e) {
                        img.src = "";
                    }
                    return img;
                }
            }
            noOfflineSupport();
        }
        return img;
    };
    /**
     * Loads a file
     * @param fileToLoad defines the file to load
     * @param callback defines the callback to call when data is loaded
     * @param progressCallBack defines the callback to call during loading process
     * @param useArrayBuffer defines a boolean indicating that data must be returned as an ArrayBuffer
     * @returns a file request object
     */
    FileTools.ReadFile = function (fileToLoad, callback, progressCallBack, useArrayBuffer) {
        var reader = new FileReader();
        var request = {
            onCompleteObservable: new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"](),
            abort: function () { return reader.abort(); },
        };
        reader.onloadend = function (e) { return request.onCompleteObservable.notifyObservers(request); };
        reader.onerror = function (e) {
            callback(JSON.stringify({ autoClear: true, clearColor: [1, 0, 0], ambientColor: [0, 0, 0], gravity: [0, -9.807, 0], meshes: [], cameras: [], lights: [] }));
        };
        reader.onload = function (e) {
            //target doesn't have result from ts 1.3
            callback(e.target['result']);
        };
        if (progressCallBack) {
            reader.onprogress = progressCallBack;
        }
        if (!useArrayBuffer) {
            // Asynchronous read
            reader.readAsText(fileToLoad);
        }
        else {
            reader.readAsArrayBuffer(fileToLoad);
        }
        return request;
    };
    /**
     * Loads a file
     * @param url url string, ArrayBuffer, or Blob to load
     * @param onSuccess callback called when the file successfully loads
     * @param onProgress callback called while file is loading (if the server supports this mode)
     * @param offlineProvider defines the offline provider for caching
     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer
     * @param onError callback called when the file fails to load
     * @returns a file request object
     */
    FileTools.LoadFile = function (url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError) {
        var _this = this;
        url = this._CleanUrl(url);
        url = this.PreprocessUrl(url);
        // If file and file input are set
        if (url.indexOf("file:") !== -1) {
            var fileName = decodeURIComponent(url.substring(5).toLowerCase());
            if (_filesInputStore__WEBPACK_IMPORTED_MODULE_4__["FilesInputStore"].FilesToLoad[fileName]) {
                return this.ReadFile(_filesInputStore__WEBPACK_IMPORTED_MODULE_4__["FilesInputStore"].FilesToLoad[fileName], onSuccess, onProgress, useArrayBuffer);
            }
        }
        var loadUrl = this.BaseUrl + url;
        var aborted = false;
        var fileRequest = {
            onCompleteObservable: new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"](),
            abort: function () { return aborted = true; },
        };
        var requestFile = function () {
            var request = new _webRequest__WEBPACK_IMPORTED_MODULE_0__["WebRequest"]();
            var retryHandle = null;
            fileRequest.abort = function () {
                aborted = true;
                if (request.readyState !== (XMLHttpRequest.DONE || 4)) {
                    request.abort();
                }
                if (retryHandle !== null) {
                    clearTimeout(retryHandle);
                    retryHandle = null;
                }
            };
            var retryLoop = function (retryIndex) {
                request.open('GET', loadUrl);
                if (useArrayBuffer) {
                    request.responseType = "arraybuffer";
                }
                if (onProgress) {
                    request.addEventListener("progress", onProgress);
                }
                var onLoadEnd = function () {
                    request.removeEventListener("loadend", onLoadEnd);
                    fileRequest.onCompleteObservable.notifyObservers(fileRequest);
                    fileRequest.onCompleteObservable.clear();
                };
                request.addEventListener("loadend", onLoadEnd);
                var onReadyStateChange = function () {
                    if (aborted) {
                        return;
                    }
                    // In case of undefined state in some browsers.
                    if (request.readyState === (XMLHttpRequest.DONE || 4)) {
                        // Some browsers have issues where onreadystatechange can be called multiple times with the same value.
                        request.removeEventListener("readystatechange", onReadyStateChange);
                        if ((request.status >= 200 && request.status < 300) || (request.status === 0 && (!_domManagement__WEBPACK_IMPORTED_MODULE_2__["DomManagement"].IsWindowObjectExist() || _this.IsFileURL()))) {
                            onSuccess(!useArrayBuffer ? request.responseText : request.response, request.responseURL);
                            return;
                        }
                        var retryStrategy = _this.DefaultRetryStrategy;
                        if (retryStrategy) {
                            var waitTime = retryStrategy(loadUrl, request, retryIndex);
                            if (waitTime !== -1) {
                                // Prevent the request from completing for retry.
                                request.removeEventListener("loadend", onLoadEnd);
                                request = new _webRequest__WEBPACK_IMPORTED_MODULE_0__["WebRequest"]();
                                retryHandle = setTimeout(function () { return retryLoop(retryIndex + 1); }, waitTime);
                                return;
                            }
                        }
                        var e = new _loadFileError__WEBPACK_IMPORTED_MODULE_1__["LoadFileError"]("Error status: " + request.status + " " + request.statusText + " - Unable to load " + loadUrl, request);
                        if (onError) {
                            onError(request, e);
                        }
                        else {
                            throw e;
                        }
                    }
                };
                request.addEventListener("readystatechange", onReadyStateChange);
                request.send();
            };
            retryLoop(0);
        };
        // Caching all files
        if (offlineProvider && offlineProvider.enableSceneOffline) {
            var noOfflineSupport_1 = function (request) {
                if (request && request.status > 400) {
                    if (onError) {
                        onError(request);
                    }
                }
                else {
                    if (!aborted) {
                        requestFile();
                    }
                }
            };
            var loadFromOfflineSupport = function () {
                // TODO: database needs to support aborting and should return a IFileRequest
                if (aborted) {
                    return;
                }
                if (offlineProvider) {
                    offlineProvider.loadFile(url, function (data) {
                        if (!aborted) {
                            onSuccess(data);
                        }
                        fileRequest.onCompleteObservable.notifyObservers(fileRequest);
                    }, onProgress ? function (event) {
                        if (!aborted) {
                            onProgress(event);
                        }
                    } : undefined, noOfflineSupport_1, useArrayBuffer);
                }
            };
            offlineProvider.open(loadFromOfflineSupport, noOfflineSupport_1);
        }
        else {
            requestFile();
        }
        return fileRequest;
    };
    /**
     * Checks if the loaded document was accessed via `file:`-Protocol.
     * @returns boolean
     */
    FileTools.IsFileURL = function () {
        return location.protocol === "file:";
    };
    /**
     * Gets or sets the retry strategy to apply when an error happens while loading an asset
     */
    FileTools.DefaultRetryStrategy = _retryStrategy__WEBPACK_IMPORTED_MODULE_5__["RetryStrategy"].ExponentialBackoff();
    /**
     * Gets or sets the base URL to use to load assets
     */
    FileTools.BaseUrl = "";
    /**
     * Default behaviour for cors in the application.
     * It can be a string if the expected behavior is identical in the entire app.
     * Or a callback to be able to set it per url or on a group of them (in case of Video source for instance)
     */
    FileTools.CorsBehavior = "anonymous";
    /**
     * Gets or sets a function used to pre-process url before using them to load assets
     */
    FileTools.PreprocessUrl = function (url) {
        return url;
    };
    return FileTools;
}());



/***/ }),

/***/ "./Misc/filesInput.ts":
/*!****************************!*\
  !*** ./Misc/filesInput.ts ***!
  \****************************/
/*! exports provided: FilesInput */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FilesInput", function() { return FilesInput; });
/* harmony import */ var _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Loading/sceneLoader */ "./Loading/sceneLoader.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _filesInputStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./filesInputStore */ "./Misc/filesInputStore.ts");



/**
 * Class used to help managing file picking and drag'n'drop
 */
var FilesInput = /** @class */ (function () {
    /**
     * Creates a new FilesInput
     * @param engine defines the rendering engine
     * @param scene defines the hosting scene
     * @param sceneLoadedCallback callback called when scene is loaded
     * @param progressCallback callback called to track progress
     * @param additionalRenderLoopLogicCallback callback called to add user logic to the rendering loop
     * @param textureLoadingCallback callback called when a texture is loading
     * @param startingProcessingFilesCallback callback called when the system is about to process all files
     * @param onReloadCallback callback called when a reload is requested
     * @param errorCallback callback call if an error occurs
     */
    function FilesInput(engine, scene, sceneLoadedCallback, progressCallback, additionalRenderLoopLogicCallback, textureLoadingCallback, startingProcessingFilesCallback, onReloadCallback, errorCallback) {
        /**
         * Callback called when a file is processed
         */
        this.onProcessFileCallback = function () { return true; };
        this._engine = engine;
        this._currentScene = scene;
        this._sceneLoadedCallback = sceneLoadedCallback;
        this._progressCallback = progressCallback;
        this._additionalRenderLoopLogicCallback = additionalRenderLoopLogicCallback;
        this._textureLoadingCallback = textureLoadingCallback;
        this._startingProcessingFilesCallback = startingProcessingFilesCallback;
        this._onReloadCallback = onReloadCallback;
        this._errorCallback = errorCallback;
    }
    Object.defineProperty(FilesInput, "FilesToLoad", {
        /**
         * List of files ready to be loaded
         */
        get: function () {
            return _filesInputStore__WEBPACK_IMPORTED_MODULE_2__["FilesInputStore"].FilesToLoad;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Calls this function to listen to drag'n'drop events on a specific DOM element
     * @param elementToMonitor defines the DOM element to track
     */
    FilesInput.prototype.monitorElementForDragNDrop = function (elementToMonitor) {
        var _this = this;
        if (elementToMonitor) {
            this._elementToMonitor = elementToMonitor;
            this._dragEnterHandler = function (e) { _this.drag(e); };
            this._dragOverHandler = function (e) { _this.drag(e); };
            this._dropHandler = function (e) { _this.drop(e); };
            this._elementToMonitor.addEventListener("dragenter", this._dragEnterHandler, false);
            this._elementToMonitor.addEventListener("dragover", this._dragOverHandler, false);
            this._elementToMonitor.addEventListener("drop", this._dropHandler, false);
        }
    };
    /**
     * Release all associated resources
     */
    FilesInput.prototype.dispose = function () {
        if (!this._elementToMonitor) {
            return;
        }
        this._elementToMonitor.removeEventListener("dragenter", this._dragEnterHandler);
        this._elementToMonitor.removeEventListener("dragover", this._dragOverHandler);
        this._elementToMonitor.removeEventListener("drop", this._dropHandler);
    };
    FilesInput.prototype.renderFunction = function () {
        if (this._additionalRenderLoopLogicCallback) {
            this._additionalRenderLoopLogicCallback();
        }
        if (this._currentScene) {
            if (this._textureLoadingCallback) {
                var remaining = this._currentScene.getWaitingItemsCount();
                if (remaining > 0) {
                    this._textureLoadingCallback(remaining);
                }
            }
            this._currentScene.render();
        }
    };
    FilesInput.prototype.drag = function (e) {
        e.stopPropagation();
        e.preventDefault();
    };
    FilesInput.prototype.drop = function (eventDrop) {
        eventDrop.stopPropagation();
        eventDrop.preventDefault();
        this.loadFiles(eventDrop);
    };
    FilesInput.prototype._traverseFolder = function (folder, files, remaining, callback) {
        var _this = this;
        var reader = folder.createReader();
        var relativePath = folder.fullPath.replace(/^\//, "").replace(/(.+?)\/?$/, "$1/");
        reader.readEntries(function (entries) {
            remaining.count += entries.length;
            for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
                var entry = entries_1[_i];
                if (entry.isFile) {
                    entry.file(function (file) {
                        file.correctName = relativePath + file.name;
                        files.push(file);
                        if (--remaining.count === 0) {
                            callback();
                        }
                    });
                }
                else if (entry.isDirectory) {
                    _this._traverseFolder(entry, files, remaining, callback);
                }
            }
            if (--remaining.count) {
                callback();
            }
        });
    };
    FilesInput.prototype._processFiles = function (files) {
        for (var i = 0; i < files.length; i++) {
            var name = files[i].correctName.toLowerCase();
            var extension = name.split('.').pop();
            if (!this.onProcessFileCallback(files[i], name, extension)) {
                continue;
            }
            if ((extension === "babylon" || extension === "stl" || extension === "obj" || extension === "gltf" || extension === "glb")
                && name.indexOf(".binary.babylon") === -1 && name.indexOf(".incremental.babylon") === -1) {
                this._sceneFileToLoad = files[i];
            }
            FilesInput.FilesToLoad[name] = files[i];
        }
    };
    /**
     * Load files from a drop event
     * @param event defines the drop event to use as source
     */
    FilesInput.prototype.loadFiles = function (event) {
        var _this = this;
        // Handling data transfer via drag'n'drop
        if (event && event.dataTransfer && event.dataTransfer.files) {
            this._filesToLoad = event.dataTransfer.files;
        }
        // Handling files from input files
        if (event && event.target && event.target.files) {
            this._filesToLoad = event.target.files;
        }
        if (!this._filesToLoad || this._filesToLoad.length === 0) {
            return;
        }
        if (this._startingProcessingFilesCallback) {
            this._startingProcessingFilesCallback(this._filesToLoad);
        }
        if (this._filesToLoad && this._filesToLoad.length > 0) {
            var files_1 = new Array();
            var folders = [];
            var items = event.dataTransfer ? event.dataTransfer.items : null;
            for (var i = 0; i < this._filesToLoad.length; i++) {
                var fileToLoad = this._filesToLoad[i];
                var name_1 = fileToLoad.name.toLowerCase();
                var entry = void 0;
                fileToLoad.correctName = name_1;
                if (items) {
                    var item = items[i];
                    if (item.getAsEntry) {
                        entry = item.getAsEntry();
                    }
                    else if (item.webkitGetAsEntry) {
                        entry = item.webkitGetAsEntry();
                    }
                }
                if (!entry) {
                    files_1.push(fileToLoad);
                }
                else {
                    if (entry.isDirectory) {
                        folders.push(entry);
                    }
                    else {
                        files_1.push(fileToLoad);
                    }
                }
            }
            if (folders.length === 0) {
                this._processFiles(files_1);
                this._processReload();
            }
            else {
                var remaining = { count: folders.length };
                for (var _i = 0, folders_1 = folders; _i < folders_1.length; _i++) {
                    var folder = folders_1[_i];
                    this._traverseFolder(folder, files_1, remaining, function () {
                        _this._processFiles(files_1);
                        if (remaining.count === 0) {
                            _this._processReload();
                        }
                    });
                }
            }
        }
    };
    FilesInput.prototype._processReload = function () {
        if (this._onReloadCallback) {
            this._onReloadCallback(this._sceneFileToLoad);
        }
        else {
            this.reload();
        }
    };
    /**
     * Reload the current scene from the loaded files
     */
    FilesInput.prototype.reload = function () {
        var _this = this;
        // If a scene file has been provided
        if (this._sceneFileToLoad) {
            if (this._currentScene) {
                if (_Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].errorsCount > 0) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].ClearLogCache();
                }
                this._engine.stopRenderLoop();
            }
            _Loading_sceneLoader__WEBPACK_IMPORTED_MODULE_0__["SceneLoader"].LoadAsync("file:", this._sceneFileToLoad, this._engine, function (progress) {
                if (_this._progressCallback) {
                    _this._progressCallback(progress);
                }
            }).then(function (scene) {
                if (_this._currentScene) {
                    _this._currentScene.dispose();
                }
                _this._currentScene = scene;
                if (_this._sceneLoadedCallback) {
                    _this._sceneLoadedCallback(_this._sceneFileToLoad, _this._currentScene);
                }
                // Wait for textures and shaders to be ready
                _this._currentScene.executeWhenReady(function () {
                    _this._engine.runRenderLoop(function () {
                        _this.renderFunction();
                    });
                });
            }).catch(function (error) {
                if (_this._errorCallback) {
                    _this._errorCallback(_this._sceneFileToLoad, _this._currentScene, error.message);
                }
            });
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Please provide a valid .babylon file.");
        }
    };
    return FilesInput;
}());



/***/ }),

/***/ "./Misc/filesInputStore.ts":
/*!*********************************!*\
  !*** ./Misc/filesInputStore.ts ***!
  \*********************************/
/*! exports provided: FilesInputStore */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FilesInputStore", function() { return FilesInputStore; });
/**
 * Class used to help managing file picking and drag'n'drop
 * File Storage
 */
var FilesInputStore = /** @class */ (function () {
    function FilesInputStore() {
    }
    /**
     * List of files ready to be loaded
     */
    FilesInputStore.FilesToLoad = {};
    return FilesInputStore;
}());



/***/ }),

/***/ "./Misc/gradients.ts":
/*!***************************!*\
  !*** ./Misc/gradients.ts ***!
  \***************************/
/*! exports provided: ColorGradient, Color3Gradient, FactorGradient, GradientHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorGradient", function() { return ColorGradient; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Color3Gradient", function() { return Color3Gradient; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FactorGradient", function() { return FactorGradient; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GradientHelper", function() { return GradientHelper; });
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");

/** Class used to store color4 gradient */
var ColorGradient = /** @class */ (function () {
    function ColorGradient() {
    }
    /**
     * Will get a color picked randomly between color1 and color2.
     * If color2 is undefined then color1 will be used
     * @param result defines the target Color4 to store the result in
     */
    ColorGradient.prototype.getColorToRef = function (result) {
        if (!this.color2) {
            result.copyFrom(this.color1);
            return;
        }
        _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__["Color4"].LerpToRef(this.color1, this.color2, Math.random(), result);
    };
    return ColorGradient;
}());

/** Class used to store color 3 gradient */
var Color3Gradient = /** @class */ (function () {
    function Color3Gradient() {
    }
    return Color3Gradient;
}());

/** Class used to store factor gradient */
var FactorGradient = /** @class */ (function () {
    function FactorGradient() {
    }
    /**
     * Will get a number picked randomly between factor1 and factor2.
     * If factor2 is undefined then factor1 will be used
     * @returns the picked number
     */
    FactorGradient.prototype.getFactor = function () {
        if (this.factor2 === undefined) {
            return this.factor1;
        }
        return this.factor1 + ((this.factor2 - this.factor1) * Math.random());
    };
    return FactorGradient;
}());

/**
 * Helper used to simplify some generic gradient tasks
 */
var GradientHelper = /** @class */ (function () {
    function GradientHelper() {
    }
    /**
     * Gets the current gradient from an array of IValueGradient
     * @param ratio defines the current ratio to get
     * @param gradients defines the array of IValueGradient
     * @param updateFunc defines the callback function used to get the final value from the selected gradients
     */
    GradientHelper.GetCurrentGradient = function (ratio, gradients, updateFunc) {
        for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
            var currentGradient = gradients[gradientIndex];
            var nextGradient = gradients[gradientIndex + 1];
            if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
                var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
                updateFunc(currentGradient, nextGradient, scale);
                return;
            }
        }
        // Use last index if over
        var lastIndex = gradients.length - 1;
        updateFunc(gradients[lastIndex], gradients[lastIndex], 1.0);
    };
    return GradientHelper;
}());



/***/ }),

/***/ "./Misc/guid.ts":
/*!**********************!*\
  !*** ./Misc/guid.ts ***!
  \**********************/
/*! exports provided: GUID */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GUID", function() { return GUID; });
/**
 * Class used to manipulate GUIDs
 */
var GUID = /** @class */ (function () {
    function GUID() {
    }
    /**
     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
     * Be aware Math.random() could cause collisions, but:
     * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
     * @returns a pseudo random id
     */
    GUID.RandomId = function () {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    };
    return GUID;
}());



/***/ }),

/***/ "./Misc/iInspectable.ts":
/*!******************************!*\
  !*** ./Misc/iInspectable.ts ***!
  \******************************/
/*! exports provided: InspectableType */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InspectableType", function() { return InspectableType; });
/**
 * Enum that determines the text-wrapping mode to use.
 */
var InspectableType;
(function (InspectableType) {
    /**
     * Checkbox for booleans
     */
    InspectableType[InspectableType["Checkbox"] = 0] = "Checkbox";
    /**
     * Sliders for numbers
     */
    InspectableType[InspectableType["Slider"] = 1] = "Slider";
    /**
     * Vector3
     */
    InspectableType[InspectableType["Vector3"] = 2] = "Vector3";
    /**
     * Quaternions
     */
    InspectableType[InspectableType["Quaternion"] = 3] = "Quaternion";
    /**
     * Color3
     */
    InspectableType[InspectableType["Color3"] = 4] = "Color3";
    /**
     * String
     */
    InspectableType[InspectableType["String"] = 5] = "String";
})(InspectableType || (InspectableType = {}));


/***/ }),

/***/ "./Misc/index.ts":
/*!***********************!*\
  !*** ./Misc/index.ts ***!
  \***********************/
/*! exports provided: AndOrNotEvaluator, AssetTaskState, AbstractAssetTask, AssetsProgressEvent, MeshAssetTask, TextFileAssetTask, BinaryFileAssetTask, ImageAssetTask, TextureAssetTask, CubeTextureAssetTask, HDRCubeTextureAssetTask, EquiRectangularCubeTextureAssetTask, AssetsManager, DDSTools, expandToProperty, serialize, serializeAsTexture, serializeAsColor3, serializeAsFresnelParameters, serializeAsVector2, serializeAsVector3, serializeAsMeshReference, serializeAsColorCurves, serializeAsColor4, serializeAsImageProcessingConfiguration, serializeAsQuaternion, serializeAsMatrix, serializeAsCameraReference, SerializationHelper, Deferred, EnvironmentTextureTools, MeshExploder, FilesInput, CubeMapToSphericalPolynomialTools, KhronosTextureContainer, EventState, Observer, MultiObserver, Observable, PerformanceMonitor, RollingAverage, PromisePolyfill, SceneOptimization, TextureOptimization, HardwareScalingOptimization, ShadowsOptimization, PostProcessesOptimization, LensFlaresOptimization, CustomOptimization, ParticlesOptimization, RenderTargetsOptimization, MergeMeshesOptimization, SceneOptimizerOptions, SceneOptimizer, SceneSerializer, SmartArray, SmartArrayNoDuplicate, StringDictionary, Tags, TextureTools, TGATools, Tools, className, AsyncLoop, VideoRecorder, JoystickAxis, VirtualJoystick, WorkerPool, Logger, _TypeStore, FilesInputStore, DeepCopier, PivotTools, PrecisionDate, ScreenshotTools, WebRequest, InspectableType, BRDFTextureTools, RGBDTextureTools, ColorGradient, Color3Gradient, FactorGradient, GradientHelper, PerfCounter, RetryStrategy, LoadFileError, HDRTools, PanoramaToCubeMapTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _andOrNotEvaluator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./andOrNotEvaluator */ "./Misc/andOrNotEvaluator.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AndOrNotEvaluator", function() { return _andOrNotEvaluator__WEBPACK_IMPORTED_MODULE_0__["AndOrNotEvaluator"]; });

/* harmony import */ var _assetsManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./assetsManager */ "./Misc/assetsManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetTaskState", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["AssetTaskState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["AbstractAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetsProgressEvent", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["AssetsProgressEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["MeshAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextFileAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["TextFileAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BinaryFileAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["BinaryFileAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["ImageAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["TextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTextureAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["CubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTextureAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["HDRCubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTextureAssetTask", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["EquiRectangularCubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetsManager", function() { return _assetsManager__WEBPACK_IMPORTED_MODULE_1__["AssetsManager"]; });

/* harmony import */ var _dds__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dds */ "./Misc/dds.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DDSTools", function() { return _dds__WEBPACK_IMPORTED_MODULE_2__["DDSTools"]; });

/* harmony import */ var _decorators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./decorators */ "./Misc/decorators.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expandToProperty", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["expandToProperty"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serialize", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serialize"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsTexture", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor3", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsColor3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsFresnelParameters", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsFresnelParameters"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector2", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsVector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector3", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsVector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsMeshReference", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsMeshReference"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColorCurves", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsColorCurves"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor4", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsColor4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsImageProcessingConfiguration", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsImageProcessingConfiguration"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsQuaternion", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsQuaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsMatrix", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsMatrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsCameraReference", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["serializeAsCameraReference"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SerializationHelper", function() { return _decorators__WEBPACK_IMPORTED_MODULE_3__["SerializationHelper"]; });

/* harmony import */ var _deferred__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./deferred */ "./Misc/deferred.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Deferred", function() { return _deferred__WEBPACK_IMPORTED_MODULE_4__["Deferred"]; });

/* harmony import */ var _environmentTextureTools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./environmentTextureTools */ "./Misc/environmentTextureTools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EnvironmentTextureTools", function() { return _environmentTextureTools__WEBPACK_IMPORTED_MODULE_5__["EnvironmentTextureTools"]; });

/* harmony import */ var _meshExploder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./meshExploder */ "./Misc/meshExploder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshExploder", function() { return _meshExploder__WEBPACK_IMPORTED_MODULE_6__["MeshExploder"]; });

/* harmony import */ var _filesInput__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./filesInput */ "./Misc/filesInput.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilesInput", function() { return _filesInput__WEBPACK_IMPORTED_MODULE_7__["FilesInput"]; });

/* harmony import */ var _HighDynamicRange_index__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./HighDynamicRange/index */ "./Misc/HighDynamicRange/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeMapToSphericalPolynomialTools", function() { return _HighDynamicRange_index__WEBPACK_IMPORTED_MODULE_8__["CubeMapToSphericalPolynomialTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRTools", function() { return _HighDynamicRange_index__WEBPACK_IMPORTED_MODULE_8__["HDRTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PanoramaToCubeMapTools", function() { return _HighDynamicRange_index__WEBPACK_IMPORTED_MODULE_8__["PanoramaToCubeMapTools"]; });

/* harmony import */ var _khronosTextureContainer__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./khronosTextureContainer */ "./Misc/khronosTextureContainer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KhronosTextureContainer", function() { return _khronosTextureContainer__WEBPACK_IMPORTED_MODULE_9__["KhronosTextureContainer"]; });

/* harmony import */ var _observable__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./observable */ "./Misc/observable.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EventState", function() { return _observable__WEBPACK_IMPORTED_MODULE_10__["EventState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observer", function() { return _observable__WEBPACK_IMPORTED_MODULE_10__["Observer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiObserver", function() { return _observable__WEBPACK_IMPORTED_MODULE_10__["MultiObserver"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return _observable__WEBPACK_IMPORTED_MODULE_10__["Observable"]; });

/* harmony import */ var _performanceMonitor__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./performanceMonitor */ "./Misc/performanceMonitor.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerformanceMonitor", function() { return _performanceMonitor__WEBPACK_IMPORTED_MODULE_11__["PerformanceMonitor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RollingAverage", function() { return _performanceMonitor__WEBPACK_IMPORTED_MODULE_11__["RollingAverage"]; });

/* harmony import */ var _promise__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./promise */ "./Misc/promise.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PromisePolyfill", function() { return _promise__WEBPACK_IMPORTED_MODULE_12__["PromisePolyfill"]; });

/* harmony import */ var _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./sceneOptimizer */ "./Misc/sceneOptimizer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["SceneOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["TextureOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HardwareScalingOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["HardwareScalingOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowsOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["ShadowsOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessesOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["PostProcessesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlaresOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["LensFlaresOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["CustomOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticlesOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["ParticlesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetsOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["RenderTargetsOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MergeMeshesOptimization", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["MergeMeshesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizerOptions", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["SceneOptimizerOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizer", function() { return _sceneOptimizer__WEBPACK_IMPORTED_MODULE_13__["SceneOptimizer"]; });

/* harmony import */ var _sceneSerializer__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./sceneSerializer */ "./Misc/sceneSerializer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneSerializer", function() { return _sceneSerializer__WEBPACK_IMPORTED_MODULE_14__["SceneSerializer"]; });

/* harmony import */ var _smartArray__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./smartArray */ "./Misc/smartArray.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SmartArray", function() { return _smartArray__WEBPACK_IMPORTED_MODULE_15__["SmartArray"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SmartArrayNoDuplicate", function() { return _smartArray__WEBPACK_IMPORTED_MODULE_15__["SmartArrayNoDuplicate"]; });

/* harmony import */ var _stringDictionary__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./stringDictionary */ "./Misc/stringDictionary.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StringDictionary", function() { return _stringDictionary__WEBPACK_IMPORTED_MODULE_16__["StringDictionary"]; });

/* harmony import */ var _tags__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./tags */ "./Misc/tags.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Tags", function() { return _tags__WEBPACK_IMPORTED_MODULE_17__["Tags"]; });

/* harmony import */ var _textureTools__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./textureTools */ "./Misc/textureTools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureTools", function() { return _textureTools__WEBPACK_IMPORTED_MODULE_18__["TextureTools"]; });

/* harmony import */ var _tga__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./tga */ "./Misc/tga.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TGATools", function() { return _tga__WEBPACK_IMPORTED_MODULE_19__["TGATools"]; });

/* harmony import */ var _tools__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./tools */ "./Misc/tools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Tools", function() { return _tools__WEBPACK_IMPORTED_MODULE_20__["Tools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "className", function() { return _tools__WEBPACK_IMPORTED_MODULE_20__["className"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AsyncLoop", function() { return _tools__WEBPACK_IMPORTED_MODULE_20__["AsyncLoop"]; });

/* harmony import */ var _videoRecorder__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./videoRecorder */ "./Misc/videoRecorder.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoRecorder", function() { return _videoRecorder__WEBPACK_IMPORTED_MODULE_21__["VideoRecorder"]; });

/* harmony import */ var _virtualJoystick__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./virtualJoystick */ "./Misc/virtualJoystick.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "JoystickAxis", function() { return _virtualJoystick__WEBPACK_IMPORTED_MODULE_22__["JoystickAxis"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualJoystick", function() { return _virtualJoystick__WEBPACK_IMPORTED_MODULE_22__["VirtualJoystick"]; });

/* harmony import */ var _workerPool__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./workerPool */ "./Misc/workerPool.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WorkerPool", function() { return _workerPool__WEBPACK_IMPORTED_MODULE_23__["WorkerPool"]; });

/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./logger */ "./Misc/logger.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Logger", function() { return _logger__WEBPACK_IMPORTED_MODULE_24__["Logger"]; });

/* harmony import */ var _typeStore__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./typeStore */ "./Misc/typeStore.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TypeStore", function() { return _typeStore__WEBPACK_IMPORTED_MODULE_25__["_TypeStore"]; });

/* harmony import */ var _filesInputStore__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./filesInputStore */ "./Misc/filesInputStore.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilesInputStore", function() { return _filesInputStore__WEBPACK_IMPORTED_MODULE_26__["FilesInputStore"]; });

/* harmony import */ var _deepCopier__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./deepCopier */ "./Misc/deepCopier.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DeepCopier", function() { return _deepCopier__WEBPACK_IMPORTED_MODULE_27__["DeepCopier"]; });

/* harmony import */ var _pivotTools__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./pivotTools */ "./Misc/pivotTools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PivotTools", function() { return _pivotTools__WEBPACK_IMPORTED_MODULE_28__["PivotTools"]; });

/* harmony import */ var _precisionDate__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./precisionDate */ "./Misc/precisionDate.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PrecisionDate", function() { return _precisionDate__WEBPACK_IMPORTED_MODULE_29__["PrecisionDate"]; });

/* harmony import */ var _screenshotTools__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./screenshotTools */ "./Misc/screenshotTools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScreenshotTools", function() { return _screenshotTools__WEBPACK_IMPORTED_MODULE_30__["ScreenshotTools"]; });

/* empty/unused harmony star reexport *//* harmony import */ var _webRequest__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./webRequest */ "./Misc/webRequest.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebRequest", function() { return _webRequest__WEBPACK_IMPORTED_MODULE_31__["WebRequest"]; });

/* harmony import */ var _iInspectable__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./iInspectable */ "./Misc/iInspectable.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InspectableType", function() { return _iInspectable__WEBPACK_IMPORTED_MODULE_32__["InspectableType"]; });

/* harmony import */ var _brdfTextureTools__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./brdfTextureTools */ "./Misc/brdfTextureTools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BRDFTextureTools", function() { return _brdfTextureTools__WEBPACK_IMPORTED_MODULE_33__["BRDFTextureTools"]; });

/* harmony import */ var _rgbdTextureTools__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./rgbdTextureTools */ "./Misc/rgbdTextureTools.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RGBDTextureTools", function() { return _rgbdTextureTools__WEBPACK_IMPORTED_MODULE_34__["RGBDTextureTools"]; });

/* harmony import */ var _gradients__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./gradients */ "./Misc/gradients.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradient", function() { return _gradients__WEBPACK_IMPORTED_MODULE_35__["ColorGradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3Gradient", function() { return _gradients__WEBPACK_IMPORTED_MODULE_35__["Color3Gradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FactorGradient", function() { return _gradients__WEBPACK_IMPORTED_MODULE_35__["FactorGradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GradientHelper", function() { return _gradients__WEBPACK_IMPORTED_MODULE_35__["GradientHelper"]; });

/* harmony import */ var _perfCounter__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./perfCounter */ "./Misc/perfCounter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerfCounter", function() { return _perfCounter__WEBPACK_IMPORTED_MODULE_36__["PerfCounter"]; });

/* harmony import */ var _retryStrategy__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./retryStrategy */ "./Misc/retryStrategy.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RetryStrategy", function() { return _retryStrategy__WEBPACK_IMPORTED_MODULE_37__["RetryStrategy"]; });

/* harmony import */ var _loadFileError__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(/*! ./loadFileError */ "./Misc/loadFileError.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LoadFileError", function() { return _loadFileError__WEBPACK_IMPORTED_MODULE_38__["LoadFileError"]; });











































/***/ }),

/***/ "./Misc/instantiationTools.ts":
/*!************************************!*\
  !*** ./Misc/instantiationTools.ts ***!
  \************************************/
/*! exports provided: InstantiationTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InstantiationTools", function() { return InstantiationTools; });
/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./Misc/logger.ts");
/* harmony import */ var _typeStore__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./typeStore */ "./Misc/typeStore.ts");


/**
 * Class used to enable instatition of objects by class name
 */
var InstantiationTools = /** @class */ (function () {
    function InstantiationTools() {
    }
    /**
     * Tries to instantiate a new object from a given class name
     * @param className defines the class name to instantiate
     * @returns the new object or null if the system was not able to do the instantiation
     */
    InstantiationTools.Instantiate = function (className) {
        if (this.RegisteredExternalClasses && this.RegisteredExternalClasses[className]) {
            return this.RegisteredExternalClasses[className];
        }
        var internalClass = _typeStore__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].GetClass(className);
        if (internalClass) {
            return internalClass;
        }
        _logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(className + " not found, you may have missed an import.");
        var arr = className.split(".");
        var fn = (window || this);
        for (var i = 0, len = arr.length; i < len; i++) {
            fn = fn[arr[i]];
        }
        if (typeof fn !== "function") {
            return null;
        }
        return fn;
    };
    /**
     * Use this object to register external classes like custom textures or material
     * to allow the laoders to instantiate them
     */
    InstantiationTools.RegisteredExternalClasses = {};
    return InstantiationTools;
}());



/***/ }),

/***/ "./Misc/khronosTextureContainer.ts":
/*!*****************************************!*\
  !*** ./Misc/khronosTextureContainer.ts ***!
  \*****************************************/
/*! exports provided: KhronosTextureContainer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KhronosTextureContainer", function() { return KhronosTextureContainer; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");

/**
 * for description see https://www.khronos.org/opengles/sdk/tools/KTX/
 * for file layout see https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
 */
var KhronosTextureContainer = /** @class */ (function () {
    /**
     * Creates a new KhronosTextureContainer
     * @param arrayBuffer contents of the KTX container file
     * @param facesExpected should be either 1 or 6, based whether a cube texture or or
     * @param threeDExpected provision for indicating that data should be a 3D texture, not implemented
     * @param textureArrayExpected provision for indicating that data should be a texture array, not implemented
     */
    function KhronosTextureContainer(
    /** contents of the KTX container file */
    arrayBuffer, facesExpected, threeDExpected, textureArrayExpected) {
        this.arrayBuffer = arrayBuffer;
        /**
         * If the container has been made invalid (eg. constructor failed to correctly load array buffer)
         */
        this.isInvalid = false;
        // Test that it is a ktx formatted file, based on the first 12 bytes, character representation is:
        // '�', 'K', 'T', 'X', ' ', '1', '1', '�', '\r', '\n', '\x1A', '\n'
        // 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
        var identifier = new Uint8Array(this.arrayBuffer, 0, 12);
        if (identifier[0] !== 0xAB || identifier[1] !== 0x4B || identifier[2] !== 0x54 || identifier[3] !== 0x58 || identifier[4] !== 0x20 || identifier[5] !== 0x31 ||
            identifier[6] !== 0x31 || identifier[7] !== 0xBB || identifier[8] !== 0x0D || identifier[9] !== 0x0A || identifier[10] !== 0x1A || identifier[11] !== 0x0A) {
            this.isInvalid = true;
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("texture missing KTX identifier");
            return;
        }
        // load the reset of the header in native 32 bit uint
        var dataSize = Uint32Array.BYTES_PER_ELEMENT;
        var headerDataView = new DataView(this.arrayBuffer, 12, 13 * dataSize);
        var endianness = headerDataView.getUint32(0, true);
        var littleEndian = endianness === 0x04030201;
        this.glType = headerDataView.getUint32(1 * dataSize, littleEndian); // must be 0 for compressed textures
        this.glTypeSize = headerDataView.getUint32(2 * dataSize, littleEndian); // must be 1 for compressed textures
        this.glFormat = headerDataView.getUint32(3 * dataSize, littleEndian); // must be 0 for compressed textures
        this.glInternalFormat = headerDataView.getUint32(4 * dataSize, littleEndian); // the value of arg passed to gl.compressedTexImage2D(,,x,,,,)
        this.glBaseInternalFormat = headerDataView.getUint32(5 * dataSize, littleEndian); // specify GL_RGB, GL_RGBA, GL_ALPHA, etc (un-compressed only)
        this.pixelWidth = headerDataView.getUint32(6 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage2D(,,,x,,,)
        this.pixelHeight = headerDataView.getUint32(7 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage2D(,,,,x,,)
        this.pixelDepth = headerDataView.getUint32(8 * dataSize, littleEndian); // level 0 value of arg passed to gl.compressedTexImage3D(,,,,,x,,)
        this.numberOfArrayElements = headerDataView.getUint32(9 * dataSize, littleEndian); // used for texture arrays
        this.numberOfFaces = headerDataView.getUint32(10 * dataSize, littleEndian); // used for cubemap textures, should either be 1 or 6
        this.numberOfMipmapLevels = headerDataView.getUint32(11 * dataSize, littleEndian); // number of levels; disregard possibility of 0 for compressed textures
        this.bytesOfKeyValueData = headerDataView.getUint32(12 * dataSize, littleEndian); // the amount of space after the header for meta-data
        // Make sure we have a compressed type.  Not only reduces work, but probably better to let dev know they are not compressing.
        if (this.glType !== 0) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("only compressed formats currently supported");
            return;
        }
        else {
            // value of zero is an indication to generate mipmaps @ runtime.  Not usually allowed for compressed, so disregard.
            this.numberOfMipmapLevels = Math.max(1, this.numberOfMipmapLevels);
        }
        if (this.pixelHeight === 0 || this.pixelDepth !== 0) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("only 2D textures currently supported");
            return;
        }
        if (this.numberOfArrayElements !== 0) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("texture arrays not currently supported");
            return;
        }
        if (this.numberOfFaces !== facesExpected) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("number of faces expected" + facesExpected + ", but found " + this.numberOfFaces);
            return;
        }
        // we now have a completely validated file, so could use existence of loadType as success
        // would need to make this more elaborate & adjust checks above to support more than one load type
        this.loadType = KhronosTextureContainer.COMPRESSED_2D;
    }
    /**
     * Uploads KTX content to a Babylon Texture.
     * It is assumed that the texture has already been created & is currently bound
     * @hidden
     */
    KhronosTextureContainer.prototype.uploadLevels = function (texture, loadMipmaps) {
        switch (this.loadType) {
            case KhronosTextureContainer.COMPRESSED_2D:
                this._upload2DCompressedLevels(texture, loadMipmaps);
                break;
            case KhronosTextureContainer.TEX_2D:
            case KhronosTextureContainer.COMPRESSED_3D:
            case KhronosTextureContainer.TEX_3D:
        }
    };
    KhronosTextureContainer.prototype._upload2DCompressedLevels = function (texture, loadMipmaps) {
        // initialize width & height for level 1
        var dataOffset = KhronosTextureContainer.HEADER_LEN + this.bytesOfKeyValueData;
        var width = this.pixelWidth;
        var height = this.pixelHeight;
        var mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;
        for (var level = 0; level < mipmapCount; level++) {
            var imageSize = new Int32Array(this.arrayBuffer, dataOffset, 1)[0]; // size per face, since not supporting array cubemaps
            dataOffset += 4; //image data starts from next multiple of 4 offset. Each face refers to same imagesize field above.
            for (var face = 0; face < this.numberOfFaces; face++) {
                var byteArray = new Uint8Array(this.arrayBuffer, dataOffset, imageSize);
                var engine = texture.getEngine();
                engine._uploadCompressedDataToTextureDirectly(texture, this.glInternalFormat, width, height, byteArray, face, level);
                dataOffset += imageSize; // add size of the image for the next face/mipmap
                dataOffset += 3 - ((imageSize + 3) % 4); // add padding for odd sized image
            }
            width = Math.max(1.0, width * 0.5);
            height = Math.max(1.0, height * 0.5);
        }
    };
    KhronosTextureContainer.HEADER_LEN = 12 + (13 * 4); // identifier + header elements (not including key value meta-data pairs)
    // load types
    KhronosTextureContainer.COMPRESSED_2D = 0; // uses a gl.compressedTexImage2D()
    KhronosTextureContainer.COMPRESSED_3D = 1; // uses a gl.compressedTexImage3D()
    KhronosTextureContainer.TEX_2D = 2; // uses a gl.texImage2D()
    KhronosTextureContainer.TEX_3D = 3; // uses a gl.texImage3D()
    return KhronosTextureContainer;
}());



/***/ }),

/***/ "./Misc/loadFileError.ts":
/*!*******************************!*\
  !*** ./Misc/loadFileError.ts ***!
  \*******************************/
/*! exports provided: LoadFileError */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LoadFileError", function() { return LoadFileError; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");

/**
 * @ignore
 * Application error to support additional information when loading a file
 */
var LoadFileError = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LoadFileError, _super);
    /**
     * Creates a new LoadFileError
     * @param message defines the message of the error
     * @param request defines the optional web request
     */
    function LoadFileError(message,
    /** defines the optional web request */
    request) {
        var _this = _super.call(this, message) || this;
        _this.request = request;
        _this.name = "LoadFileError";
        LoadFileError._setPrototypeOf(_this, LoadFileError.prototype);
        return _this;
    }
    // See https://stackoverflow.com/questions/12915412/how-do-i-extend-a-host-object-e-g-error-in-typescript
    // and https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
    // Polyfill for Object.setPrototypeOf if necessary.
    LoadFileError._setPrototypeOf = Object.setPrototypeOf || (function (o, proto) { o.__proto__ = proto; return o; });
    return LoadFileError;
}(Error));



/***/ }),

/***/ "./Misc/logger.ts":
/*!************************!*\
  !*** ./Misc/logger.ts ***!
  \************************/
/*! exports provided: Logger */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Logger", function() { return Logger; });
/**
 * Logger used througouht the application to allow configuration of
 * the log level required for the messages.
 */
var Logger = /** @class */ (function () {
    function Logger() {
    }
    Logger._AddLogEntry = function (entry) {
        Logger._LogCache = entry + Logger._LogCache;
        if (Logger.OnNewCacheEntry) {
            Logger.OnNewCacheEntry(entry);
        }
    };
    Logger._FormatMessage = function (message) {
        var padStr = function (i) { return (i < 10) ? "0" + i : "" + i; };
        var date = new Date();
        return "[" + padStr(date.getHours()) + ":" + padStr(date.getMinutes()) + ":" + padStr(date.getSeconds()) + "]: " + message;
    };
    Logger._LogDisabled = function (message) {
        // nothing to do
    };
    Logger._LogEnabled = function (message) {
        var formattedMessage = Logger._FormatMessage(message);
        console.log("BJS - " + formattedMessage);
        var entry = "<div style='color:white'>" + formattedMessage + "</div><br>";
        Logger._AddLogEntry(entry);
    };
    Logger._WarnDisabled = function (message) {
        // nothing to do
    };
    Logger._WarnEnabled = function (message) {
        var formattedMessage = Logger._FormatMessage(message);
        console.warn("BJS - " + formattedMessage);
        var entry = "<div style='color:orange'>" + formattedMessage + "</div><br>";
        Logger._AddLogEntry(entry);
    };
    Logger._ErrorDisabled = function (message) {
        // nothing to do
    };
    Logger._ErrorEnabled = function (message) {
        Logger.errorsCount++;
        var formattedMessage = Logger._FormatMessage(message);
        console.error("BJS - " + formattedMessage);
        var entry = "<div style='color:red'>" + formattedMessage + "</div><br>";
        Logger._AddLogEntry(entry);
    };
    Object.defineProperty(Logger, "LogCache", {
        /**
         * Gets current log cache (list of logs)
         */
        get: function () {
            return Logger._LogCache;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Clears the log cache
     */
    Logger.ClearLogCache = function () {
        Logger._LogCache = "";
        Logger.errorsCount = 0;
    };
    Object.defineProperty(Logger, "LogLevels", {
        /**
         * Sets the current log level (MessageLogLevel / WarningLogLevel / ErrorLogLevel)
         */
        set: function (level) {
            if ((level & Logger.MessageLogLevel) === Logger.MessageLogLevel) {
                Logger.Log = Logger._LogEnabled;
            }
            else {
                Logger.Log = Logger._LogDisabled;
            }
            if ((level & Logger.WarningLogLevel) === Logger.WarningLogLevel) {
                Logger.Warn = Logger._WarnEnabled;
            }
            else {
                Logger.Warn = Logger._WarnDisabled;
            }
            if ((level & Logger.ErrorLogLevel) === Logger.ErrorLogLevel) {
                Logger.Error = Logger._ErrorEnabled;
            }
            else {
                Logger.Error = Logger._ErrorDisabled;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * No log
     */
    Logger.NoneLogLevel = 0;
    /**
     * Only message logs
     */
    Logger.MessageLogLevel = 1;
    /**
     * Only warning logs
     */
    Logger.WarningLogLevel = 2;
    /**
     * Only error logs
     */
    Logger.ErrorLogLevel = 4;
    /**
     * All logs
     */
    Logger.AllLogLevel = 7;
    Logger._LogCache = "";
    /**
     * Gets a value indicating the number of loading errors
     * @ignorenaming
     */
    Logger.errorsCount = 0;
    /**
     * Log a message to the console
     */
    Logger.Log = Logger._LogEnabled;
    /**
     * Write a warning message to the console
     */
    Logger.Warn = Logger._WarnEnabled;
    /**
     * Write an error message to the console
     */
    Logger.Error = Logger._ErrorEnabled;
    return Logger;
}());



/***/ }),

/***/ "./Misc/meshExploder.ts":
/*!******************************!*\
  !*** ./Misc/meshExploder.ts ***!
  \******************************/
/*! exports provided: MeshExploder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MeshExploder", function() { return MeshExploder; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");

/**
 * Class used to explode meshes (ie. to have a center and move them away from that center to better see the overall organization)
 */
var MeshExploder = /** @class */ (function () {
    /**
     * Explodes meshes from a center mesh.
     * @param meshes The meshes to explode.
     * @param centerMesh The mesh to be center of explosion.
     */
    function MeshExploder(meshes, centerMesh) {
        this._meshesOrigins = [];
        this._toCenterVectors = [];
        this._scaledDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._newPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._centerPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._meshes = meshes.slice();
        if (centerMesh) {
            this._centerMesh = centerMesh;
        }
        else {
            this._setCenterMesh();
        }
        var centerMeshIndex = this._meshes.indexOf(this._centerMesh);
        if (centerMeshIndex >= 0) {
            this._meshes.splice(centerMeshIndex, 1);
        }
        this._centerPosition = this._centerMesh.getAbsolutePosition().clone();
        for (var index = 0; index < this._meshes.length; index++) {
            if (this._meshes[index]) {
                var mesh = this._meshes[index];
                this._meshesOrigins[index] = mesh.getAbsolutePosition().clone();
                this._toCenterVectors[index] = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
                if (mesh._boundingInfo && this._centerMesh._boundingInfo) {
                    mesh._boundingInfo.boundingBox.centerWorld.subtractToRef(this._centerMesh._boundingInfo.boundingBox.centerWorld, this._toCenterVectors[index]);
                }
            }
        }
    }
    MeshExploder.prototype._setCenterMesh = function () {
        var averageCenter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        var totalCenters = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        var shortestToCenter = Number.MAX_VALUE;
        for (var index = 0; index < this._meshes.length; index++) {
            if (this._meshes[index]) {
                var mesh = this._meshes[index];
                var boundingInfo = mesh.getBoundingInfo();
                if (boundingInfo) {
                    totalCenters.addInPlace(boundingInfo.boundingBox.centerWorld);
                }
            }
        }
        averageCenter = totalCenters.scale(1 / this._meshes.length);
        for (var index = 0; index < this._meshes.length; index++) {
            if (this._meshes[index]) {
                var mesh = this._meshes[index];
                var boundingInfo = mesh.getBoundingInfo();
                if (boundingInfo) {
                    var distanceToCenter = boundingInfo.boundingBox.centerWorld.subtract(averageCenter).lengthSquared();
                    if (distanceToCenter < shortestToCenter) {
                        this._centerMesh = mesh;
                        shortestToCenter = distanceToCenter;
                    }
                }
            }
        }
    };
    /**
     * Get class name
     * @returns "MeshExploder"
     */
    MeshExploder.prototype.getClassName = function () {
        return "MeshExploder";
    };
    /**
     * "Exploded meshes"
     * @returns Array of meshes with the centerMesh at index 0.
     */
    MeshExploder.prototype.getMeshes = function () {
        var meshArray = this._meshes.slice();
        meshArray.unshift(this._centerMesh);
        return meshArray;
    };
    /**
     * Explodes meshes giving a specific direction
     * @param direction Number to multiply distance of each mesh's origin from center. Use a negative number to implode, or zero to reset.
     */
    MeshExploder.prototype.explode = function (direction) {
        if (direction === void 0) { direction = 1.0; }
        for (var index = 0; index < this._meshes.length; index++) {
            if (this._meshes[index] && this._meshesOrigins[index] && this._toCenterVectors[index]) {
                this._toCenterVectors[index].scaleToRef(direction, this._scaledDirection);
                this._meshesOrigins[index].addToRef(this._scaledDirection, this._newPosition);
                this._meshes[index].setAbsolutePosition(this._newPosition);
            }
        }
        this._centerMesh.setAbsolutePosition(this._centerPosition);
    };
    return MeshExploder;
}());



/***/ }),

/***/ "./Misc/observable.ts":
/*!****************************!*\
  !*** ./Misc/observable.ts ***!
  \****************************/
/*! exports provided: EventState, Observer, MultiObserver, Observable */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EventState", function() { return EventState; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Observer", function() { return Observer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiObserver", function() { return MultiObserver; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return Observable; });
/**
 * A class serves as a medium between the observable and its observers
 */
var EventState = /** @class */ (function () {
    /**
     * Create a new EventState
     * @param mask defines the mask associated with this state
     * @param skipNextObservers defines a flag which will instruct the observable to skip following observers when set to true
     * @param target defines the original target of the state
     * @param currentTarget defines the current target of the state
     */
    function EventState(mask, skipNextObservers, target, currentTarget) {
        if (skipNextObservers === void 0) { skipNextObservers = false; }
        this.initalize(mask, skipNextObservers, target, currentTarget);
    }
    /**
     * Initialize the current event state
     * @param mask defines the mask associated with this state
     * @param skipNextObservers defines a flag which will instruct the observable to skip following observers when set to true
     * @param target defines the original target of the state
     * @param currentTarget defines the current target of the state
     * @returns the current event state
     */
    EventState.prototype.initalize = function (mask, skipNextObservers, target, currentTarget) {
        if (skipNextObservers === void 0) { skipNextObservers = false; }
        this.mask = mask;
        this.skipNextObservers = skipNextObservers;
        this.target = target;
        this.currentTarget = currentTarget;
        return this;
    };
    return EventState;
}());

/**
 * Represent an Observer registered to a given Observable object.
 */
var Observer = /** @class */ (function () {
    /**
     * Creates a new observer
     * @param callback defines the callback to call when the observer is notified
     * @param mask defines the mask of the observer (used to filter notifications)
     * @param scope defines the current scope used to restore the JS context
     */
    function Observer(
    /**
     * Defines the callback to call when the observer is notified
     */
    callback,
    /**
     * Defines the mask of the observer (used to filter notifications)
     */
    mask,
    /**
     * Defines the current scope used to restore the JS context
     */
    scope) {
        if (scope === void 0) { scope = null; }
        this.callback = callback;
        this.mask = mask;
        this.scope = scope;
        /** @hidden */
        this._willBeUnregistered = false;
        /**
         * Gets or sets a property defining that the observer as to be unregistered after the next notification
         */
        this.unregisterOnNextCall = false;
    }
    return Observer;
}());

/**
 * Represent a list of observers registered to multiple Observables object.
 */
var MultiObserver = /** @class */ (function () {
    function MultiObserver() {
    }
    /**
     * Release associated resources
     */
    MultiObserver.prototype.dispose = function () {
        if (this._observers && this._observables) {
            for (var index = 0; index < this._observers.length; index++) {
                this._observables[index].remove(this._observers[index]);
            }
        }
        this._observers = null;
        this._observables = null;
    };
    /**
     * Raise a callback when one of the observable will notify
     * @param observables defines a list of observables to watch
     * @param callback defines the callback to call on notification
     * @param mask defines the mask used to filter notifications
     * @param scope defines the current scope used to restore the JS context
     * @returns the new MultiObserver
     */
    MultiObserver.Watch = function (observables, callback, mask, scope) {
        if (mask === void 0) { mask = -1; }
        if (scope === void 0) { scope = null; }
        var result = new MultiObserver();
        result._observers = new Array();
        result._observables = observables;
        for (var _i = 0, observables_1 = observables; _i < observables_1.length; _i++) {
            var observable = observables_1[_i];
            var observer = observable.add(callback, mask, false, scope);
            if (observer) {
                result._observers.push(observer);
            }
        }
        return result;
    };
    return MultiObserver;
}());

/**
 * The Observable class is a simple implementation of the Observable pattern.
 *
 * There's one slight particularity though: a given Observable can notify its observer using a particular mask value, only the Observers registered with this mask value will be notified.
 * This enable a more fine grained execution without having to rely on multiple different Observable objects.
 * For instance you may have a given Observable that have four different types of notifications: Move (mask = 0x01), Stop (mask = 0x02), Turn Right (mask = 0X04), Turn Left (mask = 0X08).
 * A given observer can register itself with only Move and Stop (mask = 0x03), then it will only be notified when one of these two occurs and will never be for Turn Left/Right.
 */
var Observable = /** @class */ (function () {
    /**
     * Creates a new observable
     * @param onObserverAdded defines a callback to call when a new observer is added
     */
    function Observable(onObserverAdded) {
        this._observers = new Array();
        this._eventState = new EventState(0);
        if (onObserverAdded) {
            this._onObserverAdded = onObserverAdded;
        }
    }
    Object.defineProperty(Observable.prototype, "observers", {
        /**
         * Gets the list of observers
         */
        get: function () {
            return this._observers;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Create a new Observer with the specified callback
     * @param callback the callback that will be executed for that Observer
     * @param mask the mask used to filter observers
     * @param insertFirst if true the callback will be inserted at the first position, hence executed before the others ones. If false (default behavior) the callback will be inserted at the last position, executed after all the others already present.
     * @param scope optional scope for the callback to be called from
     * @param unregisterOnFirstCall defines if the observer as to be unregistered after the next notification
     * @returns the new observer created for the callback
     */
    Observable.prototype.add = function (callback, mask, insertFirst, scope, unregisterOnFirstCall) {
        if (mask === void 0) { mask = -1; }
        if (insertFirst === void 0) { insertFirst = false; }
        if (scope === void 0) { scope = null; }
        if (unregisterOnFirstCall === void 0) { unregisterOnFirstCall = false; }
        if (!callback) {
            return null;
        }
        var observer = new Observer(callback, mask, scope);
        observer.unregisterOnNextCall = unregisterOnFirstCall;
        if (insertFirst) {
            this._observers.unshift(observer);
        }
        else {
            this._observers.push(observer);
        }
        if (this._onObserverAdded) {
            this._onObserverAdded(observer);
        }
        return observer;
    };
    /**
     * Create a new Observer with the specified callback and unregisters after the next notification
     * @param callback the callback that will be executed for that Observer
     * @returns the new observer created for the callback
     */
    Observable.prototype.addOnce = function (callback) {
        return this.add(callback, undefined, undefined, undefined, true);
    };
    /**
     * Remove an Observer from the Observable object
     * @param observer the instance of the Observer to remove
     * @returns false if it doesn't belong to this Observable
     */
    Observable.prototype.remove = function (observer) {
        if (!observer) {
            return false;
        }
        var index = this._observers.indexOf(observer);
        if (index !== -1) {
            this._deferUnregister(observer);
            return true;
        }
        return false;
    };
    /**
     * Remove a callback from the Observable object
     * @param callback the callback to remove
     * @param scope optional scope. If used only the callbacks with this scope will be removed
     * @returns false if it doesn't belong to this Observable
    */
    Observable.prototype.removeCallback = function (callback, scope) {
        for (var index = 0; index < this._observers.length; index++) {
            var observer = this._observers[index];
            if (observer._willBeUnregistered) {
                continue;
            }
            if (observer.callback === callback && (!scope || scope === observer.scope)) {
                this._deferUnregister(observer);
                return true;
            }
        }
        return false;
    };
    Observable.prototype._deferUnregister = function (observer) {
        var _this = this;
        observer.unregisterOnNextCall = false;
        observer._willBeUnregistered = true;
        setTimeout(function () {
            _this._remove(observer);
        }, 0);
    };
    // This should only be called when not iterating over _observers to avoid callback skipping.
    // Removes an observer from the _observer Array.
    Observable.prototype._remove = function (observer) {
        if (!observer) {
            return false;
        }
        var index = this._observers.indexOf(observer);
        if (index !== -1) {
            this._observers.splice(index, 1);
            return true;
        }
        return false;
    };
    /**
     * Moves the observable to the top of the observer list making it get called first when notified
     * @param observer the observer to move
     */
    Observable.prototype.makeObserverTopPriority = function (observer) {
        this._remove(observer);
        this._observers.unshift(observer);
    };
    /**
     * Moves the observable to the bottom of the observer list making it get called last when notified
     * @param observer the observer to move
     */
    Observable.prototype.makeObserverBottomPriority = function (observer) {
        this._remove(observer);
        this._observers.push(observer);
    };
    /**
     * Notify all Observers by calling their respective callback with the given data
     * Will return true if all observers were executed, false if an observer set skipNextObservers to true, then prevent the subsequent ones to execute
     * @param eventData defines the data to send to all observers
     * @param mask defines the mask of the current notification (observers with incompatible mask (ie mask & observer.mask === 0) will not be notified)
     * @param target defines the original target of the state
     * @param currentTarget defines the current target of the state
     * @returns false if the complete observer chain was not processed (because one observer set the skipNextObservers to true)
     */
    Observable.prototype.notifyObservers = function (eventData, mask, target, currentTarget) {
        if (mask === void 0) { mask = -1; }
        if (!this._observers.length) {
            return true;
        }
        var state = this._eventState;
        state.mask = mask;
        state.target = target;
        state.currentTarget = currentTarget;
        state.skipNextObservers = false;
        state.lastReturnValue = eventData;
        for (var _i = 0, _a = this._observers; _i < _a.length; _i++) {
            var obs = _a[_i];
            if (obs._willBeUnregistered) {
                continue;
            }
            if (obs.mask & mask) {
                if (obs.scope) {
                    state.lastReturnValue = obs.callback.apply(obs.scope, [eventData, state]);
                }
                else {
                    state.lastReturnValue = obs.callback(eventData, state);
                }
                if (obs.unregisterOnNextCall) {
                    this._deferUnregister(obs);
                }
            }
            if (state.skipNextObservers) {
                return false;
            }
        }
        return true;
    };
    /**
     * Calling this will execute each callback, expecting it to be a promise or return a value.
     * If at any point in the chain one function fails, the promise will fail and the execution will not continue.
     * This is useful when a chain of events (sometimes async events) is needed to initialize a certain object
     * and it is crucial that all callbacks will be executed.
     * The order of the callbacks is kept, callbacks are not executed parallel.
     *
     * @param eventData The data to be sent to each callback
     * @param mask is used to filter observers defaults to -1
     * @param target defines the callback target (see EventState)
     * @param currentTarget defines he current object in the bubbling phase
     * @returns {Promise<T>} will return a Promise than resolves when all callbacks executed successfully.
     */
    Observable.prototype.notifyObserversWithPromise = function (eventData, mask, target, currentTarget) {
        var _this = this;
        if (mask === void 0) { mask = -1; }
        // create an empty promise
        var p = Promise.resolve(eventData);
        // no observers? return this promise.
        if (!this._observers.length) {
            return p;
        }
        var state = this._eventState;
        state.mask = mask;
        state.target = target;
        state.currentTarget = currentTarget;
        state.skipNextObservers = false;
        // execute one callback after another (not using Promise.all, the order is important)
        this._observers.forEach(function (obs) {
            if (state.skipNextObservers) {
                return;
            }
            if (obs._willBeUnregistered) {
                return;
            }
            if (obs.mask & mask) {
                if (obs.scope) {
                    p = p.then(function (lastReturnedValue) {
                        state.lastReturnValue = lastReturnedValue;
                        return obs.callback.apply(obs.scope, [eventData, state]);
                    });
                }
                else {
                    p = p.then(function (lastReturnedValue) {
                        state.lastReturnValue = lastReturnedValue;
                        return obs.callback(eventData, state);
                    });
                }
                if (obs.unregisterOnNextCall) {
                    _this._deferUnregister(obs);
                }
            }
        });
        // return the eventData
        return p.then(function () { return eventData; });
    };
    /**
     * Notify a specific observer
     * @param observer defines the observer to notify
     * @param eventData defines the data to be sent to each callback
     * @param mask is used to filter observers defaults to -1
     */
    Observable.prototype.notifyObserver = function (observer, eventData, mask) {
        if (mask === void 0) { mask = -1; }
        var state = this._eventState;
        state.mask = mask;
        state.skipNextObservers = false;
        observer.callback(eventData, state);
    };
    /**
     * Gets a boolean indicating if the observable has at least one observer
     * @returns true is the Observable has at least one Observer registered
     */
    Observable.prototype.hasObservers = function () {
        return this._observers.length > 0;
    };
    /**
    * Clear the list of observers
    */
    Observable.prototype.clear = function () {
        this._observers = new Array();
        this._onObserverAdded = null;
    };
    /**
     * Clone the current observable
     * @returns a new observable
     */
    Observable.prototype.clone = function () {
        var result = new Observable();
        result._observers = this._observers.slice(0);
        return result;
    };
    /**
     * Does this observable handles observer registered with a given mask
     * @param mask defines the mask to be tested
     * @return whether or not one observer registered with the given mask is handeled
    **/
    Observable.prototype.hasSpecificMask = function (mask) {
        if (mask === void 0) { mask = -1; }
        for (var _i = 0, _a = this._observers; _i < _a.length; _i++) {
            var obs = _a[_i];
            if (obs.mask & mask || obs.mask === mask) {
                return true;
            }
        }
        return false;
    };
    return Observable;
}());



/***/ }),

/***/ "./Misc/perfCounter.ts":
/*!*****************************!*\
  !*** ./Misc/perfCounter.ts ***!
  \*****************************/
/*! exports provided: PerfCounter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PerfCounter", function() { return PerfCounter; });
/* harmony import */ var _precisionDate__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./precisionDate */ "./Misc/precisionDate.ts");

/**
 * This class is used to track a performance counter which is number based.
 * The user has access to many properties which give statistics of different nature.
 *
 * The implementer can track two kinds of Performance Counter: time and count.
 * For time you can optionally call fetchNewFrame() to notify the start of a new frame to monitor, then call beginMonitoring() to start and endMonitoring() to record the lapsed time. endMonitoring takes a newFrame parameter for you to specify if the monitored time should be set for a new frame or accumulated to the current frame being monitored.
 * For count you first have to call fetchNewFrame() to notify the start of a new frame to monitor, then call addCount() how many time required to increment the count value you monitor.
 */
var PerfCounter = /** @class */ (function () {
    /**
     * Creates a new counter
     */
    function PerfCounter() {
        this._startMonitoringTime = 0;
        this._min = 0;
        this._max = 0;
        this._average = 0;
        this._lastSecAverage = 0;
        this._current = 0;
        this._totalValueCount = 0;
        this._totalAccumulated = 0;
        this._lastSecAccumulated = 0;
        this._lastSecTime = 0;
        this._lastSecValueCount = 0;
    }
    Object.defineProperty(PerfCounter.prototype, "min", {
        /**
         * Returns the smallest value ever
         */
        get: function () {
            return this._min;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerfCounter.prototype, "max", {
        /**
         * Returns the biggest value ever
         */
        get: function () {
            return this._max;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerfCounter.prototype, "average", {
        /**
         * Returns the average value since the performance counter is running
         */
        get: function () {
            return this._average;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerfCounter.prototype, "lastSecAverage", {
        /**
         * Returns the average value of the last second the counter was monitored
         */
        get: function () {
            return this._lastSecAverage;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerfCounter.prototype, "current", {
        /**
         * Returns the current value
         */
        get: function () {
            return this._current;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerfCounter.prototype, "total", {
        /**
         * Gets the accumulated total
         */
        get: function () {
            return this._totalAccumulated;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerfCounter.prototype, "count", {
        /**
         * Gets the total value count
         */
        get: function () {
            return this._totalValueCount;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Call this method to start monitoring a new frame.
     * This scenario is typically used when you accumulate monitoring time many times for a single frame, you call this method at the start of the frame, then beginMonitoring to start recording and endMonitoring(false) to accumulated the recorded time to the PerfCounter or addCount() to accumulate a monitored count.
     */
    PerfCounter.prototype.fetchNewFrame = function () {
        this._totalValueCount++;
        this._current = 0;
        this._lastSecValueCount++;
    };
    /**
     * Call this method to monitor a count of something (e.g. mesh drawn in viewport count)
     * @param newCount the count value to add to the monitored count
     * @param fetchResult true when it's the last time in the frame you add to the counter and you wish to update the statistics properties (min/max/average), false if you only want to update statistics.
     */
    PerfCounter.prototype.addCount = function (newCount, fetchResult) {
        if (!PerfCounter.Enabled) {
            return;
        }
        this._current += newCount;
        if (fetchResult) {
            this._fetchResult();
        }
    };
    /**
     * Start monitoring this performance counter
     */
    PerfCounter.prototype.beginMonitoring = function () {
        if (!PerfCounter.Enabled) {
            return;
        }
        this._startMonitoringTime = _precisionDate__WEBPACK_IMPORTED_MODULE_0__["PrecisionDate"].Now;
    };
    /**
     * Compute the time lapsed since the previous beginMonitoring() call.
     * @param newFrame true by default to fetch the result and monitor a new frame, if false the time monitored will be added to the current frame counter
     */
    PerfCounter.prototype.endMonitoring = function (newFrame) {
        if (newFrame === void 0) { newFrame = true; }
        if (!PerfCounter.Enabled) {
            return;
        }
        if (newFrame) {
            this.fetchNewFrame();
        }
        var currentTime = _precisionDate__WEBPACK_IMPORTED_MODULE_0__["PrecisionDate"].Now;
        this._current = currentTime - this._startMonitoringTime;
        if (newFrame) {
            this._fetchResult();
        }
    };
    PerfCounter.prototype._fetchResult = function () {
        this._totalAccumulated += this._current;
        this._lastSecAccumulated += this._current;
        // Min/Max update
        this._min = Math.min(this._min, this._current);
        this._max = Math.max(this._max, this._current);
        this._average = this._totalAccumulated / this._totalValueCount;
        // Reset last sec?
        var now = _precisionDate__WEBPACK_IMPORTED_MODULE_0__["PrecisionDate"].Now;
        if ((now - this._lastSecTime) > 1000) {
            this._lastSecAverage = this._lastSecAccumulated / this._lastSecValueCount;
            this._lastSecTime = now;
            this._lastSecAccumulated = 0;
            this._lastSecValueCount = 0;
        }
    };
    /**
     * Gets or sets a global boolean to turn on and off all the counters
     */
    PerfCounter.Enabled = true;
    return PerfCounter;
}());



/***/ }),

/***/ "./Misc/performanceMonitor.ts":
/*!************************************!*\
  !*** ./Misc/performanceMonitor.ts ***!
  \************************************/
/*! exports provided: PerformanceMonitor, RollingAverage */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PerformanceMonitor", function() { return PerformanceMonitor; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RollingAverage", function() { return RollingAverage; });
/* harmony import */ var _precisionDate__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./precisionDate */ "./Misc/precisionDate.ts");

/**
 * Performance monitor tracks rolling average frame-time and frame-time variance over a user defined sliding-window
 */
var PerformanceMonitor = /** @class */ (function () {
    /**
     * constructor
     * @param frameSampleSize The number of samples required to saturate the sliding window
     */
    function PerformanceMonitor(frameSampleSize) {
        if (frameSampleSize === void 0) { frameSampleSize = 30; }
        this._enabled = true;
        this._rollingFrameTime = new RollingAverage(frameSampleSize);
    }
    /**
     * Samples current frame
     * @param timeMs A timestamp in milliseconds of the current frame to compare with other frames
     */
    PerformanceMonitor.prototype.sampleFrame = function (timeMs) {
        if (timeMs === void 0) { timeMs = _precisionDate__WEBPACK_IMPORTED_MODULE_0__["PrecisionDate"].Now; }
        if (!this._enabled) {
            return;
        }
        if (this._lastFrameTimeMs != null) {
            var dt = timeMs - this._lastFrameTimeMs;
            this._rollingFrameTime.add(dt);
        }
        this._lastFrameTimeMs = timeMs;
    };
    Object.defineProperty(PerformanceMonitor.prototype, "averageFrameTime", {
        /**
         * Returns the average frame time in milliseconds over the sliding window (or the subset of frames sampled so far)
         */
        get: function () {
            return this._rollingFrameTime.average;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerformanceMonitor.prototype, "averageFrameTimeVariance", {
        /**
         * Returns the variance frame time in milliseconds over the sliding window (or the subset of frames sampled so far)
         */
        get: function () {
            return this._rollingFrameTime.variance;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerformanceMonitor.prototype, "instantaneousFrameTime", {
        /**
         * Returns the frame time of the most recent frame
         */
        get: function () {
            return this._rollingFrameTime.history(0);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerformanceMonitor.prototype, "averageFPS", {
        /**
         * Returns the average framerate in frames per second over the sliding window (or the subset of frames sampled so far)
         */
        get: function () {
            return 1000.0 / this._rollingFrameTime.average;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerformanceMonitor.prototype, "instantaneousFPS", {
        /**
         * Returns the average framerate in frames per second using the most recent frame time
         */
        get: function () {
            var history = this._rollingFrameTime.history(0);
            if (history === 0) {
                return 0;
            }
            return 1000.0 / history;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PerformanceMonitor.prototype, "isSaturated", {
        /**
         * Returns true if enough samples have been taken to completely fill the sliding window
         */
        get: function () {
            return this._rollingFrameTime.isSaturated();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Enables contributions to the sliding window sample set
     */
    PerformanceMonitor.prototype.enable = function () {
        this._enabled = true;
    };
    /**
     * Disables contributions to the sliding window sample set
     * Samples will not be interpolated over the disabled period
     */
    PerformanceMonitor.prototype.disable = function () {
        this._enabled = false;
        //clear last sample to avoid interpolating over the disabled period when next enabled
        this._lastFrameTimeMs = null;
    };
    Object.defineProperty(PerformanceMonitor.prototype, "isEnabled", {
        /**
         * Returns true if sampling is enabled
         */
        get: function () {
            return this._enabled;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resets performance monitor
     */
    PerformanceMonitor.prototype.reset = function () {
        //clear last sample to avoid interpolating over the disabled period when next enabled
        this._lastFrameTimeMs = null;
        //wipe record
        this._rollingFrameTime.reset();
    };
    return PerformanceMonitor;
}());

/**
 * RollingAverage
 *
 * Utility to efficiently compute the rolling average and variance over a sliding window of samples
 */
var RollingAverage = /** @class */ (function () {
    /**
     * constructor
     * @param length The number of samples required to saturate the sliding window
     */
    function RollingAverage(length) {
        this._samples = new Array(length);
        this.reset();
    }
    /**
     * Adds a sample to the sample set
     * @param v The sample value
     */
    RollingAverage.prototype.add = function (v) {
        //http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
        var delta;
        //we need to check if we've already wrapped round
        if (this.isSaturated()) {
            //remove bottom of stack from mean
            var bottomValue = this._samples[this._pos];
            delta = bottomValue - this.average;
            this.average -= delta / (this._sampleCount - 1);
            this._m2 -= delta * (bottomValue - this.average);
        }
        else {
            this._sampleCount++;
        }
        //add new value to mean
        delta = v - this.average;
        this.average += delta / (this._sampleCount);
        this._m2 += delta * (v - this.average);
        //set the new variance
        this.variance = this._m2 / (this._sampleCount - 1);
        this._samples[this._pos] = v;
        this._pos++;
        this._pos %= this._samples.length; //positive wrap around
    };
    /**
     * Returns previously added values or null if outside of history or outside the sliding window domain
     * @param i Index in history. For example, pass 0 for the most recent value and 1 for the value before that
     * @return Value previously recorded with add() or null if outside of range
     */
    RollingAverage.prototype.history = function (i) {
        if ((i >= this._sampleCount) || (i >= this._samples.length)) {
            return 0;
        }
        var i0 = this._wrapPosition(this._pos - 1.0);
        return this._samples[this._wrapPosition(i0 - i)];
    };
    /**
     * Returns true if enough samples have been taken to completely fill the sliding window
     * @return true if sample-set saturated
     */
    RollingAverage.prototype.isSaturated = function () {
        return this._sampleCount >= this._samples.length;
    };
    /**
     * Resets the rolling average (equivalent to 0 samples taken so far)
     */
    RollingAverage.prototype.reset = function () {
        this.average = 0;
        this.variance = 0;
        this._sampleCount = 0;
        this._pos = 0;
        this._m2 = 0;
    };
    /**
     * Wraps a value around the sample range boundaries
     * @param i Position in sample range, for example if the sample length is 5, and i is -3, then 2 will be returned.
     * @return Wrapped position in sample range
     */
    RollingAverage.prototype._wrapPosition = function (i) {
        var max = this._samples.length;
        return ((i % max) + max) % max;
    };
    return RollingAverage;
}());



/***/ }),

/***/ "./Misc/pivotTools.ts":
/*!****************************!*\
  !*** ./Misc/pivotTools.ts ***!
  \****************************/
/*! exports provided: PivotTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PivotTools", function() { return PivotTools; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");

/**
 * Class containing a set of static utilities functions for managing Pivots
 * @hidden
 */
var PivotTools = /** @class */ (function () {
    function PivotTools() {
    }
    /** @hidden */
    PivotTools._RemoveAndStorePivotPoint = function (mesh) {
        if (mesh && PivotTools._PivotCached === 0) {
            // Save old pivot and set pivot to 0,0,0
            mesh.getPivotPointToRef(PivotTools._OldPivotPoint);
            if (!PivotTools._OldPivotPoint.equalsToFloats(0, 0, 0)) {
                mesh.setPivotMatrix(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].IdentityReadOnly);
                PivotTools._OldPivotPoint.subtractToRef(mesh.getPivotPoint(), PivotTools._PivotTranslation);
                PivotTools._PivotTmpVector.copyFromFloats(1, 1, 1);
                PivotTools._PivotTmpVector.subtractInPlace(mesh.scaling);
                PivotTools._PivotTmpVector.multiplyInPlace(PivotTools._PivotTranslation);
                mesh.position.addInPlace(PivotTools._PivotTmpVector);
            }
        }
        PivotTools._PivotCached++;
    };
    /** @hidden */
    PivotTools._RestorePivotPoint = function (mesh) {
        if (mesh && !PivotTools._OldPivotPoint.equalsToFloats(0, 0, 0) && PivotTools._PivotCached === 1) {
            mesh.setPivotPoint(PivotTools._OldPivotPoint);
            PivotTools._PivotTmpVector.copyFromFloats(1, 1, 1);
            PivotTools._PivotTmpVector.subtractInPlace(mesh.scaling);
            PivotTools._PivotTmpVector.multiplyInPlace(PivotTools._PivotTranslation);
            mesh.position.subtractInPlace(PivotTools._PivotTmpVector);
        }
        this._PivotCached--;
    };
    // Stores the state of the pivot cache (_oldPivotPoint, _pivotTranslation)
    // store/remove pivot point should only be applied during their outermost calls
    PivotTools._PivotCached = 0;
    PivotTools._OldPivotPoint = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
    PivotTools._PivotTranslation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
    PivotTools._PivotTmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
    return PivotTools;
}());



/***/ }),

/***/ "./Misc/precisionDate.ts":
/*!*******************************!*\
  !*** ./Misc/precisionDate.ts ***!
  \*******************************/
/*! exports provided: PrecisionDate */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PrecisionDate", function() { return PrecisionDate; });
/* harmony import */ var _domManagement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./domManagement */ "./Misc/domManagement.ts");

/**
 * Class containing a set of static utilities functions for precision date
 */
var PrecisionDate = /** @class */ (function () {
    function PrecisionDate() {
    }
    Object.defineProperty(PrecisionDate, "Now", {
        /**
         * Gets either window.performance.now() if supported or Date.now() else
         */
        get: function () {
            if (_domManagement__WEBPACK_IMPORTED_MODULE_0__["DomManagement"].IsWindowObjectExist() && window.performance && window.performance.now) {
                return window.performance.now();
            }
            return Date.now();
        },
        enumerable: true,
        configurable: true
    });
    return PrecisionDate;
}());



/***/ }),

/***/ "./Misc/promise.ts":
/*!*************************!*\
  !*** ./Misc/promise.ts ***!
  \*************************/
/*! exports provided: PromisePolyfill */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PromisePolyfill", function() { return PromisePolyfill; });
var PromiseStates;
(function (PromiseStates) {
    PromiseStates[PromiseStates["Pending"] = 0] = "Pending";
    PromiseStates[PromiseStates["Fulfilled"] = 1] = "Fulfilled";
    PromiseStates[PromiseStates["Rejected"] = 2] = "Rejected";
})(PromiseStates || (PromiseStates = {}));
var FulFillmentAgregator = /** @class */ (function () {
    function FulFillmentAgregator() {
        this.count = 0;
        this.target = 0;
        this.results = [];
    }
    return FulFillmentAgregator;
}());
var InternalPromise = /** @class */ (function () {
    function InternalPromise(resolver) {
        var _this = this;
        this._state = PromiseStates.Pending;
        this._children = new Array();
        this._rejectWasConsumed = false;
        if (!resolver) {
            return;
        }
        try {
            resolver(function (value) {
                _this._resolve(value);
            }, function (reason) {
                _this._reject(reason);
            });
        }
        catch (e) {
            this._reject(e);
        }
    }
    Object.defineProperty(InternalPromise.prototype, "_result", {
        get: function () {
            return this._resultValue;
        },
        set: function (value) {
            this._resultValue = value;
            if (this._parent && this._parent._result === undefined) {
                this._parent._result = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    InternalPromise.prototype.catch = function (onRejected) {
        return this.then(undefined, onRejected);
    };
    InternalPromise.prototype.then = function (onFulfilled, onRejected) {
        var _this = this;
        var newPromise = new InternalPromise();
        newPromise._onFulfilled = onFulfilled;
        newPromise._onRejected = onRejected;
        // Composition
        this._children.push(newPromise);
        newPromise._parent = this;
        if (this._state !== PromiseStates.Pending) {
            setTimeout(function () {
                if (_this._state === PromiseStates.Fulfilled || _this._rejectWasConsumed) {
                    var returnedValue = newPromise._resolve(_this._result);
                    if (returnedValue !== undefined && returnedValue !== null) {
                        if (returnedValue._state !== undefined) {
                            var returnedPromise = returnedValue;
                            newPromise._children.push(returnedPromise);
                            returnedPromise._parent = newPromise;
                            newPromise = returnedPromise;
                        }
                        else {
                            newPromise._result = returnedValue;
                        }
                    }
                }
                else {
                    newPromise._reject(_this._reason);
                }
            });
        }
        return newPromise;
    };
    InternalPromise.prototype._moveChildren = function (children) {
        var _a;
        var _this = this;
        (_a = this._children).push.apply(_a, children.splice(0, children.length));
        this._children.forEach(function (child) {
            child._parent = _this;
        });
        if (this._state === PromiseStates.Fulfilled) {
            for (var _i = 0, _b = this._children; _i < _b.length; _i++) {
                var child = _b[_i];
                child._resolve(this._result);
            }
        }
        else if (this._state === PromiseStates.Rejected) {
            for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
                var child = _d[_c];
                child._reject(this._reason);
            }
        }
    };
    InternalPromise.prototype._resolve = function (value) {
        try {
            this._state = PromiseStates.Fulfilled;
            var returnedValue = null;
            if (this._onFulfilled) {
                returnedValue = this._onFulfilled(value);
            }
            if (returnedValue !== undefined && returnedValue !== null) {
                if (returnedValue._state !== undefined) {
                    // Transmit children
                    var returnedPromise = returnedValue;
                    returnedPromise._parent = this;
                    returnedPromise._moveChildren(this._children);
                    value = returnedPromise._result;
                }
                else {
                    value = returnedValue;
                }
            }
            this._result = value;
            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
                var child = _a[_i];
                child._resolve(value);
            }
            this._children.length = 0;
            delete this._onFulfilled;
            delete this._onRejected;
        }
        catch (e) {
            this._reject(e, true);
        }
    };
    InternalPromise.prototype._reject = function (reason, onLocalThrow) {
        if (onLocalThrow === void 0) { onLocalThrow = false; }
        this._state = PromiseStates.Rejected;
        this._reason = reason;
        if (this._onRejected && !onLocalThrow) {
            try {
                this._onRejected(reason);
                this._rejectWasConsumed = true;
            }
            catch (e) {
                reason = e;
            }
        }
        for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
            var child = _a[_i];
            if (this._rejectWasConsumed) {
                child._resolve(null);
            }
            else {
                child._reject(reason);
            }
        }
        this._children.length = 0;
        delete this._onFulfilled;
        delete this._onRejected;
    };
    InternalPromise.resolve = function (value) {
        var newPromise = new InternalPromise();
        newPromise._resolve(value);
        return newPromise;
    };
    InternalPromise._RegisterForFulfillment = function (promise, agregator, index) {
        promise.then(function (value) {
            agregator.results[index] = value;
            agregator.count++;
            if (agregator.count === agregator.target) {
                agregator.rootPromise._resolve(agregator.results);
            }
            return null;
        }, function (reason) {
            if (agregator.rootPromise._state !== PromiseStates.Rejected) {
                agregator.rootPromise._reject(reason);
            }
        });
    };
    InternalPromise.all = function (promises) {
        var newPromise = new InternalPromise();
        var agregator = new FulFillmentAgregator();
        agregator.target = promises.length;
        agregator.rootPromise = newPromise;
        if (promises.length) {
            for (var index = 0; index < promises.length; index++) {
                InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
            }
        }
        else {
            newPromise._resolve([]);
        }
        return newPromise;
    };
    InternalPromise.race = function (promises) {
        var newPromise = new InternalPromise();
        if (promises.length) {
            for (var _i = 0, promises_1 = promises; _i < promises_1.length; _i++) {
                var promise = promises_1[_i];
                promise.then(function (value) {
                    if (newPromise) {
                        newPromise._resolve(value);
                        newPromise = null;
                    }
                    return null;
                }, function (reason) {
                    if (newPromise) {
                        newPromise._reject(reason);
                        newPromise = null;
                    }
                });
            }
        }
        return newPromise;
    };
    return InternalPromise;
}());
/**
 * Helper class that provides a small promise polyfill
 */
var PromisePolyfill = /** @class */ (function () {
    function PromisePolyfill() {
    }
    /**
     * Static function used to check if the polyfill is required
     * If this is the case then the function will inject the polyfill to window.Promise
     * @param force defines a boolean used to force the injection (mostly for testing purposes)
     */
    PromisePolyfill.Apply = function (force) {
        if (force === void 0) { force = false; }
        if (force || typeof Promise === 'undefined') {
            var root = window;
            root.Promise = InternalPromise;
        }
    };
    return PromisePolyfill;
}());



/***/ }),

/***/ "./Misc/retryStrategy.ts":
/*!*******************************!*\
  !*** ./Misc/retryStrategy.ts ***!
  \*******************************/
/*! exports provided: RetryStrategy */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RetryStrategy", function() { return RetryStrategy; });
/**
 * Class used to define a retry strategy when error happens while loading assets
 */
var RetryStrategy = /** @class */ (function () {
    function RetryStrategy() {
    }
    /**
     * Function used to defines an exponential back off strategy
     * @param maxRetries defines the maximum number of retries (3 by default)
     * @param baseInterval defines the interval between retries
     * @returns the strategy function to use
     */
    RetryStrategy.ExponentialBackoff = function (maxRetries, baseInterval) {
        if (maxRetries === void 0) { maxRetries = 3; }
        if (baseInterval === void 0) { baseInterval = 500; }
        return function (url, request, retryIndex) {
            if (request.status !== 0 || retryIndex >= maxRetries || url.indexOf("file:") !== -1) {
                return -1;
            }
            return Math.pow(2, retryIndex) * baseInterval;
        };
    };
    return RetryStrategy;
}());



/***/ }),

/***/ "./Misc/rgbdTextureTools.ts":
/*!**********************************!*\
  !*** ./Misc/rgbdTextureTools.ts ***!
  \**********************************/
/*! exports provided: RGBDTextureTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RGBDTextureTools", function() { return RGBDTextureTools; });
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_rgbdDecode_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Shaders/rgbdDecode.fragment */ "./Shaders/rgbdDecode.fragment.ts");



/**
 * Class used to host RGBD texture specific utilities
 */
var RGBDTextureTools = /** @class */ (function () {
    function RGBDTextureTools() {
    }
    /**
     * Expand the RGBD Texture from RGBD to Half Float if possible.
     * @param texture the texture to expand.
     */
    RGBDTextureTools.ExpandRGBDTexture = function (texture) {
        var internalTexture = texture._texture;
        if (!internalTexture || !texture.isRGBD) {
            return;
        }
        texture.onLoadObservable.addOnce(function () {
            // Gets everything ready.
            var engine = internalTexture.getEngine();
            var caps = engine.getCaps();
            var expandTexture = false;
            // If half float available we can uncompress the texture
            if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                expandTexture = true;
                internalTexture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].TEXTURETYPE_HALF_FLOAT;
            }
            // If full float available we can uncompress the texture
            else if (caps.textureFloatRender && caps.textureFloatLinearFiltering) {
                expandTexture = true;
                internalTexture.type = _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].TEXTURETYPE_FLOAT;
            }
            // Expand the texture if possible
            if (expandTexture) {
                // Do not use during decode.
                internalTexture.isReady = false;
                // Simply run through the decode PP.
                var rgbdPostProcess_1 = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]("rgbdDecode", "rgbdDecode", null, null, 1, null, _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE, engine, false, undefined, internalTexture.type, undefined, null, false);
                internalTexture._isRGBD = false;
                internalTexture.invertY = false;
                // Hold the output of the decoding.
                var expandedTexture_1 = engine.createRenderTargetTexture(internalTexture.width, {
                    generateDepthBuffer: false,
                    generateMipMaps: false,
                    generateStencilBuffer: false,
                    samplingMode: internalTexture.samplingMode,
                    type: internalTexture.type,
                    format: _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].TEXTUREFORMAT_RGBA
                });
                rgbdPostProcess_1.getEffect().executeWhenCompiled(function () {
                    // PP Render Pass
                    rgbdPostProcess_1.onApply = function (effect) {
                        effect._bindTexture("textureSampler", internalTexture);
                        effect.setFloat2("scale", 1, 1);
                    };
                    engine.scenes[0].postProcessManager.directRender([rgbdPostProcess_1], expandedTexture_1, true);
                    // Cleanup
                    engine.restoreDefaultFramebuffer();
                    engine._releaseTexture(internalTexture);
                    engine._releaseFramebufferObjects(expandedTexture_1);
                    if (rgbdPostProcess_1) {
                        rgbdPostProcess_1.dispose();
                    }
                    // Internal Swap
                    expandedTexture_1._swapAndDie(internalTexture);
                    // Ready to get rolling again.
                    internalTexture.isReady = true;
                });
            }
        });
    };
    return RGBDTextureTools;
}());



/***/ }),

/***/ "./Misc/sceneOptimizer.ts":
/*!********************************!*\
  !*** ./Misc/sceneOptimizer.ts ***!
  \********************************/
/*! exports provided: SceneOptimization, TextureOptimization, HardwareScalingOptimization, ShadowsOptimization, PostProcessesOptimization, LensFlaresOptimization, CustomOptimization, ParticlesOptimization, RenderTargetsOptimization, MergeMeshesOptimization, SceneOptimizerOptions, SceneOptimizer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneOptimization", function() { return SceneOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextureOptimization", function() { return TextureOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HardwareScalingOptimization", function() { return HardwareScalingOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ShadowsOptimization", function() { return ShadowsOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcessesOptimization", function() { return PostProcessesOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LensFlaresOptimization", function() { return LensFlaresOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomOptimization", function() { return CustomOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticlesOptimization", function() { return ParticlesOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderTargetsOptimization", function() { return RenderTargetsOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMeshesOptimization", function() { return MergeMeshesOptimization; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizerOptions", function() { return SceneOptimizerOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizer", function() { return SceneOptimizer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./observable */ "./Misc/observable.ts");




/**
 * Defines the root class used to create scene optimization to use with SceneOptimizer
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var SceneOptimization = /** @class */ (function () {
    /**
     * Creates the SceneOptimization object
     * @param priority defines the priority of this optimization (0 by default which means first in the list)
     * @param desc defines the description associated with the optimization
     */
    function SceneOptimization(
    /**
     * Defines the priority of this optimization (0 by default which means first in the list)
     */
    priority) {
        if (priority === void 0) { priority = 0; }
        this.priority = priority;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @returns description string
     */
    SceneOptimization.prototype.getDescription = function () {
        return "";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    SceneOptimization.prototype.apply = function (scene, optimizer) {
        return true;
    };
    return SceneOptimization;
}());

/**
 * Defines an optimization used to reduce the size of render target textures
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var TextureOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TextureOptimization, _super);
    /**
     * Creates the TextureOptimization object
     * @param priority defines the priority of this optimization (0 by default which means first in the list)
     * @param maximumSize defines the maximum sized allowed for textures (1024 is the default value). If a texture is bigger, it will be scaled down using a factor defined by the step parameter
     * @param step defines the factor (0.5 by default) used to scale down textures bigger than maximum sized allowed.
     */
    function TextureOptimization(
    /**
     * Defines the priority of this optimization (0 by default which means first in the list)
     */
    priority,
    /**
     * Defines the maximum sized allowed for textures (1024 is the default value). If a texture is bigger, it will be scaled down using a factor defined by the step parameter
     */
    maximumSize,
    /**
     * Defines the factor (0.5 by default) used to scale down textures bigger than maximum sized allowed.
     */
    step) {
        if (priority === void 0) { priority = 0; }
        if (maximumSize === void 0) { maximumSize = 1024; }
        if (step === void 0) { step = 0.5; }
        var _this = _super.call(this, priority) || this;
        _this.priority = priority;
        _this.maximumSize = maximumSize;
        _this.step = step;
        return _this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @returns description string
     */
    TextureOptimization.prototype.getDescription = function () {
        return "Reducing render target texture size to " + this.maximumSize;
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    TextureOptimization.prototype.apply = function (scene, optimizer) {
        var allDone = true;
        for (var index = 0; index < scene.textures.length; index++) {
            var texture = scene.textures[index];
            if (!texture.canRescale || texture.getContext) {
                continue;
            }
            var currentSize = texture.getSize();
            var maxDimension = Math.max(currentSize.width, currentSize.height);
            if (maxDimension > this.maximumSize) {
                texture.scale(this.step);
                allDone = false;
            }
        }
        return allDone;
    };
    return TextureOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to increase or decrease the rendering resolution
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var HardwareScalingOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HardwareScalingOptimization, _super);
    /**
     * Creates the HardwareScalingOptimization object
     * @param priority defines the priority of this optimization (0 by default which means first in the list)
     * @param maximumScale defines the maximum scale to use (2 by default)
     * @param step defines the step to use between two passes (0.5 by default)
     */
    function HardwareScalingOptimization(
    /**
     * Defines the priority of this optimization (0 by default which means first in the list)
     */
    priority,
    /**
     * Defines the maximum scale to use (2 by default)
     */
    maximumScale,
    /**
     * Defines the step to use between two passes (0.5 by default)
     */
    step) {
        if (priority === void 0) { priority = 0; }
        if (maximumScale === void 0) { maximumScale = 2; }
        if (step === void 0) { step = 0.25; }
        var _this = _super.call(this, priority) || this;
        _this.priority = priority;
        _this.maximumScale = maximumScale;
        _this.step = step;
        _this._currentScale = -1;
        _this._directionOffset = 1;
        return _this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    HardwareScalingOptimization.prototype.getDescription = function () {
        return "Setting hardware scaling level to " + this._currentScale;
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    HardwareScalingOptimization.prototype.apply = function (scene, optimizer) {
        if (this._currentScale === -1) {
            this._currentScale = scene.getEngine().getHardwareScalingLevel();
            if (this._currentScale > this.maximumScale) {
                this._directionOffset = -1;
            }
        }
        this._currentScale += this._directionOffset * this.step;
        scene.getEngine().setHardwareScalingLevel(this._currentScale);
        return this._directionOffset === 1 ? this._currentScale >= this.maximumScale : this._currentScale <= this.maximumScale;
    };
    return HardwareScalingOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to remove shadows
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var ShadowsOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ShadowsOptimization, _super);
    function ShadowsOptimization() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    ShadowsOptimization.prototype.getDescription = function () {
        return "Turning shadows on/off";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    ShadowsOptimization.prototype.apply = function (scene, optimizer) {
        scene.shadowsEnabled = optimizer.isInImprovementMode;
        return true;
    };
    return ShadowsOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to turn post-processes off
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var PostProcessesOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PostProcessesOptimization, _super);
    function PostProcessesOptimization() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    PostProcessesOptimization.prototype.getDescription = function () {
        return "Turning post-processes on/off";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    PostProcessesOptimization.prototype.apply = function (scene, optimizer) {
        scene.postProcessesEnabled = optimizer.isInImprovementMode;
        return true;
    };
    return PostProcessesOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to turn lens flares off
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var LensFlaresOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LensFlaresOptimization, _super);
    function LensFlaresOptimization() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    LensFlaresOptimization.prototype.getDescription = function () {
        return "Turning lens flares on/off";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    LensFlaresOptimization.prototype.apply = function (scene, optimizer) {
        scene.lensFlaresEnabled = optimizer.isInImprovementMode;
        return true;
    };
    return LensFlaresOptimization;
}(SceneOptimization));

/**
 * Defines an optimization based on user defined callback.
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var CustomOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CustomOptimization, _super);
    function CustomOptimization() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @returns description string
     */
    CustomOptimization.prototype.getDescription = function () {
        if (this.onGetDescription) {
            return this.onGetDescription();
        }
        return "Running user defined callback";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    CustomOptimization.prototype.apply = function (scene, optimizer) {
        if (this.onApply) {
            return this.onApply(scene, optimizer);
        }
        return true;
    };
    return CustomOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to turn particles off
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var ParticlesOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ParticlesOptimization, _super);
    function ParticlesOptimization() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    ParticlesOptimization.prototype.getDescription = function () {
        return "Turning particles on/off";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    ParticlesOptimization.prototype.apply = function (scene, optimizer) {
        scene.particlesEnabled = optimizer.isInImprovementMode;
        return true;
    };
    return ParticlesOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to turn render targets off
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var RenderTargetsOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RenderTargetsOptimization, _super);
    function RenderTargetsOptimization() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    RenderTargetsOptimization.prototype.getDescription = function () {
        return "Turning render targets off";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @returns true if everything that can be done was applied
     */
    RenderTargetsOptimization.prototype.apply = function (scene, optimizer) {
        scene.renderTargetsEnabled = optimizer.isInImprovementMode;
        return true;
    };
    return RenderTargetsOptimization;
}(SceneOptimization));

/**
 * Defines an optimization used to merge meshes with compatible materials
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var MergeMeshesOptimization = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeMeshesOptimization, _super);
    function MergeMeshesOptimization() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._canBeMerged = function (abstractMesh) {
            if (!(abstractMesh instanceof _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"])) {
                return false;
            }
            var mesh = abstractMesh;
            if (mesh.isDisposed()) {
                return false;
            }
            if (!mesh.isVisible || !mesh.isEnabled()) {
                return false;
            }
            if (mesh.instances.length > 0) {
                return false;
            }
            if (mesh.skeleton || mesh.hasLODLevels) {
                return false;
            }
            return true;
        };
        return _this;
    }
    Object.defineProperty(MergeMeshesOptimization, "UpdateSelectionTree", {
        /**
         * Gets or sets a boolean which defines if optimization octree has to be updated
         */
        get: function () {
            return MergeMeshesOptimization._UpdateSelectionTree;
        },
        /**
         * Gets or sets a boolean which defines if optimization octree has to be updated
         */
        set: function (value) {
            MergeMeshesOptimization._UpdateSelectionTree = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets a string describing the action executed by the current optimization
     * @return description string
     */
    MergeMeshesOptimization.prototype.getDescription = function () {
        return "Merging similar meshes together";
    };
    /**
     * This function will be called by the SceneOptimizer when its priority is reached in order to apply the change required by the current optimization
     * @param scene defines the current scene where to apply this optimization
     * @param optimizer defines the current optimizer
     * @param updateSelectionTree defines that the selection octree has to be updated (false by default)
     * @returns true if everything that can be done was applied
     */
    MergeMeshesOptimization.prototype.apply = function (scene, optimizer, updateSelectionTree) {
        var globalPool = scene.meshes.slice(0);
        var globalLength = globalPool.length;
        for (var index = 0; index < globalLength; index++) {
            var currentPool = new Array();
            var current = globalPool[index];
            // Checks
            if (!this._canBeMerged(current)) {
                continue;
            }
            currentPool.push(current);
            // Find compatible meshes
            for (var subIndex = index + 1; subIndex < globalLength; subIndex++) {
                var otherMesh = globalPool[subIndex];
                if (!this._canBeMerged(otherMesh)) {
                    continue;
                }
                if (otherMesh.material !== current.material) {
                    continue;
                }
                if (otherMesh.checkCollisions !== current.checkCollisions) {
                    continue;
                }
                currentPool.push(otherMesh);
                globalLength--;
                globalPool.splice(subIndex, 1);
                subIndex--;
            }
            if (currentPool.length < 2) {
                continue;
            }
            // Merge meshes
            _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"].MergeMeshes(currentPool, undefined, true);
        }
        // Call the octree system optimization if it is defined.
        var sceneAsAny = scene;
        if (sceneAsAny.createOrUpdateSelectionOctree) {
            if (updateSelectionTree != undefined) {
                if (updateSelectionTree) {
                    sceneAsAny.createOrUpdateSelectionOctree();
                }
            }
            else if (MergeMeshesOptimization.UpdateSelectionTree) {
                sceneAsAny.createOrUpdateSelectionOctree();
            }
        }
        return true;
    };
    MergeMeshesOptimization._UpdateSelectionTree = false;
    return MergeMeshesOptimization;
}(SceneOptimization));

/**
 * Defines a list of options used by SceneOptimizer
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var SceneOptimizerOptions = /** @class */ (function () {
    /**
     * Creates a new list of options used by SceneOptimizer
     * @param targetFrameRate defines the target frame rate to reach (60 by default)
     * @param trackerDuration defines the interval between two checkes (2000ms by default)
     */
    function SceneOptimizerOptions(
    /**
     * Defines the target frame rate to reach (60 by default)
     */
    targetFrameRate,
    /**
     * Defines the interval between two checkes (2000ms by default)
     */
    trackerDuration) {
        if (targetFrameRate === void 0) { targetFrameRate = 60; }
        if (trackerDuration === void 0) { trackerDuration = 2000; }
        this.targetFrameRate = targetFrameRate;
        this.trackerDuration = trackerDuration;
        /**
         * Gets the list of optimizations to apply
         */
        this.optimizations = new Array();
    }
    /**
     * Add a new optimization
     * @param optimization defines the SceneOptimization to add to the list of active optimizations
     * @returns the current SceneOptimizerOptions
     */
    SceneOptimizerOptions.prototype.addOptimization = function (optimization) {
        this.optimizations.push(optimization);
        return this;
    };
    /**
     * Add a new custom optimization
     * @param onApply defines the callback called to apply the custom optimization (true if everything that can be done was applied)
     * @param onGetDescription defines the callback called to get the description attached with the optimization.
     * @param priority defines the priority of this optimization (0 by default which means first in the list)
     * @returns the current SceneOptimizerOptions
     */
    SceneOptimizerOptions.prototype.addCustomOptimization = function (onApply, onGetDescription, priority) {
        if (priority === void 0) { priority = 0; }
        var optimization = new CustomOptimization(priority);
        optimization.onApply = onApply;
        optimization.onGetDescription = onGetDescription;
        this.optimizations.push(optimization);
        return this;
    };
    /**
     * Creates a list of pre-defined optimizations aimed to reduce the visual impact on the scene
     * @param targetFrameRate defines the target frame rate (60 by default)
     * @returns a SceneOptimizerOptions object
     */
    SceneOptimizerOptions.LowDegradationAllowed = function (targetFrameRate) {
        var result = new SceneOptimizerOptions(targetFrameRate);
        var priority = 0;
        result.addOptimization(new MergeMeshesOptimization(priority));
        result.addOptimization(new ShadowsOptimization(priority));
        result.addOptimization(new LensFlaresOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new PostProcessesOptimization(priority));
        result.addOptimization(new ParticlesOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new TextureOptimization(priority, 1024));
        return result;
    };
    /**
     * Creates a list of pre-defined optimizations aimed to have a moderate impact on the scene visual
     * @param targetFrameRate defines the target frame rate (60 by default)
     * @returns a SceneOptimizerOptions object
     */
    SceneOptimizerOptions.ModerateDegradationAllowed = function (targetFrameRate) {
        var result = new SceneOptimizerOptions(targetFrameRate);
        var priority = 0;
        result.addOptimization(new MergeMeshesOptimization(priority));
        result.addOptimization(new ShadowsOptimization(priority));
        result.addOptimization(new LensFlaresOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new PostProcessesOptimization(priority));
        result.addOptimization(new ParticlesOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new TextureOptimization(priority, 512));
        // Next priority
        priority++;
        result.addOptimization(new RenderTargetsOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new HardwareScalingOptimization(priority, 2));
        return result;
    };
    /**
     * Creates a list of pre-defined optimizations aimed to have a big impact on the scene visual
     * @param targetFrameRate defines the target frame rate (60 by default)
     * @returns a SceneOptimizerOptions object
     */
    SceneOptimizerOptions.HighDegradationAllowed = function (targetFrameRate) {
        var result = new SceneOptimizerOptions(targetFrameRate);
        var priority = 0;
        result.addOptimization(new MergeMeshesOptimization(priority));
        result.addOptimization(new ShadowsOptimization(priority));
        result.addOptimization(new LensFlaresOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new PostProcessesOptimization(priority));
        result.addOptimization(new ParticlesOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new TextureOptimization(priority, 256));
        // Next priority
        priority++;
        result.addOptimization(new RenderTargetsOptimization(priority));
        // Next priority
        priority++;
        result.addOptimization(new HardwareScalingOptimization(priority, 4));
        return result;
    };
    return SceneOptimizerOptions;
}());

/**
 * Class used to run optimizations in order to reach a target frame rate
 * @description More details at http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer
 */
var SceneOptimizer = /** @class */ (function () {
    /**
     * Creates a new SceneOptimizer
     * @param scene defines the scene to work on
     * @param options defines the options to use with the SceneOptimizer
     * @param autoGeneratePriorities defines if priorities must be generated and not read from SceneOptimization property (true by default)
     * @param improvementMode defines if the scene optimizer must run the maximum optimization while staying over a target frame instead of trying to reach the target framerate (false by default)
     */
    function SceneOptimizer(scene, options, autoGeneratePriorities, improvementMode) {
        var _this = this;
        if (autoGeneratePriorities === void 0) { autoGeneratePriorities = true; }
        if (improvementMode === void 0) { improvementMode = false; }
        this._isRunning = false;
        this._currentPriorityLevel = 0;
        this._targetFrameRate = 60;
        this._trackerDuration = 2000;
        this._currentFrameRate = 0;
        this._improvementMode = false;
        /**
         * Defines an observable called when the optimizer reaches the target frame rate
         */
        this.onSuccessObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Defines an observable called when the optimizer enables an optimization
         */
        this.onNewOptimizationAppliedObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Defines an observable called when the optimizer is not able to reach the target frame rate
         */
        this.onFailureObservable = new _observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        if (!options) {
            this._options = new SceneOptimizerOptions();
        }
        else {
            this._options = options;
        }
        if (this._options.targetFrameRate) {
            this._targetFrameRate = this._options.targetFrameRate;
        }
        if (this._options.trackerDuration) {
            this._trackerDuration = this._options.trackerDuration;
        }
        if (autoGeneratePriorities) {
            var priority = 0;
            for (var _i = 0, _a = this._options.optimizations; _i < _a.length; _i++) {
                var optim = _a[_i];
                optim.priority = priority++;
            }
        }
        this._improvementMode = improvementMode;
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_1__["EngineStore"].LastCreatedScene;
        this._sceneDisposeObserver = this._scene.onDisposeObservable.add(function () {
            _this._sceneDisposeObserver = null;
            _this.dispose();
        });
    }
    Object.defineProperty(SceneOptimizer.prototype, "isInImprovementMode", {
        /**
         * Gets a boolean indicating if the optimizer is in improvement mode
         */
        get: function () {
            return this._improvementMode;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneOptimizer.prototype, "currentPriorityLevel", {
        /**
         * Gets the current priority level (0 at start)
         */
        get: function () {
            return this._currentPriorityLevel;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneOptimizer.prototype, "currentFrameRate", {
        /**
         * Gets the current frame rate checked by the SceneOptimizer
         */
        get: function () {
            return this._currentFrameRate;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneOptimizer.prototype, "targetFrameRate", {
        /**
         * Gets or sets the current target frame rate (60 by default)
         */
        get: function () {
            return this._targetFrameRate;
        },
        /**
         * Gets or sets the current target frame rate (60 by default)
         */
        set: function (value) {
            this._targetFrameRate = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneOptimizer.prototype, "trackerDuration", {
        /**
         * Gets or sets the current interval between two checks (every 2000ms by default)
         */
        get: function () {
            return this._trackerDuration;
        },
        /**
         * Gets or sets the current interval between two checks (every 2000ms by default)
         */
        set: function (value) {
            this._trackerDuration = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SceneOptimizer.prototype, "optimizations", {
        /**
         * Gets the list of active optimizations
         */
        get: function () {
            return this._options.optimizations;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Stops the current optimizer
     */
    SceneOptimizer.prototype.stop = function () {
        this._isRunning = false;
    };
    /**
     * Reset the optimizer to initial step (current priority level = 0)
     */
    SceneOptimizer.prototype.reset = function () {
        this._currentPriorityLevel = 0;
    };
    /**
     * Start the optimizer. By default it will try to reach a specific framerate
     * but if the optimizer is set with improvementMode === true then it will run all optimiatiation while frame rate is above the target frame rate
     */
    SceneOptimizer.prototype.start = function () {
        var _this = this;
        if (this._isRunning) {
            return;
        }
        this._isRunning = true;
        // Let's wait for the scene to be ready before running our check
        this._scene.executeWhenReady(function () {
            setTimeout(function () {
                _this._checkCurrentState();
            }, _this._trackerDuration);
        });
    };
    SceneOptimizer.prototype._checkCurrentState = function () {
        var _this = this;
        if (!this._isRunning) {
            return;
        }
        var scene = this._scene;
        var options = this._options;
        this._currentFrameRate = Math.round(scene.getEngine().getFps());
        if (this._improvementMode && this._currentFrameRate <= this._targetFrameRate ||
            !this._improvementMode && this._currentFrameRate >= this._targetFrameRate) {
            this._isRunning = false;
            this.onSuccessObservable.notifyObservers(this);
            return;
        }
        // Apply current level of optimizations
        var allDone = true;
        var noOptimizationApplied = true;
        for (var index = 0; index < options.optimizations.length; index++) {
            var optimization = options.optimizations[index];
            if (optimization.priority === this._currentPriorityLevel) {
                noOptimizationApplied = false;
                allDone = allDone && optimization.apply(scene, this);
                this.onNewOptimizationAppliedObservable.notifyObservers(optimization);
            }
        }
        // If no optimization was applied, this is a failure :(
        if (noOptimizationApplied) {
            this._isRunning = false;
            this.onFailureObservable.notifyObservers(this);
            return;
        }
        // If all optimizations were done, move to next level
        if (allDone) {
            this._currentPriorityLevel++;
        }
        // Let's the system running for a specific amount of time before checking FPS
        scene.executeWhenReady(function () {
            setTimeout(function () {
                _this._checkCurrentState();
            }, _this._trackerDuration);
        });
    };
    /**
     * Release all resources
     */
    SceneOptimizer.prototype.dispose = function () {
        this.stop();
        this.onSuccessObservable.clear();
        this.onFailureObservable.clear();
        this.onNewOptimizationAppliedObservable.clear();
        if (this._sceneDisposeObserver) {
            this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);
        }
    };
    /**
     * Helper function to create a SceneOptimizer with one single line of code
     * @param scene defines the scene to work on
     * @param options defines the options to use with the SceneOptimizer
     * @param onSuccess defines a callback to call on success
     * @param onFailure defines a callback to call on failure
     * @returns the new SceneOptimizer object
     */
    SceneOptimizer.OptimizeAsync = function (scene, options, onSuccess, onFailure) {
        var optimizer = new SceneOptimizer(scene, options || SceneOptimizerOptions.ModerateDegradationAllowed(), false);
        if (onSuccess) {
            optimizer.onSuccessObservable.add(function () {
                onSuccess();
            });
        }
        if (onFailure) {
            optimizer.onFailureObservable.add(function () {
                onFailure();
            });
        }
        optimizer.start();
        return optimizer;
    };
    return SceneOptimizer;
}());



/***/ }),

/***/ "./Misc/sceneSerializer.ts":
/*!*********************************!*\
  !*** ./Misc/sceneSerializer.ts ***!
  \*********************************/
/*! exports provided: SceneSerializer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneSerializer", function() { return SceneSerializer; });
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/multiMaterial */ "./Materials/multiMaterial.ts");
/* harmony import */ var _decorators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./decorators */ "./Misc/decorators.ts");




var serializedGeometries = [];
var serializeGeometry = function (geometry, serializationGeometries) {
    if (serializedGeometries[geometry.id]) {
        return;
    }
    if (geometry.doNotSerialize) {
        return;
    }
    serializationGeometries.vertexData.push(geometry.serializeVerticeData());
    serializedGeometries[geometry.id] = true;
};
var serializeMesh = function (mesh, serializationScene) {
    var serializationObject = {};
    // Geometry
    var geometry = mesh._geometry;
    if (geometry) {
        if (!mesh.getScene().getGeometryByID(geometry.id)) {
            // Geometry was in the memory but not added to the scene, nevertheless it's better to serialize to be able to reload the mesh with its geometry
            serializeGeometry(geometry, serializationScene.geometries);
        }
    }
    // Custom
    if (mesh.serialize) {
        mesh.serialize(serializationObject);
    }
    return serializationObject;
};
var finalizeSingleMesh = function (mesh, serializationObject) {
    //only works if the mesh is already loaded
    if (mesh.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].DELAYLOADSTATE_LOADED || mesh.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].DELAYLOADSTATE_NONE) {
        //serialize material
        if (mesh.material && !mesh.material.doNotSerialize) {
            if (mesh.material instanceof _Materials_multiMaterial__WEBPACK_IMPORTED_MODULE_2__["MultiMaterial"]) {
                serializationObject.multiMaterials = serializationObject.multiMaterials || [];
                serializationObject.materials = serializationObject.materials || [];
                if (!serializationObject.multiMaterials.some(function (mat) { return (mat.id === mesh.material.id); })) {
                    serializationObject.multiMaterials.push(mesh.material.serialize());
                    var _loop_1 = function (submaterial) {
                        if (submaterial) {
                            if (!serializationObject.materials.some(function (mat) { return (mat.id === submaterial.id); })) {
                                serializationObject.materials.push(submaterial.serialize());
                            }
                        }
                    };
                    for (var _i = 0, _a = mesh.material.subMaterials; _i < _a.length; _i++) {
                        var submaterial = _a[_i];
                        _loop_1(submaterial);
                    }
                }
            }
            else {
                serializationObject.materials = serializationObject.materials || [];
                if (!serializationObject.materials.some(function (mat) { return (mat.id === mesh.material.id); })) {
                    serializationObject.materials.push(mesh.material.serialize());
                }
            }
        }
        //serialize geometry
        var geometry = mesh._geometry;
        if (geometry) {
            if (!serializationObject.geometries) {
                serializationObject.geometries = {};
                serializationObject.geometries.boxes = [];
                serializationObject.geometries.spheres = [];
                serializationObject.geometries.cylinders = [];
                serializationObject.geometries.toruses = [];
                serializationObject.geometries.grounds = [];
                serializationObject.geometries.planes = [];
                serializationObject.geometries.torusKnots = [];
                serializationObject.geometries.vertexData = [];
            }
            serializeGeometry(geometry, serializationObject.geometries);
        }
        // Skeletons
        if (mesh.skeleton && !mesh.skeleton.doNotSerialize) {
            serializationObject.skeletons = serializationObject.skeletons || [];
            serializationObject.skeletons.push(mesh.skeleton.serialize());
        }
        //serialize the actual mesh
        serializationObject.meshes = serializationObject.meshes || [];
        serializationObject.meshes.push(serializeMesh(mesh, serializationObject));
    }
};
/**
 * Class used to serialize a scene into a string
 */
var SceneSerializer = /** @class */ (function () {
    function SceneSerializer() {
    }
    /**
     * Clear cache used by a previous serialization
     */
    SceneSerializer.ClearCache = function () {
        serializedGeometries = [];
    };
    /**
     * Serialize a scene into a JSON compatible object
     * @param scene defines the scene to serialize
     * @returns a JSON compatible object
     */
    SceneSerializer.Serialize = function (scene) {
        var serializationObject = {};
        SceneSerializer.ClearCache();
        // Scene
        serializationObject.useDelayedTextureLoading = scene.useDelayedTextureLoading;
        serializationObject.autoClear = scene.autoClear;
        serializationObject.clearColor = scene.clearColor.asArray();
        serializationObject.ambientColor = scene.ambientColor.asArray();
        serializationObject.gravity = scene.gravity.asArray();
        serializationObject.collisionsEnabled = scene.collisionsEnabled;
        // Fog
        if (scene.fogMode && scene.fogMode !== 0) {
            serializationObject.fogMode = scene.fogMode;
            serializationObject.fogColor = scene.fogColor.asArray();
            serializationObject.fogStart = scene.fogStart;
            serializationObject.fogEnd = scene.fogEnd;
            serializationObject.fogDensity = scene.fogDensity;
        }
        //Physics
        if (scene.isPhysicsEnabled()) {
            var physicEngine = scene.getPhysicsEngine();
            if (physicEngine) {
                serializationObject.physicsEnabled = true;
                serializationObject.physicsGravity = physicEngine.gravity.asArray();
                serializationObject.physicsEngine = physicEngine.getPhysicsPluginName();
            }
        }
        // Metadata
        if (scene.metadata) {
            serializationObject.metadata = scene.metadata;
        }
        // Morph targets
        serializationObject.morphTargetManagers = [];
        for (var _i = 0, _a = scene.meshes; _i < _a.length; _i++) {
            var abstractMesh = _a[_i];
            var manager = abstractMesh.morphTargetManager;
            if (manager) {
                serializationObject.morphTargetManagers.push(manager.serialize());
            }
        }
        // Lights
        serializationObject.lights = [];
        var index;
        var light;
        for (index = 0; index < scene.lights.length; index++) {
            light = scene.lights[index];
            if (!light.doNotSerialize) {
                serializationObject.lights.push(light.serialize());
            }
        }
        // Cameras
        serializationObject.cameras = [];
        for (index = 0; index < scene.cameras.length; index++) {
            var camera = scene.cameras[index];
            if (!camera.doNotSerialize) {
                serializationObject.cameras.push(camera.serialize());
            }
        }
        if (scene.activeCamera) {
            serializationObject.activeCameraID = scene.activeCamera.id;
        }
        // Animations
        _decorators__WEBPACK_IMPORTED_MODULE_3__["SerializationHelper"].AppendSerializedAnimations(scene, serializationObject);
        // Animation Groups
        if (scene.animationGroups && scene.animationGroups.length > 0) {
            serializationObject.animationGroups = [];
            for (var animationGroupIndex = 0; animationGroupIndex < scene.animationGroups.length; animationGroupIndex++) {
                var animationGroup = scene.animationGroups[animationGroupIndex];
                serializationObject.animationGroups.push(animationGroup.serialize());
            }
        }
        // Reflection probes
        if (scene.reflectionProbes && scene.reflectionProbes.length > 0) {
            serializationObject.reflectionProbes = [];
            for (index = 0; index < scene.reflectionProbes.length; index++) {
                var reflectionProbe = scene.reflectionProbes[index];
                serializationObject.reflectionProbes.push(reflectionProbe.serialize());
            }
        }
        // Materials
        serializationObject.materials = [];
        serializationObject.multiMaterials = [];
        var material;
        for (index = 0; index < scene.materials.length; index++) {
            material = scene.materials[index];
            if (!material.doNotSerialize) {
                serializationObject.materials.push(material.serialize());
            }
        }
        // MultiMaterials
        serializationObject.multiMaterials = [];
        for (index = 0; index < scene.multiMaterials.length; index++) {
            var multiMaterial = scene.multiMaterials[index];
            serializationObject.multiMaterials.push(multiMaterial.serialize());
        }
        // Environment texture
        if (scene.environmentTexture) {
            serializationObject.environmentTexture = scene.environmentTexture.name;
        }
        // Environment Intensity
        serializationObject.environmentIntensity = scene.environmentIntensity;
        // Skeletons
        serializationObject.skeletons = [];
        for (index = 0; index < scene.skeletons.length; index++) {
            var skeleton = scene.skeletons[index];
            if (!skeleton.doNotSerialize) {
                serializationObject.skeletons.push(skeleton.serialize());
            }
        }
        // Transform nodes
        serializationObject.transformNodes = [];
        for (index = 0; index < scene.transformNodes.length; index++) {
            serializationObject.transformNodes.push(scene.transformNodes[index].serialize());
        }
        // Geometries
        serializationObject.geometries = {};
        serializationObject.geometries.boxes = [];
        serializationObject.geometries.spheres = [];
        serializationObject.geometries.cylinders = [];
        serializationObject.geometries.toruses = [];
        serializationObject.geometries.grounds = [];
        serializationObject.geometries.planes = [];
        serializationObject.geometries.torusKnots = [];
        serializationObject.geometries.vertexData = [];
        serializedGeometries = [];
        var geometries = scene.getGeometries();
        for (index = 0; index < geometries.length; index++) {
            var geometry = geometries[index];
            if (geometry.isReady()) {
                serializeGeometry(geometry, serializationObject.geometries);
            }
        }
        // Meshes
        serializationObject.meshes = [];
        for (index = 0; index < scene.meshes.length; index++) {
            var abstractMesh = scene.meshes[index];
            if (abstractMesh instanceof _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"]) {
                var mesh = abstractMesh;
                if (!mesh.doNotSerialize) {
                    if (mesh.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].DELAYLOADSTATE_LOADED || mesh.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].DELAYLOADSTATE_NONE) {
                        serializationObject.meshes.push(serializeMesh(mesh, serializationObject));
                    }
                }
            }
        }
        // Particles Systems
        serializationObject.particleSystems = [];
        for (index = 0; index < scene.particleSystems.length; index++) {
            serializationObject.particleSystems.push(scene.particleSystems[index].serialize());
        }
        // Action Manager
        if (scene.actionManager) {
            serializationObject.actions = scene.actionManager.serialize("scene");
        }
        // Components
        for (var _b = 0, _c = scene._serializableComponents; _b < _c.length; _b++) {
            var component = _c[_b];
            component.serialize(serializationObject);
        }
        return serializationObject;
    };
    /**
     * Serialize a mesh into a JSON compatible object
     * @param toSerialize defines the mesh to serialize
     * @param withParents defines if parents must be serialized as well
     * @param withChildren defines if children must be serialized as well
     * @returns a JSON compatible object
     */
    SceneSerializer.SerializeMesh = function (toSerialize /* Mesh || Mesh[] */, withParents, withChildren) {
        if (withParents === void 0) { withParents = false; }
        if (withChildren === void 0) { withChildren = false; }
        var serializationObject = {};
        SceneSerializer.ClearCache();
        toSerialize = (toSerialize instanceof Array) ? toSerialize : [toSerialize];
        if (withParents || withChildren) {
            //deliberate for loop! not for each, appended should be processed as well.
            for (var i = 0; i < toSerialize.length; ++i) {
                if (withChildren) {
                    toSerialize[i].getDescendants().forEach(function (node) {
                        if (node instanceof _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"] && (toSerialize.indexOf(node) < 0) && !node.doNotSerialize) {
                            toSerialize.push(node);
                        }
                    });
                }
                //make sure the array doesn't contain the object already
                if (withParents && toSerialize[i].parent && (toSerialize.indexOf(toSerialize[i].parent) < 0) && !toSerialize[i].parent.doNotSerialize) {
                    toSerialize.push(toSerialize[i].parent);
                }
            }
        }
        toSerialize.forEach(function (mesh) {
            finalizeSingleMesh(mesh, serializationObject);
        });
        return serializationObject;
    };
    return SceneSerializer;
}());



/***/ }),

/***/ "./Misc/screenshotTools.ts":
/*!*********************************!*\
  !*** ./Misc/screenshotTools.ts ***!
  \*********************************/
/*! exports provided: ScreenshotTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScreenshotTools", function() { return ScreenshotTools; });
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _PostProcesses_fxaaPostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../PostProcesses/fxaaPostProcess */ "./PostProcesses/fxaaPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./logger */ "./Misc/logger.ts");
/* harmony import */ var _tools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./tools */ "./Misc/tools.ts");






/**
 * Class containing a set of static utilities functions for screenshots
 */
var ScreenshotTools = /** @class */ (function () {
    function ScreenshotTools() {
    }
    /**
     * Captures a screenshot of the current rendering
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine defines the rendering engine
     * @param camera defines the source camera
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param successCallback defines the callback receives a single parameter which contains the
     * screenshot as a string of base64-encoded characters. This string can be assigned to the
     * src parameter of an <img> to display it
     * @param mimeType defines the MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     */
    ScreenshotTools.CreateScreenshot = function (engine, camera, size, successCallback, mimeType) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        var _a = ScreenshotTools._getScreenshotSize(engine, camera, size), height = _a.height, width = _a.width;
        if (!(height && width)) {
            _logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Invalid 'size' parameter !");
            return;
        }
        if (!_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"]._ScreenshotCanvas) {
            _tools__WEBPACK_IMPORTED_MODULE_5__["Tools"]._ScreenshotCanvas = document.createElement('canvas');
        }
        _tools__WEBPACK_IMPORTED_MODULE_5__["Tools"]._ScreenshotCanvas.width = width;
        _tools__WEBPACK_IMPORTED_MODULE_5__["Tools"]._ScreenshotCanvas.height = height;
        var renderContext = _tools__WEBPACK_IMPORTED_MODULE_5__["Tools"]._ScreenshotCanvas.getContext("2d");
        var ratio = engine.getRenderWidth() / engine.getRenderHeight();
        var newWidth = width;
        var newHeight = newWidth / ratio;
        if (newHeight > height) {
            newHeight = height;
            newWidth = newHeight * ratio;
        }
        var offsetX = Math.max(0, width - newWidth) / 2;
        var offsetY = Math.max(0, height - newHeight) / 2;
        var renderingCanvas = engine.getRenderingCanvas();
        if (renderContext && renderingCanvas) {
            renderContext.drawImage(renderingCanvas, offsetX, offsetY, newWidth, newHeight);
        }
        _tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].EncodeScreenshotCanvasData(successCallback, mimeType);
    };
    /**
     * Captures a screenshot of the current rendering
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine defines the rendering engine
     * @param camera defines the source camera
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param mimeType defines the MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     * @returns screenshot as a string of base64-encoded characters. This string can be assigned
     * to the src parameter of an <img> to display it
     */
    ScreenshotTools.CreateScreenshotAsync = function (engine, camera, size, mimeType) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        return new Promise(function (resolve, reject) {
            ScreenshotTools.CreateScreenshot(engine, camera, size, function (data) {
                if (typeof (data) !== "undefined") {
                    resolve(data);
                }
                else {
                    reject(new Error("Data is undefined"));
                }
            }, mimeType);
        });
    };
    /**
     * Generates an image screenshot from the specified camera.
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine The engine to use for rendering
     * @param camera The camera to use for rendering
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param successCallback The callback receives a single parameter which contains the
     * screenshot as a string of base64-encoded characters. This string can be assigned to the
     * src parameter of an <img> to display it
     * @param mimeType The MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     * @param samples Texture samples (default: 1)
     * @param antialiasing Whether antialiasing should be turned on or not (default: false)
     * @param fileName A name for for the downloaded file.
     */
    ScreenshotTools.CreateScreenshotUsingRenderTarget = function (engine, camera, size, successCallback, mimeType, samples, antialiasing, fileName) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        if (samples === void 0) { samples = 1; }
        if (antialiasing === void 0) { antialiasing = false; }
        var _a = ScreenshotTools._getScreenshotSize(engine, camera, size), height = _a.height, width = _a.width;
        var targetTextureSize = { width: width, height: height };
        if (!(height && width)) {
            _logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("Invalid 'size' parameter !");
            return;
        }
        var scene = camera.getScene();
        var previousCamera = null;
        if (scene.activeCamera !== camera) {
            previousCamera = scene.activeCamera;
            scene.activeCamera = camera;
        }
        var renderCanvas = engine.getRenderingCanvas();
        if (!renderCanvas) {
            _logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Error("No rendering canvas found !");
            return;
        }
        var originalSize = { width: renderCanvas.width, height: renderCanvas.height };
        engine.setSize(width, height);
        scene.render();
        // At this point size can be a number, or an object (according to engine.prototype.createRenderTargetTexture method)
        var texture = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_1__["RenderTargetTexture"]("screenShot", targetTextureSize, scene, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].NEAREST_SAMPLINGMODE);
        texture.renderList = null;
        texture.samples = samples;
        if (antialiasing) {
            texture.addPostProcess(new _PostProcesses_fxaaPostProcess__WEBPACK_IMPORTED_MODULE_2__["FxaaPostProcess"]('antialiasing', 1.0, scene.activeCamera));
        }
        texture.onAfterRenderObservable.add(function () {
            _tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].DumpFramebuffer(width, height, engine, successCallback, mimeType, fileName);
        });
        scene.incrementRenderId();
        scene.resetCachedMaterial();
        texture.render(true);
        texture.dispose();
        if (previousCamera) {
            scene.activeCamera = previousCamera;
        }
        engine.setSize(originalSize.width, originalSize.height);
        camera.getProjectionMatrix(true); // Force cache refresh;
    };
    /**
     * Generates an image screenshot from the specified camera.
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine The engine to use for rendering
     * @param camera The camera to use for rendering
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param mimeType The MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     * @param samples Texture samples (default: 1)
     * @param antialiasing Whether antialiasing should be turned on or not (default: false)
     * @param fileName A name for for the downloaded file.
     * @returns screenshot as a string of base64-encoded characters. This string can be assigned
     * to the src parameter of an <img> to display it
     */
    ScreenshotTools.CreateScreenshotUsingRenderTargetAsync = function (engine, camera, size, mimeType, samples, antialiasing, fileName) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        if (samples === void 0) { samples = 1; }
        if (antialiasing === void 0) { antialiasing = false; }
        return new Promise(function (resolve, reject) {
            ScreenshotTools.CreateScreenshotUsingRenderTarget(engine, camera, size, function (data) {
                if (typeof (data) !== "undefined") {
                    resolve(data);
                }
                else {
                    reject(new Error("Data is undefined"));
                }
            }, mimeType, samples, antialiasing, fileName);
        });
    };
    /**
     * Gets height and width for screenshot size
     * @private
     */
    ScreenshotTools._getScreenshotSize = function (engine, camera, size) {
        var height = 0;
        var width = 0;
        //If a size value defined as object
        if (typeof (size) === 'object') {
            var precision = size.precision
                ? Math.abs(size.precision) // prevent GL_INVALID_VALUE : glViewport: negative width/height
                : 1;
            //If a width and height values is specified
            if (size.width && size.height) {
                height = size.height * precision;
                width = size.width * precision;
            }
            //If passing only width, computing height to keep display canvas ratio.
            else if (size.width && !size.height) {
                width = size.width * precision;
                height = Math.round(width / engine.getAspectRatio(camera));
            }
            //If passing only height, computing width to keep display canvas ratio.
            else if (size.height && !size.width) {
                height = size.height * precision;
                width = Math.round(height * engine.getAspectRatio(camera));
            }
            else {
                width = Math.round(engine.getRenderWidth() * precision);
                height = Math.round(width / engine.getAspectRatio(camera));
            }
        }
        //Assuming here that "size" parameter is a number
        else if (!isNaN(size)) {
            height = size;
            width = size;
        }
        return { height: height, width: width };
    };
    return ScreenshotTools;
}());

_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].CreateScreenshot = ScreenshotTools.CreateScreenshot;
_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].CreateScreenshotAsync = ScreenshotTools.CreateScreenshotAsync;
_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].CreateScreenshotUsingRenderTarget = ScreenshotTools.CreateScreenshotUsingRenderTarget;
_tools__WEBPACK_IMPORTED_MODULE_5__["Tools"].CreateScreenshotUsingRenderTargetAsync = ScreenshotTools.CreateScreenshotUsingRenderTargetAsync;


/***/ }),

/***/ "./Misc/smartArray.ts":
/*!****************************!*\
  !*** ./Misc/smartArray.ts ***!
  \****************************/
/*! exports provided: SmartArray, SmartArrayNoDuplicate */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SmartArray", function() { return SmartArray; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SmartArrayNoDuplicate", function() { return SmartArrayNoDuplicate; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");

/**
 * Defines an GC Friendly array where the backfield array do not shrink to prevent over allocations.
 */
var SmartArray = /** @class */ (function () {
    /**
     * Instantiates a Smart Array.
     * @param capacity defines the default capacity of the array.
     */
    function SmartArray(capacity) {
        /**
         * The active length of the array.
         */
        this.length = 0;
        this.data = new Array(capacity);
        this._id = SmartArray._GlobalId++;
    }
    /**
     * Pushes a value at the end of the active data.
     * @param value defines the object to push in the array.
     */
    SmartArray.prototype.push = function (value) {
        this.data[this.length++] = value;
        if (this.length > this.data.length) {
            this.data.length *= 2;
        }
    };
    /**
     * Iterates over the active data and apply the lambda to them.
     * @param func defines the action to apply on each value.
     */
    SmartArray.prototype.forEach = function (func) {
        for (var index = 0; index < this.length; index++) {
            func(this.data[index]);
        }
    };
    /**
     * Sorts the full sets of data.
     * @param compareFn defines the comparison function to apply.
     */
    SmartArray.prototype.sort = function (compareFn) {
        this.data.sort(compareFn);
    };
    /**
     * Resets the active data to an empty array.
     */
    SmartArray.prototype.reset = function () {
        this.length = 0;
    };
    /**
     * Releases all the data from the array as well as the array.
     */
    SmartArray.prototype.dispose = function () {
        this.reset();
        if (this.data) {
            this.data.length = 0;
            this.data = [];
        }
    };
    /**
     * Concats the active data with a given array.
     * @param array defines the data to concatenate with.
     */
    SmartArray.prototype.concat = function (array) {
        if (array.length === 0) {
            return;
        }
        if (this.length + array.length > this.data.length) {
            this.data.length = (this.length + array.length) * 2;
        }
        for (var index = 0; index < array.length; index++) {
            this.data[this.length++] = (array.data || array)[index];
        }
    };
    /**
     * Returns the position of a value in the active data.
     * @param value defines the value to find the index for
     * @returns the index if found in the active data otherwise -1
     */
    SmartArray.prototype.indexOf = function (value) {
        var position = this.data.indexOf(value);
        if (position >= this.length) {
            return -1;
        }
        return position;
    };
    /**
     * Returns whether an element is part of the active data.
     * @param value defines the value to look for
     * @returns true if found in the active data otherwise false
     */
    SmartArray.prototype.contains = function (value) {
        return this.indexOf(value) !== -1;
    };
    // Statics
    SmartArray._GlobalId = 0;
    return SmartArray;
}());

/**
 * Defines an GC Friendly array where the backfield array do not shrink to prevent over allocations.
 * The data in this array can only be present once
 */
var SmartArrayNoDuplicate = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SmartArrayNoDuplicate, _super);
    function SmartArrayNoDuplicate() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._duplicateId = 0;
        return _this;
    }
    /**
     * Pushes a value at the end of the active data.
     * THIS DOES NOT PREVENT DUPPLICATE DATA
     * @param value defines the object to push in the array.
     */
    SmartArrayNoDuplicate.prototype.push = function (value) {
        _super.prototype.push.call(this, value);
        if (!value.__smartArrayFlags) {
            value.__smartArrayFlags = {};
        }
        value.__smartArrayFlags[this._id] = this._duplicateId;
    };
    /**
     * Pushes a value at the end of the active data.
     * If the data is already present, it won t be added again
     * @param value defines the object to push in the array.
     * @returns true if added false if it was already present
     */
    SmartArrayNoDuplicate.prototype.pushNoDuplicate = function (value) {
        if (value.__smartArrayFlags && value.__smartArrayFlags[this._id] === this._duplicateId) {
            return false;
        }
        this.push(value);
        return true;
    };
    /**
     * Resets the active data to an empty array.
     */
    SmartArrayNoDuplicate.prototype.reset = function () {
        _super.prototype.reset.call(this);
        this._duplicateId++;
    };
    /**
     * Concats the active data with a given array.
     * This ensures no dupplicate will be present in the result.
     * @param array defines the data to concatenate with.
     */
    SmartArrayNoDuplicate.prototype.concatWithNoDuplicate = function (array) {
        if (array.length === 0) {
            return;
        }
        if (this.length + array.length > this.data.length) {
            this.data.length = (this.length + array.length) * 2;
        }
        for (var index = 0; index < array.length; index++) {
            var item = (array.data || array)[index];
            this.pushNoDuplicate(item);
        }
    };
    return SmartArrayNoDuplicate;
}(SmartArray));



/***/ }),

/***/ "./Misc/stringDictionary.ts":
/*!**********************************!*\
  !*** ./Misc/stringDictionary.ts ***!
  \**********************************/
/*! exports provided: StringDictionary */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StringDictionary", function() { return StringDictionary; });
/**
 * This class implement a typical dictionary using a string as key and the generic type T as value.
 * The underlying implementation relies on an associative array to ensure the best performances.
 * The value can be anything including 'null' but except 'undefined'
 */
var StringDictionary = /** @class */ (function () {
    function StringDictionary() {
        this._count = 0;
        this._data = {};
    }
    /**
     * This will clear this dictionary and copy the content from the 'source' one.
     * If the T value is a custom object, it won't be copied/cloned, the same object will be used
     * @param source the dictionary to take the content from and copy to this dictionary
     */
    StringDictionary.prototype.copyFrom = function (source) {
        var _this = this;
        this.clear();
        source.forEach(function (t, v) { return _this.add(t, v); });
    };
    /**
     * Get a value based from its key
     * @param key the given key to get the matching value from
     * @return the value if found, otherwise undefined is returned
     */
    StringDictionary.prototype.get = function (key) {
        var val = this._data[key];
        if (val !== undefined) {
            return val;
        }
        return undefined;
    };
    /**
     * Get a value from its key or add it if it doesn't exist.
     * This method will ensure you that a given key/data will be present in the dictionary.
     * @param key the given key to get the matching value from
     * @param factory the factory that will create the value if the key is not present in the dictionary.
     * The factory will only be invoked if there's no data for the given key.
     * @return the value corresponding to the key.
     */
    StringDictionary.prototype.getOrAddWithFactory = function (key, factory) {
        var val = this.get(key);
        if (val !== undefined) {
            return val;
        }
        val = factory(key);
        if (val) {
            this.add(key, val);
        }
        return val;
    };
    /**
     * Get a value from its key if present in the dictionary otherwise add it
     * @param key the key to get the value from
     * @param val if there's no such key/value pair in the dictionary add it with this value
     * @return the value corresponding to the key
     */
    StringDictionary.prototype.getOrAdd = function (key, val) {
        var curVal = this.get(key);
        if (curVal !== undefined) {
            return curVal;
        }
        this.add(key, val);
        return val;
    };
    /**
     * Check if there's a given key in the dictionary
     * @param key the key to check for
     * @return true if the key is present, false otherwise
     */
    StringDictionary.prototype.contains = function (key) {
        return this._data[key] !== undefined;
    };
    /**
     * Add a new key and its corresponding value
     * @param key the key to add
     * @param value the value corresponding to the key
     * @return true if the operation completed successfully, false if we couldn't insert the key/value because there was already this key in the dictionary
     */
    StringDictionary.prototype.add = function (key, value) {
        if (this._data[key] !== undefined) {
            return false;
        }
        this._data[key] = value;
        ++this._count;
        return true;
    };
    /**
     * Update a specific value associated to a key
     * @param key defines the key to use
     * @param value defines the value to store
     * @returns true if the value was updated (or false if the key was not found)
     */
    StringDictionary.prototype.set = function (key, value) {
        if (this._data[key] === undefined) {
            return false;
        }
        this._data[key] = value;
        return true;
    };
    /**
     * Get the element of the given key and remove it from the dictionary
     * @param key defines the key to search
     * @returns the value associated with the key or null if not found
     */
    StringDictionary.prototype.getAndRemove = function (key) {
        var val = this.get(key);
        if (val !== undefined) {
            delete this._data[key];
            --this._count;
            return val;
        }
        return null;
    };
    /**
     * Remove a key/value from the dictionary.
     * @param key the key to remove
     * @return true if the item was successfully deleted, false if no item with such key exist in the dictionary
     */
    StringDictionary.prototype.remove = function (key) {
        if (this.contains(key)) {
            delete this._data[key];
            --this._count;
            return true;
        }
        return false;
    };
    /**
     * Clear the whole content of the dictionary
     */
    StringDictionary.prototype.clear = function () {
        this._data = {};
        this._count = 0;
    };
    Object.defineProperty(StringDictionary.prototype, "count", {
        /**
         * Gets the current count
         */
        get: function () {
            return this._count;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Execute a callback on each key/val of the dictionary.
     * Note that you can remove any element in this dictionary in the callback implementation
     * @param callback the callback to execute on a given key/value pair
     */
    StringDictionary.prototype.forEach = function (callback) {
        for (var cur in this._data) {
            var val = this._data[cur];
            callback(cur, val);
        }
    };
    /**
     * Execute a callback on every occurrence of the dictionary until it returns a valid TRes object.
     * If the callback returns null or undefined the method will iterate to the next key/value pair
     * Note that you can remove any element in this dictionary in the callback implementation
     * @param callback the callback to execute, if it return a valid T instanced object the enumeration will stop and the object will be returned
     * @returns the first item
     */
    StringDictionary.prototype.first = function (callback) {
        for (var cur in this._data) {
            var val = this._data[cur];
            var res = callback(cur, val);
            if (res) {
                return res;
            }
        }
        return null;
    };
    return StringDictionary;
}());



/***/ }),

/***/ "./Misc/stringTools.ts":
/*!*****************************!*\
  !*** ./Misc/stringTools.ts ***!
  \*****************************/
/*! exports provided: StringTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StringTools", function() { return StringTools; });
/**
 * Helper to manipulate strings
 */
var StringTools = /** @class */ (function () {
    function StringTools() {
    }
    /**
     * Checks for a matching suffix at the end of a string (for ES5 and lower)
     * @param str Source string
     * @param suffix Suffix to search for in the source string
     * @returns Boolean indicating whether the suffix was found (true) or not (false)
     */
    StringTools.EndsWith = function (str, suffix) {
        return str.indexOf(suffix, str.length - suffix.length) !== -1;
    };
    /**
     * Checks for a matching suffix at the beginning of a string (for ES5 and lower)
     * @param str Source string
     * @param suffix Suffix to search for in the source string
     * @returns Boolean indicating whether the suffix was found (true) or not (false)
     */
    StringTools.StartsWith = function (str, suffix) {
        return str.indexOf(suffix) === 0;
    };
    return StringTools;
}());



/***/ }),

/***/ "./Misc/tags.ts":
/*!**********************!*\
  !*** ./Misc/tags.ts ***!
  \**********************/
/*! exports provided: Tags */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tags", function() { return Tags; });
/* harmony import */ var _andOrNotEvaluator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./andOrNotEvaluator */ "./Misc/andOrNotEvaluator.ts");

/**
 * Class used to store custom tags
 */
var Tags = /** @class */ (function () {
    function Tags() {
    }
    /**
     * Adds support for tags on the given object
     * @param obj defines the object to use
     */
    Tags.EnableFor = function (obj) {
        obj._tags = obj._tags || {};
        obj.hasTags = function () {
            return Tags.HasTags(obj);
        };
        obj.addTags = function (tagsString) {
            return Tags.AddTagsTo(obj, tagsString);
        };
        obj.removeTags = function (tagsString) {
            return Tags.RemoveTagsFrom(obj, tagsString);
        };
        obj.matchesTagsQuery = function (tagsQuery) {
            return Tags.MatchesQuery(obj, tagsQuery);
        };
    };
    /**
     * Removes tags support
     * @param obj defines the object to use
     */
    Tags.DisableFor = function (obj) {
        delete obj._tags;
        delete obj.hasTags;
        delete obj.addTags;
        delete obj.removeTags;
        delete obj.matchesTagsQuery;
    };
    /**
     * Gets a boolean indicating if the given object has tags
     * @param obj defines the object to use
     * @returns a boolean
     */
    Tags.HasTags = function (obj) {
        if (!obj._tags) {
            return false;
        }
        var tags = obj._tags;
        for (var i in tags) {
            if (tags.hasOwnProperty(i)) {
                return true;
            }
        }
        return false;
    };
    /**
     * Gets the tags available on a given object
     * @param obj defines the object to use
     * @param asString defines if the tags must be returned as a string instead of an array of strings
     * @returns the tags
     */
    Tags.GetTags = function (obj, asString) {
        if (asString === void 0) { asString = true; }
        if (!obj._tags) {
            return null;
        }
        if (asString) {
            var tagsArray = [];
            for (var tag in obj._tags) {
                if (obj._tags.hasOwnProperty(tag) && obj._tags[tag] === true) {
                    tagsArray.push(tag);
                }
            }
            return tagsArray.join(" ");
        }
        else {
            return obj._tags;
        }
    };
    /**
     * Adds tags to an object
     * @param obj defines the object to use
     * @param tagsString defines the tag string. The tags 'true' and 'false' are reserved and cannot be used as tags.
     * A tag cannot start with '||', '&&', and '!'. It cannot contain whitespaces
     */
    Tags.AddTagsTo = function (obj, tagsString) {
        if (!tagsString) {
            return;
        }
        if (typeof tagsString !== "string") {
            return;
        }
        var tags = tagsString.split(" ");
        tags.forEach(function (tag, index, array) {
            Tags._AddTagTo(obj, tag);
        });
    };
    /**
     * @hidden
     */
    Tags._AddTagTo = function (obj, tag) {
        tag = tag.trim();
        if (tag === "" || tag === "true" || tag === "false") {
            return;
        }
        if (tag.match(/[\s]/) || tag.match(/^([!]|([|]|[&]){2})/)) {
            return;
        }
        Tags.EnableFor(obj);
        obj._tags[tag] = true;
    };
    /**
     * Removes specific tags from a specific object
     * @param obj defines the object to use
     * @param tagsString defines the tags to remove
     */
    Tags.RemoveTagsFrom = function (obj, tagsString) {
        if (!Tags.HasTags(obj)) {
            return;
        }
        var tags = tagsString.split(" ");
        for (var t in tags) {
            Tags._RemoveTagFrom(obj, tags[t]);
        }
    };
    /**
     * @hidden
     */
    Tags._RemoveTagFrom = function (obj, tag) {
        delete obj._tags[tag];
    };
    /**
     * Defines if tags hosted on an object match a given query
     * @param obj defines the object to use
     * @param tagsQuery defines the tag query
     * @returns a boolean
     */
    Tags.MatchesQuery = function (obj, tagsQuery) {
        if (tagsQuery === undefined) {
            return true;
        }
        if (tagsQuery === "") {
            return Tags.HasTags(obj);
        }
        return _andOrNotEvaluator__WEBPACK_IMPORTED_MODULE_0__["AndOrNotEvaluator"].Eval(tagsQuery, function (r) { return Tags.HasTags(obj) && obj._tags[r]; });
    };
    return Tags;
}());



/***/ }),

/***/ "./Misc/textureTools.ts":
/*!******************************!*\
  !*** ./Misc/textureTools.ts ***!
  \******************************/
/*! exports provided: TextureTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextureTools", function() { return TextureTools; });
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../PostProcesses/passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");




/**
 * Class used to host texture specific utilities
 */
var TextureTools = /** @class */ (function () {
    function TextureTools() {
    }
    /**
     * Uses the GPU to create a copy texture rescaled at a given size
     * @param texture Texture to copy from
     * @param width defines the desired width
     * @param height defines the desired height
     * @param useBilinearMode defines if bilinear mode has to be used
     * @return the generated texture
     */
    TextureTools.CreateResizedCopy = function (texture, width, height, useBilinearMode) {
        if (useBilinearMode === void 0) { useBilinearMode = true; }
        var scene = texture.getScene();
        var engine = scene.getEngine();
        var rtt = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_1__["RenderTargetTexture"]('resized' + texture.name, { width: width, height: height }, scene, !texture.noMipmap, true, texture._texture.type, false, texture.samplingMode, false);
        rtt.wrapU = texture.wrapU;
        rtt.wrapV = texture.wrapV;
        rtt.uOffset = texture.uOffset;
        rtt.vOffset = texture.vOffset;
        rtt.uScale = texture.uScale;
        rtt.vScale = texture.vScale;
        rtt.uAng = texture.uAng;
        rtt.vAng = texture.vAng;
        rtt.wAng = texture.wAng;
        rtt.coordinatesIndex = texture.coordinatesIndex;
        rtt.level = texture.level;
        rtt.anisotropicFilteringLevel = texture.anisotropicFilteringLevel;
        rtt._texture.isReady = false;
        texture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].CLAMP_ADDRESSMODE;
        texture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].CLAMP_ADDRESSMODE;
        var passPostProcess = new _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_2__["PassPostProcess"]("pass", 1, null, useBilinearMode ? _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].BILINEAR_SAMPLINGMODE : _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__["Texture"].NEAREST_SAMPLINGMODE, engine, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        passPostProcess.getEffect().executeWhenCompiled(function () {
            passPostProcess.onApply = function (effect) {
                effect.setTexture("textureSampler", texture);
            };
            var internalTexture = rtt.getInternalTexture();
            if (internalTexture) {
                scene.postProcessManager.directRender([passPostProcess], internalTexture);
                engine.unBindFramebuffer(internalTexture);
                rtt.disposeFramebufferObjects();
                passPostProcess.dispose();
                internalTexture.isReady = true;
            }
        });
        return rtt;
    };
    return TextureTools;
}());



/***/ }),

/***/ "./Misc/tga.ts":
/*!*********************!*\
  !*** ./Misc/tga.ts ***!
  \*********************/
/*! exports provided: TGATools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TGATools", function() { return TGATools; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");

/**
 * Based on jsTGALoader - Javascript loader for TGA file
 * By Vincent Thibault
 * @see http://blog.robrowser.com/javascript-tga-loader.html
 */
var TGATools = /** @class */ (function () {
    function TGATools() {
    }
    /**
     * Gets the header of a TGA file
     * @param data defines the TGA data
     * @returns the header
     */
    TGATools.GetTGAHeader = function (data) {
        var offset = 0;
        var header = {
            id_length: data[offset++],
            colormap_type: data[offset++],
            image_type: data[offset++],
            colormap_index: data[offset++] | data[offset++] << 8,
            colormap_length: data[offset++] | data[offset++] << 8,
            colormap_size: data[offset++],
            origin: [
                data[offset++] | data[offset++] << 8,
                data[offset++] | data[offset++] << 8
            ],
            width: data[offset++] | data[offset++] << 8,
            height: data[offset++] | data[offset++] << 8,
            pixel_size: data[offset++],
            flags: data[offset++]
        };
        return header;
    };
    /**
     * Uploads TGA content to a Babylon Texture
     * @hidden
     */
    TGATools.UploadContent = function (texture, data) {
        // Not enough data to contain header ?
        if (data.length < 19) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Unable to load TGA file - Not enough data to contain header");
            return;
        }
        // Read Header
        var offset = 18;
        var header = TGATools.GetTGAHeader(data);
        // Assume it's a valid Targa file.
        if (header.id_length + offset > data.length) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Unable to load TGA file - Not enough data");
            return;
        }
        // Skip not needed data
        offset += header.id_length;
        var use_rle = false;
        var use_pal = false;
        var use_grey = false;
        // Get some informations.
        switch (header.image_type) {
            case TGATools._TYPE_RLE_INDEXED:
                use_rle = true;
            case TGATools._TYPE_INDEXED:
                use_pal = true;
                break;
            case TGATools._TYPE_RLE_RGB:
                use_rle = true;
            case TGATools._TYPE_RGB:
                // use_rgb = true;
                break;
            case TGATools._TYPE_RLE_GREY:
                use_rle = true;
            case TGATools._TYPE_GREY:
                use_grey = true;
                break;
        }
        var pixel_data;
        // var numAlphaBits = header.flags & 0xf;
        var pixel_size = header.pixel_size >> 3;
        var pixel_total = header.width * header.height * pixel_size;
        // Read palettes
        var palettes;
        if (use_pal) {
            palettes = data.subarray(offset, offset += header.colormap_length * (header.colormap_size >> 3));
        }
        // Read LRE
        if (use_rle) {
            pixel_data = new Uint8Array(pixel_total);
            var c, count, i;
            var localOffset = 0;
            var pixels = new Uint8Array(pixel_size);
            while (offset < pixel_total && localOffset < pixel_total) {
                c = data[offset++];
                count = (c & 0x7f) + 1;
                // RLE pixels
                if (c & 0x80) {
                    // Bind pixel tmp array
                    for (i = 0; i < pixel_size; ++i) {
                        pixels[i] = data[offset++];
                    }
                    // Copy pixel array
                    for (i = 0; i < count; ++i) {
                        pixel_data.set(pixels, localOffset + i * pixel_size);
                    }
                    localOffset += pixel_size * count;
                }
                // Raw pixels
                else {
                    count *= pixel_size;
                    for (i = 0; i < count; ++i) {
                        pixel_data[localOffset + i] = data[offset++];
                    }
                    localOffset += count;
                }
            }
        }
        // RAW Pixels
        else {
            pixel_data = data.subarray(offset, offset += (use_pal ? header.width * header.height : pixel_total));
        }
        // Load to texture
        var x_start, y_start, x_step, y_step, y_end, x_end;
        switch ((header.flags & TGATools._ORIGIN_MASK) >> TGATools._ORIGIN_SHIFT) {
            default:
            case TGATools._ORIGIN_UL:
                x_start = 0;
                x_step = 1;
                x_end = header.width;
                y_start = 0;
                y_step = 1;
                y_end = header.height;
                break;
            case TGATools._ORIGIN_BL:
                x_start = 0;
                x_step = 1;
                x_end = header.width;
                y_start = header.height - 1;
                y_step = -1;
                y_end = -1;
                break;
            case TGATools._ORIGIN_UR:
                x_start = header.width - 1;
                x_step = -1;
                x_end = -1;
                y_start = 0;
                y_step = 1;
                y_end = header.height;
                break;
            case TGATools._ORIGIN_BR:
                x_start = header.width - 1;
                x_step = -1;
                x_end = -1;
                y_start = header.height - 1;
                y_step = -1;
                y_end = -1;
                break;
        }
        // Load the specify method
        var func = '_getImageData' + (use_grey ? 'Grey' : '') + (header.pixel_size) + 'bits';
        var imageData = TGATools[func](header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end);
        var engine = texture.getEngine();
        engine._uploadDataToTextureDirectly(texture, imageData);
    };
    /** @hidden */
    TGATools._getImageData8bits = function (header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end) {
        var image = pixel_data, colormap = palettes;
        var width = header.width, height = header.height;
        var color, i = 0, x, y;
        var imageData = new Uint8Array(width * height * 4);
        for (y = y_start; y !== y_end; y += y_step) {
            for (x = x_start; x !== x_end; x += x_step, i++) {
                color = image[i];
                imageData[(x + width * y) * 4 + 3] = 255;
                imageData[(x + width * y) * 4 + 2] = colormap[(color * 3) + 0];
                imageData[(x + width * y) * 4 + 1] = colormap[(color * 3) + 1];
                imageData[(x + width * y) * 4 + 0] = colormap[(color * 3) + 2];
            }
        }
        return imageData;
    };
    /** @hidden */
    TGATools._getImageData16bits = function (header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end) {
        var image = pixel_data;
        var width = header.width, height = header.height;
        var color, i = 0, x, y;
        var imageData = new Uint8Array(width * height * 4);
        for (y = y_start; y !== y_end; y += y_step) {
            for (x = x_start; x !== x_end; x += x_step, i += 2) {
                color = image[i + 0] + (image[i + 1] << 8); // Inversed ?
                var r = (((color & 0x7C00) >> 10) * 255) / 0x1F | 0;
                var g = (((color & 0x03E0) >> 5) * 255) / 0x1F | 0;
                var b = ((color & 0x001F) * 255) / 0x1F | 0;
                imageData[(x + width * y) * 4 + 0] = r;
                imageData[(x + width * y) * 4 + 1] = g;
                imageData[(x + width * y) * 4 + 2] = b;
                imageData[(x + width * y) * 4 + 3] = (color & 0x8000) ? 0 : 255;
            }
        }
        return imageData;
    };
    /** @hidden */
    TGATools._getImageData24bits = function (header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end) {
        var image = pixel_data;
        var width = header.width, height = header.height;
        var i = 0, x, y;
        var imageData = new Uint8Array(width * height * 4);
        for (y = y_start; y !== y_end; y += y_step) {
            for (x = x_start; x !== x_end; x += x_step, i += 3) {
                imageData[(x + width * y) * 4 + 3] = 255;
                imageData[(x + width * y) * 4 + 2] = image[i + 0];
                imageData[(x + width * y) * 4 + 1] = image[i + 1];
                imageData[(x + width * y) * 4 + 0] = image[i + 2];
            }
        }
        return imageData;
    };
    /** @hidden */
    TGATools._getImageData32bits = function (header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end) {
        var image = pixel_data;
        var width = header.width, height = header.height;
        var i = 0, x, y;
        var imageData = new Uint8Array(width * height * 4);
        for (y = y_start; y !== y_end; y += y_step) {
            for (x = x_start; x !== x_end; x += x_step, i += 4) {
                imageData[(x + width * y) * 4 + 2] = image[i + 0];
                imageData[(x + width * y) * 4 + 1] = image[i + 1];
                imageData[(x + width * y) * 4 + 0] = image[i + 2];
                imageData[(x + width * y) * 4 + 3] = image[i + 3];
            }
        }
        return imageData;
    };
    /** @hidden */
    TGATools._getImageDataGrey8bits = function (header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end) {
        var image = pixel_data;
        var width = header.width, height = header.height;
        var color, i = 0, x, y;
        var imageData = new Uint8Array(width * height * 4);
        for (y = y_start; y !== y_end; y += y_step) {
            for (x = x_start; x !== x_end; x += x_step, i++) {
                color = image[i];
                imageData[(x + width * y) * 4 + 0] = color;
                imageData[(x + width * y) * 4 + 1] = color;
                imageData[(x + width * y) * 4 + 2] = color;
                imageData[(x + width * y) * 4 + 3] = 255;
            }
        }
        return imageData;
    };
    /** @hidden */
    TGATools._getImageDataGrey16bits = function (header, palettes, pixel_data, y_start, y_step, y_end, x_start, x_step, x_end) {
        var image = pixel_data;
        var width = header.width, height = header.height;
        var i = 0, x, y;
        var imageData = new Uint8Array(width * height * 4);
        for (y = y_start; y !== y_end; y += y_step) {
            for (x = x_start; x !== x_end; x += x_step, i += 2) {
                imageData[(x + width * y) * 4 + 0] = image[i + 0];
                imageData[(x + width * y) * 4 + 1] = image[i + 0];
                imageData[(x + width * y) * 4 + 2] = image[i + 0];
                imageData[(x + width * y) * 4 + 3] = image[i + 1];
            }
        }
        return imageData;
    };
    //private static _TYPE_NO_DATA = 0;
    TGATools._TYPE_INDEXED = 1;
    TGATools._TYPE_RGB = 2;
    TGATools._TYPE_GREY = 3;
    TGATools._TYPE_RLE_INDEXED = 9;
    TGATools._TYPE_RLE_RGB = 10;
    TGATools._TYPE_RLE_GREY = 11;
    TGATools._ORIGIN_MASK = 0x30;
    TGATools._ORIGIN_SHIFT = 0x04;
    TGATools._ORIGIN_BL = 0x00;
    TGATools._ORIGIN_BR = 0x01;
    TGATools._ORIGIN_UL = 0x02;
    TGATools._ORIGIN_UR = 0x03;
    return TGATools;
}());



/***/ }),

/***/ "./Misc/timingTools.ts":
/*!*****************************!*\
  !*** ./Misc/timingTools.ts ***!
  \*****************************/
/*! exports provided: TimingTools */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimingTools", function() { return TimingTools; });
/* harmony import */ var _domManagement__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./domManagement */ "./Misc/domManagement.ts");

/**
 * Class used to provide helper for timing
 */
var TimingTools = /** @class */ (function () {
    function TimingTools() {
    }
    /**
     * Polyfill for setImmediate
     * @param action defines the action to execute after the current execution block
     */
    TimingTools.SetImmediate = function (action) {
        if (_domManagement__WEBPACK_IMPORTED_MODULE_0__["DomManagement"].IsWindowObjectExist() && window.setImmediate) {
            window.setImmediate(action);
        }
        else {
            setTimeout(action, 1);
        }
    };
    return TimingTools;
}());



/***/ }),

/***/ "./Misc/tools.ts":
/*!***********************!*\
  !*** ./Misc/tools.ts ***!
  \***********************/
/*! exports provided: Tools, className, AsyncLoop */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tools", function() { return Tools; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "className", function() { return className; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AsyncLoop", function() { return AsyncLoop; });
/* harmony import */ var _observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./observable */ "./Misc/observable.ts");
/* harmony import */ var _domManagement__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./domManagement */ "./Misc/domManagement.ts");
/* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./logger */ "./Misc/logger.ts");
/* harmony import */ var _deepCopier__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _precisionDate__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./precisionDate */ "./Misc/precisionDate.ts");
/* harmony import */ var _devTools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./devTools */ "./Misc/devTools.ts");
/* harmony import */ var _webRequest__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./webRequest */ "./Misc/webRequest.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _fileTools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./fileTools */ "./Misc/fileTools.ts");
/* harmony import */ var _promise__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./promise */ "./Misc/promise.ts");
/* harmony import */ var _timingTools__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./timingTools */ "./Misc/timingTools.ts");
/* harmony import */ var _instantiationTools__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./instantiationTools */ "./Misc/instantiationTools.ts");
/* harmony import */ var _guid__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./guid */ "./Misc/guid.ts");













/**
 * Class containing a set of static utilities functions
 */
var Tools = /** @class */ (function () {
    function Tools() {
    }
    Object.defineProperty(Tools, "BaseUrl", {
        /**
         * Gets or sets the base URL to use to load assets
         */
        get: function () {
            return _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].BaseUrl;
        },
        set: function (value) {
            _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].BaseUrl = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tools, "DefaultRetryStrategy", {
        /**
         * Gets or sets the retry strategy to apply when an error happens while loading an asset
         */
        get: function () {
            return _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].DefaultRetryStrategy;
        },
        set: function (strategy) {
            _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].DefaultRetryStrategy = strategy;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tools, "UseFallbackTexture", {
        /**
         * Gets or sets a global variable indicating if fallback texture must be used when a texture cannot be loaded
         * @ignorenaming
         */
        get: function () {
            return _Engines_engineStore__WEBPACK_IMPORTED_MODULE_7__["EngineStore"].UseFallbackTexture;
        },
        set: function (value) {
            _Engines_engineStore__WEBPACK_IMPORTED_MODULE_7__["EngineStore"].UseFallbackTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tools, "RegisteredExternalClasses", {
        /**
         * Use this object to register external classes like custom textures or material
         * to allow the laoders to instantiate them
         */
        get: function () {
            return _instantiationTools__WEBPACK_IMPORTED_MODULE_11__["InstantiationTools"].RegisteredExternalClasses;
        },
        set: function (classes) {
            _instantiationTools__WEBPACK_IMPORTED_MODULE_11__["InstantiationTools"].RegisteredExternalClasses = classes;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tools, "fallbackTexture", {
        /**
         * Texture content used if a texture cannot loaded
         * @ignorenaming
         */
        get: function () {
            return _Engines_engineStore__WEBPACK_IMPORTED_MODULE_7__["EngineStore"].FallbackTexture;
        },
        set: function (value) {
            _Engines_engineStore__WEBPACK_IMPORTED_MODULE_7__["EngineStore"].FallbackTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Read the content of a byte array at a specified coordinates (taking in account wrapping)
     * @param u defines the coordinate on X axis
     * @param v defines the coordinate on Y axis
     * @param width defines the width of the source data
     * @param height defines the height of the source data
     * @param pixels defines the source byte array
     * @param color defines the output color
     */
    Tools.FetchToRef = function (u, v, width, height, pixels, color) {
        var wrappedU = ((Math.abs(u) * width) % width) | 0;
        var wrappedV = ((Math.abs(v) * height) % height) | 0;
        var position = (wrappedU + wrappedV * width) * 4;
        color.r = pixels[position] / 255;
        color.g = pixels[position + 1] / 255;
        color.b = pixels[position + 2] / 255;
        color.a = pixels[position + 3] / 255;
    };
    /**
     * Interpolates between a and b via alpha
     * @param a The lower value (returned when alpha = 0)
     * @param b The upper value (returned when alpha = 1)
     * @param alpha The interpolation-factor
     * @return The mixed value
     */
    Tools.Mix = function (a, b, alpha) {
        return a * (1 - alpha) + b * alpha;
    };
    /**
     * Tries to instantiate a new object from a given class name
     * @param className defines the class name to instantiate
     * @returns the new object or null if the system was not able to do the instantiation
     */
    Tools.Instantiate = function (className) {
        return _instantiationTools__WEBPACK_IMPORTED_MODULE_11__["InstantiationTools"].Instantiate(className);
    };
    /**
     * Provides a slice function that will work even on IE
     * @param data defines the array to slice
     * @param start defines the start of the data (optional)
     * @param end defines the end of the data (optional)
     * @returns the new sliced array
     */
    Tools.Slice = function (data, start, end) {
        if (data.slice) {
            return data.slice(start, end);
        }
        return Array.prototype.slice.call(data, start, end);
    };
    /**
     * Polyfill for setImmediate
     * @param action defines the action to execute after the current execution block
     */
    Tools.SetImmediate = function (action) {
        _timingTools__WEBPACK_IMPORTED_MODULE_10__["TimingTools"].SetImmediate(action);
    };
    /**
     * Function indicating if a number is an exponent of 2
     * @param value defines the value to test
     * @returns true if the value is an exponent of 2
     */
    Tools.IsExponentOfTwo = function (value) {
        var count = 1;
        do {
            count *= 2;
        } while (count < value);
        return count === value;
    };
    /**
     * Returns the nearest 32-bit single precision float representation of a Number
     * @param value A Number.  If the parameter is of a different type, it will get converted
     * to a number or to NaN if it cannot be converted
     * @returns number
     */
    Tools.FloatRound = function (value) {
        if (Math.fround) {
            return Math.fround(value);
        }
        return (Tools._tmpFloatArray[0] = value);
    };
    /**
     * Extracts the filename from a path
     * @param path defines the path to use
     * @returns the filename
     */
    Tools.GetFilename = function (path) {
        var index = path.lastIndexOf("/");
        if (index < 0) {
            return path;
        }
        return path.substring(index + 1);
    };
    /**
     * Extracts the "folder" part of a path (everything before the filename).
     * @param uri The URI to extract the info from
     * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present
     * @returns The "folder" part of the path
     */
    Tools.GetFolderPath = function (uri, returnUnchangedIfNoSlash) {
        if (returnUnchangedIfNoSlash === void 0) { returnUnchangedIfNoSlash = false; }
        var index = uri.lastIndexOf("/");
        if (index < 0) {
            if (returnUnchangedIfNoSlash) {
                return uri;
            }
            return "";
        }
        return uri.substring(0, index + 1);
    };
    /**
     * Convert an angle in radians to degrees
     * @param angle defines the angle to convert
     * @returns the angle in degrees
     */
    Tools.ToDegrees = function (angle) {
        return angle * 180 / Math.PI;
    };
    /**
     * Convert an angle in degrees to radians
     * @param angle defines the angle to convert
     * @returns the angle in radians
     */
    Tools.ToRadians = function (angle) {
        return angle * Math.PI / 180;
    };
    /**
     * Encode a buffer to a base64 string
     * @param buffer defines the buffer to encode
     * @returns the encoded string
     */
    Tools.EncodeArrayBufferTobase64 = function (buffer) {
        var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
        var bytes = new Uint8Array(buffer);
        while (i < bytes.length) {
            chr1 = bytes[i++];
            chr2 = i < bytes.length ? bytes[i++] : Number.NaN; // Not sure if the index
            chr3 = i < bytes.length ? bytes[i++] : Number.NaN; // checks are needed here
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            }
            else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output += keyStr.charAt(enc1) + keyStr.charAt(enc2) +
                keyStr.charAt(enc3) + keyStr.charAt(enc4);
        }
        return "data:image/png;base64," + output;
    };
    /**
     * Returns an array if obj is not an array
     * @param obj defines the object to evaluate as an array
     * @param allowsNullUndefined defines a boolean indicating if obj is allowed to be null or undefined
     * @returns either obj directly if obj is an array or a new array containing obj
     */
    Tools.MakeArray = function (obj, allowsNullUndefined) {
        if (allowsNullUndefined !== true && (obj === undefined || obj == null)) {
            return null;
        }
        return Array.isArray(obj) ? obj : [obj];
    };
    /**
     * Gets the pointer prefix to use
     * @returns "pointer" if touch is enabled. Else returns "mouse"
     */
    Tools.GetPointerPrefix = function () {
        var eventPrefix = "pointer";
        // Check if pointer events are supported
        if (_domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsWindowObjectExist() && !window.PointerEvent && _domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsNavigatorAvailable() && !navigator.pointerEnabled) {
            eventPrefix = "mouse";
        }
        return eventPrefix;
    };
    /**
     * Sets the cors behavior on a dom element. This will add the required Tools.CorsBehavior to the element.
     * @param url define the url we are trying
     * @param element define the dom element where to configure the cors policy
     */
    Tools.SetCorsBehavior = function (url, element) {
        _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].SetCorsBehavior(url, element);
    };
    // External files
    /**
     * Removes unwanted characters from an url
     * @param url defines the url to clean
     * @returns the cleaned url
     */
    Tools.CleanUrl = function (url) {
        url = url.replace(/#/mg, "%23");
        return url;
    };
    Object.defineProperty(Tools, "PreprocessUrl", {
        /**
         * Gets or sets a function used to pre-process url before using them to load assets
         */
        get: function () {
            return _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].PreprocessUrl;
        },
        set: function (processor) {
            _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].PreprocessUrl = processor;
        },
        enumerable: true,
        configurable: true
    });
    /**
    * Loads an image as an HTMLImageElement.
    * @param input url string, ArrayBuffer, or Blob to load
    * @param onLoad callback called when the image successfully loads
    * @param onError callback called when the image fails to load
    * @param offlineProvider offline provider for caching
    * @returns the HTMLImageElement of the loaded image
    */
    Tools.LoadImage = function (input, onLoad, onError, offlineProvider) {
        return _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].LoadImage(input, onLoad, onError, offlineProvider);
    };
    /**
     * Loads a file
     * @param url url string, ArrayBuffer, or Blob to load
     * @param onSuccess callback called when the file successfully loads
     * @param onProgress callback called while file is loading (if the server supports this mode)
     * @param offlineProvider defines the offline provider for caching
     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer
     * @param onError callback called when the file fails to load
     * @returns a file request object
     */
    Tools.LoadFile = function (url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError) {
        return _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);
    };
    /**
     * Loads a file from a url
     * @param url the file url to load
     * @returns a promise containing an ArrayBuffer corrisponding to the loaded file
     */
    Tools.LoadFileAsync = function (url) {
        return new Promise(function (resolve, reject) {
            _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].LoadFile(url, function (data) {
                resolve(data);
            }, undefined, undefined, true, function (request, exception) {
                reject(exception);
            });
        });
    };
    /**
     * Load a script (identified by an url). When the url returns, the
     * content of this file is added into a new script element, attached to the DOM (body element)
     * @param scriptUrl defines the url of the script to laod
     * @param onSuccess defines the callback called when the script is loaded
     * @param onError defines the callback to call if an error occurs
     * @param scriptId defines the id of the script element
     */
    Tools.LoadScript = function (scriptUrl, onSuccess, onError, scriptId) {
        if (!_domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsWindowObjectExist()) {
            return;
        }
        var head = document.getElementsByTagName('head')[0];
        var script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', scriptUrl);
        if (scriptId) {
            script.id = scriptId;
        }
        script.onload = function () {
            if (onSuccess) {
                onSuccess();
            }
        };
        script.onerror = function (e) {
            if (onError) {
                onError("Unable to load script '" + scriptUrl + "'", e);
            }
        };
        head.appendChild(script);
    };
    /**
     * Load an asynchronous script (identified by an url). When the url returns, the
     * content of this file is added into a new script element, attached to the DOM (body element)
     * @param scriptUrl defines the url of the script to laod
     * @param scriptId defines the id of the script element
     * @returns a promise request object
     */
    Tools.LoadScriptAsync = function (scriptUrl, scriptId) {
        return new Promise(function (resolve, reject) {
            if (!_domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsWindowObjectExist()) {
                resolve(false);
                return;
            }
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');
            script.setAttribute('type', 'text/javascript');
            script.setAttribute('src', scriptUrl);
            if (scriptId) {
                script.id = scriptId;
            }
            script.onload = function () {
                resolve(true);
            };
            script.onerror = function (e) {
                resolve(false);
            };
            head.appendChild(script);
        });
    };
    /**
     * Loads a file from a blob
     * @param fileToLoad defines the blob to use
     * @param callback defines the callback to call when data is loaded
     * @param progressCallback defines the callback to call during loading process
     * @returns a file request object
     */
    Tools.ReadFileAsDataURL = function (fileToLoad, callback, progressCallback) {
        var reader = new FileReader();
        var request = {
            onCompleteObservable: new _observable__WEBPACK_IMPORTED_MODULE_0__["Observable"](),
            abort: function () { return reader.abort(); },
        };
        reader.onloadend = function (e) {
            request.onCompleteObservable.notifyObservers(request);
        };
        reader.onload = function (e) {
            //target doesn't have result from ts 1.3
            callback(e.target['result']);
        };
        reader.onprogress = progressCallback;
        reader.readAsDataURL(fileToLoad);
        return request;
    };
    /**
     * Loads a file
     * @param fileToLoad defines the file to load
     * @param callback defines the callback to call when data is loaded
     * @param progressCallBack defines the callback to call during loading process
     * @param useArrayBuffer defines a boolean indicating that data must be returned as an ArrayBuffer
     * @returns a file request object
     */
    Tools.ReadFile = function (fileToLoad, callback, progressCallBack, useArrayBuffer) {
        return _fileTools__WEBPACK_IMPORTED_MODULE_8__["FileTools"].ReadFile(fileToLoad, callback, progressCallBack, useArrayBuffer);
    };
    /**
     * Creates a data url from a given string content
     * @param content defines the content to convert
     * @returns the new data url link
     */
    Tools.FileAsURL = function (content) {
        var fileBlob = new Blob([content]);
        var url = window.URL || window.webkitURL;
        var link = url.createObjectURL(fileBlob);
        return link;
    };
    /**
     * Format the given number to a specific decimal format
     * @param value defines the number to format
     * @param decimals defines the number of decimals to use
     * @returns the formatted string
     */
    Tools.Format = function (value, decimals) {
        if (decimals === void 0) { decimals = 2; }
        return value.toFixed(decimals);
    };
    /**
     * Tries to copy an object by duplicating every property
     * @param source defines the source object
     * @param destination defines the target object
     * @param doNotCopyList defines a list of properties to avoid
     * @param mustCopyList defines a list of properties to copy (even if they start with _)
     */
    Tools.DeepCopy = function (source, destination, doNotCopyList, mustCopyList) {
        _deepCopier__WEBPACK_IMPORTED_MODULE_3__["DeepCopier"].DeepCopy(source, destination, doNotCopyList, mustCopyList);
    };
    /**
     * Gets a boolean indicating if the given object has no own property
     * @param obj defines the object to test
     * @returns true if object has no own property
     */
    Tools.IsEmpty = function (obj) {
        for (var i in obj) {
            if (obj.hasOwnProperty(i)) {
                return false;
            }
        }
        return true;
    };
    /**
     * Function used to register events at window level
     * @param windowElement defines the Window object to use
     * @param events defines the events to register
     */
    Tools.RegisterTopRootEvents = function (windowElement, events) {
        for (var index = 0; index < events.length; index++) {
            var event = events[index];
            windowElement.addEventListener(event.name, event.handler, false);
            try {
                if (window.parent) {
                    window.parent.addEventListener(event.name, event.handler, false);
                }
            }
            catch (e) {
                // Silently fails...
            }
        }
    };
    /**
     * Function used to unregister events from window level
     * @param windowElement defines the Window object to use
     * @param events defines the events to unregister
     */
    Tools.UnregisterTopRootEvents = function (windowElement, events) {
        for (var index = 0; index < events.length; index++) {
            var event = events[index];
            windowElement.removeEventListener(event.name, event.handler);
            try {
                if (windowElement.parent) {
                    windowElement.parent.removeEventListener(event.name, event.handler);
                }
            }
            catch (e) {
                // Silently fails...
            }
        }
    };
    /**
     * Dumps the current bound framebuffer
     * @param width defines the rendering width
     * @param height defines the rendering height
     * @param engine defines the hosting engine
     * @param successCallback defines the callback triggered once the data are available
     * @param mimeType defines the mime type of the result
     * @param fileName defines the filename to download. If present, the result will automatically be downloaded
     */
    Tools.DumpFramebuffer = function (width, height, engine, successCallback, mimeType, fileName) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        // Read the contents of the framebuffer
        var numberOfChannelsByLine = width * 4;
        var halfHeight = height / 2;
        //Reading datas from WebGL
        var data = engine.readPixels(0, 0, width, height);
        //To flip image on Y axis.
        for (var i = 0; i < halfHeight; i++) {
            for (var j = 0; j < numberOfChannelsByLine; j++) {
                var currentCell = j + i * numberOfChannelsByLine;
                var targetLine = height - i - 1;
                var targetCell = j + targetLine * numberOfChannelsByLine;
                var temp = data[currentCell];
                data[currentCell] = data[targetCell];
                data[targetCell] = temp;
            }
        }
        // Create a 2D canvas to store the result
        if (!Tools._ScreenshotCanvas) {
            Tools._ScreenshotCanvas = document.createElement('canvas');
        }
        Tools._ScreenshotCanvas.width = width;
        Tools._ScreenshotCanvas.height = height;
        var context = Tools._ScreenshotCanvas.getContext('2d');
        if (context) {
            // Copy the pixels to a 2D canvas
            var imageData = context.createImageData(width, height);
            var castData = (imageData.data);
            castData.set(data);
            context.putImageData(imageData, 0, 0);
            Tools.EncodeScreenshotCanvasData(successCallback, mimeType, fileName);
        }
    };
    /**
     * Converts the canvas data to blob.
     * This acts as a polyfill for browsers not supporting the to blob function.
     * @param canvas Defines the canvas to extract the data from
     * @param successCallback Defines the callback triggered once the data are available
     * @param mimeType Defines the mime type of the result
     */
    Tools.ToBlob = function (canvas, successCallback, mimeType) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        // We need HTMLCanvasElement.toBlob for HD screenshots
        if (!canvas.toBlob) {
            //  low performance polyfill based on toDataURL (https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob)
            canvas.toBlob = function (callback, type, quality) {
                var _this = this;
                setTimeout(function () {
                    var binStr = atob(_this.toDataURL(type, quality).split(',')[1]), len = binStr.length, arr = new Uint8Array(len);
                    for (var i = 0; i < len; i++) {
                        arr[i] = binStr.charCodeAt(i);
                    }
                    callback(new Blob([arr]));
                });
            };
        }
        canvas.toBlob(function (blob) {
            successCallback(blob);
        }, mimeType);
    };
    /**
     * Encodes the canvas data to base 64 or automatically download the result if filename is defined
     * @param successCallback defines the callback triggered once the data are available
     * @param mimeType defines the mime type of the result
     * @param fileName defines he filename to download. If present, the result will automatically be downloaded
     */
    Tools.EncodeScreenshotCanvasData = function (successCallback, mimeType, fileName) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        if (successCallback) {
            var base64Image = Tools._ScreenshotCanvas.toDataURL(mimeType);
            successCallback(base64Image);
        }
        else {
            this.ToBlob(Tools._ScreenshotCanvas, function (blob) {
                //Creating a link if the browser have the download attribute on the a tag, to automatically start download generated image.
                if (("download" in document.createElement("a"))) {
                    if (!fileName) {
                        var date = new Date();
                        var stringDate = (date.getFullYear() + "-" + (date.getMonth() + 1)).slice(2) + "-" + date.getDate() + "_" + date.getHours() + "-" + ('0' + date.getMinutes()).slice(-2);
                        fileName = "screenshot_" + stringDate + ".png";
                    }
                    Tools.Download(blob, fileName);
                }
                else {
                    var url = URL.createObjectURL(blob);
                    var newWindow = window.open("");
                    if (!newWindow) {
                        return;
                    }
                    var img = newWindow.document.createElement("img");
                    img.onload = function () {
                        // no longer need to read the blob so it's revoked
                        URL.revokeObjectURL(url);
                    };
                    img.src = url;
                    newWindow.document.body.appendChild(img);
                }
            }, mimeType);
        }
    };
    /**
     * Downloads a blob in the browser
     * @param blob defines the blob to download
     * @param fileName defines the name of the downloaded file
     */
    Tools.Download = function (blob, fileName) {
        if (navigator && navigator.msSaveBlob) {
            navigator.msSaveBlob(blob, fileName);
            return;
        }
        var url = window.URL.createObjectURL(blob);
        var a = document.createElement("a");
        document.body.appendChild(a);
        a.style.display = "none";
        a.href = url;
        a.download = fileName;
        a.addEventListener("click", function () {
            if (a.parentElement) {
                a.parentElement.removeChild(a);
            }
        });
        a.click();
        window.URL.revokeObjectURL(url);
    };
    /**
     * Captures a screenshot of the current rendering
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine defines the rendering engine
     * @param camera defines the source camera
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param successCallback defines the callback receives a single parameter which contains the
     * screenshot as a string of base64-encoded characters. This string can be assigned to the
     * src parameter of an <img> to display it
     * @param mimeType defines the MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     */
    Tools.CreateScreenshot = function (engine, camera, size, successCallback, mimeType) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        throw _devTools__WEBPACK_IMPORTED_MODULE_5__["_DevTools"].WarnImport("ScreenshotTools");
    };
    /**
     * Captures a screenshot of the current rendering
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine defines the rendering engine
     * @param camera defines the source camera
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param mimeType defines the MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     * @returns screenshot as a string of base64-encoded characters. This string can be assigned
     * to the src parameter of an <img> to display it
     */
    Tools.CreateScreenshotAsync = function (engine, camera, size, mimeType) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        throw _devTools__WEBPACK_IMPORTED_MODULE_5__["_DevTools"].WarnImport("ScreenshotTools");
    };
    /**
     * Generates an image screenshot from the specified camera.
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine The engine to use for rendering
     * @param camera The camera to use for rendering
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param successCallback The callback receives a single parameter which contains the
     * screenshot as a string of base64-encoded characters. This string can be assigned to the
     * src parameter of an <img> to display it
     * @param mimeType The MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     * @param samples Texture samples (default: 1)
     * @param antialiasing Whether antialiasing should be turned on or not (default: false)
     * @param fileName A name for for the downloaded file.
     */
    Tools.CreateScreenshotUsingRenderTarget = function (engine, camera, size, successCallback, mimeType, samples, antialiasing, fileName) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        if (samples === void 0) { samples = 1; }
        if (antialiasing === void 0) { antialiasing = false; }
        throw _devTools__WEBPACK_IMPORTED_MODULE_5__["_DevTools"].WarnImport("ScreenshotTools");
    };
    /**
     * Generates an image screenshot from the specified camera.
     * @see http://doc.babylonjs.com/how_to/render_scene_on_a_png
     * @param engine The engine to use for rendering
     * @param camera The camera to use for rendering
     * @param size This parameter can be set to a single number or to an object with the
     * following (optional) properties: precision, width, height. If a single number is passed,
     * it will be used for both width and height. If an object is passed, the screenshot size
     * will be derived from the parameters. The precision property is a multiplier allowing
     * rendering at a higher or lower resolution
     * @param mimeType The MIME type of the screenshot image (default: image/png).
     * Check your browser for supported MIME types
     * @param samples Texture samples (default: 1)
     * @param antialiasing Whether antialiasing should be turned on or not (default: false)
     * @param fileName A name for for the downloaded file.
     * @returns screenshot as a string of base64-encoded characters. This string can be assigned
     * to the src parameter of an <img> to display it
     */
    Tools.CreateScreenshotUsingRenderTargetAsync = function (engine, camera, size, mimeType, samples, antialiasing, fileName) {
        if (mimeType === void 0) { mimeType = "image/png"; }
        if (samples === void 0) { samples = 1; }
        if (antialiasing === void 0) { antialiasing = false; }
        throw _devTools__WEBPACK_IMPORTED_MODULE_5__["_DevTools"].WarnImport("ScreenshotTools");
    };
    /**
     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
     * Be aware Math.random() could cause collisions, but:
     * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
     * @returns a pseudo random id
     */
    Tools.RandomId = function () {
        return _guid__WEBPACK_IMPORTED_MODULE_12__["GUID"].RandomId();
    };
    /**
    * Test if the given uri is a base64 string
    * @param uri The uri to test
    * @return True if the uri is a base64 string or false otherwise
    */
    Tools.IsBase64 = function (uri) {
        return uri.length < 5 ? false : uri.substr(0, 5) === "data:";
    };
    /**
    * Decode the given base64 uri.
    * @param uri The uri to decode
    * @return The decoded base64 data.
    */
    Tools.DecodeBase64 = function (uri) {
        var decodedString = atob(uri.split(",")[1]);
        var bufferLength = decodedString.length;
        var bufferView = new Uint8Array(new ArrayBuffer(bufferLength));
        for (var i = 0; i < bufferLength; i++) {
            bufferView[i] = decodedString.charCodeAt(i);
        }
        return bufferView.buffer;
    };
    /**
     * Gets the absolute url.
     * @param url the input url
     * @return the absolute url
     */
    Tools.GetAbsoluteUrl = function (url) {
        var a = document.createElement("a");
        a.href = url;
        return a.href;
    };
    Object.defineProperty(Tools, "errorsCount", {
        /**
         * Gets a value indicating the number of loading errors
         * @ignorenaming
         */
        get: function () {
            return _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].errorsCount;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Log a message to the console
     * @param message defines the message to log
     */
    Tools.Log = function (message) {
        _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Log(message);
    };
    /**
     * Write a warning message to the console
     * @param message defines the message to log
     */
    Tools.Warn = function (message) {
        _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn(message);
    };
    /**
     * Write an error message to the console
     * @param message defines the message to log
     */
    Tools.Error = function (message) {
        _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Error(message);
    };
    Object.defineProperty(Tools, "LogCache", {
        /**
         * Gets current log cache (list of logs)
         */
        get: function () {
            return _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].LogCache;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Clears the log cache
     */
    Tools.ClearLogCache = function () {
        _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].ClearLogCache();
    };
    Object.defineProperty(Tools, "LogLevels", {
        /**
         * Sets the current log level (MessageLogLevel / WarningLogLevel / ErrorLogLevel)
         */
        set: function (level) {
            _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].LogLevels = level;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Tools, "PerformanceLogLevel", {
        /**
         * Sets the current performance log level
         */
        set: function (level) {
            if ((level & Tools.PerformanceUserMarkLogLevel) === Tools.PerformanceUserMarkLogLevel) {
                Tools.StartPerformanceCounter = Tools._StartUserMark;
                Tools.EndPerformanceCounter = Tools._EndUserMark;
                return;
            }
            if ((level & Tools.PerformanceConsoleLogLevel) === Tools.PerformanceConsoleLogLevel) {
                Tools.StartPerformanceCounter = Tools._StartPerformanceConsole;
                Tools.EndPerformanceCounter = Tools._EndPerformanceConsole;
                return;
            }
            Tools.StartPerformanceCounter = Tools._StartPerformanceCounterDisabled;
            Tools.EndPerformanceCounter = Tools._EndPerformanceCounterDisabled;
        },
        enumerable: true,
        configurable: true
    });
    Tools._StartPerformanceCounterDisabled = function (counterName, condition) {
    };
    Tools._EndPerformanceCounterDisabled = function (counterName, condition) {
    };
    Tools._StartUserMark = function (counterName, condition) {
        if (condition === void 0) { condition = true; }
        if (!Tools._performance) {
            if (!_domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsWindowObjectExist()) {
                return;
            }
            Tools._performance = window.performance;
        }
        if (!condition || !Tools._performance.mark) {
            return;
        }
        Tools._performance.mark(counterName + "-Begin");
    };
    Tools._EndUserMark = function (counterName, condition) {
        if (condition === void 0) { condition = true; }
        if (!condition || !Tools._performance.mark) {
            return;
        }
        Tools._performance.mark(counterName + "-End");
        Tools._performance.measure(counterName, counterName + "-Begin", counterName + "-End");
    };
    Tools._StartPerformanceConsole = function (counterName, condition) {
        if (condition === void 0) { condition = true; }
        if (!condition) {
            return;
        }
        Tools._StartUserMark(counterName, condition);
        if (console.time) {
            console.time(counterName);
        }
    };
    Tools._EndPerformanceConsole = function (counterName, condition) {
        if (condition === void 0) { condition = true; }
        if (!condition) {
            return;
        }
        Tools._EndUserMark(counterName, condition);
        if (console.time) {
            console.timeEnd(counterName);
        }
    };
    Object.defineProperty(Tools, "Now", {
        /**
         * Gets either window.performance.now() if supported or Date.now() else
         */
        get: function () {
            return _precisionDate__WEBPACK_IMPORTED_MODULE_4__["PrecisionDate"].Now;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * This method will return the name of the class used to create the instance of the given object.
     * It will works only on Javascript basic data types (number, string, ...) and instance of class declared with the @className decorator.
     * @param object the object to get the class name from
     * @param isType defines if the object is actually a type
     * @returns the name of the class, will be "object" for a custom data type not using the @className decorator
     */
    Tools.GetClassName = function (object, isType) {
        if (isType === void 0) { isType = false; }
        var name = null;
        if (!isType && object.getClassName) {
            name = object.getClassName();
        }
        else {
            if (object instanceof Object) {
                var classObj = isType ? object : Object.getPrototypeOf(object);
                name = classObj.constructor["__bjsclassName__"];
            }
            if (!name) {
                name = typeof object;
            }
        }
        return name;
    };
    /**
     * Gets the first element of an array satisfying a given predicate
     * @param array defines the array to browse
     * @param predicate defines the predicate to use
     * @returns null if not found or the element
     */
    Tools.First = function (array, predicate) {
        for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
            var el = array_1[_i];
            if (predicate(el)) {
                return el;
            }
        }
        return null;
    };
    /**
     * This method will return the name of the full name of the class, including its owning module (if any).
     * It will works only on Javascript basic data types (number, string, ...) and instance of class declared with the @className decorator or implementing a method getClassName():string (in which case the module won't be specified).
     * @param object the object to get the class name from
     * @param isType defines if the object is actually a type
     * @return a string that can have two forms: "moduleName.className" if module was specified when the class' Name was registered or "className" if there was not module specified.
     * @ignorenaming
     */
    Tools.getFullClassName = function (object, isType) {
        if (isType === void 0) { isType = false; }
        var className = null;
        var moduleName = null;
        if (!isType && object.getClassName) {
            className = object.getClassName();
        }
        else {
            if (object instanceof Object) {
                var classObj = isType ? object : Object.getPrototypeOf(object);
                className = classObj.constructor["__bjsclassName__"];
                moduleName = classObj.constructor["__bjsmoduleName__"];
            }
            if (!className) {
                className = typeof object;
            }
        }
        if (!className) {
            return null;
        }
        return ((moduleName != null) ? (moduleName + ".") : "") + className;
    };
    /**
     * Returns a promise that resolves after the given amount of time.
     * @param delay Number of milliseconds to delay
     * @returns Promise that resolves after the given amount of time
     */
    Tools.DelayAsync = function (delay) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                resolve();
            }, delay);
        });
    };
    /**
     * Enable/Disable Custom HTTP Request Headers globally.
     * default = false
     * @see CustomRequestHeaders
     */
    Tools.UseCustomRequestHeaders = false;
    /**
     * Custom HTTP Request Headers to be sent with XMLHttpRequests
     * i.e. when loading files, where the server/service expects an Authorization header
     */
    Tools.CustomRequestHeaders = _webRequest__WEBPACK_IMPORTED_MODULE_6__["WebRequest"].CustomRequestHeaders;
    /**
     * Default behaviour for cors in the application.
     * It can be a string if the expected behavior is identical in the entire app.
     * Or a callback to be able to set it per url or on a group of them (in case of Video source for instance)
     */
    Tools.CorsBehavior = "anonymous";
    Tools._tmpFloatArray = new Float32Array(1);
    /**
     * Extracts text content from a DOM element hierarchy
     * Back Compat only, please use DomManagement.GetDOMTextContent instead.
     */
    Tools.GetDOMTextContent = _domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].GetDOMTextContent;
    // Logs
    /**
     * No log
     */
    Tools.NoneLogLevel = _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].NoneLogLevel;
    /**
     * Only message logs
     */
    Tools.MessageLogLevel = _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].MessageLogLevel;
    /**
     * Only warning logs
     */
    Tools.WarningLogLevel = _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].WarningLogLevel;
    /**
     * Only error logs
     */
    Tools.ErrorLogLevel = _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].ErrorLogLevel;
    /**
     * All logs
     */
    Tools.AllLogLevel = _logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].AllLogLevel;
    /**
     * Checks if the window object exists
     * Back Compat only, please use DomManagement.IsWindowObjectExist instead.
     */
    Tools.IsWindowObjectExist = _domManagement__WEBPACK_IMPORTED_MODULE_1__["DomManagement"].IsWindowObjectExist;
    // Performances
    /**
     * No performance log
     */
    Tools.PerformanceNoneLogLevel = 0;
    /**
     * Use user marks to log performance
     */
    Tools.PerformanceUserMarkLogLevel = 1;
    /**
     * Log performance to the console
     */
    Tools.PerformanceConsoleLogLevel = 2;
    /**
     * Starts a performance counter
     */
    Tools.StartPerformanceCounter = Tools._StartPerformanceCounterDisabled;
    /**
     * Ends a specific performance coutner
     */
    Tools.EndPerformanceCounter = Tools._EndPerformanceCounterDisabled;
    return Tools;
}());

/**
 * Use this className as a decorator on a given class definition to add it a name and optionally its module.
 * You can then use the Tools.getClassName(obj) on an instance to retrieve its class name.
 * This method is the only way to get it done in all cases, even if the .js file declaring the class is minified
 * @param name The name of the class, case should be preserved
 * @param module The name of the Module hosting the class, optional, but strongly recommended to specify if possible. Case should be preserved.
 */
function className(name, module) {
    return function (target) {
        target["__bjsclassName__"] = name;
        target["__bjsmoduleName__"] = (module != null) ? module : null;
    };
}
/**
 * An implementation of a loop for asynchronous functions.
 */
var AsyncLoop = /** @class */ (function () {
    /**
     * Constructor.
     * @param iterations the number of iterations.
     * @param func the function to run each iteration
     * @param successCallback the callback that will be called upon succesful execution
     * @param offset starting offset.
     */
    function AsyncLoop(
    /**
     * Defines the number of iterations for the loop
     */
    iterations, func, successCallback, offset) {
        if (offset === void 0) { offset = 0; }
        this.iterations = iterations;
        this.index = offset - 1;
        this._done = false;
        this._fn = func;
        this._successCallback = successCallback;
    }
    /**
     * Execute the next iteration. Must be called after the last iteration was finished.
     */
    AsyncLoop.prototype.executeNext = function () {
        if (!this._done) {
            if (this.index + 1 < this.iterations) {
                ++this.index;
                this._fn(this);
            }
            else {
                this.breakLoop();
            }
        }
    };
    /**
     * Break the loop and run the success callback.
     */
    AsyncLoop.prototype.breakLoop = function () {
        this._done = true;
        this._successCallback();
    };
    /**
     * Create and run an async loop.
     * @param iterations the number of iterations.
     * @param fn the function to run each iteration
     * @param successCallback the callback that will be called upon succesful execution
     * @param offset starting offset.
     * @returns the created async loop object
     */
    AsyncLoop.Run = function (iterations, fn, successCallback, offset) {
        if (offset === void 0) { offset = 0; }
        var loop = new AsyncLoop(iterations, fn, successCallback, offset);
        loop.executeNext();
        return loop;
    };
    /**
     * A for-loop that will run a given number of iterations synchronous and the rest async.
     * @param iterations total number of iterations
     * @param syncedIterations number of synchronous iterations in each async iteration.
     * @param fn the function to call each iteration.
     * @param callback a success call back that will be called when iterating stops.
     * @param breakFunction a break condition (optional)
     * @param timeout timeout settings for the setTimeout function. default - 0.
     * @returns the created async loop object
     */
    AsyncLoop.SyncAsyncForLoop = function (iterations, syncedIterations, fn, callback, breakFunction, timeout) {
        if (timeout === void 0) { timeout = 0; }
        return AsyncLoop.Run(Math.ceil(iterations / syncedIterations), function (loop) {
            if (breakFunction && breakFunction()) {
                loop.breakLoop();
            }
            else {
                setTimeout(function () {
                    for (var i = 0; i < syncedIterations; ++i) {
                        var iteration = (loop.index * syncedIterations) + i;
                        if (iteration >= iterations) {
                            break;
                        }
                        fn(iteration);
                        if (breakFunction && breakFunction()) {
                            loop.breakLoop();
                            break;
                        }
                    }
                    loop.executeNext();
                }, timeout);
            }
        }, callback);
    };
    return AsyncLoop;
}());

// Will only be define if Tools is imported freeing up some space when only engine is required
_Engines_engineStore__WEBPACK_IMPORTED_MODULE_7__["EngineStore"].FallbackTexture = "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QBmRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAAExAAIAAAAQAAAATgAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQubmV0IDQuMC41AP/bAEMABAIDAwMCBAMDAwQEBAQFCQYFBQUFCwgIBgkNCw0NDQsMDA4QFBEODxMPDAwSGBITFRYXFxcOERkbGRYaFBYXFv/bAEMBBAQEBQUFCgYGChYPDA8WFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFv/AABEIAQABAAMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APH6KKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FCiiigD6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++gooooA+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gUKKKKAPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76CiiigD5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BQooooA+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/voKKKKAPl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FCiiigD6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++gooooA+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gUKKKKAPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76CiiigD5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BQooooA+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/voKKKKAPl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FCiiigD6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++gooooA+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gUKKKKAPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76Pl+iiivuj+BT6gooor4U/vo+X6KKK+6P4FPqCiiivhT++j5fooor7o/gU+oKKKK+FP76P//Z";
// Register promise fallback for IE
_promise__WEBPACK_IMPORTED_MODULE_9__["PromisePolyfill"].Apply();


/***/ }),

/***/ "./Misc/typeStore.ts":
/*!***************************!*\
  !*** ./Misc/typeStore.ts ***!
  \***************************/
/*! exports provided: _TypeStore */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_TypeStore", function() { return _TypeStore; });
/** @hidden */
var _TypeStore = /** @class */ (function () {
    function _TypeStore() {
    }
    /** @hidden */
    _TypeStore.GetClass = function (fqdn) {
        if (this.RegisteredTypes && this.RegisteredTypes[fqdn]) {
            return this.RegisteredTypes[fqdn];
        }
        return null;
    };
    /** @hidden */
    _TypeStore.RegisteredTypes = {};
    return _TypeStore;
}());



/***/ }),

/***/ "./Misc/uniqueIdGenerator.ts":
/*!***********************************!*\
  !*** ./Misc/uniqueIdGenerator.ts ***!
  \***********************************/
/*! exports provided: UniqueIdGenerator */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UniqueIdGenerator", function() { return UniqueIdGenerator; });
/**
 * Helper class used to generate session unique ID
 */
var UniqueIdGenerator = /** @class */ (function () {
    function UniqueIdGenerator() {
    }
    Object.defineProperty(UniqueIdGenerator, "UniqueId", {
        /**
         * Gets an unique (relatively to the current scene) Id
         */
        get: function () {
            var result = this._UniqueIdCounter;
            this._UniqueIdCounter++;
            return result;
        },
        enumerable: true,
        configurable: true
    });
    // Statics
    UniqueIdGenerator._UniqueIdCounter = 0;
    return UniqueIdGenerator;
}());



/***/ }),

/***/ "./Misc/videoRecorder.ts":
/*!*******************************!*\
  !*** ./Misc/videoRecorder.ts ***!
  \*******************************/
/*! exports provided: VideoRecorder */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VideoRecorder", function() { return VideoRecorder; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tools */ "./Misc/tools.ts");


/**
 * This can help with recording videos from BabylonJS.
 * This is based on the available WebRTC functionalities of the browser.
 *
 * @see http://doc.babylonjs.com/how_to/render_scene_on_a_video
 */
var VideoRecorder = /** @class */ (function () {
    /**
     * Create a new VideoCapture object which can help converting what you see in Babylon to a video file.
     * @param engine Defines the BabylonJS Engine you wish to record.
     * @param options Defines options that can be used to customize the capture.
     */
    function VideoRecorder(engine, options) {
        if (options === void 0) { options = null; }
        if (!VideoRecorder.IsSupported(engine)) {
            throw "Your browser does not support recording so far.";
        }
        var canvas = engine.getRenderingCanvas();
        if (!canvas) {
            throw "The babylon engine must have a canvas to be recorded";
        }
        this._canvas = canvas;
        this._canvas.isRecording = false;
        this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, VideoRecorder._defaultOptions, options);
        var stream = this._canvas.captureStream(this._options.fps);
        if (this._options.audioTracks) {
            for (var _i = 0, _a = this._options.audioTracks; _i < _a.length; _i++) {
                var track = _a[_i];
                stream.addTrack(track);
            }
        }
        this._mediaRecorder = new MediaRecorder(stream, { mimeType: this._options.mimeType });
        this._mediaRecorder.ondataavailable = this._handleDataAvailable.bind(this);
        this._mediaRecorder.onerror = this._handleError.bind(this);
        this._mediaRecorder.onstop = this._handleStop.bind(this);
    }
    /**
     * Returns whether or not the VideoRecorder is available in your browser.
     * @param engine Defines the Babylon Engine.
     * @returns true if supported otherwise false.
     */
    VideoRecorder.IsSupported = function (engine) {
        var canvas = engine.getRenderingCanvas();
        return (!!canvas && typeof canvas.captureStream === "function");
    };
    Object.defineProperty(VideoRecorder.prototype, "isRecording", {
        /**
         * True when a recording is already in progress.
         */
        get: function () {
            return !!this._canvas && this._canvas.isRecording;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Stops the current recording before the default capture timeout passed in the startRecording function.
     */
    VideoRecorder.prototype.stopRecording = function () {
        if (!this._canvas || !this._mediaRecorder) {
            return;
        }
        if (!this.isRecording) {
            return;
        }
        this._canvas.isRecording = false;
        this._mediaRecorder.stop();
    };
    /**
     * Starts recording the canvas for a max duration specified in parameters.
     * @param fileName Defines the name of the file to be downloaded when the recording stop.
     * If null no automatic download will start and you can rely on the promise to get the data back.
     * @param maxDuration Defines the maximum recording time in seconds.
     * It defaults to 7 seconds. A value of zero will not stop automatically, you would need to call stopRecording manually.
     * @return A promise callback at the end of the recording with the video data in Blob.
     */
    VideoRecorder.prototype.startRecording = function (fileName, maxDuration) {
        var _this = this;
        if (fileName === void 0) { fileName = "babylonjs.webm"; }
        if (maxDuration === void 0) { maxDuration = 7; }
        if (!this._canvas || !this._mediaRecorder) {
            throw "Recorder has already been disposed";
        }
        if (this.isRecording) {
            throw "Recording already in progress";
        }
        if (maxDuration > 0) {
            setTimeout(function () {
                _this.stopRecording();
            }, maxDuration * 1000);
        }
        this._fileName = fileName;
        this._recordedChunks = [];
        this._resolve = null;
        this._reject = null;
        this._canvas.isRecording = true;
        this._mediaRecorder.start(this._options.recordChunckSize);
        return new Promise(function (resolve, reject) {
            _this._resolve = resolve;
            _this._reject = reject;
        });
    };
    /**
     * Releases internal resources used during the recording.
     */
    VideoRecorder.prototype.dispose = function () {
        this._canvas = null;
        this._mediaRecorder = null;
        this._recordedChunks = [];
        this._fileName = null;
        this._resolve = null;
        this._reject = null;
    };
    VideoRecorder.prototype._handleDataAvailable = function (event) {
        if (event.data.size > 0) {
            this._recordedChunks.push(event.data);
        }
    };
    VideoRecorder.prototype._handleError = function (event) {
        this.stopRecording();
        if (this._reject) {
            this._reject(event.error);
        }
        else {
            throw new event.error();
        }
    };
    VideoRecorder.prototype._handleStop = function () {
        this.stopRecording();
        var superBuffer = new Blob(this._recordedChunks);
        if (this._resolve) {
            this._resolve(superBuffer);
        }
        window.URL.createObjectURL(superBuffer);
        if (this._fileName) {
            _tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].Download(superBuffer, this._fileName);
        }
    };
    VideoRecorder._defaultOptions = {
        mimeType: "video/webm",
        fps: 25,
        recordChunckSize: 3000
    };
    return VideoRecorder;
}());



/***/ }),

/***/ "./Misc/virtualJoystick.ts":
/*!*********************************!*\
  !*** ./Misc/virtualJoystick.ts ***!
  \*********************************/
/*! exports provided: JoystickAxis, VirtualJoystick */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "JoystickAxis", function() { return JoystickAxis; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualJoystick", function() { return VirtualJoystick; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _stringDictionary__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./stringDictionary */ "./Misc/stringDictionary.ts");


// Mainly based on these 2 articles :
// Creating an universal virtual touch joystick working for all Touch models thanks to Hand.JS : http://blogs.msdn.com/b/davrous/archive/2013/02/22/creating-an-universal-virtual-touch-joystick-working-for-all-touch-models-thanks-to-hand-js.aspx
// & on Seb Lee-Delisle original work: http://seb.ly/2011/04/multi-touch-game-controller-in-javascripthtml5-for-ipad/
/**
 * Defines the potential axis of a Joystick
 */
var JoystickAxis;
(function (JoystickAxis) {
    /** X axis */
    JoystickAxis[JoystickAxis["X"] = 0] = "X";
    /** Y axis */
    JoystickAxis[JoystickAxis["Y"] = 1] = "Y";
    /** Z axis */
    JoystickAxis[JoystickAxis["Z"] = 2] = "Z";
})(JoystickAxis || (JoystickAxis = {}));
/**
 * Class used to define virtual joystick (used in touch mode)
 */
var VirtualJoystick = /** @class */ (function () {
    /**
     * Creates a new virtual joystick
     * @param leftJoystick defines that the joystick is for left hand (false by default)
     */
    function VirtualJoystick(leftJoystick) {
        var _this = this;
        if (leftJoystick) {
            this._leftJoystick = true;
        }
        else {
            this._leftJoystick = false;
        }
        VirtualJoystick._globalJoystickIndex++;
        // By default left & right arrow keys are moving the X
        // and up & down keys are moving the Y
        this._axisTargetedByLeftAndRight = JoystickAxis.X;
        this._axisTargetedByUpAndDown = JoystickAxis.Y;
        this.reverseLeftRight = false;
        this.reverseUpDown = false;
        // collections of pointers
        this._touches = new _stringDictionary__WEBPACK_IMPORTED_MODULE_1__["StringDictionary"]();
        this.deltaPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._joystickSensibility = 25;
        this._inversedSensibility = 1 / (this._joystickSensibility / 1000);
        this._onResize = function (evt) {
            VirtualJoystick.vjCanvasWidth = window.innerWidth;
            VirtualJoystick.vjCanvasHeight = window.innerHeight;
            if (VirtualJoystick.Canvas) {
                VirtualJoystick.Canvas.width = VirtualJoystick.vjCanvasWidth;
                VirtualJoystick.Canvas.height = VirtualJoystick.vjCanvasHeight;
            }
            VirtualJoystick.halfWidth = VirtualJoystick.vjCanvasWidth / 2;
        };
        // injecting a canvas element on top of the canvas 3D game
        if (!VirtualJoystick.Canvas) {
            window.addEventListener("resize", this._onResize, false);
            VirtualJoystick.Canvas = document.createElement("canvas");
            VirtualJoystick.vjCanvasWidth = window.innerWidth;
            VirtualJoystick.vjCanvasHeight = window.innerHeight;
            VirtualJoystick.Canvas.width = window.innerWidth;
            VirtualJoystick.Canvas.height = window.innerHeight;
            VirtualJoystick.Canvas.style.width = "100%";
            VirtualJoystick.Canvas.style.height = "100%";
            VirtualJoystick.Canvas.style.position = "absolute";
            VirtualJoystick.Canvas.style.backgroundColor = "transparent";
            VirtualJoystick.Canvas.style.top = "0px";
            VirtualJoystick.Canvas.style.left = "0px";
            VirtualJoystick.Canvas.style.zIndex = "5";
            VirtualJoystick.Canvas.style.msTouchAction = "none";
            // Support for jQuery PEP polyfill
            VirtualJoystick.Canvas.setAttribute("touch-action", "none");
            var context = VirtualJoystick.Canvas.getContext('2d');
            if (!context) {
                throw new Error("Unable to create canvas for virtual joystick");
            }
            VirtualJoystick.vjCanvasContext = context;
            VirtualJoystick.vjCanvasContext.strokeStyle = "#ffffff";
            VirtualJoystick.vjCanvasContext.lineWidth = 2;
            document.body.appendChild(VirtualJoystick.Canvas);
        }
        VirtualJoystick.halfWidth = VirtualJoystick.Canvas.width / 2;
        this.pressed = false;
        // default joystick color
        this._joystickColor = "cyan";
        this._joystickPointerID = -1;
        // current joystick position
        this._joystickPointerPos = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
        this._joystickPreviousPointerPos = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
        // origin joystick position
        this._joystickPointerStartPos = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
        this._deltaJoystickVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
        this._onPointerDownHandlerRef = function (evt) {
            _this._onPointerDown(evt);
        };
        this._onPointerMoveHandlerRef = function (evt) {
            _this._onPointerMove(evt);
        };
        this._onPointerUpHandlerRef = function (evt) {
            _this._onPointerUp(evt);
        };
        VirtualJoystick.Canvas.addEventListener('pointerdown', this._onPointerDownHandlerRef, false);
        VirtualJoystick.Canvas.addEventListener('pointermove', this._onPointerMoveHandlerRef, false);
        VirtualJoystick.Canvas.addEventListener('pointerup', this._onPointerUpHandlerRef, false);
        VirtualJoystick.Canvas.addEventListener('pointerout', this._onPointerUpHandlerRef, false);
        VirtualJoystick.Canvas.addEventListener("contextmenu", function (evt) {
            evt.preventDefault(); // Disables system menu
        }, false);
        requestAnimationFrame(function () { _this._drawVirtualJoystick(); });
    }
    /**
     * Defines joystick sensibility (ie. the ratio beteen a physical move and virtual joystick position change)
     * @param newJoystickSensibility defines the new sensibility
     */
    VirtualJoystick.prototype.setJoystickSensibility = function (newJoystickSensibility) {
        this._joystickSensibility = newJoystickSensibility;
        this._inversedSensibility = 1 / (this._joystickSensibility / 1000);
    };
    VirtualJoystick.prototype._onPointerDown = function (e) {
        var positionOnScreenCondition;
        e.preventDefault();
        if (this._leftJoystick === true) {
            positionOnScreenCondition = (e.clientX < VirtualJoystick.halfWidth);
        }
        else {
            positionOnScreenCondition = (e.clientX > VirtualJoystick.halfWidth);
        }
        if (positionOnScreenCondition && this._joystickPointerID < 0) {
            // First contact will be dedicated to the virtual joystick
            this._joystickPointerID = e.pointerId;
            this._joystickPointerStartPos.x = e.clientX;
            this._joystickPointerStartPos.y = e.clientY;
            this._joystickPointerPos = this._joystickPointerStartPos.clone();
            this._joystickPreviousPointerPos = this._joystickPointerStartPos.clone();
            this._deltaJoystickVector.x = 0;
            this._deltaJoystickVector.y = 0;
            this.pressed = true;
            this._touches.add(e.pointerId.toString(), e);
        }
        else {
            // You can only trigger the action buttons with a joystick declared
            if (VirtualJoystick._globalJoystickIndex < 2 && this._action) {
                this._action();
                this._touches.add(e.pointerId.toString(), { x: e.clientX, y: e.clientY, prevX: e.clientX, prevY: e.clientY });
            }
        }
    };
    VirtualJoystick.prototype._onPointerMove = function (e) {
        // If the current pointer is the one associated to the joystick (first touch contact)
        if (this._joystickPointerID == e.pointerId) {
            this._joystickPointerPos.x = e.clientX;
            this._joystickPointerPos.y = e.clientY;
            this._deltaJoystickVector = this._joystickPointerPos.clone();
            this._deltaJoystickVector = this._deltaJoystickVector.subtract(this._joystickPointerStartPos);
            var directionLeftRight = this.reverseLeftRight ? -1 : 1;
            var deltaJoystickX = directionLeftRight * this._deltaJoystickVector.x / this._inversedSensibility;
            switch (this._axisTargetedByLeftAndRight) {
                case JoystickAxis.X:
                    this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickX));
                    break;
                case JoystickAxis.Y:
                    this.deltaPosition.y = Math.min(1, Math.max(-1, deltaJoystickX));
                    break;
                case JoystickAxis.Z:
                    this.deltaPosition.z = Math.min(1, Math.max(-1, deltaJoystickX));
                    break;
            }
            var directionUpDown = this.reverseUpDown ? 1 : -1;
            var deltaJoystickY = directionUpDown * this._deltaJoystickVector.y / this._inversedSensibility;
            switch (this._axisTargetedByUpAndDown) {
                case JoystickAxis.X:
                    this.deltaPosition.x = Math.min(1, Math.max(-1, deltaJoystickY));
                    break;
                case JoystickAxis.Y:
                    this.deltaPosition.y = Math.min(1, Math.max(-1, deltaJoystickY));
                    break;
                case JoystickAxis.Z:
                    this.deltaPosition.z = Math.min(1, Math.max(-1, deltaJoystickY));
                    break;
            }
        }
        else {
            var data = this._touches.get(e.pointerId.toString());
            if (data) {
                data.x = e.clientX;
                data.y = e.clientY;
            }
        }
    };
    VirtualJoystick.prototype._onPointerUp = function (e) {
        if (this._joystickPointerID == e.pointerId) {
            VirtualJoystick.vjCanvasContext.clearRect(this._joystickPointerStartPos.x - 64, this._joystickPointerStartPos.y - 64, 128, 128);
            VirtualJoystick.vjCanvasContext.clearRect(this._joystickPreviousPointerPos.x - 42, this._joystickPreviousPointerPos.y - 42, 84, 84);
            this._joystickPointerID = -1;
            this.pressed = false;
        }
        else {
            var touch = this._touches.get(e.pointerId.toString());
            if (touch) {
                VirtualJoystick.vjCanvasContext.clearRect(touch.prevX - 44, touch.prevY - 44, 88, 88);
            }
        }
        this._deltaJoystickVector.x = 0;
        this._deltaJoystickVector.y = 0;
        this._touches.remove(e.pointerId.toString());
    };
    /**
    * Change the color of the virtual joystick
    * @param newColor a string that must be a CSS color value (like "red") or the hexa value (like "#FF0000")
    */
    VirtualJoystick.prototype.setJoystickColor = function (newColor) {
        this._joystickColor = newColor;
    };
    /**
     * Defines a callback to call when the joystick is touched
     * @param action defines the callback
     */
    VirtualJoystick.prototype.setActionOnTouch = function (action) {
        this._action = action;
    };
    /**
     * Defines which axis you'd like to control for left & right
     * @param axis defines the axis to use
     */
    VirtualJoystick.prototype.setAxisForLeftRight = function (axis) {
        switch (axis) {
            case JoystickAxis.X:
            case JoystickAxis.Y:
            case JoystickAxis.Z:
                this._axisTargetedByLeftAndRight = axis;
                break;
            default:
                this._axisTargetedByLeftAndRight = JoystickAxis.X;
                break;
        }
    };
    /**
     * Defines which axis you'd like to control for up & down
     * @param axis defines the axis to use
     */
    VirtualJoystick.prototype.setAxisForUpDown = function (axis) {
        switch (axis) {
            case JoystickAxis.X:
            case JoystickAxis.Y:
            case JoystickAxis.Z:
                this._axisTargetedByUpAndDown = axis;
                break;
            default:
                this._axisTargetedByUpAndDown = JoystickAxis.Y;
                break;
        }
    };
    VirtualJoystick.prototype._drawVirtualJoystick = function () {
        var _this = this;
        if (this.pressed) {
            this._touches.forEach(function (key, touch) {
                if (touch.pointerId === _this._joystickPointerID) {
                    VirtualJoystick.vjCanvasContext.clearRect(_this._joystickPointerStartPos.x - 64, _this._joystickPointerStartPos.y - 64, 128, 128);
                    VirtualJoystick.vjCanvasContext.clearRect(_this._joystickPreviousPointerPos.x - 42, _this._joystickPreviousPointerPos.y - 42, 84, 84);
                    VirtualJoystick.vjCanvasContext.beginPath();
                    VirtualJoystick.vjCanvasContext.lineWidth = 6;
                    VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
                    VirtualJoystick.vjCanvasContext.arc(_this._joystickPointerStartPos.x, _this._joystickPointerStartPos.y, 40, 0, Math.PI * 2, true);
                    VirtualJoystick.vjCanvasContext.stroke();
                    VirtualJoystick.vjCanvasContext.closePath();
                    VirtualJoystick.vjCanvasContext.beginPath();
                    VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
                    VirtualJoystick.vjCanvasContext.lineWidth = 2;
                    VirtualJoystick.vjCanvasContext.arc(_this._joystickPointerStartPos.x, _this._joystickPointerStartPos.y, 60, 0, Math.PI * 2, true);
                    VirtualJoystick.vjCanvasContext.stroke();
                    VirtualJoystick.vjCanvasContext.closePath();
                    VirtualJoystick.vjCanvasContext.beginPath();
                    VirtualJoystick.vjCanvasContext.strokeStyle = _this._joystickColor;
                    VirtualJoystick.vjCanvasContext.arc(_this._joystickPointerPos.x, _this._joystickPointerPos.y, 40, 0, Math.PI * 2, true);
                    VirtualJoystick.vjCanvasContext.stroke();
                    VirtualJoystick.vjCanvasContext.closePath();
                    _this._joystickPreviousPointerPos = _this._joystickPointerPos.clone();
                }
                else {
                    VirtualJoystick.vjCanvasContext.clearRect(touch.prevX - 44, touch.prevY - 44, 88, 88);
                    VirtualJoystick.vjCanvasContext.beginPath();
                    VirtualJoystick.vjCanvasContext.fillStyle = "white";
                    VirtualJoystick.vjCanvasContext.beginPath();
                    VirtualJoystick.vjCanvasContext.strokeStyle = "red";
                    VirtualJoystick.vjCanvasContext.lineWidth = 6;
                    VirtualJoystick.vjCanvasContext.arc(touch.x, touch.y, 40, 0, Math.PI * 2, true);
                    VirtualJoystick.vjCanvasContext.stroke();
                    VirtualJoystick.vjCanvasContext.closePath();
                    touch.prevX = touch.x;
                    touch.prevY = touch.y;
                }
            });
        }
        requestAnimationFrame(function () { _this._drawVirtualJoystick(); });
    };
    /**
     * Release internal HTML canvas
     */
    VirtualJoystick.prototype.releaseCanvas = function () {
        if (VirtualJoystick.Canvas) {
            VirtualJoystick.Canvas.removeEventListener('pointerdown', this._onPointerDownHandlerRef);
            VirtualJoystick.Canvas.removeEventListener('pointermove', this._onPointerMoveHandlerRef);
            VirtualJoystick.Canvas.removeEventListener('pointerup', this._onPointerUpHandlerRef);
            VirtualJoystick.Canvas.removeEventListener('pointerout', this._onPointerUpHandlerRef);
            window.removeEventListener("resize", this._onResize);
            document.body.removeChild(VirtualJoystick.Canvas);
            VirtualJoystick.Canvas = null;
        }
    };
    // Used to draw the virtual joystick inside a 2D canvas on top of the WebGL rendering canvas
    VirtualJoystick._globalJoystickIndex = 0;
    return VirtualJoystick;
}());



/***/ }),

/***/ "./Misc/webRequest.ts":
/*!****************************!*\
  !*** ./Misc/webRequest.ts ***!
  \****************************/
/*! exports provided: WebRequest */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WebRequest", function() { return WebRequest; });
/**
 * Extended version of XMLHttpRequest with support for customizations (headers, ...)
 */
var WebRequest = /** @class */ (function () {
    function WebRequest() {
        this._xhr = new XMLHttpRequest();
    }
    WebRequest.prototype._injectCustomRequestHeaders = function () {
        for (var key in WebRequest.CustomRequestHeaders) {
            var val = WebRequest.CustomRequestHeaders[key];
            if (val) {
                this._xhr.setRequestHeader(key, val);
            }
        }
    };
    Object.defineProperty(WebRequest.prototype, "onprogress", {
        /**
         * Gets or sets a function to be called when loading progress changes
         */
        get: function () {
            return this._xhr.onprogress;
        },
        set: function (value) {
            this._xhr.onprogress = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "readyState", {
        /**
         * Returns client's state
         */
        get: function () {
            return this._xhr.readyState;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "status", {
        /**
         * Returns client's status
         */
        get: function () {
            return this._xhr.status;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "statusText", {
        /**
         * Returns client's status as a text
         */
        get: function () {
            return this._xhr.statusText;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "response", {
        /**
         * Returns client's response
         */
        get: function () {
            return this._xhr.response;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "responseURL", {
        /**
         * Returns client's response url
         */
        get: function () {
            return this._xhr.responseURL;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "responseText", {
        /**
         * Returns client's response as text
         */
        get: function () {
            return this._xhr.responseText;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(WebRequest.prototype, "responseType", {
        /**
         * Gets or sets the expected response type
         */
        get: function () {
            return this._xhr.responseType;
        },
        set: function (value) {
            this._xhr.responseType = value;
        },
        enumerable: true,
        configurable: true
    });
    WebRequest.prototype.addEventListener = function (type, listener, options) {
        this._xhr.addEventListener(type, listener, options);
    };
    WebRequest.prototype.removeEventListener = function (type, listener, options) {
        this._xhr.removeEventListener(type, listener, options);
    };
    /**
     * Cancels any network activity
     */
    WebRequest.prototype.abort = function () {
        this._xhr.abort();
    };
    /**
     * Initiates the request. The optional argument provides the request body. The argument is ignored if request method is GET or HEAD
     * @param body defines an optional request body
     */
    WebRequest.prototype.send = function (body) {
        if (WebRequest.CustomRequestHeaders) {
            this._injectCustomRequestHeaders();
        }
        this._xhr.send(body);
    };
    /**
     * Sets the request method, request URL
     * @param method defines the method to use (GET, POST, etc..)
     * @param url defines the url to connect with
     */
    WebRequest.prototype.open = function (method, url) {
        for (var _i = 0, _a = WebRequest.CustomRequestModifiers; _i < _a.length; _i++) {
            var update = _a[_i];
            update(this._xhr, url);
        }
        // Clean url
        url = url.replace("file:http:", "http:");
        url = url.replace("file:https:", "https:");
        return this._xhr.open(method, url, true);
    };
    /**
     * Custom HTTP Request Headers to be sent with XMLHttpRequests
     * i.e. when loading files, where the server/service expects an Authorization header
     */
    WebRequest.CustomRequestHeaders = {};
    /**
     * Add callback functions in this array to update all the requests before they get sent to the network
     */
    WebRequest.CustomRequestModifiers = new Array();
    return WebRequest;
}());



/***/ }),

/***/ "./Misc/workerPool.ts":
/*!****************************!*\
  !*** ./Misc/workerPool.ts ***!
  \****************************/
/*! exports provided: WorkerPool */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WorkerPool", function() { return WorkerPool; });
/**
 * Helper class to push actions to a pool of workers.
 */
var WorkerPool = /** @class */ (function () {
    /**
     * Constructor
     * @param workers Array of workers to use for actions
     */
    function WorkerPool(workers) {
        this._pendingActions = new Array();
        this._workerInfos = workers.map(function (worker) { return ({
            worker: worker,
            active: false
        }); });
    }
    /**
     * Terminates all workers and clears any pending actions.
     */
    WorkerPool.prototype.dispose = function () {
        for (var _i = 0, _a = this._workerInfos; _i < _a.length; _i++) {
            var workerInfo = _a[_i];
            workerInfo.worker.terminate();
        }
        delete this._workerInfos;
        delete this._pendingActions;
    };
    /**
     * Pushes an action to the worker pool. If all the workers are active, the action will be
     * pended until a worker has completed its action.
     * @param action The action to perform. Call onComplete when the action is complete.
     */
    WorkerPool.prototype.push = function (action) {
        for (var _i = 0, _a = this._workerInfos; _i < _a.length; _i++) {
            var workerInfo = _a[_i];
            if (!workerInfo.active) {
                this._execute(workerInfo, action);
                return;
            }
        }
        this._pendingActions.push(action);
    };
    WorkerPool.prototype._execute = function (workerInfo, action) {
        var _this = this;
        workerInfo.active = true;
        action(workerInfo.worker, function () {
            workerInfo.active = false;
            var nextAction = _this._pendingActions.shift();
            if (nextAction) {
                _this._execute(workerInfo, nextAction);
            }
        });
    };
    return WorkerPool;
}());



/***/ }),

/***/ "./Morph/index.ts":
/*!************************!*\
  !*** ./Morph/index.ts ***!
  \************************/
/*! exports provided: MorphTarget, MorphTargetManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _morphTarget__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./morphTarget */ "./Morph/morphTarget.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTarget", function() { return _morphTarget__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"]; });

/* harmony import */ var _morphTargetManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./morphTargetManager */ "./Morph/morphTargetManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetManager", function() { return _morphTargetManager__WEBPACK_IMPORTED_MODULE_1__["MorphTargetManager"]; });





/***/ }),

/***/ "./Morph/morphTarget.ts":
/*!******************************!*\
  !*** ./Morph/morphTarget.ts ***!
  \******************************/
/*! exports provided: MorphTarget */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MorphTarget", function() { return MorphTarget; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");






/**
 * Defines a target to use with MorphTargetManager
 * @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
 */
var MorphTarget = /** @class */ (function () {
    /**
     * Creates a new MorphTarget
     * @param name defines the name of the target
     * @param influence defines the influence to use
     * @param scene defines the scene the morphtarget belongs to
     */
    function MorphTarget(
    /** defines the name of the target */
    name, influence, scene) {
        if (influence === void 0) { influence = 0; }
        if (scene === void 0) { scene = null; }
        this.name = name;
        /**
         * Gets or sets the list of animations
         */
        this.animations = new Array();
        this._positions = null;
        this._normals = null;
        this._tangents = null;
        this._uvs = null;
        /**
         * Observable raised when the influence changes
         */
        this.onInfluenceChanged = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /** @hidden */
        this._onDataLayoutChanged = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._animationPropertiesOverride = null;
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["EngineStore"].LastCreatedScene;
        this.influence = influence;
    }
    Object.defineProperty(MorphTarget.prototype, "influence", {
        /**
         * Gets or sets the influence of this target (ie. its weight in the overall morphing)
         */
        get: function () {
            return this._influence;
        },
        set: function (influence) {
            if (this._influence === influence) {
                return;
            }
            var previous = this._influence;
            this._influence = influence;
            if (this.onInfluenceChanged.hasObservers) {
                this.onInfluenceChanged.notifyObservers(previous === 0 || influence === 0);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTarget.prototype, "animationPropertiesOverride", {
        /**
         * Gets or sets the animation properties override
         */
        get: function () {
            if (!this._animationPropertiesOverride && this._scene) {
                return this._scene.animationPropertiesOverride;
            }
            return this._animationPropertiesOverride;
        },
        set: function (value) {
            this._animationPropertiesOverride = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTarget.prototype, "hasPositions", {
        /**
         * Gets a boolean defining if the target contains position data
         */
        get: function () {
            return !!this._positions;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTarget.prototype, "hasNormals", {
        /**
         * Gets a boolean defining if the target contains normal data
         */
        get: function () {
            return !!this._normals;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTarget.prototype, "hasTangents", {
        /**
         * Gets a boolean defining if the target contains tangent data
         */
        get: function () {
            return !!this._tangents;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTarget.prototype, "hasUVs", {
        /**
         * Gets a boolean defining if the target contains texture coordinates data
         */
        get: function () {
            return !!this._uvs;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Affects position data to this target
     * @param data defines the position data to use
     */
    MorphTarget.prototype.setPositions = function (data) {
        var hadPositions = this.hasPositions;
        this._positions = data;
        if (hadPositions !== this.hasPositions) {
            this._onDataLayoutChanged.notifyObservers(undefined);
        }
    };
    /**
     * Gets the position data stored in this target
     * @returns a FloatArray containing the position data (or null if not present)
     */
    MorphTarget.prototype.getPositions = function () {
        return this._positions;
    };
    /**
     * Affects normal data to this target
     * @param data defines the normal data to use
     */
    MorphTarget.prototype.setNormals = function (data) {
        var hadNormals = this.hasNormals;
        this._normals = data;
        if (hadNormals !== this.hasNormals) {
            this._onDataLayoutChanged.notifyObservers(undefined);
        }
    };
    /**
     * Gets the normal data stored in this target
     * @returns a FloatArray containing the normal data (or null if not present)
     */
    MorphTarget.prototype.getNormals = function () {
        return this._normals;
    };
    /**
     * Affects tangent data to this target
     * @param data defines the tangent data to use
     */
    MorphTarget.prototype.setTangents = function (data) {
        var hadTangents = this.hasTangents;
        this._tangents = data;
        if (hadTangents !== this.hasTangents) {
            this._onDataLayoutChanged.notifyObservers(undefined);
        }
    };
    /**
     * Gets the tangent data stored in this target
     * @returns a FloatArray containing the tangent data (or null if not present)
     */
    MorphTarget.prototype.getTangents = function () {
        return this._tangents;
    };
    /**
     * Affects texture coordinates data to this target
     * @param data defines the texture coordinates data to use
     */
    MorphTarget.prototype.setUVs = function (data) {
        var hadUVs = this.hasUVs;
        this._uvs = data;
        if (hadUVs !== this.hasUVs) {
            this._onDataLayoutChanged.notifyObservers(undefined);
        }
    };
    /**
     * Gets the texture coordinates data stored in this target
     * @returns a FloatArray containing the texture coordinates data (or null if not present)
     */
    MorphTarget.prototype.getUVs = function () {
        return this._uvs;
    };
    /**
     * Serializes the current target into a Serialization object
     * @returns the serialized object
     */
    MorphTarget.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.name = this.name;
        serializationObject.influence = this.influence;
        serializationObject.positions = Array.prototype.slice.call(this.getPositions());
        if (this.id != null) {
            serializationObject.id = this.id;
        }
        if (this.hasNormals) {
            serializationObject.normals = Array.prototype.slice.call(this.getNormals());
        }
        if (this.hasTangents) {
            serializationObject.tangents = Array.prototype.slice.call(this.getTangents());
        }
        if (this.hasUVs) {
            serializationObject.uvs = Array.prototype.slice.call(this.getUVs());
        }
        // Animations
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_4__["SerializationHelper"].AppendSerializedAnimations(this, serializationObject);
        return serializationObject;
    };
    /**
     * Returns the string "MorphTarget"
     * @returns "MorphTarget"
     */
    MorphTarget.prototype.getClassName = function () {
        return "MorphTarget";
    };
    // Statics
    /**
     * Creates a new target from serialized data
     * @param serializationObject defines the serialized data to use
     * @returns a new MorphTarget
     */
    MorphTarget.Parse = function (serializationObject) {
        var result = new MorphTarget(serializationObject.name, serializationObject.influence);
        result.setPositions(serializationObject.positions);
        if (serializationObject.id != null) {
            result.id = serializationObject.id;
        }
        if (serializationObject.normals) {
            result.setNormals(serializationObject.normals);
        }
        if (serializationObject.tangents) {
            result.setTangents(serializationObject.tangents);
        }
        if (serializationObject.uvs) {
            result.setUVs(serializationObject.uvs);
        }
        // Animations
        if (serializationObject.animations) {
            for (var animationIndex = 0; animationIndex < serializationObject.animations.length; animationIndex++) {
                var parsedAnimation = serializationObject.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    result.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
        }
        return result;
    };
    /**
     * Creates a MorphTarget from mesh data
     * @param mesh defines the source mesh
     * @param name defines the name to use for the new target
     * @param influence defines the influence to attach to the target
     * @returns a new MorphTarget
     */
    MorphTarget.FromMesh = function (mesh, name, influence) {
        if (!name) {
            name = mesh.name;
        }
        var result = new MorphTarget(name, influence, mesh.getScene());
        result.setPositions(mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].PositionKind));
        if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind)) {
            result.setNormals(mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].NormalKind));
        }
        if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind)) {
            result.setTangents(mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].TangentKind));
        }
        if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind)) {
            result.setUVs(mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_3__["VertexBuffer"].UVKind));
        }
        return result;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_4__["serialize"])()
    ], MorphTarget.prototype, "id", void 0);
    return MorphTarget;
}());



/***/ }),

/***/ "./Morph/morphTargetManager.ts":
/*!*************************************!*\
  !*** ./Morph/morphTargetManager.ts ***!
  \*************************************/
/*! exports provided: MorphTargetManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MorphTargetManager", function() { return MorphTargetManager; });
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _morphTarget__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./morphTarget */ "./Morph/morphTarget.ts");




/**
 * This class is used to deform meshes using morphing between different targets
 * @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
 */
var MorphTargetManager = /** @class */ (function () {
    /**
     * Creates a new MorphTargetManager
     * @param scene defines the current scene
     */
    function MorphTargetManager(scene) {
        if (scene === void 0) { scene = null; }
        this._targets = new Array();
        this._targetInfluenceChangedObservers = new Array();
        this._targetDataLayoutChangedObservers = new Array();
        this._activeTargets = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](16);
        this._supportsNormals = false;
        this._supportsTangents = false;
        this._supportsUVs = false;
        this._vertexCount = 0;
        this._uniqueId = 0;
        this._tempInfluences = new Array();
        /**
         * Gets or sets a boolean indicating if normals must be morphed
         */
        this.enableNormalMorphing = true;
        /**
         * Gets or sets a boolean indicating if tangents must be morphed
         */
        this.enableTangentMorphing = true;
        /**
         * Gets or sets a boolean indicating if UV must be morphed
         */
        this.enableUVMorphing = true;
        if (!scene) {
            scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_2__["EngineStore"].LastCreatedScene;
        }
        this._scene = scene;
        if (this._scene) {
            this._scene.morphTargetManagers.push(this);
            this._uniqueId = this._scene.getUniqueId();
        }
    }
    Object.defineProperty(MorphTargetManager.prototype, "uniqueId", {
        /**
         * Gets the unique ID of this manager
         */
        get: function () {
            return this._uniqueId;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "vertexCount", {
        /**
         * Gets the number of vertices handled by this manager
         */
        get: function () {
            return this._vertexCount;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "supportsNormals", {
        /**
         * Gets a boolean indicating if this manager supports morphing of normals
         */
        get: function () {
            return this._supportsNormals && this.enableNormalMorphing;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "supportsTangents", {
        /**
         * Gets a boolean indicating if this manager supports morphing of tangents
         */
        get: function () {
            return this._supportsTangents && this.enableTangentMorphing;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "supportsUVs", {
        /**
         * Gets a boolean indicating if this manager supports morphing of texture coordinates
         */
        get: function () {
            return this._supportsUVs && this.enableUVMorphing;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "numTargets", {
        /**
         * Gets the number of targets stored in this manager
         */
        get: function () {
            return this._targets.length;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "numInfluencers", {
        /**
         * Gets the number of influencers (ie. the number of targets with influences > 0)
         */
        get: function () {
            return this._activeTargets.length;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(MorphTargetManager.prototype, "influences", {
        /**
         * Gets the list of influences (one per target)
         */
        get: function () {
            return this._influences;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the active target at specified index. An active target is a target with an influence > 0
     * @param index defines the index to check
     * @returns the requested target
     */
    MorphTargetManager.prototype.getActiveTarget = function (index) {
        return this._activeTargets.data[index];
    };
    /**
     * Gets the target at specified index
     * @param index defines the index to check
     * @returns the requested target
     */
    MorphTargetManager.prototype.getTarget = function (index) {
        return this._targets[index];
    };
    /**
     * Add a new target to this manager
     * @param target defines the target to add
     */
    MorphTargetManager.prototype.addTarget = function (target) {
        var _this = this;
        this._targets.push(target);
        this._targetInfluenceChangedObservers.push(target.onInfluenceChanged.add(function (needUpdate) {
            _this._syncActiveTargets(needUpdate);
        }));
        this._targetDataLayoutChangedObservers.push(target._onDataLayoutChanged.add(function () {
            _this._syncActiveTargets(true);
        }));
        this._syncActiveTargets(true);
    };
    /**
     * Removes a target from the manager
     * @param target defines the target to remove
     */
    MorphTargetManager.prototype.removeTarget = function (target) {
        var index = this._targets.indexOf(target);
        if (index >= 0) {
            this._targets.splice(index, 1);
            target.onInfluenceChanged.remove(this._targetInfluenceChangedObservers.splice(index, 1)[0]);
            target._onDataLayoutChanged.remove(this._targetDataLayoutChangedObservers.splice(index, 1)[0]);
            this._syncActiveTargets(true);
        }
    };
    /**
     * Serializes the current manager into a Serialization object
     * @returns the serialized object
     */
    MorphTargetManager.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.id = this.uniqueId;
        serializationObject.targets = [];
        for (var _i = 0, _a = this._targets; _i < _a.length; _i++) {
            var target = _a[_i];
            serializationObject.targets.push(target.serialize());
        }
        return serializationObject;
    };
    MorphTargetManager.prototype._syncActiveTargets = function (needUpdate) {
        var influenceCount = 0;
        this._activeTargets.reset();
        this._supportsNormals = true;
        this._supportsTangents = true;
        this._supportsUVs = true;
        this._vertexCount = 0;
        for (var _i = 0, _a = this._targets; _i < _a.length; _i++) {
            var target = _a[_i];
            if (target.influence === 0) {
                continue;
            }
            this._activeTargets.push(target);
            this._tempInfluences[influenceCount++] = target.influence;
            this._supportsNormals = this._supportsNormals && target.hasNormals;
            this._supportsTangents = this._supportsTangents && target.hasTangents;
            this._supportsUVs = this._supportsUVs && target.hasUVs;
            var positions = target.getPositions();
            if (positions) {
                var vertexCount = positions.length / 3;
                if (this._vertexCount === 0) {
                    this._vertexCount = vertexCount;
                }
                else if (this._vertexCount !== vertexCount) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Incompatible target. Targets must all have the same vertices count.");
                    return;
                }
            }
        }
        if (!this._influences || this._influences.length !== influenceCount) {
            this._influences = new Float32Array(influenceCount);
        }
        for (var index = 0; index < influenceCount; index++) {
            this._influences[index] = this._tempInfluences[index];
        }
        if (needUpdate) {
            this.synchronize();
        }
    };
    /**
     * Syncrhonize the targets with all the meshes using this morph target manager
     */
    MorphTargetManager.prototype.synchronize = function () {
        if (!this._scene) {
            return;
        }
        // Flag meshes as dirty to resync with the active targets
        for (var _i = 0, _a = this._scene.meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            if (mesh.morphTargetManager === this) {
                mesh._syncGeometryWithMorphTargetManager();
            }
        }
    };
    // Statics
    /**
     * Creates a new MorphTargetManager from serialized data
     * @param serializationObject defines the serialized data
     * @param scene defines the hosting scene
     * @returns the new MorphTargetManager
     */
    MorphTargetManager.Parse = function (serializationObject, scene) {
        var result = new MorphTargetManager(scene);
        result._uniqueId = serializationObject.id;
        for (var _i = 0, _a = serializationObject.targets; _i < _a.length; _i++) {
            var targetData = _a[_i];
            result.addTarget(_morphTarget__WEBPACK_IMPORTED_MODULE_3__["MorphTarget"].Parse(targetData));
        }
        return result;
    };
    return MorphTargetManager;
}());



/***/ }),

/***/ "./Navigation/Plugins/index.ts":
/*!*************************************!*\
  !*** ./Navigation/Plugins/index.ts ***!
  \*************************************/
/*! exports provided: RecastJSPlugin, RecastJSCrowd */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _recastJSPlugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./recastJSPlugin */ "./Navigation/Plugins/recastJSPlugin.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSPlugin", function() { return _recastJSPlugin__WEBPACK_IMPORTED_MODULE_0__["RecastJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSCrowd", function() { return _recastJSPlugin__WEBPACK_IMPORTED_MODULE_0__["RecastJSCrowd"]; });




/***/ }),

/***/ "./Navigation/Plugins/recastJSPlugin.ts":
/*!**********************************************!*\
  !*** ./Navigation/Plugins/recastJSPlugin.ts ***!
  \**********************************************/
/*! exports provided: RecastJSPlugin, RecastJSCrowd */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RecastJSPlugin", function() { return RecastJSPlugin; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RecastJSCrowd", function() { return RecastJSCrowd; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Maths_math__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math */ "./Maths/math.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");





/**
 * RecastJS navigation plugin
 */
var RecastJSPlugin = /** @class */ (function () {
    /**
     * Initializes the recastJS plugin
     * @param recastInjection can be used to inject your own recast reference
     */
    function RecastJSPlugin(recastInjection) {
        if (recastInjection === void 0) { recastInjection = Recast; }
        /**
         * Reference to the Recast library
         */
        this.bjsRECAST = {};
        /**
         * plugin name
         */
        this.name = "RecastJSPlugin";
        if (typeof recastInjection === "function") {
            recastInjection(this.bjsRECAST);
        }
        else {
            this.bjsRECAST = recastInjection;
        }
        if (!this.isSupported()) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("RecastJS is not available. Please make sure you included the js file.");
            return;
        }
    }
    /**
     * Creates a navigation mesh
     * @param meshes array of all the geometry used to compute the navigatio mesh
     * @param parameters bunch of parameters used to filter geometry
     */
    RecastJSPlugin.prototype.createMavMesh = function (meshes, parameters) {
        var rc = new this.bjsRECAST.rcConfig();
        rc.cs = parameters.cs;
        rc.ch = parameters.ch;
        rc.borderSize = 0;
        rc.tileSize = 0;
        rc.walkableSlopeAngle = parameters.walkableSlopeAngle;
        rc.walkableHeight = parameters.walkableHeight;
        rc.walkableClimb = parameters.walkableClimb;
        rc.walkableRadius = parameters.walkableRadius;
        rc.maxEdgeLen = parameters.maxEdgeLen;
        rc.maxSimplificationError = parameters.maxSimplificationError;
        rc.minRegionArea = parameters.minRegionArea;
        rc.mergeRegionArea = parameters.mergeRegionArea;
        rc.maxVertsPerPoly = parameters.maxVertsPerPoly;
        rc.detailSampleDist = parameters.detailSampleDist;
        rc.detailSampleMaxError = parameters.detailSampleMaxError;
        this.navMesh = new this.bjsRECAST.NavMesh();
        var index;
        var tri;
        var pt;
        var indices = [];
        var positions = [];
        var offset = 0;
        for (index = 0; index < meshes.length; index++) {
            if (meshes[index]) {
                var mesh = meshes[index];
                var meshIndices = mesh.getIndices();
                if (!meshIndices) {
                    continue;
                }
                var meshPositions = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind, false, false);
                if (!meshPositions) {
                    continue;
                }
                var wm = mesh.computeWorldMatrix(false);
                for (tri = 0; tri < meshIndices.length; tri++) {
                    indices.push(meshIndices[tri] + offset);
                }
                var transformed = _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
                var position = _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
                for (pt = 0; pt < meshPositions.length; pt += 3) {
                    _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"].FromArrayToRef(meshPositions, pt, position);
                    _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(position, wm, transformed);
                    positions.push(transformed.x, transformed.y, transformed.z);
                }
                offset += meshPositions.length / 3;
            }
        }
        this.navMesh.build(positions, offset, indices, indices.length, rc);
    };
    /**
     * Create a navigation mesh debug mesh
     * @param scene is where the mesh will be added
     * @returns debug display mesh
     */
    RecastJSPlugin.prototype.createDebugNavMesh = function (scene) {
        var tri;
        var pt;
        var debugNavMesh = this.navMesh.getDebugNavMesh();
        var triangleCount = debugNavMesh.getTriangleCount();
        var indices = [];
        var positions = [];
        for (tri = 0; tri < triangleCount * 3; tri++) {
            indices.push(tri);
        }
        for (tri = 0; tri < triangleCount; tri++) {
            for (pt = 0; pt < 3; pt++) {
                var point = debugNavMesh.getTriangle(tri).getPoint(pt);
                positions.push(point.x, point.y, point.z);
            }
        }
        var mesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]("NavMeshDebug", scene);
        var vertexData = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_1__["VertexData"]();
        vertexData.indices = indices;
        vertexData.positions = positions;
        vertexData.applyToMesh(mesh, false);
        return mesh;
    };
    /**
     * Get a navigation mesh constrained position, closest to the parameter position
     * @param position world position
     * @returns the closest point to position constrained by the navigation mesh
     */
    RecastJSPlugin.prototype.getClosestPoint = function (position) {
        var p = new this.bjsRECAST.Vec3(position.x, position.y, position.z);
        var ret = this.navMesh.getClosestPoint(p);
        var pr = new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](ret.x, ret.y, ret.z);
        return pr;
    };
    /**
     * Get a navigation mesh constrained position, within a particular radius
     * @param position world position
     * @param maxRadius the maximum distance to the constrained world position
     * @returns the closest point to position constrained by the navigation mesh
     */
    RecastJSPlugin.prototype.getRandomPointAround = function (position, maxRadius) {
        var p = new this.bjsRECAST.Vec3(position.x, position.y, position.z);
        var ret = this.navMesh.getRandomPointAround(p, maxRadius);
        var pr = new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](ret.x, ret.y, ret.z);
        return pr;
    };
    /**
     * Compute the final position from a segment made of destination-position
     * @param position world position
     * @param destination world position
     * @returns the resulting point along the navmesh
     */
    RecastJSPlugin.prototype.moveAlong = function (position, destination) {
        var p = new this.bjsRECAST.Vec3(position.x, position.y, position.z);
        var d = new this.bjsRECAST.Vec3(destination.x, destination.y, destination.z);
        var ret = this.navMesh.moveAlong(p, d);
        var pr = new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](ret.x, ret.y, ret.z);
        return pr;
    };
    /**
     * Compute a navigation path from start to end. Returns an empty array if no path can be computed
     * @param start world position
     * @param end world position
     * @returns array containing world position composing the path
     */
    RecastJSPlugin.prototype.computePath = function (start, end) {
        var pt;
        var startPos = new this.bjsRECAST.Vec3(start.x, start.y, start.z);
        var endPos = new this.bjsRECAST.Vec3(end.x, end.y, end.z);
        var navPath = this.navMesh.computePath(startPos, endPos);
        var pointCount = navPath.getPointCount();
        var positions = [];
        for (pt = 0; pt < pointCount; pt++) {
            var p = navPath.getPoint(pt);
            positions.push(new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](p.x, p.y, p.z));
        }
        return positions;
    };
    /**
     * Create a new Crowd so you can add agents
     * @param maxAgents the maximum agent count in the crowd
     * @param maxAgentRadius the maximum radius an agent can have
     * @param scene to attach the crowd to
     * @returns the crowd you can add agents to
     */
    RecastJSPlugin.prototype.createCrowd = function (maxAgents, maxAgentRadius, scene) {
        var crowd = new RecastJSCrowd(this, maxAgents, maxAgentRadius, scene);
        return crowd;
    };
    /**
     * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)
     * The queries will try to find a solution within those bounds
     * default is (1,1,1)
     * @param extent x,y,z value that define the extent around the queries point of reference
     */
    RecastJSPlugin.prototype.setDefaultQueryExtent = function (extent) {
        var ext = new this.bjsRECAST.Vec3(extent.x, extent.y, extent.z);
        this.navMesh.setDefaultQueryExtent(ext);
    };
    /**
     * Get the Bounding box extent specified by setDefaultQueryExtent
     * @returns the box extent values
     */
    RecastJSPlugin.prototype.getDefaultQueryExtent = function () {
        var p = this.navMesh.getDefaultQueryExtent();
        return new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](p.x, p.y, p.z);
    };
    /**
     * Disposes
     */
    RecastJSPlugin.prototype.dispose = function () {
    };
    /**
     * If this plugin is supported
     * @returns true if plugin is supported
     */
    RecastJSPlugin.prototype.isSupported = function () {
        return this.bjsRECAST !== undefined;
    };
    return RecastJSPlugin;
}());

/**
 * Recast detour crowd implementation
 */
var RecastJSCrowd = /** @class */ (function () {
    /**
     * Constructor
     * @param plugin recastJS plugin
     * @param maxAgents the maximum agent count in the crowd
     * @param maxAgentRadius the maximum radius an agent can have
     * @param scene to attach the crowd to
     * @returns the crowd you can add agents to
     */
    function RecastJSCrowd(plugin, maxAgents, maxAgentRadius, scene) {
        var _this = this;
        /**
         * Link to the detour crowd
         */
        this.recastCrowd = {};
        /**
         * One transform per agent
         */
        this.transforms = new Array();
        /**
         * All agents created
         */
        this.agents = new Array();
        /**
         * Observer for crowd updates
         */
        this._onBeforeAnimationsObserver = null;
        this.bjsRECASTPlugin = plugin;
        this.recastCrowd = new this.bjsRECASTPlugin.bjsRECAST.Crowd(maxAgents, maxAgentRadius, this.bjsRECASTPlugin.navMesh.getNavMesh());
        this._scene = scene;
        this._onBeforeAnimationsObserver = scene.onBeforeAnimationsObservable.add(function () {
            _this.update(scene.getEngine().getDeltaTime() * 0.001);
        });
    }
    /**
     * Add a new agent to the crowd with the specified parameter a corresponding transformNode.
     * You can attach anything to that node. The node position is updated in the scene update tick.
     * @param pos world position that will be constrained by the navigation mesh
     * @param parameters agent parameters
     * @param transform hooked to the agent that will be update by the scene
     * @returns agent index
     */
    RecastJSCrowd.prototype.addAgent = function (pos, parameters, transform) {
        var agentParams = new this.bjsRECASTPlugin.bjsRECAST.dtCrowdAgentParams();
        agentParams.radius = parameters.radius;
        agentParams.height = parameters.height;
        agentParams.maxAcceleration = parameters.maxAcceleration;
        agentParams.maxSpeed = parameters.maxSpeed;
        agentParams.collisionQueryRange = parameters.collisionQueryRange;
        agentParams.pathOptimizationRange = parameters.pathOptimizationRange;
        agentParams.separationWeight = parameters.separationWeight;
        agentParams.updateFlags = 7;
        agentParams.obstacleAvoidanceType = 0;
        agentParams.queryFilterType = 0;
        agentParams.userData = 0;
        var agentIndex = this.recastCrowd.addAgent(new this.bjsRECASTPlugin.bjsRECAST.Vec3(pos.x, pos.y, pos.z), agentParams);
        this.transforms.push(transform);
        this.agents.push(agentIndex);
        return agentIndex;
    };
    /**
     * Returns the agent position in world space
     * @param index agent index returned by addAgent
     * @returns world space position
     */
    RecastJSCrowd.prototype.getAgentPosition = function (index) {
        var agentPos = this.recastCrowd.getAgentPosition(index);
        return new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](agentPos.x, agentPos.y, agentPos.z);
    };
    /**
     * Returns the agent velocity in world space
     * @param index agent index returned by addAgent
     * @returns world space velocity
     */
    RecastJSCrowd.prototype.getAgentVelocity = function (index) {
        var agentVel = this.recastCrowd.getAgentVelocity(index);
        return new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](agentVel.x, agentVel.y, agentVel.z);
    };
    /**
     * Asks a particular agent to go to a destination. That destination is constrained by the navigation mesh
     * @param index agent index returned by addAgent
     * @param destination targeted world position
     */
    RecastJSCrowd.prototype.agentGoto = function (index, destination) {
        this.recastCrowd.agentGoto(index, new this.bjsRECASTPlugin.bjsRECAST.Vec3(destination.x, destination.y, destination.z));
    };
    /**
     * remove a particular agent previously created
     * @param index agent index returned by addAgent
     */
    RecastJSCrowd.prototype.removeAgent = function (index) {
        this.recastCrowd.removeAgent(index);
        var item = this.agents.indexOf(index);
        if (item > -1) {
            this.agents.splice(item, 1);
            this.transforms.splice(item, 1);
        }
    };
    /**
     * get the list of all agents attached to this crowd
     * @returns list of agent indices
     */
    RecastJSCrowd.prototype.getAgents = function () {
        return this.agents;
    };
    /**
     * Tick update done by the Scene. Agent position/velocity/acceleration is updated by this function
     * @param deltaTime in seconds
     */
    RecastJSCrowd.prototype.update = function (deltaTime) {
        // update crowd
        this.recastCrowd.update(deltaTime);
        // update transforms
        for (var index = 0; index < this.agents.length; index++) {
            this.transforms[index].position = this.getAgentPosition(this.agents[index]);
        }
    };
    /**
     * Set the Bounding box extent for doing spatial queries (getClosestPoint, getRandomPointAround, ...)
     * The queries will try to find a solution within those bounds
     * default is (1,1,1)
     * @param extent x,y,z value that define the extent around the queries point of reference
     */
    RecastJSCrowd.prototype.setDefaultQueryExtent = function (extent) {
        var ext = new this.bjsRECASTPlugin.bjsRECAST.Vec3(extent.x, extent.y, extent.z);
        this.recastCrowd.setDefaultQueryExtent(ext);
    };
    /**
     * Get the Bounding box extent specified by setDefaultQueryExtent
     * @returns the box extent values
     */
    RecastJSCrowd.prototype.getDefaultQueryExtent = function () {
        var p = this.recastCrowd.getDefaultQueryExtent();
        return new _Maths_math__WEBPACK_IMPORTED_MODULE_3__["Vector3"](p.x, p.y, p.z);
    };
    /**
     * Release all resources
     */
    RecastJSCrowd.prototype.dispose = function () {
        this.recastCrowd.destroy();
        this._scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);
        this._onBeforeAnimationsObserver = null;
    };
    return RecastJSCrowd;
}());



/***/ }),

/***/ "./Navigation/index.ts":
/*!*****************************!*\
  !*** ./Navigation/index.ts ***!
  \*****************************/
/*! exports provided: RecastJSPlugin, RecastJSCrowd */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Plugins_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Plugins/index */ "./Navigation/Plugins/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSPlugin", function() { return _Plugins_index__WEBPACK_IMPORTED_MODULE_0__["RecastJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSCrowd", function() { return _Plugins_index__WEBPACK_IMPORTED_MODULE_0__["RecastJSCrowd"]; });




/***/ }),

/***/ "./Offline/database.ts":
/*!*****************************!*\
  !*** ./Offline/database.ts ***!
  \*****************************/
/*! exports provided: Database */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Database", function() { return Database; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_tga__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/tga */ "./Misc/tga.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Misc_webRequest__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Misc/webRequest */ "./Misc/webRequest.ts");





// Sets the default offline provider to Babylon.js
_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].OfflineProviderFactory = function (urlToScene, callbackManifestChecked, disableManifestCheck) {
    if (disableManifestCheck === void 0) { disableManifestCheck = false; }
    return new Database(urlToScene, callbackManifestChecked, disableManifestCheck);
};
/**
 * Class used to enable access to IndexedDB
 * @see http://doc.babylonjs.com/how_to/caching_resources_in_indexeddb
 */
var Database = /** @class */ (function () {
    /**
     * Creates a new Database
     * @param urlToScene defines the url to load the scene
     * @param callbackManifestChecked defines the callback to use when manifest is checked
     * @param disableManifestCheck defines a boolean indicating that we want to skip the manifest validation (it will be considered validated and up to date)
     */
    function Database(urlToScene, callbackManifestChecked, disableManifestCheck) {
        var _this = this;
        if (disableManifestCheck === void 0) { disableManifestCheck = false; }
        // Handling various flavors of prefixed version of IndexedDB
        this._idbFactory = (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB);
        this._callbackManifestChecked = callbackManifestChecked;
        this._currentSceneUrl = Database._ReturnFullUrlLocation(urlToScene);
        this._db = null;
        this._enableSceneOffline = false;
        this._enableTexturesOffline = false;
        this._manifestVersionFound = 0;
        this._mustUpdateRessources = false;
        this._hasReachedQuota = false;
        if (!Database.IDBStorageEnabled) {
            this._callbackManifestChecked(true);
        }
        else {
            if (disableManifestCheck) {
                this._enableSceneOffline = true;
                this._enableTexturesOffline = true;
                this._manifestVersionFound = 1;
                _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].SetImmediate(function () {
                    _this._callbackManifestChecked(true);
                });
            }
            else {
                this._checkManifestFile();
            }
        }
    }
    Object.defineProperty(Database.prototype, "enableSceneOffline", {
        /**
         * Gets a boolean indicating if scene must be saved in the database
         */
        get: function () {
            return this._enableSceneOffline;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Database.prototype, "enableTexturesOffline", {
        /**
         * Gets a boolean indicating if textures must be saved in the database
         */
        get: function () {
            return this._enableTexturesOffline;
        },
        enumerable: true,
        configurable: true
    });
    Database.prototype._checkManifestFile = function () {
        var _this = this;
        var noManifestFile = function () {
            _this._enableSceneOffline = false;
            _this._enableTexturesOffline = false;
            _this._callbackManifestChecked(false);
        };
        var timeStampUsed = false;
        var manifestURL = this._currentSceneUrl + ".manifest";
        var xhr = new _Misc_webRequest__WEBPACK_IMPORTED_MODULE_4__["WebRequest"]();
        if (navigator.onLine) {
            // Adding a timestamp to by-pass browsers' cache
            timeStampUsed = true;
            manifestURL = manifestURL + (manifestURL.match(/\?/) == null ? "?" : "&") + Date.now();
        }
        xhr.open("GET", manifestURL);
        xhr.addEventListener("load", function () {
            if (xhr.status === 200 || Database._ValidateXHRData(xhr, 1)) {
                try {
                    var manifestFile = JSON.parse(xhr.response);
                    _this._enableSceneOffline = manifestFile.enableSceneOffline;
                    _this._enableTexturesOffline = manifestFile.enableTexturesOffline && Database.IsUASupportingBlobStorage;
                    if (manifestFile.version && !isNaN(parseInt(manifestFile.version))) {
                        _this._manifestVersionFound = manifestFile.version;
                    }
                    if (_this._callbackManifestChecked) {
                        _this._callbackManifestChecked(true);
                    }
                }
                catch (ex) {
                    noManifestFile();
                }
            }
            else {
                noManifestFile();
            }
        }, false);
        xhr.addEventListener("error", function () {
            if (timeStampUsed) {
                timeStampUsed = false;
                // Let's retry without the timeStamp
                // It could fail when coupled with HTML5 Offline API
                var retryManifestURL = _this._currentSceneUrl + ".manifest";
                xhr.open("GET", retryManifestURL);
                xhr.send();
            }
            else {
                noManifestFile();
            }
        }, false);
        try {
            xhr.send();
        }
        catch (ex) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error on XHR send request.");
            this._callbackManifestChecked(false);
        }
    };
    /**
     * Open the database and make it available
     * @param successCallback defines the callback to call on success
     * @param errorCallback defines the callback to call on error
     */
    Database.prototype.open = function (successCallback, errorCallback) {
        var _this = this;
        var handleError = function () {
            _this._isSupported = false;
            if (errorCallback) {
                errorCallback();
            }
        };
        if (!this._idbFactory || !(this._enableSceneOffline || this._enableTexturesOffline)) {
            // Your browser doesn't support IndexedDB
            this._isSupported = false;
            if (errorCallback) {
                errorCallback();
            }
        }
        else {
            // If the DB hasn't been opened or created yet
            if (!this._db) {
                this._hasReachedQuota = false;
                this._isSupported = true;
                var request = this._idbFactory.open("babylonjs", 1);
                // Could occur if user is blocking the quota for the DB and/or doesn't grant access to IndexedDB
                request.onerror = function () {
                    handleError();
                };
                // executes when a version change transaction cannot complete due to other active transactions
                request.onblocked = function () {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("IDB request blocked. Please reload the page.");
                    handleError();
                };
                // DB has been opened successfully
                request.onsuccess = function () {
                    _this._db = request.result;
                    successCallback();
                };
                // Initialization of the DB. Creating Scenes & Textures stores
                request.onupgradeneeded = function (event) {
                    _this._db = (event.target).result;
                    if (_this._db) {
                        try {
                            _this._db.createObjectStore("scenes", { keyPath: "sceneUrl" });
                            _this._db.createObjectStore("versions", { keyPath: "sceneUrl" });
                            _this._db.createObjectStore("textures", { keyPath: "textureUrl" });
                        }
                        catch (ex) {
                            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error while creating object stores. Exception: " + ex.message);
                            handleError();
                        }
                    }
                };
            }
            // DB has already been created and opened
            else {
                if (successCallback) {
                    successCallback();
                }
            }
        }
    };
    /**
     * Loads an image from the database
     * @param url defines the url to load from
     * @param image defines the target DOM image
     */
    Database.prototype.loadImage = function (url, image) {
        var _this = this;
        var completeURL = Database._ReturnFullUrlLocation(url);
        var saveAndLoadImage = function () {
            if (!_this._hasReachedQuota && _this._db !== null) {
                // the texture is not yet in the DB, let's try to save it
                _this._saveImageIntoDBAsync(completeURL, image);
            }
            // If the texture is not in the DB and we've reached the DB quota limit
            // let's load it directly from the web
            else {
                image.src = url;
            }
        };
        if (!this._mustUpdateRessources) {
            this._loadImageFromDBAsync(completeURL, image, saveAndLoadImage);
        }
        // First time we're download the images or update requested in the manifest file by a version change
        else {
            saveAndLoadImage();
        }
    };
    Database.prototype._loadImageFromDBAsync = function (url, image, notInDBCallback) {
        if (this._isSupported && this._db !== null) {
            var texture;
            var transaction = this._db.transaction(["textures"]);
            transaction.onabort = function () {
                image.src = url;
            };
            transaction.oncomplete = function () {
                var blobTextureURL;
                if (texture) {
                    var URL = window.URL || window.webkitURL;
                    blobTextureURL = URL.createObjectURL(texture.data);
                    image.onerror = function () {
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error loading image from blob URL: " + blobTextureURL + " switching back to web url: " + url);
                        image.src = url;
                    };
                    image.src = blobTextureURL;
                }
                else {
                    notInDBCallback();
                }
            };
            var getRequest = transaction.objectStore("textures").get(url);
            getRequest.onsuccess = function (event) {
                texture = (event.target).result;
            };
            getRequest.onerror = function () {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error loading texture " + url + " from DB.");
                image.src = url;
            };
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error: IndexedDB not supported by your browser or BabylonJS Database is not open.");
            image.src = url;
        }
    };
    Database.prototype._saveImageIntoDBAsync = function (url, image) {
        var _this = this;
        if (this._isSupported) {
            // In case of error (type not supported or quota exceeded), we're at least sending back XHR data to allow texture loading later on
            var generateBlobUrl = function () {
                var blobTextureURL;
                if (blob) {
                    var URL = window.URL || window.webkitURL;
                    try {
                        blobTextureURL = URL.createObjectURL(blob);
                    }
                    // Chrome is raising a type error if we're setting the oneTimeOnly parameter
                    catch (ex) {
                        blobTextureURL = URL.createObjectURL(blob);
                    }
                }
                if (blobTextureURL) {
                    image.src = blobTextureURL;
                }
            };
            if (Database.IsUASupportingBlobStorage) { // Create XHR
                var xhr = new _Misc_webRequest__WEBPACK_IMPORTED_MODULE_4__["WebRequest"](), blob;
                xhr.open("GET", url);
                xhr.responseType = "blob";
                xhr.addEventListener("load", function () {
                    if (xhr.status === 200 && _this._db) {
                        // Blob as response (XHR2)
                        blob = xhr.response;
                        var transaction = _this._db.transaction(["textures"], "readwrite");
                        // the transaction could abort because of a QuotaExceededError error
                        transaction.onabort = function (event) {
                            try {
                                //backwards compatibility with ts 1.0, srcElement doesn't have an "error" according to ts 1.3
                                var srcElement = (event.srcElement || event.target);
                                var error = srcElement.error;
                                if (error && error.name === "QuotaExceededError") {
                                    _this._hasReachedQuota = true;
                                }
                            }
                            catch (ex) { }
                            generateBlobUrl();
                        };
                        transaction.oncomplete = function () {
                            generateBlobUrl();
                        };
                        var newTexture = { textureUrl: url, data: blob };
                        try {
                            // Put the blob into the dabase
                            var addRequest = transaction.objectStore("textures").put(newTexture);
                            addRequest.onsuccess = function () {
                            };
                            addRequest.onerror = function () {
                                generateBlobUrl();
                            };
                        }
                        catch (ex) {
                            // "DataCloneError" generated by Chrome when you try to inject blob into IndexedDB
                            if (ex.code === 25) {
                                Database.IsUASupportingBlobStorage = false;
                                _this._enableTexturesOffline = false;
                            }
                            image.src = url;
                        }
                    }
                    else {
                        image.src = url;
                    }
                }, false);
                xhr.addEventListener("error", function () {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error in XHR request in BABYLON.Database.");
                    image.src = url;
                }, false);
                xhr.send();
            }
            else {
                image.src = url;
            }
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error: IndexedDB not supported by your browser or BabylonJS Database is not open.");
            image.src = url;
        }
    };
    Database.prototype._checkVersionFromDB = function (url, versionLoaded) {
        var _this = this;
        var updateVersion = function () {
            // the version is not yet in the DB or we need to update it
            _this._saveVersionIntoDBAsync(url, versionLoaded);
        };
        this._loadVersionFromDBAsync(url, versionLoaded, updateVersion);
    };
    Database.prototype._loadVersionFromDBAsync = function (url, callback, updateInDBCallback) {
        var _this = this;
        if (this._isSupported && this._db) {
            var version;
            try {
                var transaction = this._db.transaction(["versions"]);
                transaction.oncomplete = function () {
                    if (version) {
                        // If the version in the JSON file is different from the version in DB
                        if (_this._manifestVersionFound !== version.data) {
                            _this._mustUpdateRessources = true;
                            updateInDBCallback();
                        }
                        else {
                            callback(version.data);
                        }
                    }
                    // version was not found in DB
                    else {
                        _this._mustUpdateRessources = true;
                        updateInDBCallback();
                    }
                };
                transaction.onabort = function () {
                    callback(-1);
                };
                var getRequest = transaction.objectStore("versions").get(url);
                getRequest.onsuccess = function (event) {
                    version = (event.target).result;
                };
                getRequest.onerror = function () {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error loading version for scene " + url + " from DB.");
                    callback(-1);
                };
            }
            catch (ex) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error while accessing 'versions' object store (READ OP). Exception: " + ex.message);
                callback(-1);
            }
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error: IndexedDB not supported by your browser or BabylonJS Database is not open.");
            callback(-1);
        }
    };
    Database.prototype._saveVersionIntoDBAsync = function (url, callback) {
        var _this = this;
        if (this._isSupported && !this._hasReachedQuota && this._db) {
            try {
                // Open a transaction to the database
                var transaction = this._db.transaction(["versions"], "readwrite");
                // the transaction could abort because of a QuotaExceededError error
                transaction.onabort = function (event) {
                    try { //backwards compatibility with ts 1.0, srcElement doesn't have an "error" according to ts 1.3
                        var error = event.srcElement['error'];
                        if (error && error.name === "QuotaExceededError") {
                            _this._hasReachedQuota = true;
                        }
                    }
                    catch (ex) { }
                    callback(-1);
                };
                transaction.oncomplete = function () {
                    callback(_this._manifestVersionFound);
                };
                var newVersion = { sceneUrl: url, data: this._manifestVersionFound };
                // Put the scene into the database
                var addRequest = transaction.objectStore("versions").put(newVersion);
                addRequest.onsuccess = function () {
                };
                addRequest.onerror = function () {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error in DB add version request in BABYLON.Database.");
                };
            }
            catch (ex) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error while accessing 'versions' object store (WRITE OP). Exception: " + ex.message);
                callback(-1);
            }
        }
        else {
            callback(-1);
        }
    };
    /**
     * Loads a file from database
     * @param url defines the URL to load from
     * @param sceneLoaded defines a callback to call on success
     * @param progressCallBack defines a callback to call when progress changed
     * @param errorCallback defines a callback to call on error
     * @param useArrayBuffer defines a boolean to use array buffer instead of text string
     */
    Database.prototype.loadFile = function (url, sceneLoaded, progressCallBack, errorCallback, useArrayBuffer) {
        var _this = this;
        var completeUrl = Database._ReturnFullUrlLocation(url);
        var saveAndLoadFile = function () {
            // the scene is not yet in the DB, let's try to save it
            _this._saveFileAsync(completeUrl, sceneLoaded, progressCallBack, useArrayBuffer, errorCallback);
        };
        this._checkVersionFromDB(completeUrl, function (version) {
            if (version !== -1) {
                if (!_this._mustUpdateRessources) {
                    _this._loadFileAsync(completeUrl, sceneLoaded, saveAndLoadFile);
                }
                else {
                    _this._saveFileAsync(completeUrl, sceneLoaded, progressCallBack, useArrayBuffer, errorCallback);
                }
            }
            else {
                if (errorCallback) {
                    errorCallback();
                }
            }
        });
    };
    Database.prototype._loadFileAsync = function (url, callback, notInDBCallback) {
        if (this._isSupported && this._db) {
            var targetStore;
            if (url.indexOf(".babylon") !== -1) {
                targetStore = "scenes";
            }
            else {
                targetStore = "textures";
            }
            var file;
            var transaction = this._db.transaction([targetStore]);
            transaction.oncomplete = function () {
                if (file) {
                    callback(file.data);
                }
                // file was not found in DB
                else {
                    notInDBCallback();
                }
            };
            transaction.onabort = function () {
                notInDBCallback();
            };
            var getRequest = transaction.objectStore(targetStore).get(url);
            getRequest.onsuccess = function (event) {
                file = (event.target).result;
            };
            getRequest.onerror = function () {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error loading file " + url + " from DB.");
                notInDBCallback();
            };
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error: IndexedDB not supported by your browser or BabylonJS Database is not open.");
            callback();
        }
    };
    Database.prototype._saveFileAsync = function (url, callback, progressCallback, useArrayBuffer, errorCallback) {
        var _this = this;
        if (this._isSupported) {
            var targetStore;
            if (url.indexOf(".babylon") !== -1) {
                targetStore = "scenes";
            }
            else {
                targetStore = "textures";
            }
            // Create XHR
            var xhr = new _Misc_webRequest__WEBPACK_IMPORTED_MODULE_4__["WebRequest"]();
            var fileData;
            xhr.open("GET", url + "?" + Date.now());
            if (useArrayBuffer) {
                xhr.responseType = "arraybuffer";
            }
            if (progressCallback) {
                xhr.onprogress = progressCallback;
            }
            xhr.addEventListener("load", function () {
                if (xhr.status === 200 || (xhr.status < 400 && Database._ValidateXHRData(xhr, !useArrayBuffer ? 1 : 6))) {
                    // Blob as response (XHR2)
                    fileData = !useArrayBuffer ? xhr.responseText : xhr.response;
                    if (!_this._hasReachedQuota && _this._db) {
                        // Open a transaction to the database
                        var transaction = _this._db.transaction([targetStore], "readwrite");
                        // the transaction could abort because of a QuotaExceededError error
                        transaction.onabort = function (event) {
                            try {
                                //backwards compatibility with ts 1.0, srcElement doesn't have an "error" according to ts 1.3
                                var error = event.srcElement['error'];
                                if (error && error.name === "QuotaExceededError") {
                                    _this._hasReachedQuota = true;
                                }
                            }
                            catch (ex) { }
                            callback(fileData);
                        };
                        transaction.oncomplete = function () {
                            callback(fileData);
                        };
                        var newFile;
                        if (targetStore === "scenes") {
                            newFile = { sceneUrl: url, data: fileData, version: _this._manifestVersionFound };
                        }
                        else {
                            newFile = { textureUrl: url, data: fileData };
                        }
                        try {
                            // Put the scene into the database
                            var addRequest = transaction.objectStore(targetStore).put(newFile);
                            addRequest.onsuccess = function () {
                            };
                            addRequest.onerror = function () {
                                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error in DB add file request in BABYLON.Database.");
                            };
                        }
                        catch (ex) {
                            callback(fileData);
                        }
                    }
                    else {
                        callback(fileData);
                    }
                }
                else {
                    if (xhr.status >= 400 && errorCallback) {
                        errorCallback(xhr);
                    }
                    else {
                        callback();
                    }
                }
            }, false);
            xhr.addEventListener("error", function () {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("error on XHR request.");
                callback();
            }, false);
            xhr.send();
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("Error: IndexedDB not supported by your browser or Babylon.js Database is not open.");
            callback();
        }
    };
    /**
     * Validates if xhr data is correct
     * @param xhr defines the request to validate
     * @param dataType defines the expected data type
     * @returns true if data is correct
     */
    Database._ValidateXHRData = function (xhr, dataType) {
        // 1 for text (.babylon, manifest and shaders), 2 for TGA, 4 for DDS, 7 for all
        if (dataType === void 0) { dataType = 7; }
        try {
            if (dataType & 1) {
                if (xhr.responseText && xhr.responseText.length > 0) {
                    return true;
                }
                else if (dataType === 1) {
                    return false;
                }
            }
            if (dataType & 2) {
                // Check header width and height since there is no "TGA" magic number
                var tgaHeader = _Misc_tga__WEBPACK_IMPORTED_MODULE_2__["TGATools"].GetTGAHeader(xhr.response);
                if (tgaHeader.width && tgaHeader.height && tgaHeader.width > 0 && tgaHeader.height > 0) {
                    return true;
                }
                else if (dataType === 2) {
                    return false;
                }
            }
            if (dataType & 4) {
                // Check for the "DDS" magic number
                var ddsHeader = new Uint8Array(xhr.response, 0, 3);
                if (ddsHeader[0] === 68 && ddsHeader[1] === 68 && ddsHeader[2] === 83) {
                    return true;
                }
                else {
                    return false;
                }
            }
        }
        catch (e) {
            // Global protection
        }
        return false;
    };
    /** Gets a boolean indicating if the user agent supports blob storage (this value will be updated after creating the first Database object) */
    Database.IsUASupportingBlobStorage = true;
    /**
     * Gets a boolean indicating if Database storate is enabled (off by default)
     */
    Database.IDBStorageEnabled = false;
    Database._ParseURL = function (url) {
        var a = document.createElement('a');
        a.href = url;
        var urlWithoutHash = url.substring(0, url.lastIndexOf("#"));
        var fileName = url.substring(urlWithoutHash.lastIndexOf("/") + 1, url.length);
        var absLocation = url.substring(0, url.indexOf(fileName, 0));
        return absLocation;
    };
    Database._ReturnFullUrlLocation = function (url) {
        if (url.indexOf("http:/") === -1 && url.indexOf("https:/") === -1) {
            return (Database._ParseURL(window.location.href) + url);
        }
        else {
            return url;
        }
    };
    return Database;
}());



/***/ }),

/***/ "./Offline/index.ts":
/*!**************************!*\
  !*** ./Offline/index.ts ***!
  \**************************/
/*! exports provided: Database */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _database__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./database */ "./Offline/database.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Database", function() { return _database__WEBPACK_IMPORTED_MODULE_0__["Database"]; });




/***/ }),

/***/ "./Particles/EmitterTypes/boxParticleEmitter.ts":
/*!******************************************************!*\
  !*** ./Particles/EmitterTypes/boxParticleEmitter.ts ***!
  \******************************************************/
/*! exports provided: BoxParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoxParticleEmitter", function() { return BoxParticleEmitter; });
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");



/**
 * Particle emitter emitting particles from the inside of a box.
 * It emits the particles randomly between 2 given directions.
 */
var BoxParticleEmitter = /** @class */ (function () {
    /**
     * Creates a new instance BoxParticleEmitter
     */
    function BoxParticleEmitter() {
        /**
         * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
         */
        this.direction1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1.0, 0);
        /**
         * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
         */
        this.direction2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1.0, 0);
        /**
         * Minimum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.
         */
        this.minEmitBox = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](-0.5, -0.5, -0.5);
        /**
         * Maximum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.
         */
        this.maxEmitBox = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0.5, 0.5, 0.5);
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    BoxParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
    };
    /**
     * Called by the particle System when the position is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param positionToUpdate is the position vector to update with the result
     * @param particle is the particle we are computed the position for
     */
    BoxParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.minEmitBox.x, this.maxEmitBox.x);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.minEmitBox.y, this.maxEmitBox.y);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    BoxParticleEmitter.prototype.clone = function () {
        var newOne = new BoxParticleEmitter();
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    BoxParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setVector3("direction1", this.direction1);
        effect.setVector3("direction2", this.direction2);
        effect.setVector3("minEmitBox", this.minEmitBox);
        effect.setVector3("maxEmitBox", this.maxEmitBox);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    BoxParticleEmitter.prototype.getEffectDefines = function () {
        return "#define BOXEMITTER";
    };
    /**
     * Returns the string "BoxParticleEmitter"
     * @returns a string containing the class name
     */
    BoxParticleEmitter.prototype.getClassName = function () {
        return "BoxParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    BoxParticleEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.getClassName();
        serializationObject.direction1 = this.direction1.asArray();
        serializationObject.direction2 = this.direction2.asArray();
        serializationObject.minEmitBox = this.minEmitBox.asArray();
        serializationObject.maxEmitBox = this.maxEmitBox.asArray();
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    BoxParticleEmitter.prototype.parse = function (serializationObject) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(serializationObject.direction1, 0, this.direction1);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(serializationObject.direction2, 0, this.direction2);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(serializationObject.minEmitBox, 0, this.minEmitBox);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(serializationObject.maxEmitBox, 0, this.maxEmitBox);
    };
    return BoxParticleEmitter;
}());



/***/ }),

/***/ "./Particles/EmitterTypes/coneParticleEmitter.ts":
/*!*******************************************************!*\
  !*** ./Particles/EmitterTypes/coneParticleEmitter.ts ***!
  \*******************************************************/
/*! exports provided: ConeParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConeParticleEmitter", function() { return ConeParticleEmitter; });
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");



/**
 * Particle emitter emitting particles from the inside of a cone.
 * It emits the particles alongside the cone volume from the base to the particle.
 * The emission direction might be randomized.
 */
var ConeParticleEmitter = /** @class */ (function () {
    /**
     * Creates a new instance ConeParticleEmitter
     * @param radius the radius of the emission cone (1 by default)
     * @param angle the cone base angle (PI by default)
     * @param directionRandomizer defines how much to randomize the particle direction [0-1] (default is 0)
     */
    function ConeParticleEmitter(radius, angle,
    /** defines how much to randomize the particle direction [0-1] (default is 0) */
    directionRandomizer) {
        if (radius === void 0) { radius = 1; }
        if (angle === void 0) { angle = Math.PI; }
        if (directionRandomizer === void 0) { directionRandomizer = 0; }
        this.directionRandomizer = directionRandomizer;
        /**
         * Gets or sets a value indicating where on the radius the start position should be picked (1 = everywhere, 0 = only surface)
         */
        this.radiusRange = 1;
        /**
         * Gets or sets a value indicating where on the height the start position should be picked (1 = everywhere, 0 = only surface)
         */
        this.heightRange = 1;
        /**
         * Gets or sets a value indicating if all the particles should be emitted from the spawn point only (the base of the cone)
         */
        this.emitFromSpawnPointOnly = false;
        this.angle = angle;
        this.radius = radius;
    }
    Object.defineProperty(ConeParticleEmitter.prototype, "radius", {
        /**
         * Gets or sets the radius of the emission cone
         */
        get: function () {
            return this._radius;
        },
        set: function (value) {
            this._radius = value;
            this._buildHeight();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ConeParticleEmitter.prototype, "angle", {
        /**
         * Gets or sets the angle of the emission cone
         */
        get: function () {
            return this._angle;
        },
        set: function (value) {
            this._angle = value;
            this._buildHeight();
        },
        enumerable: true,
        configurable: true
    });
    ConeParticleEmitter.prototype._buildHeight = function () {
        if (this._angle !== 0) {
            this._height = this._radius / Math.tan(this._angle / 2);
        }
        else {
            this._height = 1;
        }
    };
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    ConeParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        if (Math.abs(Math.cos(this._angle)) === 1.0) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(0, 1.0, 0, worldMatrix, directionToUpdate);
        }
        else {
            // measure the direction Vector from the emitter to the particle.
            var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
            var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
            var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
            var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
            direction.x += randX;
            direction.y += randY;
            direction.z += randZ;
            direction.normalize();
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
        }
    };
    /**
     * Called by the particle System when the position is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param positionToUpdate is the position vector to update with the result
     * @param particle is the particle we are computed the position for
     */
    ConeParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
        var s = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, Math.PI * 2);
        var h;
        if (!this.emitFromSpawnPointOnly) {
            h = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.heightRange);
            // Better distribution in a cone at normal angles.
            h = 1 - h * h;
        }
        else {
            h = 0.0001;
        }
        var radius = this._radius - _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this._radius * this.radiusRange);
        radius = radius * h;
        var randX = radius * Math.sin(s);
        var randZ = radius * Math.cos(s);
        var randY = h * this._height;
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    ConeParticleEmitter.prototype.clone = function () {
        var newOne = new ConeParticleEmitter(this._radius, this._angle, this.directionRandomizer);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    ConeParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setFloat2("radius", this._radius, this.radiusRange);
        effect.setFloat("coneAngle", this._angle);
        effect.setFloat2("height", this._height, this.heightRange);
        effect.setFloat("directionRandomizer", this.directionRandomizer);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    ConeParticleEmitter.prototype.getEffectDefines = function () {
        var defines = "#define CONEEMITTER";
        if (this.emitFromSpawnPointOnly) {
            defines += "\n#define CONEEMITTERSPAWNPOINT";
        }
        return defines;
    };
    /**
     * Returns the string "ConeParticleEmitter"
     * @returns a string containing the class name
     */
    ConeParticleEmitter.prototype.getClassName = function () {
        return "ConeParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    ConeParticleEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.getClassName();
        serializationObject.radius = this._radius;
        serializationObject.angle = this._angle;
        serializationObject.directionRandomizer = this.directionRandomizer;
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    ConeParticleEmitter.prototype.parse = function (serializationObject) {
        this.radius = serializationObject.radius;
        this.angle = serializationObject.angle;
        this.directionRandomizer = serializationObject.directionRandomizer;
    };
    return ConeParticleEmitter;
}());



/***/ }),

/***/ "./Particles/EmitterTypes/cylinderParticleEmitter.ts":
/*!***********************************************************!*\
  !*** ./Particles/EmitterTypes/cylinderParticleEmitter.ts ***!
  \***********************************************************/
/*! exports provided: CylinderParticleEmitter, CylinderDirectedParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderParticleEmitter", function() { return CylinderParticleEmitter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderDirectedParticleEmitter", function() { return CylinderDirectedParticleEmitter; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/deepCopier */ "./Misc/deepCopier.ts");




/**
 * Particle emitter emitting particles from the inside of a cylinder.
 * It emits the particles alongside the cylinder radius. The emission direction might be randomized.
 */
var CylinderParticleEmitter = /** @class */ (function () {
    /**
    * Creates a new instance CylinderParticleEmitter
    * @param radius the radius of the emission cylinder (1 by default)
    * @param height the height of the emission cylinder (1 by default)
    * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)
    * @param directionRandomizer defines how much to randomize the particle direction [0-1]
    */
    function CylinderParticleEmitter(
    /**
     * The radius of the emission cylinder.
     */
    radius,
    /**
     * The height of the emission cylinder.
     */
    height,
    /**
     * The range of emission [0-1] 0 Surface only, 1 Entire Radius.
     */
    radiusRange,
    /**
     * How much to randomize the particle direction [0-1].
     */
    directionRandomizer) {
        if (radius === void 0) { radius = 1; }
        if (height === void 0) { height = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        if (directionRandomizer === void 0) { directionRandomizer = 0; }
        this.radius = radius;
        this.height = height;
        this.radiusRange = radiusRange;
        this.directionRandomizer = directionRandomizer;
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    CylinderParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(-this.directionRandomizer / 2, this.directionRandomizer / 2);
        var angle = Math.atan2(direction.x, direction.z);
        angle += _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(-Math.PI / 2, Math.PI / 2) * this.directionRandomizer;
        direction.y = randY; // set direction y to rand y to mirror normal of cylinder surface
        direction.x = Math.sin(angle);
        direction.z = Math.cos(angle);
        direction.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
    };
    /**
     * Called by the particle System when the position is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param positionToUpdate is the position vector to update with the result
     * @param particle is the particle we are computed the position for
     */
    CylinderParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
        var yPos = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(-this.height / 2, this.height / 2);
        var angle = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 2 * Math.PI);
        // Pick a properly distributed point within the circle https://programming.guide/random-point-within-circle.html
        var radiusDistribution = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange((1 - this.radiusRange) * (1 - this.radiusRange), 1);
        var positionRadius = Math.sqrt(radiusDistribution) * this.radius;
        var xPos = positionRadius * Math.cos(angle);
        var zPos = positionRadius * Math.sin(angle);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(xPos, yPos, zPos, worldMatrix, positionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    CylinderParticleEmitter.prototype.clone = function () {
        var newOne = new CylinderParticleEmitter(this.radius, this.directionRandomizer);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    CylinderParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setFloat("radius", this.radius);
        effect.setFloat("height", this.height);
        effect.setFloat("radiusRange", this.radiusRange);
        effect.setFloat("directionRandomizer", this.directionRandomizer);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    CylinderParticleEmitter.prototype.getEffectDefines = function () {
        return "#define CYLINDEREMITTER";
    };
    /**
     * Returns the string "CylinderParticleEmitter"
     * @returns a string containing the class name
     */
    CylinderParticleEmitter.prototype.getClassName = function () {
        return "CylinderParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    CylinderParticleEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.getClassName();
        serializationObject.radius = this.radius;
        serializationObject.height = this.height;
        serializationObject.radiusRange = this.radiusRange;
        serializationObject.directionRandomizer = this.directionRandomizer;
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    CylinderParticleEmitter.prototype.parse = function (serializationObject) {
        this.radius = serializationObject.radius;
        this.height = serializationObject.height;
        this.radiusRange = serializationObject.radiusRange;
        this.directionRandomizer = serializationObject.directionRandomizer;
    };
    return CylinderParticleEmitter;
}());

/**
 * Particle emitter emitting particles from the inside of a cylinder.
 * It emits the particles randomly between two vectors.
 */
var CylinderDirectedParticleEmitter = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CylinderDirectedParticleEmitter, _super);
    /**
     * Creates a new instance CylinderDirectedParticleEmitter
     * @param radius the radius of the emission cylinder (1 by default)
     * @param height the height of the emission cylinder (1 by default)
     * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)
     * @param direction1 the min limit of the emission direction (up vector by default)
     * @param direction2 the max limit of the emission direction (up vector by default)
     */
    function CylinderDirectedParticleEmitter(radius, height, radiusRange,
    /**
     * The min limit of the emission direction.
     */
    direction1,
    /**
     * The max limit of the emission direction.
     */
    direction2) {
        if (radius === void 0) { radius = 1; }
        if (height === void 0) { height = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        if (direction1 === void 0) { direction1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1, 0); }
        if (direction2 === void 0) { direction2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1, 0); }
        var _this = _super.call(this, radius, height, radiusRange) || this;
        _this.direction1 = direction1;
        _this.direction2 = direction2;
        return _this;
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    CylinderDirectedParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    CylinderDirectedParticleEmitter.prototype.clone = function () {
        var newOne = new CylinderDirectedParticleEmitter(this.radius, this.height, this.radiusRange, this.direction1, this.direction2);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    CylinderDirectedParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setFloat("radius", this.radius);
        effect.setFloat("height", this.height);
        effect.setFloat("radiusRange", this.radiusRange);
        effect.setVector3("direction1", this.direction1);
        effect.setVector3("direction2", this.direction2);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    CylinderDirectedParticleEmitter.prototype.getEffectDefines = function () {
        return "#define CYLINDEREMITTER\n#define DIRECTEDCYLINDEREMITTER";
    };
    /**
     * Returns the string "CylinderDirectedParticleEmitter"
     * @returns a string containing the class name
     */
    CylinderDirectedParticleEmitter.prototype.getClassName = function () {
        return "CylinderDirectedParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    CylinderDirectedParticleEmitter.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.direction1 = this.direction1.asArray();
        serializationObject.direction2 = this.direction2.asArray();
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    CylinderDirectedParticleEmitter.prototype.parse = function (serializationObject) {
        _super.prototype.parse.call(this, serializationObject);
        this.direction1.copyFrom(serializationObject.direction1);
        this.direction2.copyFrom(serializationObject.direction2);
    };
    return CylinderDirectedParticleEmitter;
}(CylinderParticleEmitter));



/***/ }),

/***/ "./Particles/EmitterTypes/hemisphericParticleEmitter.ts":
/*!**************************************************************!*\
  !*** ./Particles/EmitterTypes/hemisphericParticleEmitter.ts ***!
  \**************************************************************/
/*! exports provided: HemisphericParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HemisphericParticleEmitter", function() { return HemisphericParticleEmitter; });
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");



/**
 * Particle emitter emitting particles from the inside of a hemisphere.
 * It emits the particles alongside the hemisphere radius. The emission direction might be randomized.
 */
var HemisphericParticleEmitter = /** @class */ (function () {
    /**
    * Creates a new instance HemisphericParticleEmitter
    * @param radius the radius of the emission hemisphere (1 by default)
    * @param radiusRange the range of the emission hemisphere [0-1] 0 Surface only, 1 Entire Radius (1 by default)
    * @param directionRandomizer defines how much to randomize the particle direction [0-1]
    */
    function HemisphericParticleEmitter(
    /**
     * The radius of the emission hemisphere.
     */
    radius,
    /**
     * The range of emission [0-1] 0 Surface only, 1 Entire Radius.
     */
    radiusRange,
    /**
     * How much to randomize the particle direction [0-1].
     */
    directionRandomizer) {
        if (radius === void 0) { radius = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        if (directionRandomizer === void 0) { directionRandomizer = 0; }
        this.radius = radius;
        this.radiusRange = radiusRange;
        this.directionRandomizer = directionRandomizer;
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    HemisphericParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
        direction.x += randX;
        direction.y += randY;
        direction.z += randZ;
        direction.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
    };
    /**
     * Called by the particle System when the position is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param positionToUpdate is the position vector to update with the result
     * @param particle is the particle we are computed the position for
     */
    HemisphericParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
        var randRadius = this.radius - _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.radius * this.radiusRange);
        var v = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 1.0);
        var phi = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 2 * Math.PI);
        var theta = Math.acos(2 * v - 1);
        var randX = randRadius * Math.cos(phi) * Math.sin(theta);
        var randY = randRadius * Math.cos(theta);
        var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, Math.abs(randY), randZ, worldMatrix, positionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    HemisphericParticleEmitter.prototype.clone = function () {
        var newOne = new HemisphericParticleEmitter(this.radius, this.directionRandomizer);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    HemisphericParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setFloat("radius", this.radius);
        effect.setFloat("radiusRange", this.radiusRange);
        effect.setFloat("directionRandomizer", this.directionRandomizer);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    HemisphericParticleEmitter.prototype.getEffectDefines = function () {
        return "#define HEMISPHERICEMITTER";
    };
    /**
     * Returns the string "HemisphericParticleEmitter"
     * @returns a string containing the class name
     */
    HemisphericParticleEmitter.prototype.getClassName = function () {
        return "HemisphericParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    HemisphericParticleEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.getClassName();
        serializationObject.radius = this.radius;
        serializationObject.radiusRange = this.radiusRange;
        serializationObject.directionRandomizer = this.directionRandomizer;
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    HemisphericParticleEmitter.prototype.parse = function (serializationObject) {
        this.radius = serializationObject.radius;
        this.radiusRange = serializationObject.radiusRange;
        this.directionRandomizer = serializationObject.directionRandomizer;
    };
    return HemisphericParticleEmitter;
}());



/***/ }),

/***/ "./Particles/EmitterTypes/index.ts":
/*!*****************************************!*\
  !*** ./Particles/EmitterTypes/index.ts ***!
  \*****************************************/
/*! exports provided: BoxParticleEmitter, ConeParticleEmitter, CylinderParticleEmitter, CylinderDirectedParticleEmitter, HemisphericParticleEmitter, PointParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _boxParticleEmitter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./boxParticleEmitter */ "./Particles/EmitterTypes/boxParticleEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxParticleEmitter", function() { return _boxParticleEmitter__WEBPACK_IMPORTED_MODULE_0__["BoxParticleEmitter"]; });

/* harmony import */ var _coneParticleEmitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./coneParticleEmitter */ "./Particles/EmitterTypes/coneParticleEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConeParticleEmitter", function() { return _coneParticleEmitter__WEBPACK_IMPORTED_MODULE_1__["ConeParticleEmitter"]; });

/* harmony import */ var _cylinderParticleEmitter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cylinderParticleEmitter */ "./Particles/EmitterTypes/cylinderParticleEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderParticleEmitter", function() { return _cylinderParticleEmitter__WEBPACK_IMPORTED_MODULE_2__["CylinderParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderDirectedParticleEmitter", function() { return _cylinderParticleEmitter__WEBPACK_IMPORTED_MODULE_2__["CylinderDirectedParticleEmitter"]; });

/* harmony import */ var _hemisphericParticleEmitter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./hemisphericParticleEmitter */ "./Particles/EmitterTypes/hemisphericParticleEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericParticleEmitter", function() { return _hemisphericParticleEmitter__WEBPACK_IMPORTED_MODULE_3__["HemisphericParticleEmitter"]; });

/* harmony import */ var _pointParticleEmitter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./pointParticleEmitter */ "./Particles/EmitterTypes/pointParticleEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointParticleEmitter", function() { return _pointParticleEmitter__WEBPACK_IMPORTED_MODULE_4__["PointParticleEmitter"]; });

/* harmony import */ var _sphereParticleEmitter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./sphereParticleEmitter */ "./Particles/EmitterTypes/sphereParticleEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereParticleEmitter", function() { return _sphereParticleEmitter__WEBPACK_IMPORTED_MODULE_5__["SphereParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereDirectedParticleEmitter", function() { return _sphereParticleEmitter__WEBPACK_IMPORTED_MODULE_5__["SphereDirectedParticleEmitter"]; });









/***/ }),

/***/ "./Particles/EmitterTypes/pointParticleEmitter.ts":
/*!********************************************************!*\
  !*** ./Particles/EmitterTypes/pointParticleEmitter.ts ***!
  \********************************************************/
/*! exports provided: PointParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PointParticleEmitter", function() { return PointParticleEmitter; });
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");



/**
 * Particle emitter emitting particles from a point.
 * It emits the particles randomly between 2 given directions.
 */
var PointParticleEmitter = /** @class */ (function () {
    /**
     * Creates a new instance PointParticleEmitter
     */
    function PointParticleEmitter() {
        /**
         * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
         */
        this.direction1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1.0, 0);
        /**
         * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
         */
        this.direction2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1.0, 0);
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    PointParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
    };
    /**
     * Called by the particle System when the position is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param positionToUpdate is the position vector to update with the result
     * @param particle is the particle we are computed the position for
     */
    PointParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(0, 0, 0, worldMatrix, positionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    PointParticleEmitter.prototype.clone = function () {
        var newOne = new PointParticleEmitter();
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_0__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    PointParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setVector3("direction1", this.direction1);
        effect.setVector3("direction2", this.direction2);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    PointParticleEmitter.prototype.getEffectDefines = function () {
        return "#define POINTEMITTER";
    };
    /**
     * Returns the string "PointParticleEmitter"
     * @returns a string containing the class name
     */
    PointParticleEmitter.prototype.getClassName = function () {
        return "PointParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    PointParticleEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.getClassName();
        serializationObject.direction1 = this.direction1.asArray();
        serializationObject.direction2 = this.direction2.asArray();
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    PointParticleEmitter.prototype.parse = function (serializationObject) {
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(serializationObject.direction1, 0, this.direction1);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(serializationObject.direction2, 0, this.direction2);
    };
    return PointParticleEmitter;
}());



/***/ }),

/***/ "./Particles/EmitterTypes/sphereParticleEmitter.ts":
/*!*********************************************************!*\
  !*** ./Particles/EmitterTypes/sphereParticleEmitter.ts ***!
  \*********************************************************/
/*! exports provided: SphereParticleEmitter, SphereDirectedParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphereParticleEmitter", function() { return SphereParticleEmitter; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SphereDirectedParticleEmitter", function() { return SphereDirectedParticleEmitter; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Misc/deepCopier */ "./Misc/deepCopier.ts");




/**
 * Particle emitter emitting particles from the inside of a sphere.
 * It emits the particles alongside the sphere radius. The emission direction might be randomized.
 */
var SphereParticleEmitter = /** @class */ (function () {
    /**
    * Creates a new instance SphereParticleEmitter
    * @param radius the radius of the emission sphere (1 by default)
    * @param radiusRange the range of the emission sphere [0-1] 0 Surface only, 1 Entire Radius (1 by default)
    * @param directionRandomizer defines how much to randomize the particle direction [0-1]
    */
    function SphereParticleEmitter(
    /**
     * The radius of the emission sphere.
     */
    radius,
    /**
     * The range of emission [0-1] 0 Surface only, 1 Entire Radius.
     */
    radiusRange,
    /**
     * How much to randomize the particle direction [0-1].
     */
    directionRandomizer) {
        if (radius === void 0) { radius = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        if (directionRandomizer === void 0) { directionRandomizer = 0; }
        this.radius = radius;
        this.radiusRange = radiusRange;
        this.directionRandomizer = directionRandomizer;
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    SphereParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
        direction.x += randX;
        direction.y += randY;
        direction.z += randZ;
        direction.normalize();
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
    };
    /**
     * Called by the particle System when the position is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param positionToUpdate is the position vector to update with the result
     * @param particle is the particle we are computed the position for
     */
    SphereParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
        var randRadius = this.radius - _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.radius * this.radiusRange);
        var v = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 1.0);
        var phi = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 2 * Math.PI);
        var theta = Math.acos(2 * v - 1);
        var randX = randRadius * Math.cos(phi) * Math.sin(theta);
        var randY = randRadius * Math.cos(theta);
        var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    SphereParticleEmitter.prototype.clone = function () {
        var newOne = new SphereParticleEmitter(this.radius, this.directionRandomizer);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    SphereParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setFloat("radius", this.radius);
        effect.setFloat("radiusRange", this.radiusRange);
        effect.setFloat("directionRandomizer", this.directionRandomizer);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    SphereParticleEmitter.prototype.getEffectDefines = function () {
        return "#define SPHEREEMITTER";
    };
    /**
     * Returns the string "SphereParticleEmitter"
     * @returns a string containing the class name
     */
    SphereParticleEmitter.prototype.getClassName = function () {
        return "SphereParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    SphereParticleEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.getClassName();
        serializationObject.radius = this.radius;
        serializationObject.radiusRange = this.radiusRange;
        serializationObject.directionRandomizer = this.directionRandomizer;
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    SphereParticleEmitter.prototype.parse = function (serializationObject) {
        this.radius = serializationObject.radius;
        this.radiusRange = serializationObject.radiusRange;
        this.directionRandomizer = serializationObject.directionRandomizer;
    };
    return SphereParticleEmitter;
}());

/**
 * Particle emitter emitting particles from the inside of a sphere.
 * It emits the particles randomly between two vectors.
 */
var SphereDirectedParticleEmitter = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SphereDirectedParticleEmitter, _super);
    /**
     * Creates a new instance SphereDirectedParticleEmitter
     * @param radius the radius of the emission sphere (1 by default)
     * @param direction1 the min limit of the emission direction (up vector by default)
     * @param direction2 the max limit of the emission direction (up vector by default)
     */
    function SphereDirectedParticleEmitter(radius,
    /**
     * The min limit of the emission direction.
     */
    direction1,
    /**
     * The max limit of the emission direction.
     */
    direction2) {
        if (radius === void 0) { radius = 1; }
        if (direction1 === void 0) { direction1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1, 0); }
        if (direction2 === void 0) { direction2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](0, 1, 0); }
        var _this = _super.call(this, radius) || this;
        _this.direction1 = direction1;
        _this.direction2 = direction2;
        return _this;
    }
    /**
     * Called by the particle System when the direction is computed for the created particle.
     * @param worldMatrix is the world matrix of the particle system
     * @param directionToUpdate is the direction vector to update with the result
     * @param particle is the particle we are computed the direction for
     */
    SphereDirectedParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
        var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
        var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
        var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
    };
    /**
     * Clones the current emitter and returns a copy of it
     * @returns the new emitter
     */
    SphereDirectedParticleEmitter.prototype.clone = function () {
        var newOne = new SphereDirectedParticleEmitter(this.radius, this.direction1, this.direction2);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_3__["DeepCopier"].DeepCopy(this, newOne);
        return newOne;
    };
    /**
     * Called by the GPUParticleSystem to setup the update shader
     * @param effect defines the update shader
     */
    SphereDirectedParticleEmitter.prototype.applyToShader = function (effect) {
        effect.setFloat("radius", this.radius);
        effect.setFloat("radiusRange", this.radiusRange);
        effect.setVector3("direction1", this.direction1);
        effect.setVector3("direction2", this.direction2);
    };
    /**
     * Returns a string to use to update the GPU particles update shader
     * @returns a string containng the defines string
     */
    SphereDirectedParticleEmitter.prototype.getEffectDefines = function () {
        return "#define SPHEREEMITTER\n#define DIRECTEDSPHEREEMITTER";
    };
    /**
     * Returns the string "SphereDirectedParticleEmitter"
     * @returns a string containing the class name
     */
    SphereDirectedParticleEmitter.prototype.getClassName = function () {
        return "SphereDirectedParticleEmitter";
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    SphereDirectedParticleEmitter.prototype.serialize = function () {
        var serializationObject = _super.prototype.serialize.call(this);
        serializationObject.direction1 = this.direction1.asArray();
        serializationObject.direction2 = this.direction2.asArray();
        return serializationObject;
    };
    /**
     * Parse properties from a JSON object
     * @param serializationObject defines the JSON object
     */
    SphereDirectedParticleEmitter.prototype.parse = function (serializationObject) {
        _super.prototype.parse.call(this, serializationObject);
        this.direction1.copyFrom(serializationObject.direction1);
        this.direction2.copyFrom(serializationObject.direction2);
    };
    return SphereDirectedParticleEmitter;
}(SphereParticleEmitter));



/***/ }),

/***/ "./Particles/baseParticleSystem.ts":
/*!*****************************************!*\
  !*** ./Particles/baseParticleSystem.ts ***!
  \*****************************************/
/*! exports provided: BaseParticleSystem */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseParticleSystem", function() { return BaseParticleSystem; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Particles/EmitterTypes/index */ "./Particles/EmitterTypes/index.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");





/**
 * This represents the base class for particle system in Babylon.
 * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
 * Particles can take different shapes while emitted like box, sphere, cone or you can write your custom function.
 * @example https://doc.babylonjs.com/babylon101/particles
 */
var BaseParticleSystem = /** @class */ (function () {
    /**
     * Instantiates a particle system.
     * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
     * @param name The name of the particle system
     */
    function BaseParticleSystem(name) {
        /**
         * List of animations used by the particle system.
         */
        this.animations = [];
        /**
         * The rendering group used by the Particle system to chose when to render.
         */
        this.renderingGroupId = 0;
        /**
         * The emitter represents the Mesh or position we are attaching the particle system to.
         */
        this.emitter = null;
        /**
         * The maximum number of particles to emit per frame
         */
        this.emitRate = 10;
        /**
         * If you want to launch only a few particles at once, that can be done, as well.
         */
        this.manualEmitCount = -1;
        /**
         * The overall motion speed (0.01 is default update speed, faster updates = faster animation)
         */
        this.updateSpeed = 0.01;
        /**
         * The amount of time the particle system is running (depends of the overall update speed).
         */
        this.targetStopDuration = 0;
        /**
         * Specifies whether the particle system will be disposed once it reaches the end of the animation.
         */
        this.disposeOnStop = false;
        /**
         * Minimum power of emitting particles.
         */
        this.minEmitPower = 1;
        /**
         * Maximum power of emitting particles.
         */
        this.maxEmitPower = 1;
        /**
         * Minimum life time of emitting particles.
         */
        this.minLifeTime = 1;
        /**
         * Maximum life time of emitting particles.
         */
        this.maxLifeTime = 1;
        /**
         * Minimum Size of emitting particles.
         */
        this.minSize = 1;
        /**
         * Maximum Size of emitting particles.
         */
        this.maxSize = 1;
        /**
         * Minimum scale of emitting particles on X axis.
         */
        this.minScaleX = 1;
        /**
         * Maximum scale of emitting particles on X axis.
         */
        this.maxScaleX = 1;
        /**
         * Minimum scale of emitting particles on Y axis.
         */
        this.minScaleY = 1;
        /**
         * Maximum scale of emitting particles on Y axis.
         */
        this.maxScaleY = 1;
        /**
         * Gets or sets the minimal initial rotation in radians.
         */
        this.minInitialRotation = 0;
        /**
         * Gets or sets the maximal initial rotation in radians.
         */
        this.maxInitialRotation = 0;
        /**
         * Minimum angular speed of emitting particles (Z-axis rotation for each particle).
         */
        this.minAngularSpeed = 0;
        /**
         * Maximum angular speed of emitting particles (Z-axis rotation for each particle).
         */
        this.maxAngularSpeed = 0;
        /**
         * The layer mask we are rendering the particles through.
         */
        this.layerMask = 0x0FFFFFFF;
        /**
         * This can help using your own shader to render the particle system.
         * The according effect will be created
         */
        this.customShader = null;
        /**
         * By default particle system starts as soon as they are created. This prevents the
         * automatic start to happen and let you decide when to start emitting particles.
         */
        this.preventAutoStart = false;
        /** Gets or sets the strength to apply to the noise value (default is (10, 10, 10)) */
        this.noiseStrength = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](10, 10, 10);
        /**
         * Callback triggered when the particle animation is ending.
         */
        this.onAnimationEnd = null;
        /**
         * Blend mode use to render the particle, it can be either ParticleSystem.BLENDMODE_ONEONE or ParticleSystem.BLENDMODE_STANDARD.
         */
        this.blendMode = BaseParticleSystem.BLENDMODE_ONEONE;
        /**
         * Forces the particle to write their depth information to the depth buffer. This can help preventing other draw calls
         * to override the particles.
         */
        this.forceDepthWrite = false;
        /** Gets or sets a value indicating how many cycles (or frames) must be executed before first rendering (this value has to be set before starting the system). Default is 0 */
        this.preWarmCycles = 0;
        /** Gets or sets a value indicating the time step multiplier to use in pre-warm mode (default is 1) */
        this.preWarmStepOffset = 1;
        /**
         * If using a spritesheet (isAnimationSheetEnabled) defines the speed of the sprite loop (default is 1 meaning the animation will play once during the entire particle lifetime)
         */
        this.spriteCellChangeSpeed = 1;
        /**
         * If using a spritesheet (isAnimationSheetEnabled) defines the first sprite cell to display
         */
        this.startSpriteCellID = 0;
        /**
         * If using a spritesheet (isAnimationSheetEnabled) defines the last sprite cell to display
         */
        this.endSpriteCellID = 0;
        /**
         * If using a spritesheet (isAnimationSheetEnabled), defines the sprite cell width to use
         */
        this.spriteCellWidth = 0;
        /**
         * If using a spritesheet (isAnimationSheetEnabled), defines the sprite cell height to use
         */
        this.spriteCellHeight = 0;
        /**
         * This allows the system to random pick the start cell ID between startSpriteCellID and endSpriteCellID
         */
        this.spriteRandomStartCell = false;
        /** Gets or sets a Vector2 used to move the pivot (by default (0,0)) */
        this.translationPivot = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
        /**
         * Gets or sets a boolean indicating that hosted animations (in the system.animations array) must be started when system.start() is called
         */
        this.beginAnimationOnStart = false;
        /**
         * Gets or sets the frame to start the animation from when beginAnimationOnStart is true
         */
        this.beginAnimationFrom = 0;
        /**
         * Gets or sets the frame to end the animation on when beginAnimationOnStart is true
         */
        this.beginAnimationTo = 60;
        /**
         * Gets or sets a boolean indicating if animations must loop when beginAnimationOnStart is true
         */
        this.beginAnimationLoop = false;
        /**
         * Gets or sets a world offset applied to all particles
         */
        this.worldOffset = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
        /**
         * You can use gravity if you want to give an orientation to your particles.
         */
        this.gravity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._colorGradients = null;
        this._sizeGradients = null;
        this._lifeTimeGradients = null;
        this._angularSpeedGradients = null;
        this._velocityGradients = null;
        this._limitVelocityGradients = null;
        this._dragGradients = null;
        this._emitRateGradients = null;
        this._startSizeGradients = null;
        this._rampGradients = null;
        this._colorRemapGradients = null;
        this._alphaRemapGradients = null;
        /**
         * Defines the delay in milliseconds before starting the system (0 by default)
         */
        this.startDelay = 0;
        /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
        this.limitVelocityDamping = 0.4;
        /**
         * Random color of each particle after it has been emitted, between color1 and color2 vectors
         */
        this.color1 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](1.0, 1.0, 1.0, 1.0);
        /**
         * Random color of each particle after it has been emitted, between color1 and color2 vectors
         */
        this.color2 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](1.0, 1.0, 1.0, 1.0);
        /**
         * Color the particle will have at the end of its lifetime
         */
        this.colorDead = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](0, 0, 0, 1.0);
        /**
         * An optional mask to filter some colors out of the texture, or filter a part of the alpha channel
         */
        this.textureMask = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"](1.0, 1.0, 1.0, 1.0);
        /** @hidden */
        this._isSubEmitter = false;
        /**
         * Gets or sets the billboard mode to use when isBillboardBased = true.
         * Value can be: ParticleSystem.BILLBOARDMODE_ALL, ParticleSystem.BILLBOARDMODE_Y, ParticleSystem.BILLBOARDMODE_STRETCHED
         */
        this.billboardMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].PARTICLES_BILLBOARDMODE_ALL;
        this._isBillboardBased = true;
        /**
         * Local cache of defines for image processing.
         */
        this._imageProcessingConfigurationDefines = new _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_1__["ImageProcessingConfigurationDefines"]();
        this.id = name;
        this.name = name;
    }
    Object.defineProperty(BaseParticleSystem.prototype, "noiseTexture", {
        /**
         * Gets or sets a texture used to add random noise to particle positions
         */
        get: function () {
            return this._noiseTexture;
        },
        set: function (value) {
            if (this._noiseTexture === value) {
                return;
            }
            this._noiseTexture = value;
            this._reset();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseParticleSystem.prototype, "isAnimationSheetEnabled", {
        /**
         * Gets or sets whether an animation sprite sheet is enabled or not on the particle system
         */
        get: function () {
            return this._isAnimationSheetEnabled;
        },
        set: function (value) {
            if (this._isAnimationSheetEnabled == value) {
                return;
            }
            this._isAnimationSheetEnabled = value;
            this._reset();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get hosting scene
     * @returns the scene
     */
    BaseParticleSystem.prototype.getScene = function () {
        return this._scene;
    };
    BaseParticleSystem.prototype._hasTargetStopDurationDependantGradient = function () {
        return (this._startSizeGradients && this._startSizeGradients.length > 0)
            || (this._emitRateGradients && this._emitRateGradients.length > 0)
            || (this._lifeTimeGradients && this._lifeTimeGradients.length > 0);
    };
    /**
     * Gets the current list of drag gradients.
     * You must use addDragGradient and removeDragGradient to udpate this list
     * @returns the list of drag gradients
     */
    BaseParticleSystem.prototype.getDragGradients = function () {
        return this._dragGradients;
    };
    /**
     * Gets the current list of limit velocity gradients.
     * You must use addLimitVelocityGradient and removeLimitVelocityGradient to udpate this list
     * @returns the list of limit velocity gradients
     */
    BaseParticleSystem.prototype.getLimitVelocityGradients = function () {
        return this._limitVelocityGradients;
    };
    /**
     * Gets the current list of color gradients.
     * You must use addColorGradient and removeColorGradient to udpate this list
     * @returns the list of color gradients
     */
    BaseParticleSystem.prototype.getColorGradients = function () {
        return this._colorGradients;
    };
    /**
     * Gets the current list of size gradients.
     * You must use addSizeGradient and removeSizeGradient to udpate this list
     * @returns the list of size gradients
     */
    BaseParticleSystem.prototype.getSizeGradients = function () {
        return this._sizeGradients;
    };
    /**
     * Gets the current list of color remap gradients.
     * You must use addColorRemapGradient and removeColorRemapGradient to udpate this list
     * @returns the list of color remap gradients
     */
    BaseParticleSystem.prototype.getColorRemapGradients = function () {
        return this._colorRemapGradients;
    };
    /**
     * Gets the current list of alpha remap gradients.
     * You must use addAlphaRemapGradient and removeAlphaRemapGradient to udpate this list
     * @returns the list of alpha remap gradients
     */
    BaseParticleSystem.prototype.getAlphaRemapGradients = function () {
        return this._alphaRemapGradients;
    };
    /**
     * Gets the current list of life time gradients.
     * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
     * @returns the list of life time gradients
     */
    BaseParticleSystem.prototype.getLifeTimeGradients = function () {
        return this._lifeTimeGradients;
    };
    /**
     * Gets the current list of angular speed gradients.
     * You must use addAngularSpeedGradient and removeAngularSpeedGradient to udpate this list
     * @returns the list of angular speed gradients
     */
    BaseParticleSystem.prototype.getAngularSpeedGradients = function () {
        return this._angularSpeedGradients;
    };
    /**
     * Gets the current list of velocity gradients.
     * You must use addVelocityGradient and removeVelocityGradient to udpate this list
     * @returns the list of velocity gradients
     */
    BaseParticleSystem.prototype.getVelocityGradients = function () {
        return this._velocityGradients;
    };
    /**
     * Gets the current list of start size gradients.
     * You must use addStartSizeGradient and removeStartSizeGradient to udpate this list
     * @returns the list of start size gradients
     */
    BaseParticleSystem.prototype.getStartSizeGradients = function () {
        return this._startSizeGradients;
    };
    /**
     * Gets the current list of emit rate gradients.
     * You must use addEmitRateGradient and removeEmitRateGradient to udpate this list
     * @returns the list of emit rate gradients
     */
    BaseParticleSystem.prototype.getEmitRateGradients = function () {
        return this._emitRateGradients;
    };
    Object.defineProperty(BaseParticleSystem.prototype, "direction1", {
        /**
         * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
         * This only works when particleEmitterTyps is a BoxParticleEmitter
         */
        get: function () {
            if (this.particleEmitterType.direction1) {
                return this.particleEmitterType.direction1;
            }
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        },
        set: function (value) {
            if (this.particleEmitterType.direction1) {
                this.particleEmitterType.direction1 = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseParticleSystem.prototype, "direction2", {
        /**
         * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
         * This only works when particleEmitterTyps is a BoxParticleEmitter
         */
        get: function () {
            if (this.particleEmitterType.direction2) {
                return this.particleEmitterType.direction2;
            }
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        },
        set: function (value) {
            if (this.particleEmitterType.direction2) {
                this.particleEmitterType.direction2 = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseParticleSystem.prototype, "minEmitBox", {
        /**
         * Minimum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.
         * This only works when particleEmitterTyps is a BoxParticleEmitter
         */
        get: function () {
            if (this.particleEmitterType.minEmitBox) {
                return this.particleEmitterType.minEmitBox;
            }
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        },
        set: function (value) {
            if (this.particleEmitterType.minEmitBox) {
                this.particleEmitterType.minEmitBox = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseParticleSystem.prototype, "maxEmitBox", {
        /**
         * Maximum box point around our emitter. Our emitter is the center of particles source, but if you want your particles to emit from more than one point, then you can tell it to do so.
         * This only works when particleEmitterTyps is a BoxParticleEmitter
         */
        get: function () {
            if (this.particleEmitterType.maxEmitBox) {
                return this.particleEmitterType.maxEmitBox;
            }
            return _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        },
        set: function (value) {
            if (this.particleEmitterType.maxEmitBox) {
                this.particleEmitterType.maxEmitBox = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseParticleSystem.prototype, "isBillboardBased", {
        /**
         * Gets or sets a boolean indicating if the particles must be rendered as billboard or aligned with the direction
         */
        get: function () {
            return this._isBillboardBased;
        },
        set: function (value) {
            if (this._isBillboardBased === value) {
                return;
            }
            this._isBillboardBased = value;
            this._reset();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BaseParticleSystem.prototype, "imageProcessingConfiguration", {
        /**
         * Gets the image processing configuration used either in this material.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        /**
         * Sets the Default image processing configuration used either in the this material.
         *
         * If sets to null, the scene one is in use.
         */
        set: function (value) {
            this._attachImageProcessingConfiguration(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attaches a new image processing configuration to the Standard Material.
     * @param configuration
     */
    BaseParticleSystem.prototype._attachImageProcessingConfiguration = function (configuration) {
        if (configuration === this._imageProcessingConfiguration) {
            return;
        }
        // Pick the scene configuration if needed.
        if (!configuration) {
            this._imageProcessingConfiguration = this._scene.imageProcessingConfiguration;
        }
        else {
            this._imageProcessingConfiguration = configuration;
        }
    };
    /** @hidden */
    BaseParticleSystem.prototype._reset = function () {
    };
    /** @hidden */
    BaseParticleSystem.prototype._removeGradientAndTexture = function (gradient, gradients, texture) {
        if (!gradients) {
            return this;
        }
        var index = 0;
        for (var _i = 0, gradients_1 = gradients; _i < gradients_1.length; _i++) {
            var valueGradient = gradients_1[_i];
            if (valueGradient.gradient === gradient) {
                gradients.splice(index, 1);
                break;
            }
            index++;
        }
        if (texture) {
            texture.dispose();
        }
        return this;
    };
    /**
     * Creates a Point Emitter for the particle system (emits directly from the emitter position)
     * @param direction1 Particles are emitted between the direction1 and direction2 from within the box
     * @param direction2 Particles are emitted between the direction1 and direction2 from within the box
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createPointEmitter = function (direction1, direction2) {
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["PointParticleEmitter"]();
        particleEmitter.direction1 = direction1;
        particleEmitter.direction2 = direction2;
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Hemisphere Emitter for the particle system (emits along the hemisphere radius)
     * @param radius The radius of the hemisphere to emit from
     * @param radiusRange The range of the hemisphere to emit from [0-1] 0 Surface Only, 1 Entire Radius
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createHemisphericEmitter = function (radius, radiusRange) {
        if (radius === void 0) { radius = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["HemisphericParticleEmitter"](radius, radiusRange);
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Sphere Emitter for the particle system (emits along the sphere radius)
     * @param radius The radius of the sphere to emit from
     * @param radiusRange The range of the sphere to emit from [0-1] 0 Surface Only, 1 Entire Radius
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createSphereEmitter = function (radius, radiusRange) {
        if (radius === void 0) { radius = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["SphereParticleEmitter"](radius, radiusRange);
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Directed Sphere Emitter for the particle system (emits between direction1 and direction2)
     * @param radius The radius of the sphere to emit from
     * @param direction1 Particles are emitted between the direction1 and direction2 from within the sphere
     * @param direction2 Particles are emitted between the direction1 and direction2 from within the sphere
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createDirectedSphereEmitter = function (radius, direction1, direction2) {
        if (radius === void 0) { radius = 1; }
        if (direction1 === void 0) { direction1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1.0, 0); }
        if (direction2 === void 0) { direction2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1.0, 0); }
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["SphereDirectedParticleEmitter"](radius, direction1, direction2);
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Cylinder Emitter for the particle system (emits from the cylinder to the particle position)
     * @param radius The radius of the emission cylinder
     * @param height The height of the emission cylinder
     * @param radiusRange The range of emission [0-1] 0 Surface only, 1 Entire Radius
     * @param directionRandomizer How much to randomize the particle direction [0-1]
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createCylinderEmitter = function (radius, height, radiusRange, directionRandomizer) {
        if (radius === void 0) { radius = 1; }
        if (height === void 0) { height = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        if (directionRandomizer === void 0) { directionRandomizer = 0; }
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["CylinderParticleEmitter"](radius, height, radiusRange, directionRandomizer);
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Directed Cylinder Emitter for the particle system (emits between direction1 and direction2)
     * @param radius The radius of the cylinder to emit from
     * @param height The height of the emission cylinder
     * @param radiusRange the range of the emission cylinder [0-1] 0 Surface only, 1 Entire Radius (1 by default)
     * @param direction1 Particles are emitted between the direction1 and direction2 from within the cylinder
     * @param direction2 Particles are emitted between the direction1 and direction2 from within the cylinder
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createDirectedCylinderEmitter = function (radius, height, radiusRange, direction1, direction2) {
        if (radius === void 0) { radius = 1; }
        if (height === void 0) { height = 1; }
        if (radiusRange === void 0) { radiusRange = 1; }
        if (direction1 === void 0) { direction1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1.0, 0); }
        if (direction2 === void 0) { direction2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 1.0, 0); }
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["CylinderDirectedParticleEmitter"](radius, height, radiusRange, direction1, direction2);
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Cone Emitter for the particle system (emits from the cone to the particle position)
     * @param radius The radius of the cone to emit from
     * @param angle The base angle of the cone
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createConeEmitter = function (radius, angle) {
        if (radius === void 0) { radius = 1; }
        if (angle === void 0) { angle = Math.PI / 4; }
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["ConeParticleEmitter"](radius, angle);
        this.particleEmitterType = particleEmitter;
        return particleEmitter;
    };
    /**
     * Creates a Box Emitter for the particle system. (emits between direction1 and direction2 from withing the box defined by minEmitBox and maxEmitBox)
     * @param direction1 Particles are emitted between the direction1 and direction2 from within the box
     * @param direction2 Particles are emitted between the direction1 and direction2 from within the box
     * @param minEmitBox Particles are emitted from the box between minEmitBox and maxEmitBox
     * @param maxEmitBox  Particles are emitted from the box between minEmitBox and maxEmitBox
     * @returns the emitter
     */
    BaseParticleSystem.prototype.createBoxEmitter = function (direction1, direction2, minEmitBox, maxEmitBox) {
        var particleEmitter = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_2__["BoxParticleEmitter"]();
        this.particleEmitterType = particleEmitter;
        this.direction1 = direction1;
        this.direction2 = direction2;
        this.minEmitBox = minEmitBox;
        this.maxEmitBox = maxEmitBox;
        return particleEmitter;
    };
    /**
     * Source color is added to the destination color without alpha affecting the result
     */
    BaseParticleSystem.BLENDMODE_ONEONE = 0;
    /**
     * Blend current color and particle color using particle’s alpha
     */
    BaseParticleSystem.BLENDMODE_STANDARD = 1;
    /**
     * Add current color and particle color multiplied by particle’s alpha
     */
    BaseParticleSystem.BLENDMODE_ADD = 2;
    /**
     * Multiply current color with particle color
     */
    BaseParticleSystem.BLENDMODE_MULTIPLY = 3;
    /**
     * Multiply current color with particle color then add current color and particle color multiplied by particle’s alpha
     */
    BaseParticleSystem.BLENDMODE_MULTIPLYADD = 4;
    return BaseParticleSystem;
}());



/***/ }),

/***/ "./Particles/gpuParticleSystem.ts":
/*!****************************************!*\
  !*** ./Particles/gpuParticleSystem.ts ***!
  \****************************************/
/*! exports provided: GPUParticleSystem */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GPUParticleSystem", function() { return GPUParticleSystem; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/gradients */ "./Misc/gradients.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _baseParticleSystem__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./baseParticleSystem */ "./Particles/baseParticleSystem.ts");
/* harmony import */ var _particleSystem__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./particleSystem */ "./Particles/particleSystem.ts");
/* harmony import */ var _Particles_EmitterTypes_boxParticleEmitter__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Particles/EmitterTypes/boxParticleEmitter */ "./Particles/EmitterTypes/boxParticleEmitter.ts");
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Materials/Textures/rawTexture */ "./Materials/Textures/rawTexture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Shaders_gpuUpdateParticles_fragment__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../Shaders/gpuUpdateParticles.fragment */ "./Shaders/gpuUpdateParticles.fragment.ts");
/* harmony import */ var _Shaders_gpuUpdateParticles_vertex__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../Shaders/gpuUpdateParticles.vertex */ "./Shaders/gpuUpdateParticles.vertex.ts");
/* harmony import */ var _Shaders_gpuRenderParticles_fragment__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../Shaders/gpuRenderParticles.fragment */ "./Shaders/gpuRenderParticles.fragment.ts");
/* harmony import */ var _Shaders_gpuRenderParticles_vertex__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../Shaders/gpuRenderParticles.vertex */ "./Shaders/gpuRenderParticles.vertex.ts");























/**
 * This represents a GPU particle system in Babylon
 * This is the fastest particle system in Babylon as it uses the GPU to update the individual particle data
 * @see https://www.babylonjs-playground.com/#PU4WYI#4
 */
var GPUParticleSystem = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GPUParticleSystem, _super);
    /**
     * Instantiates a GPU particle system.
     * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
     * @param name The name of the particle system
     * @param options The options used to create the system
     * @param scene The scene the particle system belongs to
     * @param isAnimationSheetEnabled Must be true if using a spritesheet to animate the particles texture
     */
    function GPUParticleSystem(name, options, scene, isAnimationSheetEnabled) {
        if (isAnimationSheetEnabled === void 0) { isAnimationSheetEnabled = false; }
        var _this = _super.call(this, name) || this;
        /**
         * The layer mask we are rendering the particles through.
         */
        _this.layerMask = 0x0FFFFFFF;
        _this._accumulatedCount = 0;
        _this._targetIndex = 0;
        _this._currentRenderId = -1;
        _this._started = false;
        _this._stopped = false;
        _this._timeDelta = 0;
        _this._actualFrame = 0;
        _this._rawTextureWidth = 256;
        /**
        * An event triggered when the system is disposed.
        */
        _this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        /**
         * Forces the particle to write their depth information to the depth buffer. This can help preventing other draw calls
         * to override the particles.
         */
        _this.forceDepthWrite = false;
        _this._preWarmDone = false;
        _this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_17__["EngineStore"].LastCreatedScene;
        // Setup the default processing configuration to the scene.
        _this._attachImageProcessingConfiguration(null);
        _this._engine = _this._scene.getEngine();
        if (!options.randomTextureSize) {
            delete options.randomTextureSize;
        }
        var fullOptions = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({ capacity: 50000, randomTextureSize: _this._engine.getCaps().maxTextureSize }, options);
        var optionsAsNumber = options;
        if (isFinite(optionsAsNumber)) {
            fullOptions.capacity = optionsAsNumber;
        }
        _this._capacity = fullOptions.capacity;
        _this._activeCount = fullOptions.capacity;
        _this._currentActiveCount = 0;
        _this._isAnimationSheetEnabled = isAnimationSheetEnabled;
        _this._scene.particleSystems.push(_this);
        _this._updateEffectOptions = {
            attributes: ["position", "age", "life", "seed", "size", "color", "direction", "initialDirection", "angle", "cellIndex", "cellStartOffset", "noiseCoordinates1", "noiseCoordinates2"],
            uniformsNames: ["currentCount", "timeDelta", "emitterWM", "lifeTime", "color1", "color2", "sizeRange", "scaleRange", "gravity", "emitPower",
                "direction1", "direction2", "minEmitBox", "maxEmitBox", "radius", "directionRandomizer", "height", "coneAngle", "stopFactor",
                "angleRange", "radiusRange", "cellInfos", "noiseStrength", "limitVelocityDamping"],
            uniformBuffersNames: [],
            samplers: ["randomSampler", "randomSampler2", "sizeGradientSampler", "angularSpeedGradientSampler", "velocityGradientSampler", "limitVelocityGradientSampler", "noiseSampler", "dragGradientSampler"],
            defines: "",
            fallbacks: null,
            onCompiled: null,
            onError: null,
            indexParameters: null,
            maxSimultaneousLights: 0,
            transformFeedbackVaryings: []
        };
        _this.particleEmitterType = new _Particles_EmitterTypes_boxParticleEmitter__WEBPACK_IMPORTED_MODULE_9__["BoxParticleEmitter"]();
        // Random data
        var maxTextureSize = Math.min(_this._engine.getCaps().maxTextureSize, fullOptions.randomTextureSize);
        var d = [];
        for (var i = 0; i < maxTextureSize; ++i) {
            d.push(Math.random());
            d.push(Math.random());
            d.push(Math.random());
            d.push(Math.random());
        }
        _this._randomTexture = new _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_15__["RawTexture"](new Float32Array(d), maxTextureSize, 1, _Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].TEXTUREFORMAT_RGBA, _this._scene, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, _Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].TEXTURETYPE_FLOAT);
        _this._randomTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"].WRAP_ADDRESSMODE;
        _this._randomTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"].WRAP_ADDRESSMODE;
        d = [];
        for (var i = 0; i < maxTextureSize; ++i) {
            d.push(Math.random());
            d.push(Math.random());
            d.push(Math.random());
            d.push(Math.random());
        }
        _this._randomTexture2 = new _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_15__["RawTexture"](new Float32Array(d), maxTextureSize, 1, _Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].TEXTUREFORMAT_RGBA, _this._scene, false, false, _Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE, _Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].TEXTURETYPE_FLOAT);
        _this._randomTexture2.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"].WRAP_ADDRESSMODE;
        _this._randomTexture2.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"].WRAP_ADDRESSMODE;
        _this._randomTextureSize = maxTextureSize;
        return _this;
    }
    Object.defineProperty(GPUParticleSystem, "IsSupported", {
        /**
         * Gets a boolean indicating if the GPU particles can be rendered on current browser
         */
        get: function () {
            if (!_Engines_engineStore__WEBPACK_IMPORTED_MODULE_17__["EngineStore"].LastCreatedEngine) {
                return false;
            }
            return _Engines_engineStore__WEBPACK_IMPORTED_MODULE_17__["EngineStore"].LastCreatedEngine.webGLVersion > 1;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the maximum number of particles active at the same time.
     * @returns The max number of active particles.
     */
    GPUParticleSystem.prototype.getCapacity = function () {
        return this._capacity;
    };
    Object.defineProperty(GPUParticleSystem.prototype, "activeParticleCount", {
        /**
         * Gets or set the number of active particles
         */
        get: function () {
            return this._activeCount;
        },
        set: function (value) {
            this._activeCount = Math.min(value, this._capacity);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Is this system ready to be used/rendered
     * @return true if the system is ready
     */
    GPUParticleSystem.prototype.isReady = function () {
        if (!this._updateEffect) {
            this._recreateUpdateEffect();
            this._recreateRenderEffect();
            return false;
        }
        if (!this.emitter || !this._updateEffect.isReady() || !this._imageProcessingConfiguration.isReady() || !this._renderEffect.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
            return false;
        }
        return true;
    };
    /**
     * Gets if the system has been started. (Note: this will still be true after stop is called)
     * @returns True if it has been started, otherwise false.
     */
    GPUParticleSystem.prototype.isStarted = function () {
        return this._started;
    };
    /**
     * Starts the particle system and begins to emit
     * @param delay defines the delay in milliseconds before starting the system (this.startDelay by default)
     */
    GPUParticleSystem.prototype.start = function (delay) {
        var _this = this;
        if (delay === void 0) { delay = this.startDelay; }
        if (!this.targetStopDuration && this._hasTargetStopDurationDependantGradient()) {
            throw "Particle system started with a targetStopDuration dependant gradient (eg. startSizeGradients) but no targetStopDuration set";
        }
        if (delay) {
            setTimeout(function () {
                _this.start(0);
            }, delay);
            return;
        }
        this._started = true;
        this._stopped = false;
        this._preWarmDone = false;
        // Animations
        if (this.beginAnimationOnStart && this.animations && this.animations.length > 0) {
            this.getScene().beginAnimation(this, this.beginAnimationFrom, this.beginAnimationTo, this.beginAnimationLoop);
        }
    };
    /**
     * Stops the particle system.
     */
    GPUParticleSystem.prototype.stop = function () {
        this._stopped = true;
    };
    /**
     * Remove all active particles
     */
    GPUParticleSystem.prototype.reset = function () {
        this._releaseBuffers();
        this._releaseVAOs();
        this._currentActiveCount = 0;
        this._targetIndex = 0;
    };
    /**
     * Returns the string "GPUParticleSystem"
     * @returns a string containing the class name
     */
    GPUParticleSystem.prototype.getClassName = function () {
        return "GPUParticleSystem";
    };
    GPUParticleSystem.prototype._removeGradientAndTexture = function (gradient, gradients, texture) {
        _super.prototype._removeGradientAndTexture.call(this, gradient, gradients, texture);
        this._releaseBuffers();
        return this;
    };
    /**
     * Adds a new color gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param color1 defines the color to affect to the specified gradient
     * @param color2 defines an additional color used to define a range ([color, color2]) with main color to pick the final color from
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addColorGradient = function (gradient, color1, color2) {
        if (!this._colorGradients) {
            this._colorGradients = [];
        }
        var colorGradient = new _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["ColorGradient"]();
        colorGradient.gradient = gradient;
        colorGradient.color1 = color1;
        this._colorGradients.push(colorGradient);
        this._colorGradients.sort(function (a, b) {
            if (a.gradient < b.gradient) {
                return -1;
            }
            else if (a.gradient > b.gradient) {
                return 1;
            }
            return 0;
        });
        if (this._colorGradientsTexture) {
            this._colorGradientsTexture.dispose();
            this._colorGradientsTexture = null;
        }
        this._releaseBuffers();
        return this;
    };
    /**
     * Remove a specific color gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeColorGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._colorGradients, this._colorGradientsTexture);
        this._colorGradientsTexture = null;
        return this;
    };
    GPUParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor) {
        var valueGradient = new _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["FactorGradient"]();
        valueGradient.gradient = gradient;
        valueGradient.factor1 = factor;
        factorGradients.push(valueGradient);
        factorGradients.sort(function (a, b) {
            if (a.gradient < b.gradient) {
                return -1;
            }
            else if (a.gradient > b.gradient) {
                return 1;
            }
            return 0;
        });
        this._releaseBuffers();
    };
    /**
     * Adds a new size gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the size factor to affect to the specified gradient
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addSizeGradient = function (gradient, factor) {
        if (!this._sizeGradients) {
            this._sizeGradients = [];
        }
        this._addFactorGradient(this._sizeGradients, gradient, factor);
        if (this._sizeGradientsTexture) {
            this._sizeGradientsTexture.dispose();
            this._sizeGradientsTexture = null;
        }
        this._releaseBuffers();
        return this;
    };
    /**
     * Remove a specific size gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeSizeGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._sizeGradients, this._sizeGradientsTexture);
        this._sizeGradientsTexture = null;
        return this;
    };
    /**
     * Adds a new angular speed gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the angular speed to affect to the specified gradient
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addAngularSpeedGradient = function (gradient, factor) {
        if (!this._angularSpeedGradients) {
            this._angularSpeedGradients = [];
        }
        this._addFactorGradient(this._angularSpeedGradients, gradient, factor);
        if (this._angularSpeedGradientsTexture) {
            this._angularSpeedGradientsTexture.dispose();
            this._angularSpeedGradientsTexture = null;
        }
        this._releaseBuffers();
        return this;
    };
    /**
     * Remove a specific angular speed gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeAngularSpeedGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._angularSpeedGradients, this._angularSpeedGradientsTexture);
        this._angularSpeedGradientsTexture = null;
        return this;
    };
    /**
     * Adds a new velocity gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the velocity to affect to the specified gradient
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addVelocityGradient = function (gradient, factor) {
        if (!this._velocityGradients) {
            this._velocityGradients = [];
        }
        this._addFactorGradient(this._velocityGradients, gradient, factor);
        if (this._velocityGradientsTexture) {
            this._velocityGradientsTexture.dispose();
            this._velocityGradientsTexture = null;
        }
        this._releaseBuffers();
        return this;
    };
    /**
     * Remove a specific velocity gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeVelocityGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._velocityGradients, this._velocityGradientsTexture);
        this._velocityGradientsTexture = null;
        return this;
    };
    /**
     * Adds a new limit velocity gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the limit velocity value to affect to the specified gradient
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addLimitVelocityGradient = function (gradient, factor) {
        if (!this._limitVelocityGradients) {
            this._limitVelocityGradients = [];
        }
        this._addFactorGradient(this._limitVelocityGradients, gradient, factor);
        if (this._limitVelocityGradientsTexture) {
            this._limitVelocityGradientsTexture.dispose();
            this._limitVelocityGradientsTexture = null;
        }
        this._releaseBuffers();
        return this;
    };
    /**
     * Remove a specific limit velocity gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeLimitVelocityGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._limitVelocityGradients, this._limitVelocityGradientsTexture);
        this._limitVelocityGradientsTexture = null;
        return this;
    };
    /**
     * Adds a new drag gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the drag value to affect to the specified gradient
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addDragGradient = function (gradient, factor) {
        if (!this._dragGradients) {
            this._dragGradients = [];
        }
        this._addFactorGradient(this._dragGradients, gradient, factor);
        if (this._dragGradientsTexture) {
            this._dragGradientsTexture.dispose();
            this._dragGradientsTexture = null;
        }
        this._releaseBuffers();
        return this;
    };
    /**
     * Remove a specific drag gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeDragGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._dragGradients, this._dragGradientsTexture);
        this._dragGradientsTexture = null;
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the emit rate value to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addEmitRateGradient = function (gradient, factor, factor2) {
        // Do nothing as emit rate is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeEmitRateGradient = function (gradient) {
        // Do nothing as emit rate is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the start size value to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
        // Do nothing as start size is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
        // Do nothing as start size is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param min defines the color remap minimal range
     * @param max defines the color remap maximal range
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addColorRemapGradient = function (gradient, min, max) {
        // Do nothing as start size is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeColorRemapGradient = function () {
        // Do nothing as start size is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param min defines the alpha remap minimal range
     * @param max defines the alpha remap maximal range
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addAlphaRemapGradient = function (gradient, min, max) {
        // Do nothing as start size is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeAlphaRemapGradient = function () {
        // Do nothing as start size is not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param color defines the color to affect to the specified gradient
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addRampGradient = function (gradient, color) {
        //Not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeRampGradient = function () {
        //Not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @returns the list of ramp gradients
     */
    GPUParticleSystem.prototype.getRampGradients = function () {
        return null;
    };
    Object.defineProperty(GPUParticleSystem.prototype, "useRampGradients", {
        /**
         * Not supported by GPUParticleSystem
         * Gets or sets a boolean indicating that ramp gradients must be used
         * @see http://doc.babylonjs.com/babylon101/particles#ramp-gradients
         */
        get: function () {
            //Not supported by GPUParticleSystem
            return false;
        },
        set: function (value) {
            //Not supported by GPUParticleSystem
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the life time factor to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.addLifeTimeGradient = function (gradient, factor, factor2) {
        //Not supported by GPUParticleSystem
        return this;
    };
    /**
     * Not supported by GPUParticleSystem
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    GPUParticleSystem.prototype.removeLifeTimeGradient = function (gradient) {
        //Not supported by GPUParticleSystem
        return this;
    };
    GPUParticleSystem.prototype._reset = function () {
        this._releaseBuffers();
    };
    GPUParticleSystem.prototype._createUpdateVAO = function (source) {
        var updateVertexBuffers = {};
        updateVertexBuffers["position"] = source.createVertexBuffer("position", 0, 3);
        updateVertexBuffers["age"] = source.createVertexBuffer("age", 3, 1);
        updateVertexBuffers["life"] = source.createVertexBuffer("life", 4, 1);
        updateVertexBuffers["seed"] = source.createVertexBuffer("seed", 5, 4);
        updateVertexBuffers["size"] = source.createVertexBuffer("size", 9, 3);
        var offset = 12;
        if (!this._colorGradientsTexture) {
            updateVertexBuffers["color"] = source.createVertexBuffer("color", offset, 4);
            offset += 4;
        }
        updateVertexBuffers["direction"] = source.createVertexBuffer("direction", offset, 3);
        offset += 3;
        if (!this._isBillboardBased) {
            updateVertexBuffers["initialDirection"] = source.createVertexBuffer("initialDirection", offset, 3);
            offset += 3;
        }
        if (this._angularSpeedGradientsTexture) {
            updateVertexBuffers["angle"] = source.createVertexBuffer("angle", offset, 1);
            offset += 1;
        }
        else {
            updateVertexBuffers["angle"] = source.createVertexBuffer("angle", offset, 2);
            offset += 2;
        }
        if (this._isAnimationSheetEnabled) {
            updateVertexBuffers["cellIndex"] = source.createVertexBuffer("cellIndex", offset, 1);
            offset += 1;
            if (this.spriteRandomStartCell) {
                updateVertexBuffers["cellStartOffset"] = source.createVertexBuffer("cellStartOffset", offset, 1);
                offset += 1;
            }
        }
        if (this.noiseTexture) {
            updateVertexBuffers["noiseCoordinates1"] = source.createVertexBuffer("noiseCoordinates1", offset, 3);
            offset += 3;
            updateVertexBuffers["noiseCoordinates2"] = source.createVertexBuffer("noiseCoordinates2", offset, 3);
            offset += 3;
        }
        var vao = this._engine.recordVertexArrayObject(updateVertexBuffers, null, this._updateEffect);
        this._engine.bindArrayBuffer(null);
        return vao;
    };
    GPUParticleSystem.prototype._createRenderVAO = function (source, spriteSource) {
        var renderVertexBuffers = {};
        renderVertexBuffers["position"] = source.createVertexBuffer("position", 0, 3, this._attributesStrideSize, true);
        renderVertexBuffers["age"] = source.createVertexBuffer("age", 3, 1, this._attributesStrideSize, true);
        renderVertexBuffers["life"] = source.createVertexBuffer("life", 4, 1, this._attributesStrideSize, true);
        renderVertexBuffers["size"] = source.createVertexBuffer("size", 9, 3, this._attributesStrideSize, true);
        var offset = 12;
        if (!this._colorGradientsTexture) {
            renderVertexBuffers["color"] = source.createVertexBuffer("color", offset, 4, this._attributesStrideSize, true);
            offset += 4;
        }
        if (this.billboardMode === _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BILLBOARDMODE_STRETCHED) {
            renderVertexBuffers["direction"] = source.createVertexBuffer("direction", offset, 3, this._attributesStrideSize, true);
        }
        offset += 3; // Direction
        if (!this._isBillboardBased) {
            renderVertexBuffers["initialDirection"] = source.createVertexBuffer("initialDirection", offset, 3, this._attributesStrideSize, true);
            offset += 3;
        }
        renderVertexBuffers["angle"] = source.createVertexBuffer("angle", offset, 1, this._attributesStrideSize, true);
        if (this._angularSpeedGradientsTexture) {
            offset++;
        }
        else {
            offset += 2;
        }
        if (this._isAnimationSheetEnabled) {
            renderVertexBuffers["cellIndex"] = source.createVertexBuffer("cellIndex", offset, 1, this._attributesStrideSize, true);
            offset += 1;
            if (this.spriteRandomStartCell) {
                renderVertexBuffers["cellStartOffset"] = source.createVertexBuffer("cellStartOffset", offset, 1, this._attributesStrideSize, true);
                offset += 1;
            }
        }
        if (this.noiseTexture) {
            renderVertexBuffers["noiseCoordinates1"] = source.createVertexBuffer("noiseCoordinates1", offset, 3, this._attributesStrideSize, true);
            offset += 3;
            renderVertexBuffers["noiseCoordinates2"] = source.createVertexBuffer("noiseCoordinates2", offset, 3, this._attributesStrideSize, true);
            offset += 3;
        }
        renderVertexBuffers["offset"] = spriteSource.createVertexBuffer("offset", 0, 2);
        renderVertexBuffers["uv"] = spriteSource.createVertexBuffer("uv", 2, 2);
        var vao = this._engine.recordVertexArrayObject(renderVertexBuffers, null, this._renderEffect);
        this._engine.bindArrayBuffer(null);
        return vao;
    };
    GPUParticleSystem.prototype._initialize = function (force) {
        if (force === void 0) { force = false; }
        if (this._buffer0 && !force) {
            return;
        }
        var engine = this._scene.getEngine();
        var data = new Array();
        this._attributesStrideSize = 21;
        this._targetIndex = 0;
        if (!this.isBillboardBased) {
            this._attributesStrideSize += 3;
        }
        if (this._colorGradientsTexture) {
            this._attributesStrideSize -= 4;
        }
        if (this._angularSpeedGradientsTexture) {
            this._attributesStrideSize -= 1;
        }
        if (this._isAnimationSheetEnabled) {
            this._attributesStrideSize += 1;
            if (this.spriteRandomStartCell) {
                this._attributesStrideSize += 1;
            }
        }
        if (this.noiseTexture) {
            this._attributesStrideSize += 6;
        }
        for (var particleIndex = 0; particleIndex < this._capacity; particleIndex++) {
            // position
            data.push(0.0);
            data.push(0.0);
            data.push(0.0);
            // Age and life
            data.push(0.0); // create the particle as a dead one to create a new one at start
            data.push(0.0);
            // Seed
            data.push(Math.random());
            data.push(Math.random());
            data.push(Math.random());
            data.push(Math.random());
            // Size
            data.push(0.0);
            data.push(0.0);
            data.push(0.0);
            if (!this._colorGradientsTexture) {
                // color
                data.push(0.0);
                data.push(0.0);
                data.push(0.0);
                data.push(0.0);
            }
            // direction
            data.push(0.0);
            data.push(0.0);
            data.push(0.0);
            if (!this.isBillboardBased) {
                // initialDirection
                data.push(0.0);
                data.push(0.0);
                data.push(0.0);
            }
            // angle
            data.push(0.0);
            if (!this._angularSpeedGradientsTexture) {
                data.push(0.0);
            }
            if (this._isAnimationSheetEnabled) {
                data.push(0.0);
                if (this.spriteRandomStartCell) {
                    data.push(0.0);
                }
            }
            if (this.noiseTexture) { // Random coordinates for reading into noise texture
                data.push(Math.random());
                data.push(Math.random());
                data.push(Math.random());
                data.push(Math.random());
                data.push(Math.random());
                data.push(Math.random());
            }
        }
        // Sprite data
        var spriteData = new Float32Array([0.5, 0.5, 1, 1,
            -0.5, 0.5, 0, 1,
            -0.5, -0.5, 0, 0,
            0.5, -0.5, 1, 0]);
        // Buffers
        this._buffer0 = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["Buffer"](engine, data, false, this._attributesStrideSize);
        this._buffer1 = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["Buffer"](engine, data, false, this._attributesStrideSize);
        this._spriteBuffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_6__["Buffer"](engine, spriteData, false, 4);
        // Update VAO
        this._updateVAO = [];
        this._updateVAO.push(this._createUpdateVAO(this._buffer0));
        this._updateVAO.push(this._createUpdateVAO(this._buffer1));
        // Render VAO
        this._renderVAO = [];
        this._renderVAO.push(this._createRenderVAO(this._buffer1, this._spriteBuffer));
        this._renderVAO.push(this._createRenderVAO(this._buffer0, this._spriteBuffer));
        // Links
        this._sourceBuffer = this._buffer0;
        this._targetBuffer = this._buffer1;
    };
    /** @hidden */
    GPUParticleSystem.prototype._recreateUpdateEffect = function () {
        var defines = this.particleEmitterType ? this.particleEmitterType.getEffectDefines() : "";
        if (this._isBillboardBased) {
            defines += "\n#define BILLBOARD";
        }
        if (this._colorGradientsTexture) {
            defines += "\n#define COLORGRADIENTS";
        }
        if (this._sizeGradientsTexture) {
            defines += "\n#define SIZEGRADIENTS";
        }
        if (this._angularSpeedGradientsTexture) {
            defines += "\n#define ANGULARSPEEDGRADIENTS";
        }
        if (this._velocityGradientsTexture) {
            defines += "\n#define VELOCITYGRADIENTS";
        }
        if (this._limitVelocityGradientsTexture) {
            defines += "\n#define LIMITVELOCITYGRADIENTS";
        }
        if (this._dragGradientsTexture) {
            defines += "\n#define DRAGGRADIENTS";
        }
        if (this.isAnimationSheetEnabled) {
            defines += "\n#define ANIMATESHEET";
            if (this.spriteRandomStartCell) {
                defines += "\n#define ANIMATESHEETRANDOMSTART";
            }
        }
        if (this.noiseTexture) {
            defines += "\n#define NOISE";
        }
        if (this._updateEffect && this._updateEffectOptions.defines === defines) {
            return;
        }
        this._updateEffectOptions.transformFeedbackVaryings = ["outPosition", "outAge", "outLife", "outSeed", "outSize"];
        if (!this._colorGradientsTexture) {
            this._updateEffectOptions.transformFeedbackVaryings.push("outColor");
        }
        this._updateEffectOptions.transformFeedbackVaryings.push("outDirection");
        if (!this._isBillboardBased) {
            this._updateEffectOptions.transformFeedbackVaryings.push("outInitialDirection");
        }
        this._updateEffectOptions.transformFeedbackVaryings.push("outAngle");
        if (this.isAnimationSheetEnabled) {
            this._updateEffectOptions.transformFeedbackVaryings.push("outCellIndex");
            if (this.spriteRandomStartCell) {
                this._updateEffectOptions.transformFeedbackVaryings.push("outCellStartOffset");
            }
        }
        if (this.noiseTexture) {
            this._updateEffectOptions.transformFeedbackVaryings.push("outNoiseCoordinates1");
            this._updateEffectOptions.transformFeedbackVaryings.push("outNoiseCoordinates2");
        }
        this._updateEffectOptions.defines = defines;
        this._updateEffect = new _Materials_effect__WEBPACK_IMPORTED_MODULE_10__["Effect"]("gpuUpdateParticles", this._updateEffectOptions, this._scene.getEngine());
    };
    /** @hidden */
    GPUParticleSystem.prototype._recreateRenderEffect = function () {
        var defines = "";
        if (this._scene.clipPlane) {
            defines = "\n#define CLIPPLANE";
        }
        if (this._scene.clipPlane2) {
            defines = "\n#define CLIPPLANE2";
        }
        if (this._scene.clipPlane3) {
            defines = "\n#define CLIPPLANE3";
        }
        if (this._scene.clipPlane4) {
            defines = "\n#define CLIPPLANE4";
        }
        if (this.blendMode === _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BLENDMODE_MULTIPLY) {
            defines = "\n#define BLENDMULTIPLYMODE";
        }
        if (this._isBillboardBased) {
            defines += "\n#define BILLBOARD";
            switch (this.billboardMode) {
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BILLBOARDMODE_Y:
                    defines += "\n#define BILLBOARDY";
                    break;
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BILLBOARDMODE_STRETCHED:
                    defines += "\n#define BILLBOARDSTRETCHED";
                    break;
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BILLBOARDMODE_ALL:
                default:
                    break;
            }
        }
        if (this._colorGradientsTexture) {
            defines += "\n#define COLORGRADIENTS";
        }
        if (this.isAnimationSheetEnabled) {
            defines += "\n#define ANIMATESHEET";
        }
        if (this._imageProcessingConfiguration) {
            this._imageProcessingConfiguration.prepareDefines(this._imageProcessingConfigurationDefines);
            defines += "\n" + this._imageProcessingConfigurationDefines.toString();
        }
        if (this._renderEffect && this._renderEffect.defines === defines) {
            return;
        }
        var uniforms = ["worldOffset", "view", "projection", "colorDead", "invView", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "sheetInfos", "translationPivot", "eyePosition"];
        var samplers = ["textureSampler", "colorGradientSampler"];
        if (_Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_13__["ImageProcessingConfiguration"]) {
            _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_13__["ImageProcessingConfiguration"].PrepareUniforms(uniforms, this._imageProcessingConfigurationDefines);
            _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_13__["ImageProcessingConfiguration"].PrepareSamplers(samplers, this._imageProcessingConfigurationDefines);
        }
        this._renderEffect = new _Materials_effect__WEBPACK_IMPORTED_MODULE_10__["Effect"]("gpuRenderParticles", ["position", "age", "life", "size", "color", "offset", "uv", "direction", "initialDirection", "angle", "cellIndex"], uniforms, samplers, this._scene.getEngine(), defines);
    };
    /**
     * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
     * @param preWarm defines if we are in the pre-warmimg phase
     */
    GPUParticleSystem.prototype.animate = function (preWarm) {
        if (preWarm === void 0) { preWarm = false; }
        this._timeDelta = this.updateSpeed * (preWarm ? this.preWarmStepOffset : this._scene.getAnimationRatio());
        this._actualFrame += this._timeDelta;
        if (!this._stopped) {
            if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration) {
                this.stop();
            }
        }
    };
    GPUParticleSystem.prototype._createFactorGradientTexture = function (factorGradients, textureName) {
        var texture = this[textureName];
        if (!factorGradients || !factorGradients.length || texture) {
            return;
        }
        var data = new Float32Array(this._rawTextureWidth);
        for (var x = 0; x < this._rawTextureWidth; x++) {
            var ratio = x / this._rawTextureWidth;
            _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, factorGradients, function (currentGradient, nextGradient, scale) {
                data[x] = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_5__["Scalar"].Lerp(currentGradient.factor1, nextGradient.factor1, scale);
            });
        }
        this[textureName] = _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_15__["RawTexture"].CreateRTexture(data, this._rawTextureWidth, 1, this._scene, false, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"].NEAREST_SAMPLINGMODE);
    };
    GPUParticleSystem.prototype._createSizeGradientTexture = function () {
        this._createFactorGradientTexture(this._sizeGradients, "_sizeGradientsTexture");
    };
    GPUParticleSystem.prototype._createAngularSpeedGradientTexture = function () {
        this._createFactorGradientTexture(this._angularSpeedGradients, "_angularSpeedGradientsTexture");
    };
    GPUParticleSystem.prototype._createVelocityGradientTexture = function () {
        this._createFactorGradientTexture(this._velocityGradients, "_velocityGradientsTexture");
    };
    GPUParticleSystem.prototype._createLimitVelocityGradientTexture = function () {
        this._createFactorGradientTexture(this._limitVelocityGradients, "_limitVelocityGradientsTexture");
    };
    GPUParticleSystem.prototype._createDragGradientTexture = function () {
        this._createFactorGradientTexture(this._dragGradients, "_dragGradientsTexture");
    };
    GPUParticleSystem.prototype._createColorGradientTexture = function () {
        if (!this._colorGradients || !this._colorGradients.length || this._colorGradientsTexture) {
            return;
        }
        var data = new Uint8Array(this._rawTextureWidth * 4);
        var tmpColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["TmpColors"].Color4[0];
        for (var x = 0; x < this._rawTextureWidth; x++) {
            var ratio = x / this._rawTextureWidth;
            _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, this._colorGradients, function (currentGradient, nextGradient, scale) {
                _Maths_math_color__WEBPACK_IMPORTED_MODULE_4__["Color4"].LerpToRef(currentGradient.color1, nextGradient.color1, scale, tmpColor);
                data[x * 4] = tmpColor.r * 255;
                data[x * 4 + 1] = tmpColor.g * 255;
                data[x * 4 + 2] = tmpColor.b * 255;
                data[x * 4 + 3] = tmpColor.a * 255;
            });
        }
        this._colorGradientsTexture = _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_15__["RawTexture"].CreateRGBATexture(data, this._rawTextureWidth, 1, this._scene, false, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"].NEAREST_SAMPLINGMODE);
    };
    /**
     * Renders the particle system in its current state
     * @param preWarm defines if the system should only update the particles but not render them
     * @returns the current number of particles
     */
    GPUParticleSystem.prototype.render = function (preWarm) {
        if (preWarm === void 0) { preWarm = false; }
        if (!this._started) {
            return 0;
        }
        this._createColorGradientTexture();
        this._createSizeGradientTexture();
        this._createAngularSpeedGradientTexture();
        this._createVelocityGradientTexture();
        this._createLimitVelocityGradientTexture();
        this._createDragGradientTexture();
        this._recreateUpdateEffect();
        this._recreateRenderEffect();
        if (!this.isReady()) {
            return 0;
        }
        if (!preWarm) {
            if (!this._preWarmDone && this.preWarmCycles) {
                for (var index = 0; index < this.preWarmCycles; index++) {
                    this.animate(true);
                    this.render(true);
                }
                this._preWarmDone = true;
            }
            if (this._currentRenderId === this._scene.getFrameId()) {
                return 0;
            }
            this._currentRenderId = this._scene.getFrameId();
        }
        // Get everything ready to render
        this._initialize();
        this._accumulatedCount += this.emitRate * this._timeDelta;
        if (this._accumulatedCount > 1) {
            var intPart = this._accumulatedCount | 0;
            this._accumulatedCount -= intPart;
            this._currentActiveCount = Math.min(this._activeCount, this._currentActiveCount + intPart);
        }
        if (!this._currentActiveCount) {
            return 0;
        }
        // Enable update effect
        this._engine.enableEffect(this._updateEffect);
        this._engine.setState(false);
        this._updateEffect.setFloat("currentCount", this._currentActiveCount);
        this._updateEffect.setFloat("timeDelta", this._timeDelta);
        this._updateEffect.setFloat("stopFactor", this._stopped ? 0 : 1);
        this._updateEffect.setTexture("randomSampler", this._randomTexture);
        this._updateEffect.setTexture("randomSampler2", this._randomTexture2);
        this._updateEffect.setFloat2("lifeTime", this.minLifeTime, this.maxLifeTime);
        this._updateEffect.setFloat2("emitPower", this.minEmitPower, this.maxEmitPower);
        if (!this._colorGradientsTexture) {
            this._updateEffect.setDirectColor4("color1", this.color1);
            this._updateEffect.setDirectColor4("color2", this.color2);
        }
        this._updateEffect.setFloat2("sizeRange", this.minSize, this.maxSize);
        this._updateEffect.setFloat4("scaleRange", this.minScaleX, this.maxScaleX, this.minScaleY, this.maxScaleY);
        this._updateEffect.setFloat4("angleRange", this.minAngularSpeed, this.maxAngularSpeed, this.minInitialRotation, this.maxInitialRotation);
        this._updateEffect.setVector3("gravity", this.gravity);
        if (this._sizeGradientsTexture) {
            this._updateEffect.setTexture("sizeGradientSampler", this._sizeGradientsTexture);
        }
        if (this._angularSpeedGradientsTexture) {
            this._updateEffect.setTexture("angularSpeedGradientSampler", this._angularSpeedGradientsTexture);
        }
        if (this._velocityGradientsTexture) {
            this._updateEffect.setTexture("velocityGradientSampler", this._velocityGradientsTexture);
        }
        if (this._limitVelocityGradientsTexture) {
            this._updateEffect.setTexture("limitVelocityGradientSampler", this._limitVelocityGradientsTexture);
            this._updateEffect.setFloat("limitVelocityDamping", this.limitVelocityDamping);
        }
        if (this._dragGradientsTexture) {
            this._updateEffect.setTexture("dragGradientSampler", this._dragGradientsTexture);
        }
        if (this.particleEmitterType) {
            this.particleEmitterType.applyToShader(this._updateEffect);
        }
        if (this._isAnimationSheetEnabled) {
            this._updateEffect.setFloat3("cellInfos", this.startSpriteCellID, this.endSpriteCellID, this.spriteCellChangeSpeed);
        }
        if (this.noiseTexture) {
            this._updateEffect.setTexture("noiseSampler", this.noiseTexture);
            this._updateEffect.setVector3("noiseStrength", this.noiseStrength);
        }
        var emitterWM;
        if (this.emitter.position) {
            var emitterMesh = this.emitter;
            emitterWM = emitterMesh.getWorldMatrix();
        }
        else {
            var emitterPosition = this.emitter;
            emitterWM = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
        }
        this._updateEffect.setMatrix("emitterWM", emitterWM);
        // Bind source VAO
        this._engine.bindVertexArrayObject(this._updateVAO[this._targetIndex], null);
        // Update
        this._engine.bindTransformFeedbackBuffer(this._targetBuffer.getBuffer());
        this._engine.setRasterizerState(false);
        this._engine.beginTransformFeedback(true);
        this._engine.drawArraysType(_Materials_material__WEBPACK_IMPORTED_MODULE_11__["Material"].PointListDrawMode, 0, this._currentActiveCount);
        this._engine.endTransformFeedback();
        this._engine.setRasterizerState(true);
        this._engine.bindTransformFeedbackBuffer(null);
        if (!preWarm) {
            // Enable render effect
            this._engine.enableEffect(this._renderEffect);
            var viewMatrix = this._scene.getViewMatrix();
            this._renderEffect.setMatrix("view", viewMatrix);
            this._renderEffect.setMatrix("projection", this._scene.getProjectionMatrix());
            this._renderEffect.setTexture("textureSampler", this.particleTexture);
            this._renderEffect.setVector2("translationPivot", this.translationPivot);
            this._renderEffect.setVector3("worldOffset", this.worldOffset);
            if (this._colorGradientsTexture) {
                this._renderEffect.setTexture("colorGradientSampler", this._colorGradientsTexture);
            }
            else {
                this._renderEffect.setDirectColor4("colorDead", this.colorDead);
            }
            if (this._isAnimationSheetEnabled && this.particleTexture) {
                var baseSize = this.particleTexture.getBaseSize();
                this._renderEffect.setFloat3("sheetInfos", this.spriteCellWidth / baseSize.width, this.spriteCellHeight / baseSize.height, baseSize.width / this.spriteCellWidth);
            }
            if (this._isBillboardBased) {
                var camera = this._scene.activeCamera;
                this._renderEffect.setVector3("eyePosition", camera.globalPosition);
            }
            if (this._scene.clipPlane || this._scene.clipPlane2 || this._scene.clipPlane3 || this._scene.clipPlane4) {
                var invView = viewMatrix.clone();
                invView.invert();
                this._renderEffect.setMatrix("invView", invView);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_12__["MaterialHelper"].BindClipPlane(this._renderEffect, this._scene);
            }
            // image processing
            if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {
                this._imageProcessingConfiguration.bind(this._renderEffect);
            }
            // Draw order
            switch (this.blendMode) {
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BLENDMODE_ADD:
                    this._engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].ALPHA_ADD);
                    break;
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BLENDMODE_ONEONE:
                    this._engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].ALPHA_ONEONE);
                    break;
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BLENDMODE_STANDARD:
                    this._engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].ALPHA_COMBINE);
                    break;
                case _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"].BLENDMODE_MULTIPLY:
                    this._engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].ALPHA_MULTIPLY);
                    break;
            }
            if (this.forceDepthWrite) {
                this._engine.setDepthWrite(true);
            }
            // Bind source VAO
            this._engine.bindVertexArrayObject(this._renderVAO[this._targetIndex], null);
            // Render
            this._engine.drawArraysType(_Materials_material__WEBPACK_IMPORTED_MODULE_11__["Material"].TriangleFanDrawMode, 0, 4, this._currentActiveCount);
            this._engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_16__["Constants"].ALPHA_DISABLE);
        }
        // Switch VAOs
        this._targetIndex++;
        if (this._targetIndex === 2) {
            this._targetIndex = 0;
        }
        // Switch buffers
        var tmpBuffer = this._sourceBuffer;
        this._sourceBuffer = this._targetBuffer;
        this._targetBuffer = tmpBuffer;
        return this._currentActiveCount;
    };
    /**
     * Rebuilds the particle system
     */
    GPUParticleSystem.prototype.rebuild = function () {
        this._initialize(true);
    };
    GPUParticleSystem.prototype._releaseBuffers = function () {
        if (this._buffer0) {
            this._buffer0.dispose();
            this._buffer0 = null;
        }
        if (this._buffer1) {
            this._buffer1.dispose();
            this._buffer1 = null;
        }
        if (this._spriteBuffer) {
            this._spriteBuffer.dispose();
            this._spriteBuffer = null;
        }
    };
    GPUParticleSystem.prototype._releaseVAOs = function () {
        if (!this._updateVAO) {
            return;
        }
        for (var index = 0; index < this._updateVAO.length; index++) {
            this._engine.releaseVertexArrayObject(this._updateVAO[index]);
        }
        this._updateVAO = [];
        for (var index = 0; index < this._renderVAO.length; index++) {
            this._engine.releaseVertexArrayObject(this._renderVAO[index]);
        }
        this._renderVAO = [];
    };
    /**
     * Disposes the particle system and free the associated resources
     * @param disposeTexture defines if the particule texture must be disposed as well (true by default)
     */
    GPUParticleSystem.prototype.dispose = function (disposeTexture) {
        if (disposeTexture === void 0) { disposeTexture = true; }
        var index = this._scene.particleSystems.indexOf(this);
        if (index > -1) {
            this._scene.particleSystems.splice(index, 1);
        }
        this._releaseBuffers();
        this._releaseVAOs();
        if (this._colorGradientsTexture) {
            this._colorGradientsTexture.dispose();
            this._colorGradientsTexture = null;
        }
        if (this._sizeGradientsTexture) {
            this._sizeGradientsTexture.dispose();
            this._sizeGradientsTexture = null;
        }
        if (this._angularSpeedGradientsTexture) {
            this._angularSpeedGradientsTexture.dispose();
            this._angularSpeedGradientsTexture = null;
        }
        if (this._velocityGradientsTexture) {
            this._velocityGradientsTexture.dispose();
            this._velocityGradientsTexture = null;
        }
        if (this._limitVelocityGradientsTexture) {
            this._limitVelocityGradientsTexture.dispose();
            this._limitVelocityGradientsTexture = null;
        }
        if (this._dragGradientsTexture) {
            this._dragGradientsTexture.dispose();
            this._dragGradientsTexture = null;
        }
        if (this._randomTexture) {
            this._randomTexture.dispose();
            this._randomTexture = null;
        }
        if (this._randomTexture2) {
            this._randomTexture2.dispose();
            this._randomTexture2 = null;
        }
        if (disposeTexture && this.particleTexture) {
            this.particleTexture.dispose();
            this.particleTexture = null;
        }
        if (disposeTexture && this.noiseTexture) {
            this.noiseTexture.dispose();
            this.noiseTexture = null;
        }
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
    };
    /**
     * Clones the particle system.
     * @param name The name of the cloned object
     * @param newEmitter The new emitter to use
     * @returns the cloned particle system
     */
    GPUParticleSystem.prototype.clone = function (name, newEmitter) {
        var result = new GPUParticleSystem(name, { capacity: this._capacity, randomTextureSize: this._randomTextureSize }, this._scene);
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_18__["DeepCopier"].DeepCopy(this, result, ["particles", "customShader", "noiseTexture", "particleTexture", "onDisposeObservable"]);
        if (newEmitter === undefined) {
            newEmitter = this.emitter;
        }
        result.emitter = newEmitter;
        if (this.particleTexture) {
            result.particleTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"](this.particleTexture.url, this._scene);
        }
        result.noiseTexture = this.noiseTexture;
        result.emitter = newEmitter;
        if (this.particleTexture) {
            result.particleTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_14__["Texture"](this.particleTexture.url, this._scene);
        }
        // Clone gradients
        if (this._colorGradients) {
            this._colorGradients.forEach(function (v) {
                result.addColorGradient(v.gradient, v.color1, v.color2);
            });
        }
        if (this._dragGradients) {
            this._dragGradients.forEach(function (v) {
                result.addDragGradient(v.gradient, v.factor1);
            });
        }
        if (this._angularSpeedGradients) {
            this._angularSpeedGradients.forEach(function (v) {
                result.addAngularSpeedGradient(v.gradient, v.factor1);
            });
        }
        if (this._emitRateGradients) {
            this._emitRateGradients.forEach(function (v) {
                result.addEmitRateGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._lifeTimeGradients) {
            this._lifeTimeGradients.forEach(function (v) {
                result.addLifeTimeGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._limitVelocityGradients) {
            this._limitVelocityGradients.forEach(function (v) {
                result.addLimitVelocityGradient(v.gradient, v.factor1);
            });
        }
        if (this._sizeGradients) {
            this._sizeGradients.forEach(function (v) {
                result.addSizeGradient(v.gradient, v.factor1);
            });
        }
        if (this._startSizeGradients) {
            this._startSizeGradients.forEach(function (v) {
                result.addStartSizeGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._velocityGradients) {
            this._velocityGradients.forEach(function (v) {
                result.addVelocityGradient(v.gradient, v.factor1);
            });
        }
        if (this._rampGradients) {
            this._rampGradients.forEach(function (v) {
                result.addRampGradient(v.gradient, v.color);
            });
        }
        if (this._colorRemapGradients) {
            this._colorRemapGradients.forEach(function (v) {
                result.addColorRemapGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._alphaRemapGradients) {
            this._alphaRemapGradients.forEach(function (v) {
                result.addAlphaRemapGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        return result;
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    GPUParticleSystem.prototype.serialize = function () {
        var serializationObject = {};
        _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"]._Serialize(serializationObject, this);
        serializationObject.activeParticleCount = this.activeParticleCount;
        return serializationObject;
    };
    /**
     * Parses a JSON object to create a GPU particle system.
     * @param parsedParticleSystem The JSON object to parse
     * @param scene The scene to create the particle system in
     * @param rootUrl The root url to use to load external dependencies like texture
     * @param doNotStart Ignore the preventAutoStart attribute and does not start
     * @returns the parsed GPU particle system
     */
    GPUParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl, doNotStart) {
        if (doNotStart === void 0) { doNotStart = false; }
        var name = parsedParticleSystem.name;
        var particleSystem = new GPUParticleSystem(name, { capacity: parsedParticleSystem.capacity, randomTextureSize: parsedParticleSystem.randomTextureSize }, scene);
        if (parsedParticleSystem.activeParticleCount) {
            particleSystem.activeParticleCount = parsedParticleSystem.activeParticleCount;
        }
        _particleSystem__WEBPACK_IMPORTED_MODULE_8__["ParticleSystem"]._Parse(parsedParticleSystem, particleSystem, scene, rootUrl);
        // Auto start
        if (parsedParticleSystem.preventAutoStart) {
            particleSystem.preventAutoStart = parsedParticleSystem.preventAutoStart;
        }
        if (!doNotStart && !particleSystem.preventAutoStart) {
            particleSystem.start();
        }
        return particleSystem;
    };
    return GPUParticleSystem;
}(_baseParticleSystem__WEBPACK_IMPORTED_MODULE_7__["BaseParticleSystem"]));



/***/ }),

/***/ "./Particles/index.ts":
/*!****************************!*\
  !*** ./Particles/index.ts ***!
  \****************************/
/*! exports provided: BaseParticleSystem, GPUParticleSystem, Particle, ParticleHelper, ParticleSystem, _IDoNeedToBeInTheBuild, ParticleSystemSet, SolidParticle, ModelShape, DepthSortedParticle, SolidParticleSystem, SubEmitterType, SubEmitter, BoxParticleEmitter, ConeParticleEmitter, CylinderParticleEmitter, CylinderDirectedParticleEmitter, HemisphericParticleEmitter, PointParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _baseParticleSystem__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./baseParticleSystem */ "./Particles/baseParticleSystem.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseParticleSystem", function() { return _baseParticleSystem__WEBPACK_IMPORTED_MODULE_0__["BaseParticleSystem"]; });

/* harmony import */ var _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./EmitterTypes/index */ "./Particles/EmitterTypes/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["BoxParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConeParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["ConeParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["CylinderParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderDirectedParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["CylinderDirectedParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["HemisphericParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["PointParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["SphereParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereDirectedParticleEmitter", function() { return _EmitterTypes_index__WEBPACK_IMPORTED_MODULE_1__["SphereDirectedParticleEmitter"]; });

/* harmony import */ var _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gpuParticleSystem */ "./Particles/gpuParticleSystem.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GPUParticleSystem", function() { return _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_2__["GPUParticleSystem"]; });

/* harmony import */ var _particle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./particle */ "./Particles/particle.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Particle", function() { return _particle__WEBPACK_IMPORTED_MODULE_3__["Particle"]; });

/* harmony import */ var _particleHelper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./particleHelper */ "./Particles/particleHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleHelper", function() { return _particleHelper__WEBPACK_IMPORTED_MODULE_4__["ParticleHelper"]; });

/* harmony import */ var _particleSystem__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./particleSystem */ "./Particles/particleSystem.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleSystem", function() { return _particleSystem__WEBPACK_IMPORTED_MODULE_5__["ParticleSystem"]; });

/* harmony import */ var _particleSystemComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./particleSystemComponent */ "./Particles/particleSystemComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_IDoNeedToBeInTheBuild", function() { return _particleSystemComponent__WEBPACK_IMPORTED_MODULE_6__["_IDoNeedToBeInTheBuild"]; });

/* harmony import */ var _particleSystemSet__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./particleSystemSet */ "./Particles/particleSystemSet.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleSystemSet", function() { return _particleSystemSet__WEBPACK_IMPORTED_MODULE_7__["ParticleSystemSet"]; });

/* harmony import */ var _solidParticle__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./solidParticle */ "./Particles/solidParticle.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SolidParticle", function() { return _solidParticle__WEBPACK_IMPORTED_MODULE_8__["SolidParticle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModelShape", function() { return _solidParticle__WEBPACK_IMPORTED_MODULE_8__["ModelShape"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthSortedParticle", function() { return _solidParticle__WEBPACK_IMPORTED_MODULE_8__["DepthSortedParticle"]; });

/* harmony import */ var _solidParticleSystem__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./solidParticleSystem */ "./Particles/solidParticleSystem.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SolidParticleSystem", function() { return _solidParticleSystem__WEBPACK_IMPORTED_MODULE_9__["SolidParticleSystem"]; });

/* harmony import */ var _subEmitter__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./subEmitter */ "./Particles/subEmitter.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubEmitterType", function() { return _subEmitter__WEBPACK_IMPORTED_MODULE_10__["SubEmitterType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubEmitter", function() { return _subEmitter__WEBPACK_IMPORTED_MODULE_10__["SubEmitter"]; });














/***/ }),

/***/ "./Particles/particle.ts":
/*!*******************************!*\
  !*** ./Particles/particle.ts ***!
  \*******************************/
/*! exports provided: Particle */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Particle", function() { return Particle; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");



/**
 * A particle represents one of the element emitted by a particle system.
 * This is mainly define by its coordinates, direction, velocity and age.
 */
var Particle = /** @class */ (function () {
    /**
     * Creates a new instance Particle
     * @param particleSystem the particle system the particle belongs to
     */
    function Particle(
    /**
     * The particle system the particle belongs to.
     */
    particleSystem) {
        this.particleSystem = particleSystem;
        /**
         * The world position of the particle in the scene.
         */
        this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The world direction of the particle in the scene.
         */
        this.direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The color of the particle.
         */
        this.color = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](0, 0, 0, 0);
        /**
         * The color change of the particle per step.
         */
        this.colorStep = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](0, 0, 0, 0);
        /**
         * Defines how long will the life of the particle be.
         */
        this.lifeTime = 1.0;
        /**
         * The current age of the particle.
         */
        this.age = 0;
        /**
         * The current size of the particle.
         */
        this.size = 0;
        /**
         * The current scale of the particle.
         */
        this.scale = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector2"](1, 1);
        /**
         * The current angle of the particle.
         */
        this.angle = 0;
        /**
         * Defines how fast is the angle changing.
         */
        this.angularSpeed = 0;
        /**
         * Defines the cell index used by the particle to be rendered from a sprite.
         */
        this.cellIndex = 0;
        /** @hidden */
        this._attachedSubEmitters = null;
        /** @hidden */
        this._currentColor1 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](0, 0, 0, 0);
        /** @hidden */
        this._currentColor2 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](0, 0, 0, 0);
        /** @hidden */
        this._currentSize1 = 0;
        /** @hidden */
        this._currentSize2 = 0;
        /** @hidden */
        this._currentAngularSpeed1 = 0;
        /** @hidden */
        this._currentAngularSpeed2 = 0;
        /** @hidden */
        this._currentVelocity1 = 0;
        /** @hidden */
        this._currentVelocity2 = 0;
        /** @hidden */
        this._currentLimitVelocity1 = 0;
        /** @hidden */
        this._currentLimitVelocity2 = 0;
        /** @hidden */
        this._currentDrag1 = 0;
        /** @hidden */
        this._currentDrag2 = 0;
        this.id = Particle._Count++;
        if (!this.particleSystem.isAnimationSheetEnabled) {
            return;
        }
        this.updateCellInfoFromSystem();
    }
    Particle.prototype.updateCellInfoFromSystem = function () {
        this.cellIndex = this.particleSystem.startSpriteCellID;
    };
    /**
     * Defines how the sprite cell index is updated for the particle
     */
    Particle.prototype.updateCellIndex = function () {
        var offsetAge = this.age;
        var changeSpeed = this.particleSystem.spriteCellChangeSpeed;
        if (this.particleSystem.spriteRandomStartCell) {
            if (this._randomCellOffset === undefined) {
                this._randomCellOffset = Math.random() * this.lifeTime;
            }
            if (changeSpeed === 0) { // Special case when speed = 0 meaning we want to stay on initial cell
                changeSpeed = 1;
                offsetAge = this._randomCellOffset;
            }
            else {
                offsetAge += this._randomCellOffset;
            }
        }
        var dist = (this._initialEndSpriteCellID - this._initialStartSpriteCellID);
        var ratio = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].Clamp(((offsetAge * changeSpeed) % this.lifeTime) / this.lifeTime);
        this.cellIndex = this._initialStartSpriteCellID + (ratio * dist) | 0;
    };
    /** @hidden */
    Particle.prototype._inheritParticleInfoToSubEmitter = function (subEmitter) {
        if (subEmitter.particleSystem.emitter.position) {
            var emitterMesh = subEmitter.particleSystem.emitter;
            emitterMesh.position.copyFrom(this.position);
            if (subEmitter.inheritDirection) {
                emitterMesh.position.subtractToRef(this.direction, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0]);
                // Look at using Y as forward
                emitterMesh.lookAt(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0], 0, Math.PI / 2);
            }
        }
        else {
            var emitterPosition = subEmitter.particleSystem.emitter;
            emitterPosition.copyFrom(this.position);
        }
        // Set inheritedVelocityOffset to be used when new particles are created
        this.direction.scaleToRef(subEmitter.inheritedVelocityAmount / 2, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0]);
        subEmitter.particleSystem._inheritedVelocityOffset.copyFrom(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0]);
    };
    /** @hidden */
    Particle.prototype._inheritParticleInfoToSubEmitters = function () {
        var _this = this;
        if (this._attachedSubEmitters && this._attachedSubEmitters.length > 0) {
            this._attachedSubEmitters.forEach(function (subEmitter) {
                _this._inheritParticleInfoToSubEmitter(subEmitter);
            });
        }
    };
    /** @hidden */
    Particle.prototype._reset = function () {
        this.age = 0;
        this._currentColorGradient = null;
        this._currentSizeGradient = null;
        this._currentAngularSpeedGradient = null;
        this._currentVelocityGradient = null;
        this._currentLimitVelocityGradient = null;
        this._currentDragGradient = null;
        this.cellIndex = this.particleSystem.startSpriteCellID;
        this._randomCellOffset = undefined;
    };
    /**
     * Copy the properties of particle to another one.
     * @param other the particle to copy the information to.
     */
    Particle.prototype.copyTo = function (other) {
        other.position.copyFrom(this.position);
        if (this._initialDirection) {
            if (other._initialDirection) {
                other._initialDirection.copyFrom(this._initialDirection);
            }
            else {
                other._initialDirection = this._initialDirection.clone();
            }
        }
        else {
            other._initialDirection = null;
        }
        other.direction.copyFrom(this.direction);
        other.color.copyFrom(this.color);
        other.colorStep.copyFrom(this.colorStep);
        other.lifeTime = this.lifeTime;
        other.age = this.age;
        other._randomCellOffset = this._randomCellOffset;
        other.size = this.size;
        other.scale.copyFrom(this.scale);
        other.angle = this.angle;
        other.angularSpeed = this.angularSpeed;
        other.particleSystem = this.particleSystem;
        other.cellIndex = this.cellIndex;
        other.id = this.id;
        other._attachedSubEmitters = this._attachedSubEmitters;
        if (this._currentColorGradient) {
            other._currentColorGradient = this._currentColorGradient;
            other._currentColor1.copyFrom(this._currentColor1);
            other._currentColor2.copyFrom(this._currentColor2);
        }
        if (this._currentSizeGradient) {
            other._currentSizeGradient = this._currentSizeGradient;
            other._currentSize1 = this._currentSize1;
            other._currentSize2 = this._currentSize2;
        }
        if (this._currentAngularSpeedGradient) {
            other._currentAngularSpeedGradient = this._currentAngularSpeedGradient;
            other._currentAngularSpeed1 = this._currentAngularSpeed1;
            other._currentAngularSpeed2 = this._currentAngularSpeed2;
        }
        if (this._currentVelocityGradient) {
            other._currentVelocityGradient = this._currentVelocityGradient;
            other._currentVelocity1 = this._currentVelocity1;
            other._currentVelocity2 = this._currentVelocity2;
        }
        if (this._currentLimitVelocityGradient) {
            other._currentLimitVelocityGradient = this._currentLimitVelocityGradient;
            other._currentLimitVelocity1 = this._currentLimitVelocity1;
            other._currentLimitVelocity2 = this._currentLimitVelocity2;
        }
        if (this._currentDragGradient) {
            other._currentDragGradient = this._currentDragGradient;
            other._currentDrag1 = this._currentDrag1;
            other._currentDrag2 = this._currentDrag2;
        }
        if (this.particleSystem.isAnimationSheetEnabled) {
            other._initialStartSpriteCellID = this._initialStartSpriteCellID;
            other._initialEndSpriteCellID = this._initialEndSpriteCellID;
        }
        if (this.particleSystem.useRampGradients) {
            other.remapData.copyFrom(this.remapData);
        }
        if (this._randomNoiseCoordinates1) {
            if (other._randomNoiseCoordinates1) {
                other._randomNoiseCoordinates1.copyFrom(this._randomNoiseCoordinates1);
                other._randomNoiseCoordinates2.copyFrom(this._randomNoiseCoordinates2);
            }
            else {
                other._randomNoiseCoordinates1 = this._randomNoiseCoordinates1.clone();
                other._randomNoiseCoordinates2 = this._randomNoiseCoordinates2.clone();
            }
        }
    };
    Particle._Count = 0;
    return Particle;
}());



/***/ }),

/***/ "./Particles/particleHelper.ts":
/*!*************************************!*\
  !*** ./Particles/particleHelper.ts ***!
  \*************************************/
/*! exports provided: ParticleHelper */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticleHelper", function() { return ParticleHelper; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./gpuParticleSystem */ "./Particles/gpuParticleSystem.ts");
/* harmony import */ var _particleSystemSet__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./particleSystemSet */ "./Particles/particleSystemSet.ts");
/* harmony import */ var _particleSystem__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./particleSystem */ "./Particles/particleSystem.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");








/**
 * This class is made for on one-liner static method to help creating particle system set.
 */
var ParticleHelper = /** @class */ (function () {
    function ParticleHelper() {
    }
    /**
     * Create a default particle system that you can tweak
     * @param emitter defines the emitter to use
     * @param capacity defines the system capacity (default is 500 particles)
     * @param scene defines the hosting scene
     * @param useGPU defines if a GPUParticleSystem must be created (default is false)
     * @returns the new Particle system
     */
    ParticleHelper.CreateDefault = function (emitter, capacity, scene, useGPU) {
        if (capacity === void 0) { capacity = 500; }
        if (useGPU === void 0) { useGPU = false; }
        var system;
        if (useGPU) {
            system = new _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_4__["GPUParticleSystem"]("default system", { capacity: capacity }, scene);
        }
        else {
            system = new _particleSystem__WEBPACK_IMPORTED_MODULE_6__["ParticleSystem"]("default system", capacity, scene);
        }
        system.emitter = emitter;
        system.particleTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"]("https://www.babylonjs.com/assets/Flare.png", system.getScene());
        system.createConeEmitter(0.1, Math.PI / 4);
        // Particle color
        system.color1 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1.0, 1.0, 1.0, 1.0);
        system.color2 = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1.0, 1.0, 1.0, 1.0);
        system.colorDead = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1.0, 1.0, 1.0, 0.0);
        // Particle Size
        system.minSize = 0.1;
        system.maxSize = 0.1;
        // Emission speed
        system.minEmitPower = 2;
        system.maxEmitPower = 2;
        // Update speed
        system.updateSpeed = 1 / 60;
        system.emitRate = 30;
        return system;
    };
    /**
     * This is the main static method (one-liner) of this helper to create different particle systems
     * @param type This string represents the type to the particle system to create
     * @param scene The scene where the particle system should live
     * @param gpu If the system will use gpu
     * @returns the ParticleSystemSet created
     */
    ParticleHelper.CreateAsync = function (type, scene, gpu) {
        if (gpu === void 0) { gpu = false; }
        if (!scene) {
            scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__["EngineStore"].LastCreatedScene;
        }
        var token = {};
        scene._addPendingData(token);
        return new Promise(function (resolve, reject) {
            if (gpu && !_gpuParticleSystem__WEBPACK_IMPORTED_MODULE_4__["GPUParticleSystem"].IsSupported) {
                scene._removePendingData(token);
                return reject("Particle system with GPU is not supported.");
            }
            _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].LoadFile(ParticleHelper.BaseAssetsUrl + "/systems/" + type + ".json", function (data) {
                scene._removePendingData(token);
                var newData = JSON.parse(data.toString());
                return resolve(_particleSystemSet__WEBPACK_IMPORTED_MODULE_5__["ParticleSystemSet"].Parse(newData, scene, gpu));
            }, undefined, undefined, undefined, function () {
                scene._removePendingData(token);
                return reject("An error occured while the creation of your particle system. Check if your type '" + type + "' exists.");
            });
        });
    };
    /**
     * Static function used to export a particle system to a ParticleSystemSet variable.
     * Please note that the emitter shape is not exported
     * @param systems defines the particle systems to export
     * @returns the created particle system set
     */
    ParticleHelper.ExportSet = function (systems) {
        var set = new _particleSystemSet__WEBPACK_IMPORTED_MODULE_5__["ParticleSystemSet"]();
        for (var _i = 0, systems_1 = systems; _i < systems_1.length; _i++) {
            var system = systems_1[_i];
            set.systems.push(system);
        }
        return set;
    };
    /**
     * Gets or sets base Assets URL
     */
    ParticleHelper.BaseAssetsUrl = _Engines_constants__WEBPACK_IMPORTED_MODULE_7__["Constants"].PARTICLES_BaseAssetsUrl;
    return ParticleHelper;
}());



/***/ }),

/***/ "./Particles/particleSystem.ts":
/*!*************************************!*\
  !*** ./Particles/particleSystem.ts ***!
  \*************************************/
/*! exports provided: ParticleSystem */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticleSystem", function() { return ParticleSystem; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/gradients */ "./Misc/gradients.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Materials/Textures/rawTexture */ "./Materials/Textures/rawTexture.ts");
/* harmony import */ var _Materials_Textures_Procedurals_proceduralTexture__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Materials/Textures/Procedurals/proceduralTexture */ "./Materials/Textures/Procedurals/proceduralTexture.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Particles/EmitterTypes/index */ "./Particles/EmitterTypes/index.ts");
/* harmony import */ var _baseParticleSystem__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./baseParticleSystem */ "./Particles/baseParticleSystem.ts");
/* harmony import */ var _particle__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./particle */ "./Particles/particle.ts");
/* harmony import */ var _subEmitter__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./subEmitter */ "./Particles/subEmitter.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../Misc/deepCopier */ "./Misc/deepCopier.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Shaders_particles_fragment__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ../Shaders/particles.fragment */ "./Shaders/particles.fragment.ts");
/* harmony import */ var _Shaders_particles_vertex__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ../Shaders/particles.vertex */ "./Shaders/particles.vertex.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");


























/**
 * This represents a particle system in Babylon.
 * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
 * Particles can take different shapes while emitted like box, sphere, cone or you can write your custom function.
 * @example https://doc.babylonjs.com/babylon101/particles
 */
var ParticleSystem = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ParticleSystem, _super);
    /**
     * Instantiates a particle system.
     * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
     * @param name The name of the particle system
     * @param capacity The max number of particles alive at the same time
     * @param scene The scene the particle system belongs to
     * @param customEffect a custom effect used to change the way particles are rendered by default
     * @param isAnimationSheetEnabled Must be true if using a spritesheet to animate the particles texture
     * @param epsilon Offset used to render the particles
     */
    function ParticleSystem(name, capacity, scene, customEffect, isAnimationSheetEnabled, epsilon) {
        if (customEffect === void 0) { customEffect = null; }
        if (isAnimationSheetEnabled === void 0) { isAnimationSheetEnabled = false; }
        if (epsilon === void 0) { epsilon = 0.01; }
        var _this = _super.call(this, name) || this;
        /**
         * @hidden
         */
        _this._inheritedVelocityOffset = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"]();
        /**
        * An event triggered when the system is disposed
        */
        _this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]();
        _this._particles = new Array();
        _this._stockParticles = new Array();
        _this._newPartsExcess = 0;
        _this._vertexBuffers = {};
        _this._scaledColorStep = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"](0, 0, 0, 0);
        _this._colorDiff = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"](0, 0, 0, 0);
        _this._scaledDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._scaledGravity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        _this._currentRenderId = -1;
        _this._useInstancing = false;
        _this._started = false;
        _this._stopped = false;
        _this._actualFrame = 0;
        /** @hidden */
        _this._currentEmitRate1 = 0;
        /** @hidden */
        _this._currentEmitRate2 = 0;
        /** @hidden */
        _this._currentStartSize1 = 0;
        /** @hidden */
        _this._currentStartSize2 = 0;
        _this._rawTextureWidth = 256;
        _this._useRampGradients = false;
        /**
         * @hidden
         * If the particle systems emitter should be disposed when the particle system is disposed
         */
        _this._disposeEmitterOnDispose = false;
        // start of sub system methods
        /**
         * "Recycles" one of the particle by copying it back to the "stock" of particles and removing it from the active list.
         * Its lifetime will start back at 0.
         */
        _this.recycleParticle = function (particle) {
            // move particle from activeParticle list to stock particles
            var lastParticle = _this._particles.pop();
            if (lastParticle !== particle) {
                lastParticle.copyTo(particle);
            }
            _this._stockParticles.push(lastParticle);
        };
        _this._createParticle = function () {
            var particle;
            if (_this._stockParticles.length !== 0) {
                particle = _this._stockParticles.pop();
                particle._reset();
            }
            else {
                particle = new _particle__WEBPACK_IMPORTED_MODULE_16__["Particle"](_this);
            }
            // Attach emitters
            if (_this._subEmitters && _this._subEmitters.length > 0) {
                var subEmitters = _this._subEmitters[Math.floor(Math.random() * _this._subEmitters.length)];
                particle._attachedSubEmitters = [];
                subEmitters.forEach(function (subEmitter) {
                    if (subEmitter.type === _subEmitter__WEBPACK_IMPORTED_MODULE_17__["SubEmitterType"].ATTACHED) {
                        var newEmitter = subEmitter.clone();
                        particle._attachedSubEmitters.push(newEmitter);
                        newEmitter.particleSystem.start();
                    }
                });
            }
            return particle;
        };
        _this._emitFromParticle = function (particle) {
            if (!_this._subEmitters || _this._subEmitters.length === 0) {
                return;
            }
            var templateIndex = Math.floor(Math.random() * _this._subEmitters.length);
            _this._subEmitters[templateIndex].forEach(function (subEmitter) {
                if (subEmitter.type === _subEmitter__WEBPACK_IMPORTED_MODULE_17__["SubEmitterType"].END) {
                    var subSystem = subEmitter.clone();
                    particle._inheritParticleInfoToSubEmitter(subSystem);
                    subSystem.particleSystem._rootParticleSystem = _this;
                    _this.activeSubSystems.push(subSystem.particleSystem);
                    subSystem.particleSystem.start();
                }
            });
        };
        _this._capacity = capacity;
        _this._epsilon = epsilon;
        _this._isAnimationSheetEnabled = isAnimationSheetEnabled;
        _this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_13__["EngineStore"].LastCreatedScene;
        // Setup the default processing configuration to the scene.
        _this._attachImageProcessingConfiguration(null);
        _this._customEffect = customEffect;
        _this._scene.particleSystems.push(_this);
        _this._useInstancing = _this._scene.getEngine().getCaps().instancedArrays;
        _this._createIndexBuffer();
        _this._createVertexBuffers();
        // Default emitter type
        _this.particleEmitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["BoxParticleEmitter"]();
        // Update
        _this.updateFunction = function (particles) {
            var noiseTextureSize = null;
            var noiseTextureData = null;
            if (_this.noiseTexture) { // We need to get texture data back to CPU
                noiseTextureSize = _this.noiseTexture.getSize();
                noiseTextureData = (_this.noiseTexture.getContent());
            }
            var _loop_1 = function () {
                particle = particles[index];
                var scaledUpdateSpeed = _this._scaledUpdateSpeed;
                var previousAge = particle.age;
                particle.age += scaledUpdateSpeed;
                // Evaluate step to death
                if (particle.age > particle.lifeTime) {
                    var diff = particle.age - previousAge;
                    var oldDiff = particle.lifeTime - previousAge;
                    scaledUpdateSpeed = (oldDiff * scaledUpdateSpeed) / diff;
                    particle.age = particle.lifeTime;
                }
                var ratio = particle.age / particle.lifeTime;
                // Color
                if (_this._colorGradients && _this._colorGradients.length > 0) {
                    _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._colorGradients, function (currentGradient, nextGradient, scale) {
                        if (currentGradient !== particle._currentColorGradient) {
                            particle._currentColor1.copyFrom(particle._currentColor2);
                            nextGradient.getColorToRef(particle._currentColor2);
                            particle._currentColorGradient = currentGradient;
                        }
                        _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].LerpToRef(particle._currentColor1, particle._currentColor2, scale, particle.color);
                    });
                }
                else {
                    particle.colorStep.scaleToRef(scaledUpdateSpeed, _this._scaledColorStep);
                    particle.color.addInPlace(_this._scaledColorStep);
                    if (particle.color.a < 0) {
                        particle.color.a = 0;
                    }
                }
                // Angular speed
                if (_this._angularSpeedGradients && _this._angularSpeedGradients.length > 0) {
                    _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._angularSpeedGradients, function (currentGradient, nextGradient, scale) {
                        if (currentGradient !== particle._currentAngularSpeedGradient) {
                            particle._currentAngularSpeed1 = particle._currentAngularSpeed2;
                            particle._currentAngularSpeed2 = nextGradient.getFactor();
                            particle._currentAngularSpeedGradient = currentGradient;
                        }
                        particle.angularSpeed = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(particle._currentAngularSpeed1, particle._currentAngularSpeed2, scale);
                    });
                }
                particle.angle += particle.angularSpeed * scaledUpdateSpeed;
                // Direction
                var directionScale = scaledUpdateSpeed;
                /// Velocity
                if (_this._velocityGradients && _this._velocityGradients.length > 0) {
                    _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._velocityGradients, function (currentGradient, nextGradient, scale) {
                        if (currentGradient !== particle._currentVelocityGradient) {
                            particle._currentVelocity1 = particle._currentVelocity2;
                            particle._currentVelocity2 = nextGradient.getFactor();
                            particle._currentVelocityGradient = currentGradient;
                        }
                        directionScale *= _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(particle._currentVelocity1, particle._currentVelocity2, scale);
                    });
                }
                particle.direction.scaleToRef(directionScale, _this._scaledDirection);
                /// Limit velocity
                if (_this._limitVelocityGradients && _this._limitVelocityGradients.length > 0) {
                    _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._limitVelocityGradients, function (currentGradient, nextGradient, scale) {
                        if (currentGradient !== particle._currentLimitVelocityGradient) {
                            particle._currentLimitVelocity1 = particle._currentLimitVelocity2;
                            particle._currentLimitVelocity2 = nextGradient.getFactor();
                            particle._currentLimitVelocityGradient = currentGradient;
                        }
                        var limitVelocity = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(particle._currentLimitVelocity1, particle._currentLimitVelocity2, scale);
                        var currentVelocity = particle.direction.length();
                        if (currentVelocity > limitVelocity) {
                            particle.direction.scaleInPlace(_this.limitVelocityDamping);
                        }
                    });
                }
                /// Drag
                if (_this._dragGradients && _this._dragGradients.length > 0) {
                    _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._dragGradients, function (currentGradient, nextGradient, scale) {
                        if (currentGradient !== particle._currentDragGradient) {
                            particle._currentDrag1 = particle._currentDrag2;
                            particle._currentDrag2 = nextGradient.getFactor();
                            particle._currentDragGradient = currentGradient;
                        }
                        var drag = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(particle._currentDrag1, particle._currentDrag2, scale);
                        _this._scaledDirection.scaleInPlace(1.0 - drag);
                    });
                }
                particle.position.addInPlace(_this._scaledDirection);
                // Noise
                if (noiseTextureData && noiseTextureSize && particle._randomNoiseCoordinates1) {
                    var fetchedColorR = _this._fetchR(particle._randomNoiseCoordinates1.x, particle._randomNoiseCoordinates1.y, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
                    var fetchedColorG = _this._fetchR(particle._randomNoiseCoordinates1.z, particle._randomNoiseCoordinates2.x, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
                    var fetchedColorB = _this._fetchR(particle._randomNoiseCoordinates2.y, particle._randomNoiseCoordinates2.z, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
                    var force = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
                    var scaledForce = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
                    force.copyFromFloats((2 * fetchedColorR - 1) * _this.noiseStrength.x, (2 * fetchedColorG - 1) * _this.noiseStrength.y, (2 * fetchedColorB - 1) * _this.noiseStrength.z);
                    force.scaleToRef(scaledUpdateSpeed, scaledForce);
                    particle.direction.addInPlace(scaledForce);
                }
                // Gravity
                _this.gravity.scaleToRef(scaledUpdateSpeed, _this._scaledGravity);
                particle.direction.addInPlace(_this._scaledGravity);
                // Size
                if (_this._sizeGradients && _this._sizeGradients.length > 0) {
                    _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
                        if (currentGradient !== particle._currentSizeGradient) {
                            particle._currentSize1 = particle._currentSize2;
                            particle._currentSize2 = nextGradient.getFactor();
                            particle._currentSizeGradient = currentGradient;
                        }
                        particle.size = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(particle._currentSize1, particle._currentSize2, scale);
                    });
                }
                // Remap data
                if (_this._useRampGradients) {
                    if (_this._colorRemapGradients && _this._colorRemapGradients.length > 0) {
                        _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._colorRemapGradients, function (currentGradient, nextGradient, scale) {
                            var min = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(currentGradient.factor1, nextGradient.factor1, scale);
                            var max = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(currentGradient.factor2, nextGradient.factor2, scale);
                            particle.remapData.x = min;
                            particle.remapData.y = max - min;
                        });
                    }
                    if (_this._alphaRemapGradients && _this._alphaRemapGradients.length > 0) {
                        _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, _this._alphaRemapGradients, function (currentGradient, nextGradient, scale) {
                            var min = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(currentGradient.factor1, nextGradient.factor1, scale);
                            var max = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(currentGradient.factor2, nextGradient.factor2, scale);
                            particle.remapData.z = min;
                            particle.remapData.w = max - min;
                        });
                    }
                }
                if (_this._isAnimationSheetEnabled) {
                    particle.updateCellIndex();
                }
                // Update the position of the attached sub-emitters to match their attached particle
                particle._inheritParticleInfoToSubEmitters();
                if (particle.age >= particle.lifeTime) { // Recycle by swapping with last particle
                    _this._emitFromParticle(particle);
                    if (particle._attachedSubEmitters) {
                        particle._attachedSubEmitters.forEach(function (subEmitter) {
                            subEmitter.particleSystem.disposeOnStop = true;
                            subEmitter.particleSystem.stop();
                        });
                        particle._attachedSubEmitters = null;
                    }
                    _this.recycleParticle(particle);
                    index--;
                    return "continue";
                }
            };
            var particle;
            for (var index = 0; index < particles.length; index++) {
                _loop_1();
            }
        };
        return _this;
    }
    Object.defineProperty(ParticleSystem.prototype, "onDispose", {
        /**
         * Sets a callback that will be triggered when the system is disposed
         */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ParticleSystem.prototype, "useRampGradients", {
        /** Gets or sets a boolean indicating that ramp gradients must be used
         * @see http://doc.babylonjs.com/babylon101/particles#ramp-gradients
         */
        get: function () {
            return this._useRampGradients;
        },
        set: function (value) {
            if (this._useRampGradients === value) {
                return;
            }
            this._useRampGradients = value;
            this._resetEffect();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ParticleSystem.prototype, "particles", {
        //end of Sub-emitter
        /**
         * Gets the current list of active particles
         */
        get: function () {
            return this._particles;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the string "ParticleSystem"
     * @returns a string containing the class name
     */
    ParticleSystem.prototype.getClassName = function () {
        return "ParticleSystem";
    };
    ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
        var newGradient = new _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["FactorGradient"]();
        newGradient.gradient = gradient;
        newGradient.factor1 = factor;
        newGradient.factor2 = factor2;
        factorGradients.push(newGradient);
        factorGradients.sort(function (a, b) {
            if (a.gradient < b.gradient) {
                return -1;
            }
            else if (a.gradient > b.gradient) {
                return 1;
            }
            return 0;
        });
    };
    ParticleSystem.prototype._removeFactorGradient = function (factorGradients, gradient) {
        if (!factorGradients) {
            return;
        }
        var index = 0;
        for (var _i = 0, factorGradients_1 = factorGradients; _i < factorGradients_1.length; _i++) {
            var factorGradient = factorGradients_1[_i];
            if (factorGradient.gradient === gradient) {
                factorGradients.splice(index, 1);
                break;
            }
            index++;
        }
    };
    /**
     * Adds a new life time gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the life time factor to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addLifeTimeGradient = function (gradient, factor, factor2) {
        if (!this._lifeTimeGradients) {
            this._lifeTimeGradients = [];
        }
        this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific life time gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeLifeTimeGradient = function (gradient) {
        this._removeFactorGradient(this._lifeTimeGradients, gradient);
        return this;
    };
    /**
     * Adds a new size gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the size factor to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addSizeGradient = function (gradient, factor, factor2) {
        if (!this._sizeGradients) {
            this._sizeGradients = [];
        }
        this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific size gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeSizeGradient = function (gradient) {
        this._removeFactorGradient(this._sizeGradients, gradient);
        return this;
    };
    /**
     * Adds a new color remap gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param min defines the color remap minimal range
     * @param max defines the color remap maximal range
     * @returns the current particle system
     */
    ParticleSystem.prototype.addColorRemapGradient = function (gradient, min, max) {
        if (!this._colorRemapGradients) {
            this._colorRemapGradients = [];
        }
        this._addFactorGradient(this._colorRemapGradients, gradient, min, max);
        return this;
    };
    /**
     * Remove a specific color remap gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeColorRemapGradient = function (gradient) {
        this._removeFactorGradient(this._colorRemapGradients, gradient);
        return this;
    };
    /**
     * Adds a new alpha remap gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param min defines the alpha remap minimal range
     * @param max defines the alpha remap maximal range
     * @returns the current particle system
     */
    ParticleSystem.prototype.addAlphaRemapGradient = function (gradient, min, max) {
        if (!this._alphaRemapGradients) {
            this._alphaRemapGradients = [];
        }
        this._addFactorGradient(this._alphaRemapGradients, gradient, min, max);
        return this;
    };
    /**
     * Remove a specific alpha remap gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeAlphaRemapGradient = function (gradient) {
        this._removeFactorGradient(this._alphaRemapGradients, gradient);
        return this;
    };
    /**
     * Adds a new angular speed gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the angular speed  to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addAngularSpeedGradient = function (gradient, factor, factor2) {
        if (!this._angularSpeedGradients) {
            this._angularSpeedGradients = [];
        }
        this._addFactorGradient(this._angularSpeedGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific angular speed gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeAngularSpeedGradient = function (gradient) {
        this._removeFactorGradient(this._angularSpeedGradients, gradient);
        return this;
    };
    /**
     * Adds a new velocity gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the velocity to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addVelocityGradient = function (gradient, factor, factor2) {
        if (!this._velocityGradients) {
            this._velocityGradients = [];
        }
        this._addFactorGradient(this._velocityGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific velocity gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeVelocityGradient = function (gradient) {
        this._removeFactorGradient(this._velocityGradients, gradient);
        return this;
    };
    /**
     * Adds a new limit velocity gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the limit velocity value to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addLimitVelocityGradient = function (gradient, factor, factor2) {
        if (!this._limitVelocityGradients) {
            this._limitVelocityGradients = [];
        }
        this._addFactorGradient(this._limitVelocityGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific limit velocity gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeLimitVelocityGradient = function (gradient) {
        this._removeFactorGradient(this._limitVelocityGradients, gradient);
        return this;
    };
    /**
     * Adds a new drag gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the drag value to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addDragGradient = function (gradient, factor, factor2) {
        if (!this._dragGradients) {
            this._dragGradients = [];
        }
        this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific drag gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeDragGradient = function (gradient) {
        this._removeFactorGradient(this._dragGradients, gradient);
        return this;
    };
    /**
     * Adds a new emit rate gradient (please note that this will only work if you set the targetStopDuration property)
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the emit rate value to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addEmitRateGradient = function (gradient, factor, factor2) {
        if (!this._emitRateGradients) {
            this._emitRateGradients = [];
        }
        this._addFactorGradient(this._emitRateGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific emit rate gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeEmitRateGradient = function (gradient) {
        this._removeFactorGradient(this._emitRateGradients, gradient);
        return this;
    };
    /**
     * Adds a new start size gradient (please note that this will only work if you set the targetStopDuration property)
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param factor defines the start size value to affect to the specified gradient
     * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
     * @returns the current particle system
     */
    ParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
        if (!this._startSizeGradients) {
            this._startSizeGradients = [];
        }
        this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);
        return this;
    };
    /**
     * Remove a specific start size gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
        this._removeFactorGradient(this._emitRateGradients, gradient);
        return this;
    };
    ParticleSystem.prototype._createRampGradientTexture = function () {
        if (!this._rampGradients || !this._rampGradients.length || this._rampGradientsTexture) {
            return;
        }
        var data = new Uint8Array(this._rawTextureWidth * 4);
        var tmpColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["TmpColors"].Color3[0];
        for (var x = 0; x < this._rawTextureWidth; x++) {
            var ratio = x / this._rawTextureWidth;
            _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, this._rampGradients, function (currentGradient, nextGradient, scale) {
                _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color3"].LerpToRef(currentGradient.color, nextGradient.color, scale, tmpColor);
                data[x * 4] = tmpColor.r * 255;
                data[x * 4 + 1] = tmpColor.g * 255;
                data[x * 4 + 2] = tmpColor.b * 255;
                data[x * 4 + 3] = 255;
            });
        }
        this._rampGradientsTexture = _Materials_Textures_rawTexture__WEBPACK_IMPORTED_MODULE_11__["RawTexture"].CreateRGBATexture(data, this._rawTextureWidth, 1, this._scene, false, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__["Texture"].NEAREST_SAMPLINGMODE);
    };
    /**
     * Gets the current list of ramp gradients.
     * You must use addRampGradient and removeRampGradient to udpate this list
     * @returns the list of ramp gradients
     */
    ParticleSystem.prototype.getRampGradients = function () {
        return this._rampGradients;
    };
    /**
     * Adds a new ramp gradient used to remap particle colors
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param color defines the color to affect to the specified gradient
     * @returns the current particle system
     */
    ParticleSystem.prototype.addRampGradient = function (gradient, color) {
        if (!this._rampGradients) {
            this._rampGradients = [];
        }
        var rampGradient = new _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["Color3Gradient"]();
        rampGradient.gradient = gradient;
        rampGradient.color = color;
        this._rampGradients.push(rampGradient);
        this._rampGradients.sort(function (a, b) {
            if (a.gradient < b.gradient) {
                return -1;
            }
            else if (a.gradient > b.gradient) {
                return 1;
            }
            return 0;
        });
        if (this._rampGradientsTexture) {
            this._rampGradientsTexture.dispose();
            this._rampGradientsTexture = null;
        }
        this._createRampGradientTexture();
        return this;
    };
    /**
     * Remove a specific ramp gradient
     * @param gradient defines the gradient to remove
     * @returns the current particle system
     */
    ParticleSystem.prototype.removeRampGradient = function (gradient) {
        this._removeGradientAndTexture(gradient, this._rampGradients, this._rampGradientsTexture);
        this._rampGradientsTexture = null;
        if (this._rampGradients && this._rampGradients.length > 0) {
            this._createRampGradientTexture();
        }
        return this;
    };
    /**
     * Adds a new color gradient
     * @param gradient defines the gradient to use (between 0 and 1)
     * @param color1 defines the color to affect to the specified gradient
     * @param color2 defines an additional color used to define a range ([color, color2]) with main color to pick the final color from
     * @returns this particle system
     */
    ParticleSystem.prototype.addColorGradient = function (gradient, color1, color2) {
        if (!this._colorGradients) {
            this._colorGradients = [];
        }
        var colorGradient = new _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["ColorGradient"]();
        colorGradient.gradient = gradient;
        colorGradient.color1 = color1;
        colorGradient.color2 = color2;
        this._colorGradients.push(colorGradient);
        this._colorGradients.sort(function (a, b) {
            if (a.gradient < b.gradient) {
                return -1;
            }
            else if (a.gradient > b.gradient) {
                return 1;
            }
            return 0;
        });
        return this;
    };
    /**
     * Remove a specific color gradient
     * @param gradient defines the gradient to remove
     * @returns this particle system
     */
    ParticleSystem.prototype.removeColorGradient = function (gradient) {
        if (!this._colorGradients) {
            return this;
        }
        var index = 0;
        for (var _i = 0, _a = this._colorGradients; _i < _a.length; _i++) {
            var colorGradient = _a[_i];
            if (colorGradient.gradient === gradient) {
                this._colorGradients.splice(index, 1);
                break;
            }
            index++;
        }
        return this;
    };
    ParticleSystem.prototype._fetchR = function (u, v, width, height, pixels) {
        u = Math.abs(u) * 0.5 + 0.5;
        v = Math.abs(v) * 0.5 + 0.5;
        var wrappedU = ((u * width) % width) | 0;
        var wrappedV = ((v * height) % height) | 0;
        var position = (wrappedU + wrappedV * width) * 4;
        return pixels[position] / 255;
    };
    ParticleSystem.prototype._reset = function () {
        this._resetEffect();
    };
    ParticleSystem.prototype._resetEffect = function () {
        if (this._vertexBuffer) {
            this._vertexBuffer.dispose();
            this._vertexBuffer = null;
        }
        if (this._spriteBuffer) {
            this._spriteBuffer.dispose();
            this._spriteBuffer = null;
        }
        this._createVertexBuffers();
    };
    ParticleSystem.prototype._createVertexBuffers = function () {
        this._vertexBufferSize = this._useInstancing ? 10 : 12;
        if (this._isAnimationSheetEnabled) {
            this._vertexBufferSize += 1;
        }
        if (!this._isBillboardBased || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
            this._vertexBufferSize += 3;
        }
        if (this._useRampGradients) {
            this._vertexBufferSize += 4;
        }
        var engine = this._scene.getEngine();
        this._vertexData = new Float32Array(this._capacity * this._vertexBufferSize * (this._useInstancing ? 1 : 4));
        this._vertexBuffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["Buffer"](engine, this._vertexData, true, this._vertexBufferSize);
        var dataOffset = 0;
        var positions = this._vertexBuffer.createVertexBuffer(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind, dataOffset, 3, this._vertexBufferSize, this._useInstancing);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind] = positions;
        dataOffset += 3;
        var colors = this._vertexBuffer.createVertexBuffer(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].ColorKind, dataOffset, 4, this._vertexBufferSize, this._useInstancing);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].ColorKind] = colors;
        dataOffset += 4;
        var options = this._vertexBuffer.createVertexBuffer("angle", dataOffset, 1, this._vertexBufferSize, this._useInstancing);
        this._vertexBuffers["angle"] = options;
        dataOffset += 1;
        var size = this._vertexBuffer.createVertexBuffer("size", dataOffset, 2, this._vertexBufferSize, this._useInstancing);
        this._vertexBuffers["size"] = size;
        dataOffset += 2;
        if (this._isAnimationSheetEnabled) {
            var cellIndexBuffer = this._vertexBuffer.createVertexBuffer("cellIndex", dataOffset, 1, this._vertexBufferSize, this._useInstancing);
            this._vertexBuffers["cellIndex"] = cellIndexBuffer;
            dataOffset += 1;
        }
        if (!this._isBillboardBased || this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
            var directionBuffer = this._vertexBuffer.createVertexBuffer("direction", dataOffset, 3, this._vertexBufferSize, this._useInstancing);
            this._vertexBuffers["direction"] = directionBuffer;
            dataOffset += 3;
        }
        if (this._useRampGradients) {
            var rampDataBuffer = this._vertexBuffer.createVertexBuffer("remapData", dataOffset, 4, this._vertexBufferSize, this._useInstancing);
            this._vertexBuffers["remapData"] = rampDataBuffer;
            dataOffset += 4;
        }
        var offsets;
        if (this._useInstancing) {
            var spriteData = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]);
            this._spriteBuffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["Buffer"](engine, spriteData, false, 2);
            offsets = this._spriteBuffer.createVertexBuffer("offset", 0, 2);
        }
        else {
            offsets = this._vertexBuffer.createVertexBuffer("offset", dataOffset, 2, this._vertexBufferSize, this._useInstancing);
            dataOffset += 2;
        }
        this._vertexBuffers["offset"] = offsets;
    };
    ParticleSystem.prototype._createIndexBuffer = function () {
        if (this._useInstancing) {
            return;
        }
        var indices = [];
        var index = 0;
        for (var count = 0; count < this._capacity; count++) {
            indices.push(index);
            indices.push(index + 1);
            indices.push(index + 2);
            indices.push(index);
            indices.push(index + 2);
            indices.push(index + 3);
            index += 4;
        }
        this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
    };
    /**
     * Gets the maximum number of particles active at the same time.
     * @returns The max number of active particles.
     */
    ParticleSystem.prototype.getCapacity = function () {
        return this._capacity;
    };
    /**
     * Gets whether there are still active particles in the system.
     * @returns True if it is alive, otherwise false.
     */
    ParticleSystem.prototype.isAlive = function () {
        return this._alive;
    };
    /**
     * Gets if the system has been started. (Note: this will still be true after stop is called)
     * @returns True if it has been started, otherwise false.
     */
    ParticleSystem.prototype.isStarted = function () {
        return this._started;
    };
    ParticleSystem.prototype._prepareSubEmitterInternalArray = function () {
        var _this = this;
        this._subEmitters = new Array();
        if (this.subEmitters) {
            this.subEmitters.forEach(function (subEmitter) {
                if (subEmitter instanceof ParticleSystem) {
                    _this._subEmitters.push([new _subEmitter__WEBPACK_IMPORTED_MODULE_17__["SubEmitter"](subEmitter)]);
                }
                else if (subEmitter instanceof _subEmitter__WEBPACK_IMPORTED_MODULE_17__["SubEmitter"]) {
                    _this._subEmitters.push([subEmitter]);
                }
                else if (subEmitter instanceof Array) {
                    _this._subEmitters.push(subEmitter);
                }
            });
        }
    };
    /**
     * Starts the particle system and begins to emit
     * @param delay defines the delay in milliseconds before starting the system (this.startDelay by default)
     */
    ParticleSystem.prototype.start = function (delay) {
        var _this = this;
        if (delay === void 0) { delay = this.startDelay; }
        if (!this.targetStopDuration && this._hasTargetStopDurationDependantGradient()) {
            throw "Particle system started with a targetStopDuration dependant gradient (eg. startSizeGradients) but no targetStopDuration set";
        }
        if (delay) {
            setTimeout(function () {
                _this.start(0);
            }, delay);
            return;
        }
        // Convert the subEmitters field to the constant type field _subEmitters
        this._prepareSubEmitterInternalArray();
        this._started = true;
        this._stopped = false;
        this._actualFrame = 0;
        if (this._subEmitters && this._subEmitters.length != 0) {
            this.activeSubSystems = new Array();
        }
        // Reset emit gradient so it acts the same on every start
        if (this._emitRateGradients) {
            if (this._emitRateGradients.length > 0) {
                this._currentEmitRateGradient = this._emitRateGradients[0];
                this._currentEmitRate1 = this._currentEmitRateGradient.getFactor();
                this._currentEmitRate2 = this._currentEmitRate1;
            }
            if (this._emitRateGradients.length > 1) {
                this._currentEmitRate2 = this._emitRateGradients[1].getFactor();
            }
        }
        // Reset start size gradient so it acts the same on every start
        if (this._startSizeGradients) {
            if (this._startSizeGradients.length > 0) {
                this._currentStartSizeGradient = this._startSizeGradients[0];
                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();
                this._currentStartSize2 = this._currentStartSize1;
            }
            if (this._startSizeGradients.length > 1) {
                this._currentStartSize2 = this._startSizeGradients[1].getFactor();
            }
        }
        if (this.preWarmCycles) {
            if (this.emitter instanceof _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_6__["AbstractMesh"]) {
                this.emitter.computeWorldMatrix(true);
            }
            var noiseTextureAsProcedural_1 = this.noiseTexture;
            if (noiseTextureAsProcedural_1 && noiseTextureAsProcedural_1.onGeneratedObservable) {
                noiseTextureAsProcedural_1.onGeneratedObservable.addOnce(function () {
                    setTimeout(function () {
                        for (var index = 0; index < _this.preWarmCycles; index++) {
                            _this.animate(true);
                            noiseTextureAsProcedural_1.render();
                        }
                    });
                });
            }
            else {
                for (var index = 0; index < this.preWarmCycles; index++) {
                    this.animate(true);
                }
            }
        }
        // Animations
        if (this.beginAnimationOnStart && this.animations && this.animations.length > 0) {
            this.getScene().beginAnimation(this, this.beginAnimationFrom, this.beginAnimationTo, this.beginAnimationLoop);
        }
    };
    /**
     * Stops the particle system.
     * @param stopSubEmitters if true it will stop the current system and all created sub-Systems if false it will stop the current root system only, this param is used by the root particle system only. the default value is true.
     */
    ParticleSystem.prototype.stop = function (stopSubEmitters) {
        if (stopSubEmitters === void 0) { stopSubEmitters = true; }
        this._stopped = true;
        if (stopSubEmitters) {
            this._stopSubEmitters();
        }
    };
    // animation sheet
    /**
     * Remove all active particles
     */
    ParticleSystem.prototype.reset = function () {
        this._stockParticles = [];
        this._particles = [];
    };
    /**
     * @hidden (for internal use only)
     */
    ParticleSystem.prototype._appendParticleVertex = function (index, particle, offsetX, offsetY) {
        var offset = index * this._vertexBufferSize;
        this._vertexData[offset++] = particle.position.x + this.worldOffset.x;
        this._vertexData[offset++] = particle.position.y + this.worldOffset.y;
        this._vertexData[offset++] = particle.position.z + this.worldOffset.z;
        this._vertexData[offset++] = particle.color.r;
        this._vertexData[offset++] = particle.color.g;
        this._vertexData[offset++] = particle.color.b;
        this._vertexData[offset++] = particle.color.a;
        this._vertexData[offset++] = particle.angle;
        this._vertexData[offset++] = particle.scale.x * particle.size;
        this._vertexData[offset++] = particle.scale.y * particle.size;
        if (this._isAnimationSheetEnabled) {
            this._vertexData[offset++] = particle.cellIndex;
        }
        if (!this._isBillboardBased) {
            if (particle._initialDirection) {
                this._vertexData[offset++] = particle._initialDirection.x;
                this._vertexData[offset++] = particle._initialDirection.y;
                this._vertexData[offset++] = particle._initialDirection.z;
            }
            else {
                this._vertexData[offset++] = particle.direction.x;
                this._vertexData[offset++] = particle.direction.y;
                this._vertexData[offset++] = particle.direction.z;
            }
        }
        else if (this.billboardMode === ParticleSystem.BILLBOARDMODE_STRETCHED) {
            this._vertexData[offset++] = particle.direction.x;
            this._vertexData[offset++] = particle.direction.y;
            this._vertexData[offset++] = particle.direction.z;
        }
        if (this._useRampGradients) {
            this._vertexData[offset++] = particle.remapData.x;
            this._vertexData[offset++] = particle.remapData.y;
            this._vertexData[offset++] = particle.remapData.z;
            this._vertexData[offset++] = particle.remapData.w;
        }
        if (!this._useInstancing) {
            if (this._isAnimationSheetEnabled) {
                if (offsetX === 0) {
                    offsetX = this._epsilon;
                }
                else if (offsetX === 1) {
                    offsetX = 1 - this._epsilon;
                }
                if (offsetY === 0) {
                    offsetY = this._epsilon;
                }
                else if (offsetY === 1) {
                    offsetY = 1 - this._epsilon;
                }
            }
            this._vertexData[offset++] = offsetX;
            this._vertexData[offset++] = offsetY;
        }
    };
    ParticleSystem.prototype._stopSubEmitters = function () {
        if (!this.activeSubSystems) {
            return;
        }
        this.activeSubSystems.forEach(function (subSystem) {
            subSystem.stop(true);
        });
        this.activeSubSystems = new Array();
    };
    ParticleSystem.prototype._removeFromRoot = function () {
        if (!this._rootParticleSystem) {
            return;
        }
        var index = this._rootParticleSystem.activeSubSystems.indexOf(this);
        if (index !== -1) {
            this._rootParticleSystem.activeSubSystems.splice(index, 1);
        }
        this._rootParticleSystem = null;
    };
    // End of sub system methods
    ParticleSystem.prototype._update = function (newParticles) {
        var _this = this;
        // Update current
        this._alive = this._particles.length > 0;
        if (this.emitter.position) {
            var emitterMesh = this.emitter;
            this._emitterWorldMatrix = emitterMesh.getWorldMatrix();
        }
        else {
            var emitterPosition = this.emitter;
            this._emitterWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
        }
        this.updateFunction(this._particles);
        // Add new ones
        var particle;
        var _loop_2 = function () {
            if (this_1._particles.length === this_1._capacity) {
                return "break";
            }
            particle = this_1._createParticle();
            this_1._particles.push(particle);
            // Emitter
            var emitPower = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minEmitPower, this_1.maxEmitPower);
            if (this_1.startPositionFunction) {
                this_1.startPositionFunction(this_1._emitterWorldMatrix, particle.position, particle);
            }
            else {
                this_1.particleEmitterType.startPositionFunction(this_1._emitterWorldMatrix, particle.position, particle);
            }
            if (this_1.startDirectionFunction) {
                this_1.startDirectionFunction(this_1._emitterWorldMatrix, particle.direction, particle);
            }
            else {
                this_1.particleEmitterType.startDirectionFunction(this_1._emitterWorldMatrix, particle.direction, particle);
            }
            if (emitPower === 0) {
                if (!particle._initialDirection) {
                    particle._initialDirection = particle.direction.clone();
                }
                else {
                    particle._initialDirection.copyFrom(particle.direction);
                }
            }
            else {
                particle._initialDirection = null;
            }
            particle.direction.scaleInPlace(emitPower);
            // Life time
            if (this_1.targetStopDuration && this_1._lifeTimeGradients && this_1._lifeTimeGradients.length > 0) {
                var ratio_1 = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Clamp(this_1._actualFrame / this_1.targetStopDuration);
                _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio_1, this_1._lifeTimeGradients, function (currentGradient, nextGradient) {
                    var factorGradient1 = currentGradient;
                    var factorGradient2 = nextGradient;
                    var lifeTime1 = factorGradient1.getFactor();
                    var lifeTime2 = factorGradient2.getFactor();
                    var gradient = (ratio_1 - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
                    particle.lifeTime = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(lifeTime1, lifeTime2, gradient);
                });
            }
            else {
                particle.lifeTime = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minLifeTime, this_1.maxLifeTime);
            }
            // Size
            if (!this_1._sizeGradients || this_1._sizeGradients.length === 0) {
                particle.size = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minSize, this_1.maxSize);
            }
            else {
                particle._currentSizeGradient = this_1._sizeGradients[0];
                particle._currentSize1 = particle._currentSizeGradient.getFactor();
                particle.size = particle._currentSize1;
                if (this_1._sizeGradients.length > 1) {
                    particle._currentSize2 = this_1._sizeGradients[1].getFactor();
                }
                else {
                    particle._currentSize2 = particle._currentSize1;
                }
            }
            // Size and scale
            particle.scale.copyFromFloats(_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minScaleX, this_1.maxScaleX), _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minScaleY, this_1.maxScaleY));
            // Adjust scale by start size
            if (this_1._startSizeGradients && this_1._startSizeGradients[0] && this_1.targetStopDuration) {
                var ratio = this_1._actualFrame / this_1.targetStopDuration;
                _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, this_1._startSizeGradients, function (currentGradient, nextGradient, scale) {
                    if (currentGradient !== _this._currentStartSizeGradient) {
                        _this._currentStartSize1 = _this._currentStartSize2;
                        _this._currentStartSize2 = nextGradient.getFactor();
                        _this._currentStartSizeGradient = currentGradient;
                    }
                    var value = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(_this._currentStartSize1, _this._currentStartSize2, scale);
                    particle.scale.scaleInPlace(value);
                });
            }
            // Angle
            if (!this_1._angularSpeedGradients || this_1._angularSpeedGradients.length === 0) {
                particle.angularSpeed = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
            }
            else {
                particle._currentAngularSpeedGradient = this_1._angularSpeedGradients[0];
                particle.angularSpeed = particle._currentAngularSpeedGradient.getFactor();
                particle._currentAngularSpeed1 = particle.angularSpeed;
                if (this_1._angularSpeedGradients.length > 1) {
                    particle._currentAngularSpeed2 = this_1._angularSpeedGradients[1].getFactor();
                }
                else {
                    particle._currentAngularSpeed2 = particle._currentAngularSpeed1;
                }
            }
            particle.angle = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(this_1.minInitialRotation, this_1.maxInitialRotation);
            // Velocity
            if (this_1._velocityGradients && this_1._velocityGradients.length > 0) {
                particle._currentVelocityGradient = this_1._velocityGradients[0];
                particle._currentVelocity1 = particle._currentVelocityGradient.getFactor();
                if (this_1._velocityGradients.length > 1) {
                    particle._currentVelocity2 = this_1._velocityGradients[1].getFactor();
                }
                else {
                    particle._currentVelocity2 = particle._currentVelocity1;
                }
            }
            // Limit velocity
            if (this_1._limitVelocityGradients && this_1._limitVelocityGradients.length > 0) {
                particle._currentLimitVelocityGradient = this_1._limitVelocityGradients[0];
                particle._currentLimitVelocity1 = particle._currentLimitVelocityGradient.getFactor();
                if (this_1._limitVelocityGradients.length > 1) {
                    particle._currentLimitVelocity2 = this_1._limitVelocityGradients[1].getFactor();
                }
                else {
                    particle._currentLimitVelocity2 = particle._currentLimitVelocity1;
                }
            }
            // Drag
            if (this_1._dragGradients && this_1._dragGradients.length > 0) {
                particle._currentDragGradient = this_1._dragGradients[0];
                particle._currentDrag1 = particle._currentDragGradient.getFactor();
                if (this_1._dragGradients.length > 1) {
                    particle._currentDrag2 = this_1._dragGradients[1].getFactor();
                }
                else {
                    particle._currentDrag2 = particle._currentDrag1;
                }
            }
            // Color
            if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
                step = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].RandomRange(0, 1.0);
                _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].LerpToRef(this_1.color1, this_1.color2, step, particle.color);
                this_1.colorDead.subtractToRef(particle.color, this_1._colorDiff);
                this_1._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
            }
            else {
                particle._currentColorGradient = this_1._colorGradients[0];
                particle._currentColorGradient.getColorToRef(particle.color);
                particle._currentColor1.copyFrom(particle.color);
                if (this_1._colorGradients.length > 1) {
                    this_1._colorGradients[1].getColorToRef(particle._currentColor2);
                }
                else {
                    particle._currentColor2.copyFrom(particle.color);
                }
            }
            // Sheet
            if (this_1._isAnimationSheetEnabled) {
                particle._initialStartSpriteCellID = this_1.startSpriteCellID;
                particle._initialEndSpriteCellID = this_1.endSpriteCellID;
            }
            // Inherited Velocity
            particle.direction.addInPlace(this_1._inheritedVelocityOffset);
            // Ramp
            if (this_1._useRampGradients) {
                particle.remapData = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector4"](0, 1, 0, 1);
            }
            // Noise texture coordinates
            if (this_1.noiseTexture) {
                if (particle._randomNoiseCoordinates1) {
                    particle._randomNoiseCoordinates1.copyFromFloats(Math.random(), Math.random(), Math.random());
                    particle._randomNoiseCoordinates2.copyFromFloats(Math.random(), Math.random(), Math.random());
                }
                else {
                    particle._randomNoiseCoordinates1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Math.random(), Math.random(), Math.random());
                    particle._randomNoiseCoordinates2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Math.random(), Math.random(), Math.random());
                }
            }
            // Update the position of the attached sub-emitters to match their attached particle
            particle._inheritParticleInfoToSubEmitters();
        };
        var this_1 = this, step;
        for (var index = 0; index < newParticles; index++) {
            var state_1 = _loop_2();
            if (state_1 === "break")
                break;
        }
    };
    /** @hidden */
    ParticleSystem._GetAttributeNamesOrOptions = function (isAnimationSheetEnabled, isBillboardBased, useRampGradients) {
        if (isAnimationSheetEnabled === void 0) { isAnimationSheetEnabled = false; }
        if (isBillboardBased === void 0) { isBillboardBased = false; }
        if (useRampGradients === void 0) { useRampGradients = false; }
        var attributeNamesOrOptions = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].PositionKind, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_5__["VertexBuffer"].ColorKind, "angle", "offset", "size"];
        if (isAnimationSheetEnabled) {
            attributeNamesOrOptions.push("cellIndex");
        }
        if (!isBillboardBased) {
            attributeNamesOrOptions.push("direction");
        }
        if (useRampGradients) {
            attributeNamesOrOptions.push("remapData");
        }
        return attributeNamesOrOptions;
    };
    /** @hidden */
    ParticleSystem._GetEffectCreationOptions = function (isAnimationSheetEnabled) {
        if (isAnimationSheetEnabled === void 0) { isAnimationSheetEnabled = false; }
        var effectCreationOption = ["invView", "view", "projection", "vClipPlane", "vClipPlane2", "vClipPlane3", "vClipPlane4", "textureMask", "translationPivot", "eyePosition"];
        if (isAnimationSheetEnabled) {
            effectCreationOption.push("particlesInfos");
        }
        return effectCreationOption;
    };
    /** @hidden */
    ParticleSystem.prototype._getEffect = function (blendMode) {
        if (this._customEffect) {
            return this._customEffect;
        }
        var defines = [];
        if (this._scene.clipPlane) {
            defines.push("#define CLIPPLANE");
        }
        if (this._scene.clipPlane2) {
            defines.push("#define CLIPPLANE2");
        }
        if (this._scene.clipPlane3) {
            defines.push("#define CLIPPLANE3");
        }
        if (this._scene.clipPlane4) {
            defines.push("#define CLIPPLANE4");
        }
        if (this._isAnimationSheetEnabled) {
            defines.push("#define ANIMATESHEET");
        }
        if (blendMode === ParticleSystem.BLENDMODE_MULTIPLY) {
            defines.push("#define BLENDMULTIPLYMODE");
        }
        if (this._useRampGradients) {
            defines.push("#define RAMPGRADIENT");
        }
        if (this._isBillboardBased) {
            defines.push("#define BILLBOARD");
            switch (this.billboardMode) {
                case ParticleSystem.BILLBOARDMODE_Y:
                    defines.push("#define BILLBOARDY");
                    break;
                case ParticleSystem.BILLBOARDMODE_STRETCHED:
                    defines.push("#define BILLBOARDSTRETCHED");
                    break;
                case ParticleSystem.BILLBOARDMODE_ALL:
                default:
                    break;
            }
        }
        if (this._imageProcessingConfiguration) {
            this._imageProcessingConfiguration.prepareDefines(this._imageProcessingConfigurationDefines);
            defines.push(this._imageProcessingConfigurationDefines.toString());
        }
        // Effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            var attributesNamesOrOptions = ParticleSystem._GetAttributeNamesOrOptions(this._isAnimationSheetEnabled, this._isBillboardBased && this.billboardMode !== ParticleSystem.BILLBOARDMODE_STRETCHED, this._useRampGradients);
            var effectCreationOption = ParticleSystem._GetEffectCreationOptions(this._isAnimationSheetEnabled);
            var samplers = ["diffuseSampler", "rampSampler"];
            if (_Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_9__["ImageProcessingConfiguration"]) {
                _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_9__["ImageProcessingConfiguration"].PrepareUniforms(effectCreationOption, this._imageProcessingConfigurationDefines);
                _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_9__["ImageProcessingConfiguration"].PrepareSamplers(samplers, this._imageProcessingConfigurationDefines);
            }
            this._effect = this._scene.getEngine().createEffect("particles", attributesNamesOrOptions, effectCreationOption, samplers, join);
        }
        return this._effect;
    };
    /**
     * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
     * @param preWarmOnly will prevent the system from updating the vertex buffer (default is false)
     */
    ParticleSystem.prototype.animate = function (preWarmOnly) {
        var _this = this;
        if (preWarmOnly === void 0) { preWarmOnly = false; }
        if (!this._started) {
            return;
        }
        if (!preWarmOnly) {
            // Check
            if (!this.isReady()) {
                return;
            }
            if (this._currentRenderId === this._scene.getFrameId()) {
                return;
            }
            this._currentRenderId = this._scene.getFrameId();
        }
        this._scaledUpdateSpeed = this.updateSpeed * (preWarmOnly ? this.preWarmStepOffset : this._scene.getAnimationRatio());
        // Determine the number of particles we need to create
        var newParticles;
        if (this.manualEmitCount > -1) {
            newParticles = this.manualEmitCount;
            this._newPartsExcess = 0;
            this.manualEmitCount = 0;
        }
        else {
            var rate_1 = this.emitRate;
            if (this._emitRateGradients && this._emitRateGradients.length > 0 && this.targetStopDuration) {
                var ratio = this._actualFrame / this.targetStopDuration;
                _Misc_gradients__WEBPACK_IMPORTED_MODULE_1__["GradientHelper"].GetCurrentGradient(ratio, this._emitRateGradients, function (currentGradient, nextGradient, scale) {
                    if (currentGradient !== _this._currentEmitRateGradient) {
                        _this._currentEmitRate1 = _this._currentEmitRate2;
                        _this._currentEmitRate2 = nextGradient.getFactor();
                        _this._currentEmitRateGradient = currentGradient;
                    }
                    rate_1 = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Lerp(_this._currentEmitRate1, _this._currentEmitRate2, scale);
                });
            }
            newParticles = ((rate_1 * this._scaledUpdateSpeed) >> 0);
            this._newPartsExcess += rate_1 * this._scaledUpdateSpeed - newParticles;
        }
        if (this._newPartsExcess > 1.0) {
            newParticles += this._newPartsExcess >> 0;
            this._newPartsExcess -= this._newPartsExcess >> 0;
        }
        this._alive = false;
        if (!this._stopped) {
            this._actualFrame += this._scaledUpdateSpeed;
            if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration) {
                this.stop();
            }
        }
        else {
            newParticles = 0;
        }
        this._update(newParticles);
        // Stopped?
        if (this._stopped) {
            if (!this._alive) {
                this._started = false;
                if (this.onAnimationEnd) {
                    this.onAnimationEnd();
                }
                if (this.disposeOnStop) {
                    this._scene._toBeDisposed.push(this);
                }
            }
        }
        if (!preWarmOnly) {
            // Update VBO
            var offset = 0;
            for (var index = 0; index < this._particles.length; index++) {
                var particle = this._particles[index];
                this._appendParticleVertices(offset, particle);
                offset += this._useInstancing ? 1 : 4;
            }
            if (this._vertexBuffer) {
                this._vertexBuffer.update(this._vertexData);
            }
        }
        if (this.manualEmitCount === 0 && this.disposeOnStop) {
            this.stop();
        }
    };
    ParticleSystem.prototype._appendParticleVertices = function (offset, particle) {
        this._appendParticleVertex(offset++, particle, 0, 0);
        if (!this._useInstancing) {
            this._appendParticleVertex(offset++, particle, 1, 0);
            this._appendParticleVertex(offset++, particle, 1, 1);
            this._appendParticleVertex(offset++, particle, 0, 1);
        }
    };
    /**
     * Rebuilds the particle system.
     */
    ParticleSystem.prototype.rebuild = function () {
        this._createIndexBuffer();
        if (this._vertexBuffer) {
            this._vertexBuffer._rebuild();
        }
        for (var key in this._vertexBuffers) {
            this._vertexBuffers[key]._rebuild();
        }
    };
    /**
     * Is this system ready to be used/rendered
     * @return true if the system is ready
     */
    ParticleSystem.prototype.isReady = function () {
        if (!this.emitter || !this._imageProcessingConfiguration.isReady() || !this.particleTexture || !this.particleTexture.isReady()) {
            return false;
        }
        if (this.blendMode !== ParticleSystem.BLENDMODE_MULTIPLYADD) {
            if (!this._getEffect(this.blendMode).isReady()) {
                return false;
            }
        }
        else {
            if (!this._getEffect(ParticleSystem.BLENDMODE_MULTIPLY).isReady()) {
                return false;
            }
            if (!this._getEffect(ParticleSystem.BLENDMODE_ADD).isReady()) {
                return false;
            }
        }
        return true;
    };
    ParticleSystem.prototype._render = function (blendMode) {
        var effect = this._getEffect(blendMode);
        var engine = this._scene.getEngine();
        // Render
        engine.enableEffect(effect);
        var viewMatrix = this._scene.getViewMatrix();
        effect.setTexture("diffuseSampler", this.particleTexture);
        effect.setMatrix("view", viewMatrix);
        effect.setMatrix("projection", this._scene.getProjectionMatrix());
        if (this._isAnimationSheetEnabled && this.particleTexture) {
            var baseSize = this.particleTexture.getBaseSize();
            effect.setFloat3("particlesInfos", this.spriteCellWidth / baseSize.width, this.spriteCellHeight / baseSize.height, baseSize.width / this.spriteCellWidth);
        }
        effect.setVector2("translationPivot", this.translationPivot);
        effect.setFloat4("textureMask", this.textureMask.r, this.textureMask.g, this.textureMask.b, this.textureMask.a);
        if (this._isBillboardBased) {
            var camera = this._scene.activeCamera;
            effect.setVector3("eyePosition", camera.globalPosition);
        }
        if (this._rampGradientsTexture) {
            effect.setTexture("rampSampler", this._rampGradientsTexture);
        }
        if (this._scene.clipPlane || this._scene.clipPlane2 || this._scene.clipPlane3 || this._scene.clipPlane4) {
            var invView = viewMatrix.clone();
            invView.invert();
            effect.setMatrix("invView", invView);
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_8__["MaterialHelper"].BindClipPlane(effect, this._scene);
        }
        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
        // image processing
        if (this._imageProcessingConfiguration && !this._imageProcessingConfiguration.applyByPostProcess) {
            this._imageProcessingConfiguration.bind(effect);
        }
        // Draw order
        switch (blendMode) {
            case ParticleSystem.BLENDMODE_ADD:
                engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].ALPHA_ADD);
                break;
            case ParticleSystem.BLENDMODE_ONEONE:
                engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].ALPHA_ONEONE);
                break;
            case ParticleSystem.BLENDMODE_STANDARD:
                engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].ALPHA_COMBINE);
                break;
            case ParticleSystem.BLENDMODE_MULTIPLY:
                engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].ALPHA_MULTIPLY);
                break;
        }
        if (this._useInstancing) {
            engine.drawArraysType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFanDrawMode, 0, 4, this._particles.length);
        }
        else {
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFillMode, 0, this._particles.length * 6);
        }
        return this._particles.length;
    };
    /**
     * Renders the particle system in its current state.
     * @returns the current number of particles
     */
    ParticleSystem.prototype.render = function () {
        // Check
        if (!this.isReady() || !this._particles.length) {
            return 0;
        }
        var engine = this._scene.getEngine();
        engine.setState(false);
        if (this.forceDepthWrite) {
            engine.setDepthWrite(true);
        }
        var outparticles = 0;
        if (this.blendMode === ParticleSystem.BLENDMODE_MULTIPLYADD) {
            outparticles = this._render(ParticleSystem.BLENDMODE_MULTIPLY) + this._render(ParticleSystem.BLENDMODE_ADD);
        }
        outparticles = this._render(this.blendMode);
        engine.unbindInstanceAttributes();
        engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].ALPHA_DISABLE);
        return outparticles;
    };
    /**
     * Disposes the particle system and free the associated resources
     * @param disposeTexture defines if the particule texture must be disposed as well (true by default)
     */
    ParticleSystem.prototype.dispose = function (disposeTexture) {
        if (disposeTexture === void 0) { disposeTexture = true; }
        if (this._vertexBuffer) {
            this._vertexBuffer.dispose();
            this._vertexBuffer = null;
        }
        if (this._spriteBuffer) {
            this._spriteBuffer.dispose();
            this._spriteBuffer = null;
        }
        if (this._indexBuffer) {
            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
            this._indexBuffer = null;
        }
        if (disposeTexture && this.particleTexture) {
            this.particleTexture.dispose();
            this.particleTexture = null;
        }
        if (disposeTexture && this.noiseTexture) {
            this.noiseTexture.dispose();
            this.noiseTexture = null;
        }
        if (this._rampGradientsTexture) {
            this._rampGradientsTexture.dispose();
            this._rampGradientsTexture = null;
        }
        this._removeFromRoot();
        if (this._subEmitters && this._subEmitters.length) {
            for (var index = 0; index < this._subEmitters.length; index++) {
                for (var _i = 0, _a = this._subEmitters[index]; _i < _a.length; _i++) {
                    var subEmitter = _a[_i];
                    subEmitter.dispose();
                }
            }
            this._subEmitters = [];
            this.subEmitters = [];
        }
        if (this._disposeEmitterOnDispose && this.emitter && this.emitter.dispose) {
            this.emitter.dispose(true);
        }
        // Remove from scene
        var index = this._scene.particleSystems.indexOf(this);
        if (index > -1) {
            this._scene.particleSystems.splice(index, 1);
        }
        this._scene._activeParticleSystems.dispose();
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
        this.reset();
    };
    // Clone
    /**
     * Clones the particle system.
     * @param name The name of the cloned object
     * @param newEmitter The new emitter to use
     * @returns the cloned particle system
     */
    ParticleSystem.prototype.clone = function (name, newEmitter) {
        var custom = null;
        var program = null;
        if (this.customShader != null) {
            program = this.customShader;
            var defines = (program.shaderOptions.defines.length > 0) ? program.shaderOptions.defines.join("\n") : "";
            custom = this._scene.getEngine().createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);
        }
        else if (this._customEffect) {
            custom = this._customEffect;
        }
        var result = new ParticleSystem(name, this._capacity, this._scene, custom);
        result.customShader = program;
        _Misc_deepCopier__WEBPACK_IMPORTED_MODULE_20__["DeepCopier"].DeepCopy(this, result, ["particles", "customShader", "noiseTexture", "particleTexture", "onDisposeObservable"]);
        if (newEmitter === undefined) {
            newEmitter = this.emitter;
        }
        result.noiseTexture = this.noiseTexture;
        result.emitter = newEmitter;
        if (this.particleTexture) {
            result.particleTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__["Texture"](this.particleTexture.url, this._scene);
        }
        // Clone gradients
        if (this._colorGradients) {
            this._colorGradients.forEach(function (v) {
                result.addColorGradient(v.gradient, v.color1, v.color2);
            });
        }
        if (this._dragGradients) {
            this._dragGradients.forEach(function (v) {
                result.addDragGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._angularSpeedGradients) {
            this._angularSpeedGradients.forEach(function (v) {
                result.addAngularSpeedGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._emitRateGradients) {
            this._emitRateGradients.forEach(function (v) {
                result.addEmitRateGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._lifeTimeGradients) {
            this._lifeTimeGradients.forEach(function (v) {
                result.addLifeTimeGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._limitVelocityGradients) {
            this._limitVelocityGradients.forEach(function (v) {
                result.addLimitVelocityGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._sizeGradients) {
            this._sizeGradients.forEach(function (v) {
                result.addSizeGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._startSizeGradients) {
            this._startSizeGradients.forEach(function (v) {
                result.addStartSizeGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._velocityGradients) {
            this._velocityGradients.forEach(function (v) {
                result.addVelocityGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._rampGradients) {
            this._rampGradients.forEach(function (v) {
                result.addRampGradient(v.gradient, v.color);
            });
        }
        if (this._colorRemapGradients) {
            this._colorRemapGradients.forEach(function (v) {
                result.addColorRemapGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (this._alphaRemapGradients) {
            this._alphaRemapGradients.forEach(function (v) {
                result.addAlphaRemapGradient(v.gradient, v.factor1, v.factor2);
            });
        }
        if (!this.preventAutoStart) {
            result.start();
        }
        return result;
    };
    /**
     * Serializes the particle system to a JSON object.
     * @returns the JSON object
     */
    ParticleSystem.prototype.serialize = function () {
        var serializationObject = {};
        ParticleSystem._Serialize(serializationObject, this);
        serializationObject.textureMask = this.textureMask.asArray();
        serializationObject.customShader = this.customShader;
        serializationObject.preventAutoStart = this.preventAutoStart;
        // SubEmitters
        if (this.subEmitters) {
            serializationObject.subEmitters = [];
            if (!this._subEmitters) {
                this._prepareSubEmitterInternalArray();
            }
            for (var _i = 0, _a = this._subEmitters; _i < _a.length; _i++) {
                var subs = _a[_i];
                var cell = [];
                for (var _b = 0, subs_1 = subs; _b < subs_1.length; _b++) {
                    var sub = subs_1[_b];
                    cell.push(sub.serialize());
                }
                serializationObject.subEmitters.push(cell);
            }
        }
        return serializationObject;
    };
    /** @hidden */
    ParticleSystem._Serialize = function (serializationObject, particleSystem) {
        serializationObject.name = particleSystem.name;
        serializationObject.id = particleSystem.id;
        serializationObject.capacity = particleSystem.getCapacity();
        // Emitter
        if (particleSystem.emitter.position) {
            var emitterMesh = particleSystem.emitter;
            serializationObject.emitterId = emitterMesh.id;
        }
        else {
            var emitterPosition = particleSystem.emitter;
            serializationObject.emitter = emitterPosition.asArray();
        }
        // Emitter
        if (particleSystem.particleEmitterType) {
            serializationObject.particleEmitterType = particleSystem.particleEmitterType.serialize();
        }
        if (particleSystem.particleTexture) {
            serializationObject.textureName = particleSystem.particleTexture.name;
            serializationObject.invertY = particleSystem.particleTexture._invertY;
        }
        // Animations
        _Misc_decorators__WEBPACK_IMPORTED_MODULE_19__["SerializationHelper"].AppendSerializedAnimations(particleSystem, serializationObject);
        serializationObject.beginAnimationOnStart = particleSystem.beginAnimationOnStart;
        serializationObject.beginAnimationFrom = particleSystem.beginAnimationFrom;
        serializationObject.beginAnimationTo = particleSystem.beginAnimationTo;
        serializationObject.beginAnimationLoop = particleSystem.beginAnimationLoop;
        // Particle system
        serializationObject.startDelay = particleSystem.startDelay;
        serializationObject.renderingGroupId = particleSystem.renderingGroupId;
        serializationObject.isBillboardBased = particleSystem.isBillboardBased;
        serializationObject.billboardMode = particleSystem.billboardMode;
        serializationObject.minAngularSpeed = particleSystem.minAngularSpeed;
        serializationObject.maxAngularSpeed = particleSystem.maxAngularSpeed;
        serializationObject.minSize = particleSystem.minSize;
        serializationObject.maxSize = particleSystem.maxSize;
        serializationObject.minScaleX = particleSystem.minScaleX;
        serializationObject.maxScaleX = particleSystem.maxScaleX;
        serializationObject.minScaleY = particleSystem.minScaleY;
        serializationObject.maxScaleY = particleSystem.maxScaleY;
        serializationObject.minEmitPower = particleSystem.minEmitPower;
        serializationObject.maxEmitPower = particleSystem.maxEmitPower;
        serializationObject.minLifeTime = particleSystem.minLifeTime;
        serializationObject.maxLifeTime = particleSystem.maxLifeTime;
        serializationObject.emitRate = particleSystem.emitRate;
        serializationObject.gravity = particleSystem.gravity.asArray();
        serializationObject.noiseStrength = particleSystem.noiseStrength.asArray();
        serializationObject.color1 = particleSystem.color1.asArray();
        serializationObject.color2 = particleSystem.color2.asArray();
        serializationObject.colorDead = particleSystem.colorDead.asArray();
        serializationObject.updateSpeed = particleSystem.updateSpeed;
        serializationObject.targetStopDuration = particleSystem.targetStopDuration;
        serializationObject.blendMode = particleSystem.blendMode;
        serializationObject.preWarmCycles = particleSystem.preWarmCycles;
        serializationObject.preWarmStepOffset = particleSystem.preWarmStepOffset;
        serializationObject.minInitialRotation = particleSystem.minInitialRotation;
        serializationObject.maxInitialRotation = particleSystem.maxInitialRotation;
        serializationObject.startSpriteCellID = particleSystem.startSpriteCellID;
        serializationObject.endSpriteCellID = particleSystem.endSpriteCellID;
        serializationObject.spriteCellChangeSpeed = particleSystem.spriteCellChangeSpeed;
        serializationObject.spriteCellWidth = particleSystem.spriteCellWidth;
        serializationObject.spriteCellHeight = particleSystem.spriteCellHeight;
        serializationObject.spriteRandomStartCell = particleSystem.spriteRandomStartCell;
        serializationObject.isAnimationSheetEnabled = particleSystem.isAnimationSheetEnabled;
        var colorGradients = particleSystem.getColorGradients();
        if (colorGradients) {
            serializationObject.colorGradients = [];
            for (var _i = 0, colorGradients_1 = colorGradients; _i < colorGradients_1.length; _i++) {
                var colorGradient = colorGradients_1[_i];
                var serializedGradient = {
                    gradient: colorGradient.gradient,
                    color1: colorGradient.color1.asArray()
                };
                if (colorGradient.color2) {
                    serializedGradient.color2 = colorGradient.color2.asArray();
                }
                serializationObject.colorGradients.push(serializedGradient);
            }
        }
        var rampGradients = particleSystem.getRampGradients();
        if (rampGradients) {
            serializationObject.rampGradients = [];
            for (var _a = 0, rampGradients_1 = rampGradients; _a < rampGradients_1.length; _a++) {
                var rampGradient = rampGradients_1[_a];
                var serializedGradient = {
                    gradient: rampGradient.gradient,
                    color: rampGradient.color.asArray()
                };
                serializationObject.rampGradients.push(serializedGradient);
            }
            serializationObject.useRampGradients = particleSystem.useRampGradients;
        }
        var colorRemapGradients = particleSystem.getColorRemapGradients();
        if (colorRemapGradients) {
            serializationObject.colorRemapGradients = [];
            for (var _b = 0, colorRemapGradients_1 = colorRemapGradients; _b < colorRemapGradients_1.length; _b++) {
                var colorRemapGradient = colorRemapGradients_1[_b];
                var serializedGradient = {
                    gradient: colorRemapGradient.gradient,
                    factor1: colorRemapGradient.factor1
                };
                if (colorRemapGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = colorRemapGradient.factor2;
                }
                serializationObject.colorRemapGradients.push(serializedGradient);
            }
        }
        var alphaRemapGradients = particleSystem.getAlphaRemapGradients();
        if (alphaRemapGradients) {
            serializationObject.alphaRemapGradients = [];
            for (var _c = 0, alphaRemapGradients_1 = alphaRemapGradients; _c < alphaRemapGradients_1.length; _c++) {
                var alphaRemapGradient = alphaRemapGradients_1[_c];
                var serializedGradient = {
                    gradient: alphaRemapGradient.gradient,
                    factor1: alphaRemapGradient.factor1
                };
                if (alphaRemapGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = alphaRemapGradient.factor2;
                }
                serializationObject.alphaRemapGradients.push(serializedGradient);
            }
        }
        var sizeGradients = particleSystem.getSizeGradients();
        if (sizeGradients) {
            serializationObject.sizeGradients = [];
            for (var _d = 0, sizeGradients_1 = sizeGradients; _d < sizeGradients_1.length; _d++) {
                var sizeGradient = sizeGradients_1[_d];
                var serializedGradient = {
                    gradient: sizeGradient.gradient,
                    factor1: sizeGradient.factor1
                };
                if (sizeGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = sizeGradient.factor2;
                }
                serializationObject.sizeGradients.push(serializedGradient);
            }
        }
        var angularSpeedGradients = particleSystem.getAngularSpeedGradients();
        if (angularSpeedGradients) {
            serializationObject.angularSpeedGradients = [];
            for (var _e = 0, angularSpeedGradients_1 = angularSpeedGradients; _e < angularSpeedGradients_1.length; _e++) {
                var angularSpeedGradient = angularSpeedGradients_1[_e];
                var serializedGradient = {
                    gradient: angularSpeedGradient.gradient,
                    factor1: angularSpeedGradient.factor1
                };
                if (angularSpeedGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = angularSpeedGradient.factor2;
                }
                serializationObject.angularSpeedGradients.push(serializedGradient);
            }
        }
        var velocityGradients = particleSystem.getVelocityGradients();
        if (velocityGradients) {
            serializationObject.velocityGradients = [];
            for (var _f = 0, velocityGradients_1 = velocityGradients; _f < velocityGradients_1.length; _f++) {
                var velocityGradient = velocityGradients_1[_f];
                var serializedGradient = {
                    gradient: velocityGradient.gradient,
                    factor1: velocityGradient.factor1
                };
                if (velocityGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = velocityGradient.factor2;
                }
                serializationObject.velocityGradients.push(serializedGradient);
            }
        }
        var dragGradients = particleSystem.getDragGradients();
        if (dragGradients) {
            serializationObject.dragGradients = [];
            for (var _g = 0, dragGradients_1 = dragGradients; _g < dragGradients_1.length; _g++) {
                var dragGradient = dragGradients_1[_g];
                var serializedGradient = {
                    gradient: dragGradient.gradient,
                    factor1: dragGradient.factor1
                };
                if (dragGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = dragGradient.factor2;
                }
                serializationObject.dragGradients.push(serializedGradient);
            }
        }
        var emitRateGradients = particleSystem.getEmitRateGradients();
        if (emitRateGradients) {
            serializationObject.emitRateGradients = [];
            for (var _h = 0, emitRateGradients_1 = emitRateGradients; _h < emitRateGradients_1.length; _h++) {
                var emitRateGradient = emitRateGradients_1[_h];
                var serializedGradient = {
                    gradient: emitRateGradient.gradient,
                    factor1: emitRateGradient.factor1
                };
                if (emitRateGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = emitRateGradient.factor2;
                }
                serializationObject.emitRateGradients.push(serializedGradient);
            }
        }
        var startSizeGradients = particleSystem.getStartSizeGradients();
        if (startSizeGradients) {
            serializationObject.startSizeGradients = [];
            for (var _j = 0, startSizeGradients_1 = startSizeGradients; _j < startSizeGradients_1.length; _j++) {
                var startSizeGradient = startSizeGradients_1[_j];
                var serializedGradient = {
                    gradient: startSizeGradient.gradient,
                    factor1: startSizeGradient.factor1
                };
                if (startSizeGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = startSizeGradient.factor2;
                }
                serializationObject.startSizeGradients.push(serializedGradient);
            }
        }
        var lifeTimeGradients = particleSystem.getLifeTimeGradients();
        if (lifeTimeGradients) {
            serializationObject.lifeTimeGradients = [];
            for (var _k = 0, lifeTimeGradients_1 = lifeTimeGradients; _k < lifeTimeGradients_1.length; _k++) {
                var lifeTimeGradient = lifeTimeGradients_1[_k];
                var serializedGradient = {
                    gradient: lifeTimeGradient.gradient,
                    factor1: lifeTimeGradient.factor1
                };
                if (lifeTimeGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = lifeTimeGradient.factor2;
                }
                serializationObject.lifeTimeGradients.push(serializedGradient);
            }
        }
        var limitVelocityGradients = particleSystem.getLimitVelocityGradients();
        if (limitVelocityGradients) {
            serializationObject.limitVelocityGradients = [];
            for (var _l = 0, limitVelocityGradients_1 = limitVelocityGradients; _l < limitVelocityGradients_1.length; _l++) {
                var limitVelocityGradient = limitVelocityGradients_1[_l];
                var serializedGradient = {
                    gradient: limitVelocityGradient.gradient,
                    factor1: limitVelocityGradient.factor1
                };
                if (limitVelocityGradient.factor2 !== undefined) {
                    serializedGradient.factor2 = limitVelocityGradient.factor2;
                }
                serializationObject.limitVelocityGradients.push(serializedGradient);
            }
            serializationObject.limitVelocityDamping = particleSystem.limitVelocityDamping;
        }
        if (particleSystem.noiseTexture) {
            serializationObject.noiseTexture = particleSystem.noiseTexture.serialize();
        }
    };
    /** @hidden */
    ParticleSystem._Parse = function (parsedParticleSystem, particleSystem, scene, rootUrl) {
        // Texture
        if (parsedParticleSystem.textureName) {
            particleSystem.particleTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__["Texture"](rootUrl + parsedParticleSystem.textureName, scene, false, parsedParticleSystem.invertY !== undefined ? parsedParticleSystem.invertY : true);
            particleSystem.particleTexture.name = parsedParticleSystem.textureName;
        }
        // Emitter
        if (!parsedParticleSystem.emitterId && parsedParticleSystem.emitterId !== 0 && parsedParticleSystem.emitter === undefined) {
            particleSystem.emitter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        }
        else if (parsedParticleSystem.emitterId) {
            particleSystem.emitter = scene.getLastMeshByID(parsedParticleSystem.emitterId);
        }
        else {
            particleSystem.emitter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].FromArray(parsedParticleSystem.emitter);
        }
        // Misc.
        if (parsedParticleSystem.renderingGroupId !== undefined) {
            particleSystem.renderingGroupId = parsedParticleSystem.renderingGroupId;
        }
        if (parsedParticleSystem.isBillboardBased !== undefined) {
            particleSystem.isBillboardBased = parsedParticleSystem.isBillboardBased;
        }
        if (parsedParticleSystem.billboardMode !== undefined) {
            particleSystem.billboardMode = parsedParticleSystem.billboardMode;
        }
        // Animations
        if (parsedParticleSystem.animations) {
            for (var animationIndex = 0; animationIndex < parsedParticleSystem.animations.length; animationIndex++) {
                var parsedAnimation = parsedParticleSystem.animations[animationIndex];
                var internalClass = _Misc_typeStore__WEBPACK_IMPORTED_MODULE_21__["_TypeStore"].GetClass("BABYLON.Animation");
                if (internalClass) {
                    particleSystem.animations.push(internalClass.Parse(parsedAnimation));
                }
            }
            particleSystem.beginAnimationOnStart = parsedParticleSystem.beginAnimationOnStart;
            particleSystem.beginAnimationFrom = parsedParticleSystem.beginAnimationFrom;
            particleSystem.beginAnimationTo = parsedParticleSystem.beginAnimationTo;
            particleSystem.beginAnimationLoop = parsedParticleSystem.beginAnimationLoop;
        }
        if (parsedParticleSystem.autoAnimate) {
            scene.beginAnimation(particleSystem, parsedParticleSystem.autoAnimateFrom, parsedParticleSystem.autoAnimateTo, parsedParticleSystem.autoAnimateLoop, parsedParticleSystem.autoAnimateSpeed || 1.0);
        }
        // Particle system
        particleSystem.startDelay = parsedParticleSystem.startDelay | 0;
        particleSystem.minAngularSpeed = parsedParticleSystem.minAngularSpeed;
        particleSystem.maxAngularSpeed = parsedParticleSystem.maxAngularSpeed;
        particleSystem.minSize = parsedParticleSystem.minSize;
        particleSystem.maxSize = parsedParticleSystem.maxSize;
        if (parsedParticleSystem.minScaleX) {
            particleSystem.minScaleX = parsedParticleSystem.minScaleX;
            particleSystem.maxScaleX = parsedParticleSystem.maxScaleX;
            particleSystem.minScaleY = parsedParticleSystem.minScaleY;
            particleSystem.maxScaleY = parsedParticleSystem.maxScaleY;
        }
        if (parsedParticleSystem.preWarmCycles !== undefined) {
            particleSystem.preWarmCycles = parsedParticleSystem.preWarmCycles;
            particleSystem.preWarmStepOffset = parsedParticleSystem.preWarmStepOffset;
        }
        if (parsedParticleSystem.minInitialRotation !== undefined) {
            particleSystem.minInitialRotation = parsedParticleSystem.minInitialRotation;
            particleSystem.maxInitialRotation = parsedParticleSystem.maxInitialRotation;
        }
        particleSystem.minLifeTime = parsedParticleSystem.minLifeTime;
        particleSystem.maxLifeTime = parsedParticleSystem.maxLifeTime;
        particleSystem.minEmitPower = parsedParticleSystem.minEmitPower;
        particleSystem.maxEmitPower = parsedParticleSystem.maxEmitPower;
        particleSystem.emitRate = parsedParticleSystem.emitRate;
        particleSystem.gravity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].FromArray(parsedParticleSystem.gravity);
        if (parsedParticleSystem.noiseStrength) {
            particleSystem.noiseStrength = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].FromArray(parsedParticleSystem.noiseStrength);
        }
        particleSystem.color1 = _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].FromArray(parsedParticleSystem.color1);
        particleSystem.color2 = _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].FromArray(parsedParticleSystem.color2);
        particleSystem.colorDead = _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].FromArray(parsedParticleSystem.colorDead);
        particleSystem.updateSpeed = parsedParticleSystem.updateSpeed;
        particleSystem.targetStopDuration = parsedParticleSystem.targetStopDuration;
        particleSystem.blendMode = parsedParticleSystem.blendMode;
        if (parsedParticleSystem.colorGradients) {
            for (var _i = 0, _a = parsedParticleSystem.colorGradients; _i < _a.length; _i++) {
                var colorGradient = _a[_i];
                particleSystem.addColorGradient(colorGradient.gradient, _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].FromArray(colorGradient.color1), colorGradient.color2 ? _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].FromArray(colorGradient.color2) : undefined);
            }
        }
        if (parsedParticleSystem.rampGradients) {
            for (var _b = 0, _c = parsedParticleSystem.rampGradients; _b < _c.length; _b++) {
                var rampGradient = _c[_b];
                particleSystem.addRampGradient(rampGradient.gradient, _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color3"].FromArray(rampGradient.color));
            }
            particleSystem.useRampGradients = parsedParticleSystem.useRampGradients;
        }
        if (parsedParticleSystem.colorRemapGradients) {
            for (var _d = 0, _e = parsedParticleSystem.colorRemapGradients; _d < _e.length; _d++) {
                var colorRemapGradient = _e[_d];
                particleSystem.addColorRemapGradient(colorRemapGradient.gradient, colorRemapGradient.factor1 !== undefined ? colorRemapGradient.factor1 : colorRemapGradient.factor, colorRemapGradient.factor2);
            }
        }
        if (parsedParticleSystem.alphaRemapGradients) {
            for (var _f = 0, _g = parsedParticleSystem.alphaRemapGradients; _f < _g.length; _f++) {
                var alphaRemapGradient = _g[_f];
                particleSystem.addAlphaRemapGradient(alphaRemapGradient.gradient, alphaRemapGradient.factor1 !== undefined ? alphaRemapGradient.factor1 : alphaRemapGradient.factor, alphaRemapGradient.factor2);
            }
        }
        if (parsedParticleSystem.sizeGradients) {
            for (var _h = 0, _j = parsedParticleSystem.sizeGradients; _h < _j.length; _h++) {
                var sizeGradient = _j[_h];
                particleSystem.addSizeGradient(sizeGradient.gradient, sizeGradient.factor1 !== undefined ? sizeGradient.factor1 : sizeGradient.factor, sizeGradient.factor2);
            }
        }
        if (parsedParticleSystem.angularSpeedGradients) {
            for (var _k = 0, _l = parsedParticleSystem.angularSpeedGradients; _k < _l.length; _k++) {
                var angularSpeedGradient = _l[_k];
                particleSystem.addAngularSpeedGradient(angularSpeedGradient.gradient, angularSpeedGradient.factor1 !== undefined ? angularSpeedGradient.factor1 : angularSpeedGradient.factor, angularSpeedGradient.factor2);
            }
        }
        if (parsedParticleSystem.velocityGradients) {
            for (var _m = 0, _o = parsedParticleSystem.velocityGradients; _m < _o.length; _m++) {
                var velocityGradient = _o[_m];
                particleSystem.addVelocityGradient(velocityGradient.gradient, velocityGradient.factor1 !== undefined ? velocityGradient.factor1 : velocityGradient.factor, velocityGradient.factor2);
            }
        }
        if (parsedParticleSystem.dragGradients) {
            for (var _p = 0, _q = parsedParticleSystem.dragGradients; _p < _q.length; _p++) {
                var dragGradient = _q[_p];
                particleSystem.addDragGradient(dragGradient.gradient, dragGradient.factor1 !== undefined ? dragGradient.factor1 : dragGradient.factor, dragGradient.factor2);
            }
        }
        if (parsedParticleSystem.emitRateGradients) {
            for (var _r = 0, _s = parsedParticleSystem.emitRateGradients; _r < _s.length; _r++) {
                var emitRateGradient = _s[_r];
                particleSystem.addEmitRateGradient(emitRateGradient.gradient, emitRateGradient.factor1 !== undefined ? emitRateGradient.factor1 : emitRateGradient.factor, emitRateGradient.factor2);
            }
        }
        if (parsedParticleSystem.startSizeGradients) {
            for (var _t = 0, _u = parsedParticleSystem.startSizeGradients; _t < _u.length; _t++) {
                var startSizeGradient = _u[_t];
                particleSystem.addStartSizeGradient(startSizeGradient.gradient, startSizeGradient.factor1 !== undefined ? startSizeGradient.factor1 : startSizeGradient.factor, startSizeGradient.factor2);
            }
        }
        if (parsedParticleSystem.lifeTimeGradients) {
            for (var _v = 0, _w = parsedParticleSystem.lifeTimeGradients; _v < _w.length; _v++) {
                var lifeTimeGradient = _w[_v];
                particleSystem.addLifeTimeGradient(lifeTimeGradient.gradient, lifeTimeGradient.factor1 !== undefined ? lifeTimeGradient.factor1 : lifeTimeGradient.factor, lifeTimeGradient.factor2);
            }
        }
        if (parsedParticleSystem.limitVelocityGradients) {
            for (var _x = 0, _y = parsedParticleSystem.limitVelocityGradients; _x < _y.length; _x++) {
                var limitVelocityGradient = _y[_x];
                particleSystem.addLimitVelocityGradient(limitVelocityGradient.gradient, limitVelocityGradient.factor1 !== undefined ? limitVelocityGradient.factor1 : limitVelocityGradient.factor, limitVelocityGradient.factor2);
            }
            particleSystem.limitVelocityDamping = parsedParticleSystem.limitVelocityDamping;
        }
        if (parsedParticleSystem.noiseTexture) {
            particleSystem.noiseTexture = _Materials_Textures_Procedurals_proceduralTexture__WEBPACK_IMPORTED_MODULE_12__["ProceduralTexture"].Parse(parsedParticleSystem.noiseTexture, scene, rootUrl);
        }
        // Emitter
        var emitterType;
        if (parsedParticleSystem.particleEmitterType) {
            switch (parsedParticleSystem.particleEmitterType.type) {
                case "SphereParticleEmitter":
                    emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["SphereParticleEmitter"]();
                    break;
                case "SphereDirectedParticleEmitter":
                    emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["SphereDirectedParticleEmitter"]();
                    break;
                case "ConeEmitter":
                case "ConeParticleEmitter":
                    emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["ConeParticleEmitter"]();
                    break;
                case "CylinderParticleEmitter":
                    emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["CylinderParticleEmitter"]();
                    break;
                case "HemisphericParticleEmitter":
                    emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["HemisphericParticleEmitter"]();
                    break;
                case "BoxEmitter":
                case "BoxParticleEmitter":
                default:
                    emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["BoxParticleEmitter"]();
                    break;
            }
            emitterType.parse(parsedParticleSystem.particleEmitterType);
        }
        else {
            emitterType = new _Particles_EmitterTypes_index__WEBPACK_IMPORTED_MODULE_14__["BoxParticleEmitter"]();
            emitterType.parse(parsedParticleSystem);
        }
        particleSystem.particleEmitterType = emitterType;
        // Animation sheet
        particleSystem.startSpriteCellID = parsedParticleSystem.startSpriteCellID;
        particleSystem.endSpriteCellID = parsedParticleSystem.endSpriteCellID;
        particleSystem.spriteCellWidth = parsedParticleSystem.spriteCellWidth;
        particleSystem.spriteCellHeight = parsedParticleSystem.spriteCellHeight;
        particleSystem.spriteCellChangeSpeed = parsedParticleSystem.spriteCellChangeSpeed;
        particleSystem.spriteRandomStartCell = parsedParticleSystem.spriteRandomStartCell;
    };
    /**
     * Parses a JSON object to create a particle system.
     * @param parsedParticleSystem The JSON object to parse
     * @param scene The scene to create the particle system in
     * @param rootUrl The root url to use to load external dependencies like texture
     * @param doNotStart Ignore the preventAutoStart attribute and does not start
     * @returns the Parsed particle system
     */
    ParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl, doNotStart) {
        if (doNotStart === void 0) { doNotStart = false; }
        var name = parsedParticleSystem.name;
        var custom = null;
        var program = null;
        if (parsedParticleSystem.customShader) {
            program = parsedParticleSystem.customShader;
            var defines = (program.shaderOptions.defines.length > 0) ? program.shaderOptions.defines.join("\n") : "";
            custom = scene.getEngine().createEffectForParticles(program.shaderPath.fragmentElement, program.shaderOptions.uniforms, program.shaderOptions.samplers, defines);
        }
        var particleSystem = new ParticleSystem(name, parsedParticleSystem.capacity, scene, custom, parsedParticleSystem.isAnimationSheetEnabled);
        particleSystem.customShader = program;
        if (parsedParticleSystem.id) {
            particleSystem.id = parsedParticleSystem.id;
        }
        // SubEmitters
        if (parsedParticleSystem.subEmitters) {
            particleSystem.subEmitters = [];
            for (var _i = 0, _a = parsedParticleSystem.subEmitters; _i < _a.length; _i++) {
                var cell = _a[_i];
                var cellArray = [];
                for (var _b = 0, cell_1 = cell; _b < cell_1.length; _b++) {
                    var sub = cell_1[_b];
                    cellArray.push(_subEmitter__WEBPACK_IMPORTED_MODULE_17__["SubEmitter"].Parse(sub, scene, rootUrl));
                }
                particleSystem.subEmitters.push(cellArray);
            }
        }
        ParticleSystem._Parse(parsedParticleSystem, particleSystem, scene, rootUrl);
        particleSystem.textureMask = _Maths_math_color__WEBPACK_IMPORTED_MODULE_24__["Color4"].FromArray(parsedParticleSystem.textureMask);
        // Auto start
        if (parsedParticleSystem.preventAutoStart) {
            particleSystem.preventAutoStart = parsedParticleSystem.preventAutoStart;
        }
        if (!doNotStart && !particleSystem.preventAutoStart) {
            particleSystem.start();
        }
        return particleSystem;
    };
    /**
     * Billboard mode will only apply to Y axis
     */
    ParticleSystem.BILLBOARDMODE_Y = _Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].PARTICLES_BILLBOARDMODE_Y;
    /**
     * Billboard mode will apply to all axes
     */
    ParticleSystem.BILLBOARDMODE_ALL = _Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].PARTICLES_BILLBOARDMODE_ALL;
    /**
     * Special billboard mode where the particle will be biilboard to the camera but rotated to align with direction
     */
    ParticleSystem.BILLBOARDMODE_STRETCHED = _Engines_constants__WEBPACK_IMPORTED_MODULE_18__["Constants"].PARTICLES_BILLBOARDMODE_STRETCHED;
    return ParticleSystem;
}(_baseParticleSystem__WEBPACK_IMPORTED_MODULE_15__["BaseParticleSystem"]));

_subEmitter__WEBPACK_IMPORTED_MODULE_17__["SubEmitter"]._ParseParticleSystem = ParticleSystem.Parse;


/***/ }),

/***/ "./Particles/particleSystemComponent.ts":
/*!**********************************************!*\
  !*** ./Particles/particleSystemComponent.ts ***!
  \**********************************************/
/*! exports provided: _IDoNeedToBeInTheBuild */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_IDoNeedToBeInTheBuild", function() { return _IDoNeedToBeInTheBuild; });
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./gpuParticleSystem */ "./Particles/gpuParticleSystem.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _particleSystem__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./particleSystem */ "./Particles/particleSystem.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Shaders_particles_vertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Shaders/particles.vertex */ "./Shaders/particles.vertex.ts");







// Adds the parsers to the scene parsers.
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].AddParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_5__["SceneComponentConstants"].NAME_PARTICLESYSTEM, function (parsedData, scene, container, rootUrl) {
    var individualParser = _abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].GetIndividualParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_5__["SceneComponentConstants"].NAME_PARTICLESYSTEM);
    if (!individualParser) {
        return;
    }
    // Particles Systems
    if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {
        for (var index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {
            var parsedParticleSystem = parsedData.particleSystems[index];
            container.particleSystems.push(individualParser(parsedParticleSystem, scene, rootUrl));
        }
    }
});
_abstractScene__WEBPACK_IMPORTED_MODULE_2__["AbstractScene"].AddIndividualParser(_sceneComponent__WEBPACK_IMPORTED_MODULE_5__["SceneComponentConstants"].NAME_PARTICLESYSTEM, function (parsedParticleSystem, scene, rootUrl) {
    if (parsedParticleSystem.activeParticleCount) {
        var ps = _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_1__["GPUParticleSystem"].Parse(parsedParticleSystem, scene, rootUrl);
        return ps;
    }
    else {
        var ps = _particleSystem__WEBPACK_IMPORTED_MODULE_4__["ParticleSystem"].Parse(parsedParticleSystem, scene, rootUrl);
        return ps;
    }
});
_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].prototype.createEffectForParticles = function (fragmentName, uniformsNames, samplers, defines, fallbacks, onCompiled, onError) {
    if (uniformsNames === void 0) { uniformsNames = []; }
    if (samplers === void 0) { samplers = []; }
    if (defines === void 0) { defines = ""; }
    var attributesNamesOrOptions = _particleSystem__WEBPACK_IMPORTED_MODULE_4__["ParticleSystem"]._GetAttributeNamesOrOptions();
    var effectCreationOption = _particleSystem__WEBPACK_IMPORTED_MODULE_4__["ParticleSystem"]._GetEffectCreationOptions();
    if (defines.indexOf(" BILLBOARD") === -1) {
        defines += "\n#define BILLBOARD\n";
    }
    if (samplers.indexOf("diffuseSampler") === -1) {
        samplers.push("diffuseSampler");
    }
    return this.createEffect({
        vertex: "particles",
        fragmentElement: fragmentName
    }, attributesNamesOrOptions, effectCreationOption.concat(uniformsNames), samplers, defines, fallbacks, onCompiled, onError);
};
_Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].prototype.getEmittedParticleSystems = function () {
    var results = new Array();
    for (var index = 0; index < this.getScene().particleSystems.length; index++) {
        var particleSystem = this.getScene().particleSystems[index];
        if (particleSystem.emitter === this) {
            results.push(particleSystem);
        }
    }
    return results;
};
_Meshes_mesh__WEBPACK_IMPORTED_MODULE_0__["Mesh"].prototype.getHierarchyEmittedParticleSystems = function () {
    var results = new Array();
    var descendants = this.getDescendants();
    descendants.push(this);
    for (var index = 0; index < this.getScene().particleSystems.length; index++) {
        var particleSystem = this.getScene().particleSystems[index];
        var emitter = particleSystem.emitter;
        if (emitter.position && descendants.indexOf(emitter) !== -1) {
            results.push(particleSystem);
        }
    }
    return results;
};
/**
 * @hidden
 */
var _IDoNeedToBeInTheBuild = 42;


/***/ }),

/***/ "./Particles/particleSystemSet.ts":
/*!****************************************!*\
  !*** ./Particles/particleSystemSet.ts ***!
  \****************************************/
/*! exports provided: ParticleSystemSet */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ParticleSystemSet", function() { return ParticleSystemSet; });
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./gpuParticleSystem */ "./Particles/gpuParticleSystem.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Particles_particleSystem__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Particles/particleSystem */ "./Particles/particleSystem.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");







/** Internal class used to store shapes for emitters */
var ParticleSystemSetEmitterCreationOptions = /** @class */ (function () {
    function ParticleSystemSetEmitterCreationOptions() {
    }
    return ParticleSystemSetEmitterCreationOptions;
}());
/**
 * Represents a set of particle systems working together to create a specific effect
 */
var ParticleSystemSet = /** @class */ (function () {
    function ParticleSystemSet() {
        /**
         * Gets the particle system list
         */
        this.systems = new Array();
    }
    Object.defineProperty(ParticleSystemSet.prototype, "emitterNode", {
        /**
         * Gets the emitter node used with this set
         */
        get: function () {
            return this._emitterNode;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Creates a new emitter mesh as a sphere
     * @param options defines the options used to create the sphere
     * @param renderingGroupId defines the renderingGroupId to use for the sphere
     * @param scene defines the hosting scene
     */
    ParticleSystemSet.prototype.setEmitterAsSphere = function (options, renderingGroupId, scene) {
        if (this._emitterNode) {
            this._emitterNode.dispose();
        }
        this._emitterCreationOptions = {
            kind: "Sphere",
            options: options,
            renderingGroupId: renderingGroupId
        };
        var emitterMesh = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_1__["SphereBuilder"].CreateSphere("emitterSphere", { diameter: options.diameter, segments: options.segments }, scene);
        emitterMesh.renderingGroupId = renderingGroupId;
        var material = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_5__["StandardMaterial"]("emitterSphereMaterial", scene);
        material.emissiveColor = options.color;
        emitterMesh.material = material;
        for (var _i = 0, _a = this.systems; _i < _a.length; _i++) {
            var system = _a[_i];
            system.emitter = emitterMesh;
        }
        this._emitterNode = emitterMesh;
    };
    /**
     * Starts all particle systems of the set
     * @param emitter defines an optional mesh to use as emitter for the particle systems
     */
    ParticleSystemSet.prototype.start = function (emitter) {
        for (var _i = 0, _a = this.systems; _i < _a.length; _i++) {
            var system = _a[_i];
            if (emitter) {
                system.emitter = emitter;
            }
            system.start();
        }
    };
    /**
     * Release all associated resources
     */
    ParticleSystemSet.prototype.dispose = function () {
        for (var _i = 0, _a = this.systems; _i < _a.length; _i++) {
            var system = _a[_i];
            system.dispose();
        }
        this.systems = [];
        if (this._emitterNode) {
            this._emitterNode.dispose();
            this._emitterNode = null;
        }
    };
    /**
     * Serialize the set into a JSON compatible object
     * @returns a JSON compatible representation of the set
     */
    ParticleSystemSet.prototype.serialize = function () {
        var result = {};
        result.systems = [];
        for (var _i = 0, _a = this.systems; _i < _a.length; _i++) {
            var system = _a[_i];
            result.systems.push(system.serialize());
        }
        if (this._emitterNode) {
            result.emitter = this._emitterCreationOptions;
        }
        return result;
    };
    /**
     * Parse a new ParticleSystemSet from a serialized source
     * @param data defines a JSON compatible representation of the set
     * @param scene defines the hosting scene
     * @param gpu defines if we want GPU particles or CPU particles
     * @returns a new ParticleSystemSet
     */
    ParticleSystemSet.Parse = function (data, scene, gpu) {
        if (gpu === void 0) { gpu = false; }
        var result = new ParticleSystemSet();
        var rootUrl = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].PARTICLES_BaseAssetsUrl + "/textures/";
        scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__["EngineStore"].LastCreatedScene;
        for (var _i = 0, _a = data.systems; _i < _a.length; _i++) {
            var system = _a[_i];
            result.systems.push(gpu ? _gpuParticleSystem__WEBPACK_IMPORTED_MODULE_2__["GPUParticleSystem"].Parse(system, scene, rootUrl, true) : _Particles_particleSystem__WEBPACK_IMPORTED_MODULE_4__["ParticleSystem"].Parse(system, scene, rootUrl, true));
        }
        if (data.emitter) {
            var options = data.emitter.options;
            switch (data.emitter.kind) {
                case "Sphere":
                    result.setEmitterAsSphere({
                        diameter: options.diameter,
                        segments: options.segments,
                        color: _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(options.color)
                    }, data.emitter.renderingGroupId, scene);
                    break;
            }
        }
        return result;
    };
    return ParticleSystemSet;
}());



/***/ }),

/***/ "./Particles/solidParticle.ts":
/*!************************************!*\
  !*** ./Particles/solidParticle.ts ***!
  \************************************/
/*! exports provided: SolidParticle, ModelShape, DepthSortedParticle */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SolidParticle", function() { return SolidParticle; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ModelShape", function() { return ModelShape; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthSortedParticle", function() { return DepthSortedParticle; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Culling/boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony import */ var _Culling_boundingSphere__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Culling/boundingSphere */ "./Culling/boundingSphere.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");





/**
 * Represents one particle of a solid particle system.
 */
var SolidParticle = /** @class */ (function () {
    /**
     * Creates a Solid Particle object.
     * Don't create particles manually, use instead the Solid Particle System internal tools like _addParticle()
     * @param particleIndex (integer) is the particle index in the Solid Particle System pool. It's also the particle identifier.
     * @param positionIndex (integer) is the starting index of the particle vertices in the SPS "positions" array.
     * @param indiceIndex (integer) is the starting index of the particle indices in the SPS "indices" array.
     * @param model (ModelShape) is a reference to the model shape on what the particle is designed.
     * @param shapeId (integer) is the model shape identifier in the SPS.
     * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
     * @param sps defines the sps it is associated to
     * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
     */
    function SolidParticle(particleIndex, positionIndex, indiceIndex, model, shapeId, idxInShape, sps, modelBoundingInfo) {
        if (modelBoundingInfo === void 0) { modelBoundingInfo = null; }
        /**
         * particle global index
         */
        this.idx = 0;
        /**
         * The color of the particle
         */
        this.color = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1.0, 1.0, 1.0, 1.0);
        /**
         * The world space position of the particle.
         */
        this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The world space rotation of the particle. (Not use if rotationQuaternion is set)
         */
        this.rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The scaling of the particle.
         */
        this.scaling = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].One();
        /**
         * The uvs of the particle.
         */
        this.uvs = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector4"](0.0, 0.0, 1.0, 1.0);
        /**
         * The current speed of the particle.
         */
        this.velocity = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * The pivot point in the particle local space.
         */
        this.pivot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        /**
         * Must the particle be translated from its pivot point in its local space ?
         * In this case, the pivot point is set at the origin of the particle local space and the particle is translated.
         * Default : false
         */
        this.translateFromPivot = false;
        /**
         * Is the particle active or not ?
         */
        this.alive = true;
        /**
         * Is the particle visible or not ?
         */
        this.isVisible = true;
        /**
         * Index of this particle in the global "positions" array (Internal use)
         * @hidden
         */
        this._pos = 0;
        /**
         * @hidden Index of this particle in the global "indices" array (Internal use)
         */
        this._ind = 0;
        /**
         * ModelShape id of this particle
         */
        this.shapeId = 0;
        /**
         * Index of the particle in its shape id
         */
        this.idxInShape = 0;
        /**
         * @hidden Still set as invisible in order to skip useless computations (Internal use)
         */
        this._stillInvisible = false;
        /**
         * @hidden Last computed particle rotation matrix
         */
        this._rotationMatrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
        /**
         * Parent particle Id, if any.
         * Default null.
         */
        this.parentId = null;
        /**
         * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
         * The possible values are :
         * - AbstractMesh.CULLINGSTRATEGY_STANDARD
         * - AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY
         * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION
         * - AbstractMesh.CULLINGSTRATEGY_OPTIMISTIC_INCLUSION_THEN_BSPHERE_ONLY
         * The default value for solid particles is AbstractMesh.CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY
         * Please read each static variable documentation in the class AbstractMesh to get details about the culling process.
         * */
        this.cullingStrategy = _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_4__["AbstractMesh"].CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY;
        /**
         * @hidden Internal global position in the SPS.
         */
        this._globalPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this.idx = particleIndex;
        this._pos = positionIndex;
        this._ind = indiceIndex;
        this._model = model;
        this.shapeId = shapeId;
        this.idxInShape = idxInShape;
        this._sps = sps;
        if (modelBoundingInfo) {
            this._modelBoundingInfo = modelBoundingInfo;
            this._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_2__["BoundingInfo"](modelBoundingInfo.minimum, modelBoundingInfo.maximum);
        }
    }
    Object.defineProperty(SolidParticle.prototype, "scale", {
        /**
         * Legacy support, changed scale to scaling
         */
        get: function () {
            return this.scaling;
        },
        /**
         * Legacy support, changed scale to scaling
         */
        set: function (scale) {
            this.scaling = scale;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticle.prototype, "quaternion", {
        /**
         * Legacy support, changed quaternion to rotationQuaternion
         */
        get: function () {
            return this.rotationQuaternion;
        },
        /**
         * Legacy support, changed quaternion to rotationQuaternion
         */
        set: function (q) {
            this.rotationQuaternion = q;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns a boolean. True if the particle intersects another particle or another mesh, else false.
     * The intersection is computed on the particle bounding sphere and Axis Aligned Bounding Box (AABB)
     * @param target is the object (solid particle or mesh) what the intersection is computed against.
     * @returns true if it intersects
     */
    SolidParticle.prototype.intersectsMesh = function (target) {
        if (!this._boundingInfo || !target._boundingInfo) {
            return false;
        }
        if (this._sps._bSphereOnly) {
            return _Culling_boundingSphere__WEBPACK_IMPORTED_MODULE_3__["BoundingSphere"].Intersects(this._boundingInfo.boundingSphere, target._boundingInfo.boundingSphere);
        }
        return this._boundingInfo.intersects(target._boundingInfo, false);
    };
    /**
     * Returns `true` if the solid particle is within the frustum defined by the passed array of planes.
     * A particle is in the frustum if its bounding box intersects the frustum
     * @param frustumPlanes defines the frustum to test
     * @returns true if the particle is in the frustum planes
     */
    SolidParticle.prototype.isInFrustum = function (frustumPlanes) {
        return this._boundingInfo !== null && this._boundingInfo.isInFrustum(frustumPlanes, this.cullingStrategy);
    };
    /**
     * get the rotation matrix of the particle
     * @hidden
     */
    SolidParticle.prototype.getRotationMatrix = function (m) {
        var quaternion;
        if (this.rotationQuaternion) {
            quaternion = this.rotationQuaternion;
        }
        else {
            quaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Quaternion[0];
            var rotation = this.rotation;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);
        }
        quaternion.toRotationMatrix(m);
    };
    return SolidParticle;
}());

/**
 * Represents the shape of the model used by one particle of a solid particle system.
 * SPS internal tool, don't use it manually.
 */
var ModelShape = /** @class */ (function () {
    /**
     * Creates a ModelShape object. This is an internal simplified reference to a mesh used as for a model to replicate particles from by the SPS.
     * SPS internal tool, don't use it manually.
     * @hidden
     */
    function ModelShape(id, shape, indicesLength, shapeUV, posFunction, vtxFunction) {
        /**
         * length of the shape in the model indices array (internal use)
         * @hidden
         */
        this._indicesLength = 0;
        this.shapeID = id;
        this._shape = shape;
        this._indicesLength = indicesLength;
        this._shapeUV = shapeUV;
        this._positionFunction = posFunction;
        this._vertexFunction = vtxFunction;
    }
    return ModelShape;
}());

/**
 * Represents a Depth Sorted Particle in the solid particle system.
 */
var DepthSortedParticle = /** @class */ (function () {
    function DepthSortedParticle() {
        /**
         * Index of the particle in the "indices" array
         */
        this.ind = 0;
        /**
         * Length of the particle shape in the "indices" array
         */
        this.indicesLength = 0;
        /**
         * Squared distance from the particle to the camera
         */
        this.sqDistance = 0.0;
    }
    return DepthSortedParticle;
}());



/***/ }),

/***/ "./Particles/solidParticleSystem.ts":
/*!******************************************!*\
  !*** ./Particles/solidParticleSystem.ts ***!
  \******************************************/
/*! exports provided: SolidParticleSystem */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SolidParticleSystem", function() { return SolidParticleSystem; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Meshes_Builders_discBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/Builders/discBuilder */ "./Meshes/Builders/discBuilder.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _solidParticle__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./solidParticle */ "./Particles/solidParticle.ts");
/* harmony import */ var _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Culling/boundingInfo */ "./Culling/boundingInfo.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");










var depthSortFunction = function (p1, p2) { return p2.sqDistance - p1.sqDistance; };
/**
 * The SPS is a single updatable mesh. The solid particles are simply separate parts or faces fo this big mesh.
 *As it is just a mesh, the SPS has all the same properties than any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.

 * The SPS is also a particle system. It provides some methods to manage the particles.
 * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.
 *
 * Full documentation here : http://doc.babylonjs.com/how_to/Solid_Particle_System
 */
var SolidParticleSystem = /** @class */ (function () {
    /**
     * Creates a SPS (Solid Particle System) object.
     * @param name (String) is the SPS name, this will be the underlying mesh name.
     * @param scene (Scene) is the scene in which the SPS is added.
     * @param options defines the options of the sps e.g.
     * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
     * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
     * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
     * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
     * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
     * * bSphereRadiusFactor (optional float, default 1.0) : a number to multiply the boundind sphere radius by in order to reduce it for instance.
     * @example bSphereRadiusFactor = 1.0 / Math.sqrt(3.0) => the bounding sphere exactly matches a spherical mesh.
     */
    function SolidParticleSystem(name, scene, options) {
        /**
         *  The SPS array of Solid Particle objects. Just access each particle as with any classic array.
         *  Example : var p = SPS.particles[i];
         */
        this.particles = new Array();
        /**
         * The SPS total number of particles. Read only. Use SPS.counter instead if you need to set your own value.
         */
        this.nbParticles = 0;
        /**
         * If the particles must ever face the camera (default false). Useful for planar particles.
         */
        this.billboard = false;
        /**
         * Recompute normals when adding a shape
         */
        this.recomputeNormals = true;
        /**
         * This a counter ofr your own usage. It's not set by any SPS functions.
         */
        this.counter = 0;
        /**
         * This empty object is intended to store some SPS specific or temporary values in order to lower the Garbage Collector activity.
         * Please read : http://doc.babylonjs.com/how_to/Solid_Particle_System#garbage-collector-concerns
         */
        this.vars = {};
        /**
         * If the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster). (Internal use only)
         * @hidden
         */
        this._bSphereOnly = false;
        /**
         * A number to multiply the boundind sphere radius by in order to reduce it for instance. (Internal use only)
         * @hidden
         */
        this._bSphereRadiusFactor = 1.0;
        this._positions = new Array();
        this._indices = new Array();
        this._normals = new Array();
        this._colors = new Array();
        this._uvs = new Array();
        this._index = 0; // indices index
        this._updatable = true;
        this._pickable = false;
        this._isVisibilityBoxLocked = false;
        this._alwaysVisible = false;
        this._depthSort = false;
        this._shapeCounter = 0;
        this._copy = new _solidParticle__WEBPACK_IMPORTED_MODULE_7__["SolidParticle"](0, 0, 0, null, 0, 0, this);
        this._color = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](0, 0, 0, 0);
        this._computeParticleColor = true;
        this._computeParticleTexture = true;
        this._computeParticleRotation = true;
        this._computeParticleVertex = false;
        this._computeBoundingBox = false;
        this._depthSortParticles = true;
        this._mustUnrotateFixedNormals = false;
        this._particlesIntersect = false;
        this._needs32Bits = false;
        this.name = name;
        this._scene = scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_6__["EngineStore"].LastCreatedScene;
        this._camera = scene.activeCamera;
        this._pickable = options ? options.isPickable : false;
        this._depthSort = options ? options.enableDepthSort : false;
        this._particlesIntersect = options ? options.particleIntersection : false;
        this._bSphereOnly = options ? options.boundingSphereOnly : false;
        this._bSphereRadiusFactor = (options && options.bSphereRadiusFactor) ? options.bSphereRadiusFactor : 1.0;
        if (options && options.updatable !== undefined) {
            this._updatable = options.updatable;
        }
        else {
            this._updatable = true;
        }
        if (this._pickable) {
            this.pickedParticles = [];
        }
        if (this._depthSort) {
            this.depthSortedParticles = [];
        }
    }
    /**
     * Builds the SPS underlying mesh. Returns a standard Mesh.
     * If no model shape was added to the SPS, the returned mesh is just a single triangular plane.
     * @returns the created mesh
     */
    SolidParticleSystem.prototype.buildMesh = function () {
        if (this.nbParticles === 0) {
            var triangle = _Meshes_Builders_discBuilder__WEBPACK_IMPORTED_MODULE_5__["DiscBuilder"].CreateDisc("", { radius: 1, tessellation: 3 }, this._scene);
            this.addShape(triangle, 1);
            triangle.dispose();
        }
        this._indices32 = (this._needs32Bits) ? new Uint32Array(this._indices) : new Uint16Array(this._indices);
        this._positions32 = new Float32Array(this._positions);
        this._uvs32 = new Float32Array(this._uvs);
        this._colors32 = new Float32Array(this._colors);
        if (this.recomputeNormals) {
            _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].ComputeNormals(this._positions32, this._indices32, this._normals);
        }
        this._normals32 = new Float32Array(this._normals);
        this._fixedNormal32 = new Float32Array(this._normals);
        if (this._mustUnrotateFixedNormals) { // the particles could be created already rotated in the mesh with a positionFunction
            this._unrotateFixedNormals();
        }
        var vertexData = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"]();
        vertexData.indices = (this._depthSort) ? this._indices : this._indices32;
        vertexData.set(this._positions32, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind);
        vertexData.set(this._normals32, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind);
        if (this._uvs32.length > 0) {
            vertexData.set(this._uvs32, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].UVKind);
        }
        if (this._colors32.length > 0) {
            vertexData.set(this._colors32, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind);
        }
        var mesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"](this.name, this._scene);
        vertexData.applyToMesh(mesh, this._updatable);
        this.mesh = mesh;
        this.mesh.isPickable = this._pickable;
        // free memory
        if (!this._depthSort) {
            this._indices = null;
        }
        this._positions = null;
        this._normals = null;
        this._uvs = null;
        this._colors = null;
        if (!this._updatable) {
            this.particles.length = 0;
        }
        return mesh;
    };
    /**
     * Digests the mesh and generates as many solid particles in the system as wanted. Returns the SPS.
     * These particles will have the same geometry than the mesh parts and will be positioned at the same localisation than the mesh original places.
     * Thus the particles generated from `digest()` have their property `position` set yet.
     * @param mesh ( Mesh ) is the mesh to be digested
     * @param options {facetNb} (optional integer, default 1) is the number of mesh facets per particle, this parameter is overriden by the parameter `number` if any
     * {delta} (optional integer, default 0) is the random extra number of facets per particle , each particle will have between `facetNb` and `facetNb + delta` facets
     * {number} (optional positive integer) is the wanted number of particles : each particle is built with `mesh_total_facets / number` facets
     * @returns the current SPS
     */
    SolidParticleSystem.prototype.digest = function (mesh, options) {
        var size = (options && options.facetNb) || 1;
        var number = (options && options.number) || 0;
        var delta = (options && options.delta) || 0;
        var meshPos = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind);
        var meshInd = mesh.getIndices();
        var meshUV = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].UVKind);
        var meshCol = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind);
        var meshNor = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind);
        var f = 0; // facet counter
        var totalFacets = meshInd.length / 3; // a facet is a triangle, so 3 indices
        // compute size from number
        if (number) {
            number = (number > totalFacets) ? totalFacets : number;
            size = Math.round(totalFacets / number);
            delta = 0;
        }
        else {
            size = (size > totalFacets) ? totalFacets : size;
        }
        var facetPos = []; // submesh positions
        var facetInd = []; // submesh indices
        var facetUV = []; // submesh UV
        var facetCol = []; // submesh colors
        var barycenter = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        var sizeO = size;
        while (f < totalFacets) {
            size = sizeO + Math.floor((1 + delta) * Math.random());
            if (f > totalFacets - size) {
                size = totalFacets - f;
            }
            // reset temp arrays
            facetPos.length = 0;
            facetInd.length = 0;
            facetUV.length = 0;
            facetCol.length = 0;
            // iterate over "size" facets
            var fi = 0;
            for (var j = f * 3; j < (f + size) * 3; j++) {
                facetInd.push(fi);
                var i = meshInd[j];
                facetPos.push(meshPos[i * 3], meshPos[i * 3 + 1], meshPos[i * 3 + 2]);
                if (meshUV) {
                    facetUV.push(meshUV[i * 2], meshUV[i * 2 + 1]);
                }
                if (meshCol) {
                    facetCol.push(meshCol[i * 4], meshCol[i * 4 + 1], meshCol[i * 4 + 2], meshCol[i * 4 + 3]);
                }
                fi++;
            }
            // create a model shape for each single particle
            var idx = this.nbParticles;
            var shape = this._posToShape(facetPos);
            var shapeUV = this._uvsToShapeUV(facetUV);
            // compute the barycenter of the shape
            barycenter.copyFromFloats(0, 0, 0);
            var v;
            for (v = 0; v < shape.length; v++) {
                barycenter.addInPlace(shape[v]);
            }
            barycenter.scaleInPlace(1 / shape.length);
            // shift the shape from its barycenter to the origin
            // and compute the BBox required for intersection.
            var minimum = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](Infinity, Infinity, Infinity);
            var maximum = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-Infinity, -Infinity, -Infinity);
            for (v = 0; v < shape.length; v++) {
                shape[v].subtractInPlace(barycenter);
                minimum.minimizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);
                maximum.maximizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);
            }
            var bInfo;
            if (this._particlesIntersect) {
                bInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_8__["BoundingInfo"](minimum, maximum);
            }
            var modelShape = new _solidParticle__WEBPACK_IMPORTED_MODULE_7__["ModelShape"](this._shapeCounter, shape, size * 3, shapeUV, null, null);
            // add the particle in the SPS
            var currentPos = this._positions.length;
            var currentInd = this._indices.length;
            this._meshBuilder(this._index, shape, this._positions, facetInd, this._indices, facetUV, this._uvs, facetCol, this._colors, meshNor, this._normals, idx, 0, null);
            this._addParticle(idx, currentPos, currentInd, modelShape, this._shapeCounter, 0, bInfo);
            // initialize the particle position
            this.particles[this.nbParticles].position.addInPlace(barycenter);
            this._index += shape.length;
            idx++;
            this.nbParticles++;
            this._shapeCounter++;
            f += size;
        }
        return this;
    };
    // unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()
    SolidParticleSystem.prototype._unrotateFixedNormals = function () {
        var index = 0;
        var idx = 0;
        var tmpNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0];
        var quaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Quaternion[0];
        var invertedRotMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
        for (var p = 0; p < this.particles.length; p++) {
            var particle = this.particles[p];
            var shape = particle._model._shape;
            // computing the inverse of the rotation matrix from the quaternion
            // is equivalent to computing the matrix of the inverse quaternion, i.e of the conjugate quaternion
            if (particle.rotationQuaternion) {
                particle.rotationQuaternion.conjugateToRef(quaternion);
            }
            else {
                var rotation = particle.rotation;
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);
                quaternion.conjugateInPlace();
            }
            quaternion.toRotationMatrix(invertedRotMatrix);
            for (var pt = 0; pt < shape.length; pt++) {
                idx = index + pt * 3;
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], invertedRotMatrix, tmpNormal);
                tmpNormal.toArray(this._fixedNormal32, idx);
            }
            index = idx + 3;
        }
    };
    //reset copy
    SolidParticleSystem.prototype._resetCopy = function () {
        var copy = this._copy;
        copy.position.setAll(0);
        copy.rotation.setAll(0);
        copy.rotationQuaternion = null;
        copy.scaling.setAll(1);
        copy.uvs.copyFromFloats(0.0, 0.0, 1.0, 1.0);
        copy.color = null;
        copy.translateFromPivot = false;
    };
    // _meshBuilder : inserts the shape model in the global SPS mesh
    SolidParticleSystem.prototype._meshBuilder = function (p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, meshNor, normals, idx, idxInShape, options) {
        var i;
        var u = 0;
        var c = 0;
        var n = 0;
        this._resetCopy();
        var copy = this._copy;
        copy.idx = idx;
        copy.idxInShape = idxInShape;
        if (options && options.positionFunction) { // call to custom positionFunction
            options.positionFunction(copy, idx, idxInShape);
            this._mustUnrotateFixedNormals = true;
        }
        var rotMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
        var tmpVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0];
        var tmpRotated = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[1];
        var pivotBackTranslation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[2];
        var scaledPivot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[3];
        copy.getRotationMatrix(rotMatrix);
        copy.pivot.multiplyToRef(copy.scaling, scaledPivot);
        if (copy.translateFromPivot) {
            pivotBackTranslation.setAll(0.0);
        }
        else {
            pivotBackTranslation.copyFrom(scaledPivot);
        }
        for (i = 0; i < shape.length; i++) {
            tmpVertex.copyFrom(shape[i]);
            if (options && options.vertexFunction) {
                options.vertexFunction(copy, tmpVertex, i);
            }
            tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);
            tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position);
            positions.push(tmpRotated.x, tmpRotated.y, tmpRotated.z);
            if (meshUV) {
                var copyUvs = copy.uvs;
                uvs.push((copyUvs.z - copyUvs.x) * meshUV[u] + copyUvs.x, (copyUvs.w - copyUvs.y) * meshUV[u + 1] + copyUvs.y);
                u += 2;
            }
            if (copy.color) {
                this._color = copy.color;
            }
            else {
                var color = this._color;
                if (meshCol && meshCol[c] !== undefined) {
                    color.r = meshCol[c];
                    color.g = meshCol[c + 1];
                    color.b = meshCol[c + 2];
                    color.a = meshCol[c + 3];
                }
                else {
                    color.r = 1.0;
                    color.g = 1.0;
                    color.b = 1.0;
                    color.a = 1.0;
                }
            }
            colors.push(this._color.r, this._color.g, this._color.b, this._color.a);
            c += 4;
            if (!this.recomputeNormals && meshNor) {
                tmpVertex.x = meshNor[n];
                tmpVertex.y = meshNor[n + 1];
                tmpVertex.z = meshNor[n + 2];
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormalToRef(tmpVertex, rotMatrix, tmpVertex);
                normals.push(tmpVertex.x, tmpVertex.y, tmpVertex.z);
                n += 3;
            }
        }
        for (i = 0; i < meshInd.length; i++) {
            var current_ind = p + meshInd[i];
            indices.push(current_ind);
            if (current_ind > 65535) {
                this._needs32Bits = true;
            }
        }
        if (this._pickable) {
            var nbfaces = meshInd.length / 3;
            for (i = 0; i < nbfaces; i++) {
                this.pickedParticles.push({ idx: idx, faceId: i });
            }
        }
        if (this._depthSort) {
            this.depthSortedParticles.push(new _solidParticle__WEBPACK_IMPORTED_MODULE_7__["DepthSortedParticle"]());
        }
        return copy;
    };
    // returns a shape array from positions array
    SolidParticleSystem.prototype._posToShape = function (positions) {
        var shape = [];
        for (var i = 0; i < positions.length; i += 3) {
            shape.push(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromArray(positions, i));
        }
        return shape;
    };
    // returns a shapeUV array from a Vector4 uvs
    SolidParticleSystem.prototype._uvsToShapeUV = function (uvs) {
        var shapeUV = [];
        if (uvs) {
            for (var i = 0; i < uvs.length; i++) {
                shapeUV.push(uvs[i]);
            }
        }
        return shapeUV;
    };
    // adds a new particle object in the particles array
    SolidParticleSystem.prototype._addParticle = function (idx, idxpos, idxind, model, shapeId, idxInShape, bInfo) {
        if (bInfo === void 0) { bInfo = null; }
        var sp = new _solidParticle__WEBPACK_IMPORTED_MODULE_7__["SolidParticle"](idx, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);
        this.particles.push(sp);
        return sp;
    };
    /**
     * Adds some particles to the SPS from the model shape. Returns the shape id.
     * Please read the doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#create-an-immutable-sps
     * @param mesh is any Mesh object that will be used as a model for the solid particles.
     * @param nb (positive integer) the number of particles to be created from this model
     * @param options {positionFunction} is an optional javascript function to called for each particle on SPS creation.
     * {vertexFunction} is an optional javascript function to called for each vertex of each particle on SPS creation
     * @returns the number of shapes in the system
     */
    SolidParticleSystem.prototype.addShape = function (mesh, nb, options) {
        var meshPos = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind);
        var meshInd = mesh.getIndices();
        var meshUV = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].UVKind);
        var meshCol = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind);
        var meshNor = mesh.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind);
        var bbInfo;
        if (this._particlesIntersect) {
            bbInfo = mesh.getBoundingInfo();
        }
        var shape = this._posToShape(meshPos);
        var shapeUV = this._uvsToShapeUV(meshUV);
        var posfunc = options ? options.positionFunction : null;
        var vtxfunc = options ? options.vertexFunction : null;
        var modelShape = new _solidParticle__WEBPACK_IMPORTED_MODULE_7__["ModelShape"](this._shapeCounter, shape, meshInd.length, shapeUV, posfunc, vtxfunc);
        // particles
        var sp;
        var currentCopy;
        var idx = this.nbParticles;
        for (var i = 0; i < nb; i++) {
            var currentPos = this._positions.length;
            var currentInd = this._indices.length;
            currentCopy = this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, meshNor, this._normals, idx, i, options);
            if (this._updatable) {
                sp = this._addParticle(idx, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo);
                sp.position.copyFrom(currentCopy.position);
                sp.rotation.copyFrom(currentCopy.rotation);
                if (currentCopy.rotationQuaternion && sp.rotationQuaternion) {
                    sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);
                }
                if (currentCopy.color && sp.color) {
                    sp.color.copyFrom(currentCopy.color);
                }
                sp.scaling.copyFrom(currentCopy.scaling);
                sp.uvs.copyFrom(currentCopy.uvs);
            }
            this._index += shape.length;
            idx++;
        }
        this.nbParticles += nb;
        this._shapeCounter++;
        return this._shapeCounter - 1;
    };
    // rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices
    SolidParticleSystem.prototype._rebuildParticle = function (particle) {
        this._resetCopy();
        var copy = this._copy;
        if (particle._model._positionFunction) { // recall to stored custom positionFunction
            particle._model._positionFunction(copy, particle.idx, particle.idxInShape);
        }
        var rotMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
        var tmpVertex = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[0];
        var tmpRotated = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[1];
        var pivotBackTranslation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[2];
        var scaledPivot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3[3];
        copy.getRotationMatrix(rotMatrix);
        particle.pivot.multiplyToRef(particle.scaling, scaledPivot);
        if (copy.translateFromPivot) {
            pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);
        }
        else {
            pivotBackTranslation.copyFrom(scaledPivot);
        }
        var shape = particle._model._shape;
        for (var pt = 0; pt < shape.length; pt++) {
            tmpVertex.copyFrom(shape[pt]);
            if (particle._model._vertexFunction) {
                particle._model._vertexFunction(copy, tmpVertex, pt); // recall to stored vertexFunction
            }
            tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);
            tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position).toArray(this._positions32, particle._pos + pt * 3);
        }
        particle.position.setAll(0.0);
        particle.rotation.setAll(0.0);
        particle.rotationQuaternion = null;
        particle.scaling.setAll(1.0);
        particle.uvs.setAll(0.0);
        particle.pivot.setAll(0.0);
        particle.translateFromPivot = false;
        particle.parentId = null;
    };
    /**
     * Rebuilds the whole mesh and updates the VBO : custom positions and vertices are recomputed if needed.
     * @returns the SPS.
     */
    SolidParticleSystem.prototype.rebuildMesh = function () {
        for (var p = 0; p < this.particles.length; p++) {
            this._rebuildParticle(this.particles[p]);
        }
        this.mesh.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, this._positions32, false, false);
        return this;
    };
    /**
     *  Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.
     *  This method calls `updateParticle()` for each particle of the SPS.
     *  For an animated SPS, it is usually called within the render loop.
     * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_
     * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_
     * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_
     * @returns the SPS.
     */
    SolidParticleSystem.prototype.setParticles = function (start, end, update) {
        if (start === void 0) { start = 0; }
        if (end === void 0) { end = this.nbParticles - 1; }
        if (update === void 0) { update = true; }
        if (!this._updatable) {
            return this;
        }
        // custom beforeUpdate
        this.beforeUpdateParticles(start, end, update);
        var rotMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[0];
        var invertedMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Matrix[1];
        var mesh = this.mesh;
        var colors32 = this._colors32;
        var positions32 = this._positions32;
        var normals32 = this._normals32;
        var uvs32 = this._uvs32;
        var indices32 = this._indices32;
        var indices = this._indices;
        var fixedNormal32 = this._fixedNormal32;
        var tempVectors = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TmpVectors"].Vector3;
        var camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);
        var camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);
        var camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);
        var minimum = tempVectors[8].setAll(Number.MAX_VALUE);
        var maximum = tempVectors[9].setAll(-Number.MAX_VALUE);
        var camInvertedPosition = tempVectors[10].setAll(0);
        // cases when the World Matrix is to be computed first
        if (this.billboard || this._depthSort) {
            this.mesh.computeWorldMatrix(true);
            this.mesh._worldMatrix.invertToRef(invertedMatrix);
        }
        // if the particles will always face the camera
        if (this.billboard) {
            // compute the camera position and un-rotate it by the current mesh rotation
            var tmpVertex = tempVectors[0];
            this._camera.getDirectionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_9__["Axis"].Z, tmpVertex);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormalToRef(tmpVertex, invertedMatrix, camAxisZ);
            camAxisZ.normalize();
            // same for camera up vector extracted from the cam view matrix
            var view = this._camera.getViewMatrix(true);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], invertedMatrix, camAxisY);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(camAxisY, camAxisZ, camAxisX);
            camAxisY.normalize();
            camAxisX.normalize();
        }
        // if depthSort, compute the camera global position in the mesh local system
        if (this._depthSort) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this._camera.globalPosition, invertedMatrix, camInvertedPosition); // then un-rotate the camera
        }
        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].IdentityToRef(rotMatrix);
        var idx = 0; // current position index in the global array positions32
        var index = 0; // position start index in the global array positions32 of the current particle
        var colidx = 0; // current color index in the global array colors32
        var colorIndex = 0; // color start index in the global array colors32 of the current particle
        var uvidx = 0; // current uv index in the global array uvs32
        var uvIndex = 0; // uv start index in the global array uvs32 of the current particle
        var pt = 0; // current index in the particle model shape
        if (this.mesh.isFacetDataEnabled) {
            this._computeBoundingBox = true;
        }
        end = (end >= this.nbParticles) ? this.nbParticles - 1 : end;
        if (this._computeBoundingBox) {
            if (start != 0 || end != this.nbParticles - 1) { // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
                var boundingInfo = this.mesh._boundingInfo;
                if (boundingInfo) {
                    minimum.copyFrom(boundingInfo.minimum);
                    maximum.copyFrom(boundingInfo.maximum);
                }
            }
        }
        // particle loop
        index = this.particles[start]._pos;
        var vpos = (index / 3) | 0;
        colorIndex = vpos * 4;
        uvIndex = vpos * 2;
        for (var p = start; p <= end; p++) {
            var particle = this.particles[p];
            // call to custom user function to update the particle properties
            this.updateParticle(particle);
            var shape = particle._model._shape;
            var shapeUV = particle._model._shapeUV;
            var particleRotationMatrix = particle._rotationMatrix;
            var particlePosition = particle.position;
            var particleRotation = particle.rotation;
            var particleScaling = particle.scaling;
            var particleGlobalPosition = particle._globalPosition;
            // camera-particle distance for depth sorting
            if (this._depthSort && this._depthSortParticles) {
                var dsp = this.depthSortedParticles[p];
                dsp.ind = particle._ind;
                dsp.indicesLength = particle._model._indicesLength;
                dsp.sqDistance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].DistanceSquared(particle.position, camInvertedPosition);
            }
            // skip the computations for inactive or already invisible particles
            if (!particle.alive || (particle._stillInvisible && !particle.isVisible)) {
                // increment indexes for the next particle
                pt = shape.length;
                index += pt * 3;
                colorIndex += pt * 4;
                uvIndex += pt * 2;
                continue;
            }
            if (particle.isVisible) {
                particle._stillInvisible = false; // un-mark permanent invisibility
                var scaledPivot = tempVectors[12];
                particle.pivot.multiplyToRef(particleScaling, scaledPivot);
                // particle rotation matrix
                if (this.billboard) {
                    particleRotation.x = 0.0;
                    particleRotation.y = 0.0;
                }
                if (this._computeParticleRotation || this.billboard) {
                    particle.getRotationMatrix(rotMatrix);
                }
                var particleHasParent = (particle.parentId !== null);
                if (particleHasParent) {
                    var parent_1 = this.particles[particle.parentId];
                    var parentRotationMatrix = parent_1._rotationMatrix;
                    var parentGlobalPosition = parent_1._globalPosition;
                    var rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];
                    var rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];
                    var rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];
                    particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;
                    particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;
                    particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;
                    if (this._computeParticleRotation || this.billboard) {
                        var rotMatrixValues = rotMatrix.m;
                        particleRotationMatrix[0] = rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];
                        particleRotationMatrix[1] = rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];
                        particleRotationMatrix[2] = rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];
                        particleRotationMatrix[3] = rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];
                        particleRotationMatrix[4] = rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];
                        particleRotationMatrix[5] = rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];
                        particleRotationMatrix[6] = rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];
                        particleRotationMatrix[7] = rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];
                        particleRotationMatrix[8] = rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];
                    }
                }
                else {
                    particleGlobalPosition.x = particlePosition.x;
                    particleGlobalPosition.y = particlePosition.y;
                    particleGlobalPosition.z = particlePosition.z;
                    if (this._computeParticleRotation || this.billboard) {
                        var rotMatrixValues = rotMatrix.m;
                        particleRotationMatrix[0] = rotMatrixValues[0];
                        particleRotationMatrix[1] = rotMatrixValues[1];
                        particleRotationMatrix[2] = rotMatrixValues[2];
                        particleRotationMatrix[3] = rotMatrixValues[4];
                        particleRotationMatrix[4] = rotMatrixValues[5];
                        particleRotationMatrix[5] = rotMatrixValues[6];
                        particleRotationMatrix[6] = rotMatrixValues[8];
                        particleRotationMatrix[7] = rotMatrixValues[9];
                        particleRotationMatrix[8] = rotMatrixValues[10];
                    }
                }
                var pivotBackTranslation = tempVectors[11];
                if (particle.translateFromPivot) {
                    pivotBackTranslation.setAll(0.0);
                }
                else {
                    pivotBackTranslation.copyFrom(scaledPivot);
                }
                // particle vertex loop
                for (pt = 0; pt < shape.length; pt++) {
                    idx = index + pt * 3;
                    colidx = colorIndex + pt * 4;
                    uvidx = uvIndex + pt * 2;
                    var tmpVertex = tempVectors[0];
                    tmpVertex.copyFrom(shape[pt]);
                    if (this._computeParticleVertex) {
                        this.updateParticleVertex(particle, tmpVertex, pt);
                    }
                    // positions
                    var vertexX = tmpVertex.x * particleScaling.x - scaledPivot.x;
                    var vertexY = tmpVertex.y * particleScaling.y - scaledPivot.y;
                    var vertexZ = tmpVertex.z * particleScaling.z - scaledPivot.z;
                    var rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];
                    var rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];
                    var rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];
                    rotatedX += pivotBackTranslation.x;
                    rotatedY += pivotBackTranslation.y;
                    rotatedZ += pivotBackTranslation.z;
                    var px = positions32[idx] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;
                    var py = positions32[idx + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;
                    var pz = positions32[idx + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;
                    if (this._computeBoundingBox) {
                        minimum.minimizeInPlaceFromFloats(px, py, pz);
                        maximum.maximizeInPlaceFromFloats(px, py, pz);
                    }
                    // normals : if the particles can't be morphed then just rotate the normals, what is much more faster than ComputeNormals()
                    if (!this._computeParticleVertex) {
                        var normalx = fixedNormal32[idx];
                        var normaly = fixedNormal32[idx + 1];
                        var normalz = fixedNormal32[idx + 2];
                        var rotatedx = normalx * particleRotationMatrix[0] + normaly * particleRotationMatrix[3] + normalz * particleRotationMatrix[6];
                        var rotatedy = normalx * particleRotationMatrix[1] + normaly * particleRotationMatrix[4] + normalz * particleRotationMatrix[7];
                        var rotatedz = normalx * particleRotationMatrix[2] + normaly * particleRotationMatrix[5] + normalz * particleRotationMatrix[8];
                        normals32[idx] = camAxisX.x * rotatedx + camAxisY.x * rotatedy + camAxisZ.x * rotatedz;
                        normals32[idx + 1] = camAxisX.y * rotatedx + camAxisY.y * rotatedy + camAxisZ.y * rotatedz;
                        normals32[idx + 2] = camAxisX.z * rotatedx + camAxisY.z * rotatedy + camAxisZ.z * rotatedz;
                    }
                    if (this._computeParticleColor && particle.color) {
                        var color = particle.color;
                        var colors32_1 = this._colors32;
                        colors32_1[colidx] = color.r;
                        colors32_1[colidx + 1] = color.g;
                        colors32_1[colidx + 2] = color.b;
                        colors32_1[colidx + 3] = color.a;
                    }
                    if (this._computeParticleTexture) {
                        var uvs = particle.uvs;
                        uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;
                        uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;
                    }
                }
            }
            // particle just set invisible : scaled to zero and positioned at the origin
            else {
                particle._stillInvisible = true; // mark the particle as invisible
                for (pt = 0; pt < shape.length; pt++) {
                    idx = index + pt * 3;
                    colidx = colorIndex + pt * 4;
                    uvidx = uvIndex + pt * 2;
                    positions32[idx] = positions32[idx + 1] = positions32[idx + 2] = 0;
                    normals32[idx] = normals32[idx + 1] = normals32[idx + 2] = 0;
                    if (this._computeParticleColor && particle.color) {
                        var color = particle.color;
                        colors32[colidx] = color.r;
                        colors32[colidx + 1] = color.g;
                        colors32[colidx + 2] = color.b;
                        colors32[colidx + 3] = color.a;
                    }
                    if (this._computeParticleTexture) {
                        var uvs = particle.uvs;
                        uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;
                        uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;
                    }
                }
            }
            // if the particle intersections must be computed : update the bbInfo
            if (this._particlesIntersect) {
                var bInfo = particle._boundingInfo;
                var bBox = bInfo.boundingBox;
                var bSphere = bInfo.boundingSphere;
                var modelBoundingInfo = particle._modelBoundingInfo;
                if (!this._bSphereOnly) {
                    // place, scale and rotate the particle bbox within the SPS local system, then update it
                    var modelBoundingInfoVectors = modelBoundingInfo.boundingBox.vectors;
                    var tempMin = tempVectors[1];
                    var tempMax = tempVectors[2];
                    tempMin.setAll(Number.MAX_VALUE);
                    tempMax.setAll(-Number.MAX_VALUE);
                    for (var b = 0; b < 8; b++) {
                        var scaledX = modelBoundingInfoVectors[b].x * particleScaling.x;
                        var scaledY = modelBoundingInfoVectors[b].y * particleScaling.y;
                        var scaledZ = modelBoundingInfoVectors[b].z * particleScaling.z;
                        var rotatedX = scaledX * particleRotationMatrix[0] + scaledY * particleRotationMatrix[3] + scaledZ * particleRotationMatrix[6];
                        var rotatedY = scaledX * particleRotationMatrix[1] + scaledY * particleRotationMatrix[4] + scaledZ * particleRotationMatrix[7];
                        var rotatedZ = scaledX * particleRotationMatrix[2] + scaledY * particleRotationMatrix[5] + scaledZ * particleRotationMatrix[8];
                        var x = particlePosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;
                        var y = particlePosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;
                        var z = particlePosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;
                        tempMin.minimizeInPlaceFromFloats(x, y, z);
                        tempMax.maximizeInPlaceFromFloats(x, y, z);
                    }
                    bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix);
                }
                // place and scale the particle bouding sphere in the SPS local system, then update it
                var minBbox = modelBoundingInfo.minimum.multiplyToRef(particleScaling, tempVectors[1]);
                var maxBbox = modelBoundingInfo.maximum.multiplyToRef(particleScaling, tempVectors[2]);
                var bSphereCenter = maxBbox.addToRef(minBbox, tempVectors[3]).scaleInPlace(0.5).addInPlace(particleGlobalPosition);
                var halfDiag = maxBbox.subtractToRef(minBbox, tempVectors[4]).scaleInPlace(0.5 * this._bSphereRadiusFactor);
                var bSphereMinBbox = bSphereCenter.subtractToRef(halfDiag, tempVectors[1]);
                var bSphereMaxBbox = bSphereCenter.addToRef(halfDiag, tempVectors[2]);
                bSphere.reConstruct(bSphereMinBbox, bSphereMaxBbox, mesh._worldMatrix);
            }
            // increment indexes for the next particle
            index = idx + 3;
            colorIndex = colidx + 4;
            uvIndex = uvidx + 2;
        }
        // if the VBO must be updated
        if (update) {
            if (this._computeParticleColor) {
                mesh.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind, colors32, false, false);
            }
            if (this._computeParticleTexture) {
                mesh.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].UVKind, uvs32, false, false);
            }
            mesh.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, positions32, false, false);
            if (!mesh.areNormalsFrozen || mesh.isFacetDataEnabled) {
                if (this._computeParticleVertex || mesh.isFacetDataEnabled) {
                    // recompute the normals only if the particles can be morphed, update then also the normal reference array _fixedNormal32[]
                    var params = mesh.isFacetDataEnabled ? mesh.getFacetDataParameters() : null;
                    _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].ComputeNormals(positions32, indices32, normals32, params);
                    for (var i = 0; i < normals32.length; i++) {
                        fixedNormal32[i] = normals32[i];
                    }
                }
                if (!mesh.areNormalsFrozen) {
                    mesh.updateVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].NormalKind, normals32, false, false);
                }
            }
            if (this._depthSort && this._depthSortParticles) {
                var depthSortedParticles = this.depthSortedParticles;
                depthSortedParticles.sort(depthSortFunction);
                var dspl = depthSortedParticles.length;
                var sid = 0;
                for (var sorted = 0; sorted < dspl; sorted++) {
                    var lind = depthSortedParticles[sorted].indicesLength;
                    var sind = depthSortedParticles[sorted].ind;
                    for (var i = 0; i < lind; i++) {
                        indices32[sid] = indices[sind + i];
                        sid++;
                    }
                }
                mesh.updateIndices(indices32);
            }
        }
        if (this._computeBoundingBox) {
            if (mesh._boundingInfo) {
                mesh._boundingInfo.reConstruct(minimum, maximum, mesh._worldMatrix);
            }
            else {
                mesh._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_8__["BoundingInfo"](minimum, maximum, mesh._worldMatrix);
            }
        }
        this.afterUpdateParticles(start, end, update);
        return this;
    };
    /**
    * Disposes the SPS.
    */
    SolidParticleSystem.prototype.dispose = function () {
        this.mesh.dispose();
        this.vars = null;
        // drop references to internal big arrays for the GC
        this._positions = null;
        this._indices = null;
        this._normals = null;
        this._uvs = null;
        this._colors = null;
        this._indices32 = null;
        this._positions32 = null;
        this._normals32 = null;
        this._fixedNormal32 = null;
        this._uvs32 = null;
        this._colors32 = null;
        this.pickedParticles = null;
    };
    /**
     * Visibilty helper : Recomputes the visible size according to the mesh bounding box
     * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
     * @returns the SPS.
     */
    SolidParticleSystem.prototype.refreshVisibleSize = function () {
        if (!this._isVisibilityBoxLocked) {
            this.mesh.refreshBoundingInfo();
        }
        return this;
    };
    /**
     * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.
     * @param size the size (float) of the visibility box
     * note : this doesn't lock the SPS mesh bounding box.
     * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
     */
    SolidParticleSystem.prototype.setVisibilityBox = function (size) {
        var vis = size / 2;
        this.mesh._boundingInfo = new _Culling_boundingInfo__WEBPACK_IMPORTED_MODULE_8__["BoundingInfo"](new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-vis, -vis, -vis), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vis, vis, vis));
    };
    Object.defineProperty(SolidParticleSystem.prototype, "isAlwaysVisible", {
        /**
         * Gets whether the SPS as always visible or not
         * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
         */
        get: function () {
            return this._alwaysVisible;
        },
        /**
         * Sets the SPS as always visible or not
         * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
         */
        set: function (val) {
            this._alwaysVisible = val;
            this.mesh.alwaysSelectAsActiveMesh = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "isVisibilityBoxLocked", {
        /**
         * Gets if the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.
         * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
         */
        get: function () {
            return this._isVisibilityBoxLocked;
        },
        /**
         * Sets the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.
         * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
         */
        set: function (val) {
            this._isVisibilityBoxLocked = val;
            var boundingInfo = this.mesh.getBoundingInfo();
            boundingInfo.isLocked = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "computeParticleRotation", {
        /**
         * Gets if `setParticles()` computes the particle rotations or not.
         * Default value : true. The SPS is faster when it's set to false.
         * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.
         */
        get: function () {
            return this._computeParticleRotation;
        },
        /**
         * Tells to `setParticles()` to compute the particle rotations or not.
         * Default value : true. The SPS is faster when it's set to false.
         * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.
         */
        set: function (val) {
            this._computeParticleRotation = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "computeParticleColor", {
        /**
         * Gets if `setParticles()` computes the particle colors or not.
         * Default value : true. The SPS is faster when it's set to false.
         * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
         */
        get: function () {
            return this._computeParticleColor;
        },
        /**
         * Tells to `setParticles()` to compute the particle colors or not.
         * Default value : true. The SPS is faster when it's set to false.
         * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
         */
        set: function (val) {
            this._computeParticleColor = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "computeParticleTexture", {
        /**
         * Gets if `setParticles()` computes the particle textures or not.
         * Default value : true. The SPS is faster when it's set to false.
         * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.
         */
        get: function () {
            return this._computeParticleTexture;
        },
        set: function (val) {
            this._computeParticleTexture = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "computeParticleVertex", {
        /**
         * Gets if `setParticles()` calls the vertex function for each vertex of each particle, or not.
         * Default value : false. The SPS is faster when it's set to false.
         * Note : the particle custom vertex positions aren't stored values.
         */
        get: function () {
            return this._computeParticleVertex;
        },
        /**
         * Tells to `setParticles()` to call the vertex function for each vertex of each particle, or not.
         * Default value : false. The SPS is faster when it's set to false.
         * Note : the particle custom vertex positions aren't stored values.
         */
        set: function (val) {
            this._computeParticleVertex = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "computeBoundingBox", {
        /**
         * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.
         */
        get: function () {
            return this._computeBoundingBox;
        },
        /**
         * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.
         */
        set: function (val) {
            this._computeBoundingBox = val;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SolidParticleSystem.prototype, "depthSortParticles", {
        /**
         * Gets if `setParticles()` sorts or not the distance between each particle and the camera.
         * Skipped when `enableDepthSort` is set to `false` (default) at construction time.
         * Default : `true`
         */
        get: function () {
            return this._depthSortParticles;
        },
        /**
         * Tells to `setParticles()` to sort or not the distance between each particle and the camera.
         * Skipped when `enableDepthSort` is set to `false` (default) at construction time.
         * Default : `true`
         */
        set: function (val) {
            this._depthSortParticles = val;
        },
        enumerable: true,
        configurable: true
    });
    // =======================================================================
    // Particle behavior logic
    // these following methods may be overwritten by the user to fit his needs
    /**
     * This function does nothing. It may be overwritten to set all the particle first values.
     * The SPS doesn't call this function, you may have to call it by your own.
     * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
     */
    SolidParticleSystem.prototype.initParticles = function () {
    };
    /**
     * This function does nothing. It may be overwritten to recycle a particle.
     * The SPS doesn't call this function, you may have to call it by your own.
     * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
     * @param particle The particle to recycle
     * @returns the recycled particle
     */
    SolidParticleSystem.prototype.recycleParticle = function (particle) {
        return particle;
    };
    /**
     * Updates a particle : this function should  be overwritten by the user.
     * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.
     * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
     * @example : just set a particle position or velocity and recycle conditions
     * @param particle The particle to update
     * @returns the updated particle
     */
    SolidParticleSystem.prototype.updateParticle = function (particle) {
        return particle;
    };
    /**
     * Updates a vertex of a particle : it can be overwritten by the user.
     * This will be called on each vertex particle by `setParticles()` if `computeParticleVertex` is set to true only.
     * @param particle the current particle
     * @param vertex the current index of the current particle
     * @param pt the index of the current vertex in the particle shape
     * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#update-each-particle-shape
     * @example : just set a vertex particle position
     * @returns the updated vertex
     */
    SolidParticleSystem.prototype.updateParticleVertex = function (particle, vertex, pt) {
        return vertex;
    };
    /**
     * This will be called before any other treatment by `setParticles()` and will be passed three parameters.
     * This does nothing and may be overwritten by the user.
     * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
     * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
     * @param update the boolean update value actually passed to setParticles()
     */
    SolidParticleSystem.prototype.beforeUpdateParticles = function (start, stop, update) {
    };
    /**
     * This will be called  by `setParticles()` after all the other treatments and just before the actual mesh update.
     * This will be passed three parameters.
     * This does nothing and may be overwritten by the user.
     * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
     * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
     * @param update the boolean update value actually passed to setParticles()
     */
    SolidParticleSystem.prototype.afterUpdateParticles = function (start, stop, update) {
    };
    return SolidParticleSystem;
}());



/***/ }),

/***/ "./Particles/subEmitter.ts":
/*!*********************************!*\
  !*** ./Particles/subEmitter.ts ***!
  \*********************************/
/*! exports provided: SubEmitterType, SubEmitter */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubEmitterType", function() { return SubEmitterType; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubEmitter", function() { return SubEmitter; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");




/**
     * Type of sub emitter
     */
var SubEmitterType;
(function (SubEmitterType) {
    /**
     * Attached to the particle over it's lifetime
     */
    SubEmitterType[SubEmitterType["ATTACHED"] = 0] = "ATTACHED";
    /**
     * Created when the particle dies
     */
    SubEmitterType[SubEmitterType["END"] = 1] = "END";
})(SubEmitterType || (SubEmitterType = {}));
/**
 * Sub emitter class used to emit particles from an existing particle
 */
var SubEmitter = /** @class */ (function () {
    /**
     * Creates a sub emitter
     * @param particleSystem the particle system to be used by the sub emitter
     */
    function SubEmitter(
    /**
     * the particle system to be used by the sub emitter
     */
    particleSystem) {
        this.particleSystem = particleSystem;
        /**
         * Type of the submitter (Default: END)
         */
        this.type = SubEmitterType.END;
        /**
         * If the particle should inherit the direction from the particle it's attached to. (+Y will face the direction the particle is moving) (Default: false)
         * Note: This only is supported when using an emitter of type Mesh
         */
        this.inheritDirection = false;
        /**
         * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
         */
        this.inheritedVelocityAmount = 0;
        // Create mesh as emitter to support rotation
        if (!particleSystem.emitter || !particleSystem.emitter.dispose) {
            particleSystem.emitter = new _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"]("SubemitterSystemEmitter", particleSystem.getScene());
        }
        // Automatically dispose of subemitter when system is disposed
        particleSystem.onDisposeObservable.add(function () {
            if (particleSystem.emitter && particleSystem.emitter.dispose) {
                particleSystem.emitter.dispose();
            }
        });
    }
    /**
     * Clones the sub emitter
     * @returns the cloned sub emitter
     */
    SubEmitter.prototype.clone = function () {
        // Clone particle system
        var emitter = this.particleSystem.emitter;
        if (!emitter) {
            emitter = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
        }
        else if (emitter instanceof _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]) {
            emitter = emitter.clone();
        }
        else if (emitter instanceof _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"]) {
            emitter = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]("", emitter.getScene());
            emitter.isVisible = false;
        }
        var clone = new SubEmitter(this.particleSystem.clone("", emitter));
        // Clone properties
        clone.particleSystem.name += "Clone";
        clone.type = this.type;
        clone.inheritDirection = this.inheritDirection;
        clone.inheritedVelocityAmount = this.inheritedVelocityAmount;
        clone.particleSystem._disposeEmitterOnDispose = true;
        clone.particleSystem.disposeOnStop = true;
        return clone;
    };
    /**
     * Serialize current object to a JSON object
     * @returns the serialized object
     */
    SubEmitter.prototype.serialize = function () {
        var serializationObject = {};
        serializationObject.type = this.type;
        serializationObject.inheritDirection = this.inheritDirection;
        serializationObject.inheritedVelocityAmount = this.inheritedVelocityAmount;
        serializationObject.particleSystem = this.particleSystem.serialize();
        return serializationObject;
    };
    /** @hidden */
    SubEmitter._ParseParticleSystem = function (system, scene, rootUrl) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_3__["_DevTools"].WarnImport("ParseParticle");
    };
    /**
     * Creates a new SubEmitter from a serialized JSON version
     * @param serializationObject defines the JSON object to read from
     * @param scene defines the hosting scene
     * @param rootUrl defines the rootUrl for data loading
     * @returns a new SubEmitter
     */
    SubEmitter.Parse = function (serializationObject, scene, rootUrl) {
        var system = serializationObject.particleSystem;
        var subEmitter = new SubEmitter(SubEmitter._ParseParticleSystem(system, scene, rootUrl));
        subEmitter.type = serializationObject.type;
        subEmitter.inheritDirection = serializationObject.inheritDirection;
        subEmitter.inheritedVelocityAmount = serializationObject.inheritedVelocityAmount;
        subEmitter.particleSystem._isSubEmitter = true;
        return subEmitter;
    };
    /** Release associated resources */
    SubEmitter.prototype.dispose = function () {
        this.particleSystem.dispose();
    };
    return SubEmitter;
}());



/***/ }),

/***/ "./Physics/Plugins/ammoJSPlugin.ts":
/*!*****************************************!*\
  !*** ./Physics/Plugins/ammoJSPlugin.ts ***!
  \*****************************************/
/*! exports provided: AmmoJSPlugin */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AmmoJSPlugin", function() { return AmmoJSPlugin; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Physics/physicsImpostor */ "./Physics/physicsImpostor.ts");
/* harmony import */ var _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Physics/physicsJoint */ "./Physics/physicsJoint.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Meshes_Builders_shapeBuilder__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../Meshes/Builders/shapeBuilder */ "./Meshes/Builders/shapeBuilder.ts");
/* harmony import */ var _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../Meshes/Builders/linesBuilder */ "./Meshes/Builders/linesBuilder.ts");
/* harmony import */ var _physicsRaycastResult__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../physicsRaycastResult */ "./Physics/physicsRaycastResult.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../Maths/math.scalar */ "./Maths/math.scalar.ts");










/**
 * AmmoJS Physics plugin
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 * @see https://github.com/kripken/ammo.js/
 */
var AmmoJSPlugin = /** @class */ (function () {
    /**
     * Initializes the ammoJS plugin
     * @param _useDeltaForWorldStep if the time between frames should be used when calculating physics steps (Default: true)
     * @param ammoInjection can be used to inject your own ammo reference
     * @param overlappingPairCache can be used to specify your own overlapping pair cache
     */
    function AmmoJSPlugin(_useDeltaForWorldStep, ammoInjection, overlappingPairCache) {
        var _this = this;
        if (_useDeltaForWorldStep === void 0) { _useDeltaForWorldStep = true; }
        if (ammoInjection === void 0) { ammoInjection = Ammo; }
        if (overlappingPairCache === void 0) { overlappingPairCache = null; }
        this._useDeltaForWorldStep = _useDeltaForWorldStep;
        /**
         * Reference to the Ammo library
         */
        this.bjsAMMO = {};
        /**
         * Name of the plugin
         */
        this.name = "AmmoJSPlugin";
        this._timeStep = 1 / 60;
        this._fixedTimeStep = 1 / 60;
        this._maxSteps = 5;
        this._tmpQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"]();
        this._tmpContactCallbackResult = false;
        this._tmpVector = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
        this._tmpMatrix = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"]();
        if (typeof ammoInjection === "function") {
            ammoInjection(this.bjsAMMO);
        }
        else {
            this.bjsAMMO = ammoInjection;
        }
        if (!this.isSupported()) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("AmmoJS is not available. Please make sure you included the js file.");
            return;
        }
        // Initialize the physics world
        this._collisionConfiguration = new this.bjsAMMO.btSoftBodyRigidBodyCollisionConfiguration();
        this._dispatcher = new this.bjsAMMO.btCollisionDispatcher(this._collisionConfiguration);
        this._overlappingPairCache = overlappingPairCache || new this.bjsAMMO.btDbvtBroadphase();
        this._solver = new this.bjsAMMO.btSequentialImpulseConstraintSolver();
        this._softBodySolver = new this.bjsAMMO.btDefaultSoftBodySolver();
        this.world = new this.bjsAMMO.btSoftRigidDynamicsWorld(this._dispatcher, this._overlappingPairCache, this._solver, this._collisionConfiguration, this._softBodySolver);
        this._tmpAmmoConcreteContactResultCallback = new this.bjsAMMO.ConcreteContactResultCallback();
        this._tmpAmmoConcreteContactResultCallback.addSingleResult = function () { _this._tmpContactCallbackResult = true; };
        this._raycastResult = new _physicsRaycastResult__WEBPACK_IMPORTED_MODULE_8__["PhysicsRaycastResult"]();
        // Create temp ammo variables
        this._tmpAmmoTransform = new this.bjsAMMO.btTransform();
        this._tmpAmmoTransform.setIdentity();
        this._tmpAmmoQuaternion = new this.bjsAMMO.btQuaternion(0, 0, 0, 1);
        this._tmpAmmoVectorA = new this.bjsAMMO.btVector3(0, 0, 0);
        this._tmpAmmoVectorB = new this.bjsAMMO.btVector3(0, 0, 0);
        this._tmpAmmoVectorC = new this.bjsAMMO.btVector3(0, 0, 0);
        this._tmpAmmoVectorD = new this.bjsAMMO.btVector3(0, 0, 0);
    }
    /**
     * Sets the gravity of the physics world (m/(s^2))
     * @param gravity Gravity to set
     */
    AmmoJSPlugin.prototype.setGravity = function (gravity) {
        this._tmpAmmoVectorA.setValue(gravity.x, gravity.y, gravity.z);
        this.world.setGravity(this._tmpAmmoVectorA);
        this.world.getWorldInfo().set_m_gravity(this._tmpAmmoVectorA);
    };
    /**
     * Amount of time to step forward on each frame (only used if useDeltaForWorldStep is false in the constructor)
     * @param timeStep timestep to use in seconds
     */
    AmmoJSPlugin.prototype.setTimeStep = function (timeStep) {
        this._timeStep = timeStep;
    };
    /**
     * Increment to step forward in the physics engine (If timeStep is set to 1/60 and fixedTimeStep is set to 1/120 the physics engine should run 2 steps per frame) (Default: 1/60)
     * @param fixedTimeStep fixedTimeStep to use in seconds
     */
    AmmoJSPlugin.prototype.setFixedTimeStep = function (fixedTimeStep) {
        this._fixedTimeStep = fixedTimeStep;
    };
    /**
     * Sets the maximum number of steps by the physics engine per frame (Default: 5)
     * @param maxSteps the maximum number of steps by the physics engine per frame
     */
    AmmoJSPlugin.prototype.setMaxSteps = function (maxSteps) {
        this._maxSteps = maxSteps;
    };
    /**
     * Gets the current timestep (only used if useDeltaForWorldStep is false in the constructor)
     * @returns the current timestep in seconds
     */
    AmmoJSPlugin.prototype.getTimeStep = function () {
        return this._timeStep;
    };
    // Ammo's contactTest and contactPairTest take a callback that runs synchronously, wrap them so that they are easier to consume
    AmmoJSPlugin.prototype._isImpostorInContact = function (impostor) {
        this._tmpContactCallbackResult = false;
        this.world.contactTest(impostor.physicsBody, this._tmpAmmoConcreteContactResultCallback);
        return this._tmpContactCallbackResult;
    };
    // Ammo's collision events have some weird quirks
    // contactPairTest fires too many events as it fires events even when objects are close together but contactTest does not
    // so only fire event if both contactTest and contactPairTest have a hit
    AmmoJSPlugin.prototype._isImpostorPairInContact = function (impostorA, impostorB) {
        this._tmpContactCallbackResult = false;
        this.world.contactPairTest(impostorA.physicsBody, impostorB.physicsBody, this._tmpAmmoConcreteContactResultCallback);
        return this._tmpContactCallbackResult;
    };
    // Ammo's behavior when maxSteps > 0 does not behave as described in docs
    // @see http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World
    //
    // When maxSteps is 0 do the entire simulation in one step
    // When maxSteps is > 0, run up to maxStep times, if on the last step the (remaining step - fixedTimeStep) is < fixedTimeStep, the remainder will be used for the step. (eg. if remainder is 1.001 and fixedTimeStep is 1 the last step will be 1.001, if instead it did 2 steps (1, 0.001) issues occuered when having a tiny step in ammo)
    // Note: To get deterministic physics, timeStep would always need to be divisible by fixedTimeStep
    AmmoJSPlugin.prototype._stepSimulation = function (timeStep, maxSteps, fixedTimeStep) {
        if (timeStep === void 0) { timeStep = 1 / 60; }
        if (maxSteps === void 0) { maxSteps = 10; }
        if (fixedTimeStep === void 0) { fixedTimeStep = 1 / 60; }
        if (maxSteps == 0) {
            this.world.stepSimulation(timeStep, 0);
        }
        else {
            while (maxSteps > 0 && timeStep > 0) {
                if (timeStep - fixedTimeStep < fixedTimeStep) {
                    this.world.stepSimulation(timeStep, 0);
                    timeStep = 0;
                }
                else {
                    timeStep -= fixedTimeStep;
                    this.world.stepSimulation(fixedTimeStep, 0);
                }
                maxSteps--;
            }
        }
    };
    /**
     * Moves the physics simulation forward delta seconds and updates the given physics imposters
     * Prior to the step the imposters physics location is set to the position of the babylon meshes
     * After the step the babylon meshes are set to the position of the physics imposters
     * @param delta amount of time to step forward
     * @param impostors array of imposters to update before/after the step
     */
    AmmoJSPlugin.prototype.executeStep = function (delta, impostors) {
        for (var _i = 0, impostors_1 = impostors; _i < impostors_1.length; _i++) {
            var impostor = impostors_1[_i];
            // Update physics world objects to match babylon world
            if (!impostor.soft) {
                impostor.beforeStep();
            }
        }
        this._stepSimulation(this._useDeltaForWorldStep ? delta : this._timeStep, this._maxSteps, this._fixedTimeStep);
        for (var _a = 0, impostors_2 = impostors; _a < impostors_2.length; _a++) {
            var mainImpostor = impostors_2[_a];
            // After physics update make babylon world objects match physics world objects
            if (mainImpostor.soft) {
                this._afterSoftStep(mainImpostor);
            }
            else {
                mainImpostor.afterStep();
            }
            // Handle collision event
            if (mainImpostor._onPhysicsCollideCallbacks.length > 0) {
                if (this._isImpostorInContact(mainImpostor)) {
                    for (var _b = 0, _c = mainImpostor._onPhysicsCollideCallbacks; _b < _c.length; _b++) {
                        var collideCallback = _c[_b];
                        for (var _d = 0, _e = collideCallback.otherImpostors; _d < _e.length; _d++) {
                            var otherImpostor = _e[_d];
                            if (mainImpostor.physicsBody.isActive() || otherImpostor.physicsBody.isActive()) {
                                if (this._isImpostorPairInContact(mainImpostor, otherImpostor)) {
                                    mainImpostor.onCollide({ body: otherImpostor.physicsBody });
                                    otherImpostor.onCollide({ body: mainImpostor.physicsBody });
                                }
                            }
                        }
                    }
                }
            }
        }
    };
    /**
     * Update babylon mesh to match physics world object
     * @param impostor imposter to match
     */
    AmmoJSPlugin.prototype._afterSoftStep = function (impostor) {
        if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].RopeImpostor) {
            this._ropeStep(impostor);
        }
        else {
            this._softbodyOrClothStep(impostor);
        }
    };
    /**
     * Update babylon mesh vertices vertices to match physics world softbody or cloth
     * @param impostor imposter to match
     */
    AmmoJSPlugin.prototype._ropeStep = function (impostor) {
        var bodyVertices = impostor.physicsBody.get_m_nodes();
        var nbVertices = bodyVertices.size();
        var node;
        var nodePositions;
        var x, y, z;
        var path = new Array();
        for (var n = 0; n < nbVertices; n++) {
            node = bodyVertices.at(n);
            nodePositions = node.get_m_x();
            x = nodePositions.x();
            y = nodePositions.y();
            z = nodePositions.z();
            path.push(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](x, y, z));
        }
        var object = impostor.object;
        var shape = impostor.getParam("shape");
        if (impostor._isFromLine) {
            impostor.object = _Meshes_Builders_linesBuilder__WEBPACK_IMPORTED_MODULE_7__["LinesBuilder"].CreateLines("lines", { points: path, instance: object });
        }
        else {
            impostor.object = _Meshes_Builders_shapeBuilder__WEBPACK_IMPORTED_MODULE_6__["ShapeBuilder"].ExtrudeShape("ext", { shape: shape, path: path, instance: object });
        }
    };
    /**
     * Update babylon mesh vertices vertices to match physics world softbody or cloth
     * @param impostor imposter to match
     */
    AmmoJSPlugin.prototype._softbodyOrClothStep = function (impostor) {
        var normalDirection = (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].ClothImpostor) ? 1 : -1;
        var object = impostor.object;
        var vertexPositions = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind);
        if (!vertexPositions) {
            vertexPositions = [];
        }
        var vertexNormals = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].NormalKind);
        if (!vertexNormals) {
            vertexNormals = [];
        }
        var nbVertices = vertexPositions.length / 3;
        var bodyVertices = impostor.physicsBody.get_m_nodes();
        var node;
        var nodePositions;
        var nodeNormals;
        var x, y, z;
        var nx, ny, nz;
        for (var n = 0; n < nbVertices; n++) {
            node = bodyVertices.at(n);
            nodePositions = node.get_m_x();
            x = nodePositions.x();
            y = nodePositions.y();
            z = nodePositions.z() * normalDirection;
            var nodeNormals = node.get_m_n();
            nx = nodeNormals.x();
            ny = nodeNormals.y();
            nz = nodeNormals.z() * normalDirection;
            vertexPositions[3 * n] = x;
            vertexPositions[3 * n + 1] = y;
            vertexPositions[3 * n + 2] = z;
            vertexNormals[3 * n] = nx;
            vertexNormals[3 * n + 1] = ny;
            vertexNormals[3 * n + 2] = nz;
        }
        var vertex_data = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_5__["VertexData"]();
        vertex_data.positions = vertexPositions;
        vertex_data.normals = vertexNormals;
        vertex_data.uvs = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].UVKind);
        vertex_data.colors = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].ColorKind);
        if (object && object.getIndices) {
            vertex_data.indices = object.getIndices();
        }
        vertex_data.applyToMesh(object);
    };
    /**
     * Applies an impulse on the imposter
     * @param impostor imposter to apply impulse to
     * @param force amount of force to be applied to the imposter
     * @param contactPoint the location to apply the impulse on the imposter
     */
    AmmoJSPlugin.prototype.applyImpulse = function (impostor, force, contactPoint) {
        if (!impostor.soft) {
            impostor.physicsBody.activate();
            var worldPoint = this._tmpAmmoVectorA;
            var impulse = this._tmpAmmoVectorB;
            // Convert contactPoint into world space
            if (impostor.object && impostor.object.getWorldMatrix) {
                impostor.object.getWorldMatrix().invertToRef(this._tmpMatrix);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(contactPoint, this._tmpMatrix, this._tmpVector);
                contactPoint = this._tmpVector;
            }
            worldPoint.setValue(contactPoint.x, contactPoint.y, contactPoint.z);
            impulse.setValue(force.x, force.y, force.z);
            impostor.physicsBody.applyImpulse(impulse, worldPoint);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Cannot be applied to a soft body");
        }
    };
    /**
     * Applies a force on the imposter
     * @param impostor imposter to apply force
     * @param force amount of force to be applied to the imposter
     * @param contactPoint the location to apply the force on the imposter
     */
    AmmoJSPlugin.prototype.applyForce = function (impostor, force, contactPoint) {
        if (!impostor.soft) {
            impostor.physicsBody.activate();
            var worldPoint = this._tmpAmmoVectorA;
            var impulse = this._tmpAmmoVectorB;
            // Convert contactPoint into world space
            if (impostor.object && impostor.object.getWorldMatrix) {
                impostor.object.getWorldMatrix().invertToRef(this._tmpMatrix);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(contactPoint, this._tmpMatrix, this._tmpVector);
                contactPoint = this._tmpVector;
            }
            worldPoint.setValue(contactPoint.x, contactPoint.y, contactPoint.z);
            impulse.setValue(force.x, force.y, force.z);
            impostor.physicsBody.applyForce(impulse, worldPoint);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Cannot be applied to a soft body");
        }
    };
    /**
     * Creates a physics body using the plugin
     * @param impostor the imposter to create the physics body on
     */
    AmmoJSPlugin.prototype.generatePhysicsBody = function (impostor) {
        // Note: this method will not be called on child imposotrs for compound impostors
        impostor._pluginData.toDispose = [];
        //parent-child relationship
        if (impostor.parent) {
            if (impostor.physicsBody) {
                this.removePhysicsBody(impostor);
                impostor.forceUpdate();
            }
            return;
        }
        if (impostor.isBodyInitRequired()) {
            var colShape = this._createShape(impostor);
            var mass = impostor.getParam("mass");
            impostor._pluginData.mass = mass;
            if (impostor.soft) {
                colShape.get_m_cfg().set_collisions(0x11);
                colShape.get_m_cfg().set_kDP(impostor.getParam("damping"));
                Ammo.castObject(colShape, Ammo.btCollisionObject).getCollisionShape().setMargin(impostor.getParam("margin"));
                colShape.setActivationState(AmmoJSPlugin.DISABLE_DEACTIVATION_FLAG);
                this.world.addSoftBody(colShape, 1, -1);
                impostor.physicsBody = colShape;
                impostor._pluginData.toDispose.push(colShape);
                this.setBodyPressure(impostor, 0);
                if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].SoftbodyImpostor) {
                    this.setBodyPressure(impostor, impostor.getParam("pressure"));
                }
                this.setBodyStiffness(impostor, impostor.getParam("stiffness"));
                this.setBodyVelocityIterations(impostor, impostor.getParam("velocityIterations"));
                this.setBodyPositionIterations(impostor, impostor.getParam("positionIterations"));
            }
            else {
                var localInertia = new Ammo.btVector3(0, 0, 0);
                var startTransform = new Ammo.btTransform();
                startTransform.setIdentity();
                if (mass !== 0) {
                    colShape.calculateLocalInertia(mass, localInertia);
                }
                this._tmpAmmoVectorA.setValue(impostor.object.position.x, impostor.object.position.y, impostor.object.position.z);
                this._tmpAmmoQuaternion.setValue(impostor.object.rotationQuaternion.x, impostor.object.rotationQuaternion.y, impostor.object.rotationQuaternion.z, impostor.object.rotationQuaternion.w);
                startTransform.setOrigin(this._tmpAmmoVectorA);
                startTransform.setRotation(this._tmpAmmoQuaternion);
                var myMotionState = new Ammo.btDefaultMotionState(startTransform);
                var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
                var body = new Ammo.btRigidBody(rbInfo);
                // Make objects kinematic if it's mass is 0
                if (mass === 0) {
                    body.setCollisionFlags(body.getCollisionFlags() | AmmoJSPlugin.KINEMATIC_FLAG);
                    body.setActivationState(AmmoJSPlugin.DISABLE_DEACTIVATION_FLAG);
                }
                // Disable collision if NoImpostor, but keep collision if shape is btCompoundShape
                if (impostor.type == _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].NoImpostor && !colShape.getChildShape) {
                    body.setCollisionFlags(body.getCollisionFlags() | AmmoJSPlugin.DISABLE_COLLISION_FLAG);
                }
                this.world.addRigidBody(body);
                impostor.physicsBody = body;
                impostor._pluginData.toDispose = impostor._pluginData.toDispose.concat([body, rbInfo, myMotionState, startTransform, localInertia, colShape]);
            }
            this.setBodyRestitution(impostor, impostor.getParam("restitution"));
            this.setBodyFriction(impostor, impostor.getParam("friction"));
        }
    };
    /**
     * Removes the physics body from the imposter and disposes of the body's memory
     * @param impostor imposter to remove the physics body from
     */
    AmmoJSPlugin.prototype.removePhysicsBody = function (impostor) {
        var _this = this;
        if (this.world) {
            if (impostor.soft) {
                this.world.removeSoftBody(impostor.physicsBody);
            }
            else {
                this.world.removeRigidBody(impostor.physicsBody);
            }
            if (impostor._pluginData) {
                impostor._pluginData.toDispose.forEach(function (d) {
                    _this.bjsAMMO.destroy(d);
                });
                impostor._pluginData.toDispose = [];
            }
        }
    };
    /**
     * Generates a joint
     * @param impostorJoint the imposter joint to create the joint with
     */
    AmmoJSPlugin.prototype.generateJoint = function (impostorJoint) {
        var mainBody = impostorJoint.mainImpostor.physicsBody;
        var connectedBody = impostorJoint.connectedImpostor.physicsBody;
        if (!mainBody || !connectedBody) {
            return;
        }
        var jointData = impostorJoint.joint.jointData;
        if (!jointData.mainPivot) {
            jointData.mainPivot = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
        }
        if (!jointData.connectedPivot) {
            jointData.connectedPivot = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
        }
        var joint;
        switch (impostorJoint.joint.type) {
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_3__["PhysicsJoint"].DistanceJoint:
                var distance = jointData.maxDistance;
                if (distance) {
                    jointData.mainPivot = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -distance / 2, 0);
                    jointData.connectedPivot = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, distance / 2, 0);
                }
                joint = new Ammo.btPoint2PointConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z));
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_3__["PhysicsJoint"].HingeJoint:
                if (!jointData.mainAxis) {
                    jointData.mainAxis = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
                }
                if (!jointData.connectedAxis) {
                    jointData.connectedAxis = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
                }
                var mainAxis = new Ammo.btVector3(jointData.mainAxis.x, jointData.mainAxis.y, jointData.mainAxis.z);
                var connectedAxis = new Ammo.btVector3(jointData.connectedAxis.x, jointData.connectedAxis.y, jointData.connectedAxis.z);
                joint = new Ammo.btHingeConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z), mainAxis, connectedAxis);
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_3__["PhysicsJoint"].BallAndSocketJoint:
                joint = new Ammo.btPoint2PointConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z));
                break;
            default:
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("JointType not currently supported by the Ammo plugin, falling back to PhysicsJoint.BallAndSocketJoint");
                joint = new Ammo.btPoint2PointConstraint(mainBody, connectedBody, new Ammo.btVector3(jointData.mainPivot.x, jointData.mainPivot.y, jointData.mainPivot.z), new Ammo.btVector3(jointData.connectedPivot.x, jointData.connectedPivot.y, jointData.connectedPivot.z));
                break;
        }
        this.world.addConstraint(joint, !impostorJoint.joint.jointData.collision);
        impostorJoint.joint.physicsJoint = joint;
    };
    /**
     * Removes a joint
     * @param impostorJoint the imposter joint to remove the joint from
     */
    AmmoJSPlugin.prototype.removeJoint = function (impostorJoint) {
        if (this.world) {
            this.world.removeConstraint(impostorJoint.joint.physicsJoint);
        }
    };
    // adds all verticies (including child verticies) to the triangle mesh
    AmmoJSPlugin.prototype._addMeshVerts = function (btTriangleMesh, topLevelObject, object) {
        var _this = this;
        var triangleCount = 0;
        if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {
            var indices = object.getIndices();
            if (!indices) {
                indices = [];
            }
            var vertexPositions = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind);
            if (!vertexPositions) {
                vertexPositions = [];
            }
            object.computeWorldMatrix(false);
            var faceCount = indices.length / 3;
            for (var i = 0; i < faceCount; i++) {
                var triPoints = [];
                for (var point = 0; point < 3; point++) {
                    var v = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vertexPositions[(indices[(i * 3) + point] * 3) + 0], vertexPositions[(indices[(i * 3) + point] * 3) + 1], vertexPositions[(indices[(i * 3) + point] * 3) + 2]);
                    // Adjust for initial scaling
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].ScalingToRef(object.scaling.x, object.scaling.y, object.scaling.z, this._tmpMatrix);
                    v = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(v, this._tmpMatrix);
                    var vec;
                    if (point == 0) {
                        vec = this._tmpAmmoVectorA;
                    }
                    else if (point == 1) {
                        vec = this._tmpAmmoVectorB;
                    }
                    else {
                        vec = this._tmpAmmoVectorC;
                    }
                    vec.setValue(v.x, v.y, v.z);
                    triPoints.push(vec);
                }
                btTriangleMesh.addTriangle(triPoints[0], triPoints[1], triPoints[2]);
                triangleCount++;
            }
            object.getChildMeshes().forEach(function (m) {
                triangleCount += _this._addMeshVerts(btTriangleMesh, topLevelObject, m);
            });
        }
        return triangleCount;
    };
    /**
     * Initialise the soft body vertices to match its object's (mesh) vertices
     * Softbody vertices (nodes) are in world space and to match this
     * The object's position and rotation is set to zero and so its vertices are also then set in world space
     * @param impostor to create the softbody for
     */
    AmmoJSPlugin.prototype._softVertexData = function (impostor) {
        var object = impostor.object;
        if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {
            var indices = object.getIndices();
            if (!indices) {
                indices = [];
            }
            var vertexPositions = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind);
            if (!vertexPositions) {
                vertexPositions = [];
            }
            var vertexNormals = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].NormalKind);
            if (!vertexNormals) {
                vertexNormals = [];
            }
            object.computeWorldMatrix(false);
            var newPoints = [];
            var newNorms = [];
            for (var i = 0; i < vertexPositions.length; i += 3) {
                var v = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vertexPositions[i], vertexPositions[i + 1], vertexPositions[i + 2]);
                var n = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vertexNormals[i], vertexNormals[i + 1], vertexNormals[i + 2]);
                v = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(v, object.getWorldMatrix());
                n = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformNormal(n, object.getWorldMatrix());
                newPoints.push(v.x, v.y, v.z);
                newNorms.push(n.x, n.y, n.z);
            }
            var vertex_data = new _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_5__["VertexData"]();
            vertex_data.positions = newPoints;
            vertex_data.normals = newNorms;
            vertex_data.uvs = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].UVKind);
            vertex_data.colors = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].ColorKind);
            if (object && object.getIndices) {
                vertex_data.indices = object.getIndices();
            }
            vertex_data.applyToMesh(object);
            object.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
            object.rotationQuaternion = null;
            object.rotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
            object.computeWorldMatrix(true);
            return vertex_data;
        }
        return _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_5__["VertexData"].ExtractFromMesh(object);
    };
    /**
     * Create an impostor's soft body
     * @param impostor to create the softbody for
     */
    AmmoJSPlugin.prototype._createSoftbody = function (impostor) {
        var object = impostor.object;
        if (object && object.getIndices) {
            var indices = object.getIndices();
            if (!indices) {
                indices = [];
            }
            var vertex_data = this._softVertexData(impostor);
            var vertexPositions = vertex_data.positions;
            var vertexNormals = vertex_data.normals;
            if (vertexPositions === null || vertexNormals === null) {
                return new Ammo.btCompoundShape();
            }
            else {
                var triPoints = [];
                var triNorms = [];
                for (var i = 0; i < vertexPositions.length; i += 3) {
                    var v = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vertexPositions[i], vertexPositions[i + 1], vertexPositions[i + 2]);
                    var n = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vertexNormals[i], vertexNormals[i + 1], vertexNormals[i + 2]);
                    triPoints.push(v.x, v.y, -v.z);
                    triNorms.push(n.x, n.y, -n.z);
                }
                var softBody = new Ammo.btSoftBodyHelpers().CreateFromTriMesh(this.world.getWorldInfo(), triPoints, object.getIndices(), indices.length / 3, true);
                var nbVertices = vertexPositions.length / 3;
                var bodyVertices = softBody.get_m_nodes();
                var node;
                var nodeNormals;
                for (var i = 0; i < nbVertices; i++) {
                    node = bodyVertices.at(i);
                    var nodeNormals = node.get_m_n();
                    nodeNormals.setX(triNorms[3 * i]);
                    nodeNormals.setY(triNorms[3 * i + 1]);
                    nodeNormals.setZ(triNorms[3 * i + 2]);
                }
                return softBody;
            }
        }
    };
    /**
     * Create cloth for an impostor
     * @param impostor to create the softbody for
     */
    AmmoJSPlugin.prototype._createCloth = function (impostor) {
        var object = impostor.object;
        if (object && object.getIndices) {
            var indices = object.getIndices();
            if (!indices) {
                indices = [];
            }
            var vertex_data = this._softVertexData(impostor);
            var vertexPositions = vertex_data.positions;
            var vertexNormals = vertex_data.normals;
            if (vertexPositions === null || vertexNormals === null) {
                return new Ammo.btCompoundShape();
            }
            else {
                var len = vertexPositions.length;
                var segments = Math.sqrt(len / 3);
                impostor.segments = segments;
                var segs = segments - 1;
                this._tmpAmmoVectorA.setValue(vertexPositions[0], vertexPositions[1], vertexPositions[2]);
                this._tmpAmmoVectorB.setValue(vertexPositions[3 * segs], vertexPositions[3 * segs + 1], vertexPositions[3 * segs + 2]);
                this._tmpAmmoVectorD.setValue(vertexPositions[len - 3], vertexPositions[len - 2], vertexPositions[len - 1]);
                this._tmpAmmoVectorC.setValue(vertexPositions[len - 3 - 3 * segs], vertexPositions[len - 2 - 3 * segs], vertexPositions[len - 1 - 3 * segs]);
                var clothBody = new Ammo.btSoftBodyHelpers().CreatePatch(this.world.getWorldInfo(), this._tmpAmmoVectorA, this._tmpAmmoVectorB, this._tmpAmmoVectorC, this._tmpAmmoVectorD, segments, segments, impostor.getParam("fixedPoints"), true);
                return clothBody;
            }
        }
    };
    /**
     * Create rope for an impostor
     * @param impostor to create the softbody for
     */
    AmmoJSPlugin.prototype._createRope = function (impostor) {
        var len;
        var segments;
        var vertex_data = this._softVertexData(impostor);
        var vertexPositions = vertex_data.positions;
        var vertexNormals = vertex_data.normals;
        if (vertexPositions === null || vertexNormals === null) {
            return new Ammo.btCompoundShape();
        }
        //force the mesh to be updatable
        vertex_data.applyToMesh(impostor.object, true);
        impostor._isFromLine = true;
        // If in lines mesh all normals will be zero
        var vertexSquared = vertexNormals.map(function (x) { return x * x; });
        var reducer = function (accumulator, currentValue) { return accumulator + currentValue; };
        var reduced = vertexSquared.reduce(reducer);
        if (reduced === 0) { // line mesh
            len = vertexPositions.length;
            segments = len / 3 - 1;
            this._tmpAmmoVectorA.setValue(vertexPositions[0], vertexPositions[1], vertexPositions[2]);
            this._tmpAmmoVectorB.setValue(vertexPositions[len - 3], vertexPositions[len - 2], vertexPositions[len - 1]);
        }
        else { //extruded mesh
            impostor._isFromLine = false;
            var pathVectors = impostor.getParam("path");
            var shape = impostor.getParam("shape");
            if (shape === null) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("No shape available for extruded mesh");
                return new Ammo.btCompoundShape();
            }
            if ((vertexPositions.length % (3 * pathVectors.length)) !== 0) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Path does not match extrusion");
                return new Ammo.btCompoundShape();
            }
            len = pathVectors.length;
            segments = len - 1;
            this._tmpAmmoVectorA.setValue(pathVectors[0].x, pathVectors[0].y, pathVectors[0].z);
            this._tmpAmmoVectorB.setValue(pathVectors[len - 1].x, pathVectors[len - 1].y, pathVectors[len - 1].z);
        }
        impostor.segments = segments;
        var fixedPoints = impostor.getParam("fixedPoints");
        fixedPoints = (fixedPoints > 3) ? 3 : fixedPoints;
        var ropeBody = new Ammo.btSoftBodyHelpers().CreateRope(this.world.getWorldInfo(), this._tmpAmmoVectorA, this._tmpAmmoVectorB, segments - 1, fixedPoints);
        ropeBody.get_m_cfg().set_collisions(0x11);
        return ropeBody;
    };
    // adds all verticies (including child verticies) to the convex hull shape
    AmmoJSPlugin.prototype._addHullVerts = function (btConvexHullShape, topLevelObject, object) {
        var _this = this;
        var triangleCount = 0;
        if (object && object.getIndices && object.getWorldMatrix && object.getChildMeshes) {
            var indices = object.getIndices();
            if (!indices) {
                indices = [];
            }
            var vertexPositions = object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind);
            if (!vertexPositions) {
                vertexPositions = [];
            }
            object.computeWorldMatrix(false);
            var faceCount = indices.length / 3;
            for (var i = 0; i < faceCount; i++) {
                var triPoints = [];
                for (var point = 0; point < 3; point++) {
                    var v = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](vertexPositions[(indices[(i * 3) + point] * 3) + 0], vertexPositions[(indices[(i * 3) + point] * 3) + 1], vertexPositions[(indices[(i * 3) + point] * 3) + 2]);
                    // Adjust for initial scaling
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].ScalingToRef(object.scaling.x, object.scaling.y, object.scaling.z, this._tmpMatrix);
                    v = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinates(v, this._tmpMatrix);
                    var vec;
                    if (point == 0) {
                        vec = this._tmpAmmoVectorA;
                    }
                    else if (point == 1) {
                        vec = this._tmpAmmoVectorB;
                    }
                    else {
                        vec = this._tmpAmmoVectorC;
                    }
                    vec.setValue(v.x, v.y, v.z);
                    triPoints.push(vec);
                }
                btConvexHullShape.addPoint(triPoints[0], true);
                btConvexHullShape.addPoint(triPoints[1], true);
                btConvexHullShape.addPoint(triPoints[2], true);
                triangleCount++;
            }
            object.getChildMeshes().forEach(function (m) {
                triangleCount += _this._addHullVerts(btConvexHullShape, topLevelObject, m);
            });
        }
        return triangleCount;
    };
    AmmoJSPlugin.prototype._createShape = function (impostor, ignoreChildren) {
        var _this = this;
        if (ignoreChildren === void 0) { ignoreChildren = false; }
        var object = impostor.object;
        var returnValue;
        var extendSize = impostor.getObjectExtendSize();
        if (!ignoreChildren) {
            var meshChildren = impostor.object.getChildMeshes ? impostor.object.getChildMeshes(true) : [];
            returnValue = new Ammo.btCompoundShape();
            // Add shape of all children to the compound shape
            var childrenAdded = 0;
            meshChildren.forEach(function (childMesh) {
                var childImpostor = childMesh.getPhysicsImpostor();
                if (childImpostor) {
                    if (childImpostor.type == _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].MeshImpostor) {
                        throw "A child MeshImpostor is not supported. Only primitive impostors are supported as children (eg. box or sphere)";
                    }
                    var shape = _this._createShape(childImpostor);
                    // Position needs to be scaled based on parent's scaling
                    var parentMat = childMesh.parent.getWorldMatrix().clone();
                    var s = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"]();
                    parentMat.decompose(s);
                    _this._tmpAmmoTransform.getOrigin().setValue(childMesh.position.x * s.x, childMesh.position.y * s.y, childMesh.position.z * s.z);
                    _this._tmpAmmoQuaternion.setValue(childMesh.rotationQuaternion.x, childMesh.rotationQuaternion.y, childMesh.rotationQuaternion.z, childMesh.rotationQuaternion.w);
                    _this._tmpAmmoTransform.setRotation(_this._tmpAmmoQuaternion);
                    returnValue.addChildShape(_this._tmpAmmoTransform, shape);
                    childImpostor.dispose();
                    childrenAdded++;
                }
            });
            if (childrenAdded > 0) {
                // Add parents shape as a child if present
                if (impostor.type != _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].NoImpostor) {
                    var shape = this._createShape(impostor, true);
                    if (shape) {
                        this._tmpAmmoTransform.getOrigin().setValue(0, 0, 0);
                        this._tmpAmmoQuaternion.setValue(0, 0, 0, 1);
                        this._tmpAmmoTransform.setRotation(this._tmpAmmoQuaternion);
                        returnValue.addChildShape(this._tmpAmmoTransform, shape);
                    }
                }
                return returnValue;
            }
            else {
                // If no children with impostors create the actual shape below instead
                Ammo.destroy(returnValue);
                returnValue = null;
            }
        }
        switch (impostor.type) {
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].SphereImpostor:
                // Is there a better way to compare floats number? With an epsylon or with a Math function
                if (_Maths_math_scalar__WEBPACK_IMPORTED_MODULE_9__["Scalar"].WithinEpsilon(extendSize.x, extendSize.y, 0.0001) && _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_9__["Scalar"].WithinEpsilon(extendSize.x, extendSize.z, 0.0001)) {
                    returnValue = new Ammo.btSphereShape(extendSize.x / 2);
                }
                else {
                    // create a btMultiSphereShape because it's not possible to set a local scaling on a btSphereShape
                    var positions = [new Ammo.btVector3(0, 0, 0)];
                    var radii = [1];
                    returnValue = new Ammo.btMultiSphereShape(positions, radii, 1);
                    returnValue.setLocalScaling(new Ammo.btVector3(extendSize.x / 2, extendSize.y / 2, extendSize.z / 2));
                }
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].CapsuleImpostor:
                returnValue = new Ammo.btCapsuleShape(extendSize.x / 2, extendSize.y / 2);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].CylinderImpostor:
                this._tmpAmmoVectorA.setValue(extendSize.x / 2, extendSize.y / 2, extendSize.z / 2);
                returnValue = new Ammo.btCylinderShape(this._tmpAmmoVectorA);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].PlaneImpostor:
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].BoxImpostor:
                this._tmpAmmoVectorA.setValue(extendSize.x / 2, extendSize.y / 2, extendSize.z / 2);
                returnValue = new Ammo.btBoxShape(this._tmpAmmoVectorA);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].MeshImpostor:
                if (impostor.getParam("mass") == 0) {
                    // Only create btBvhTriangleMeshShape impostor is static
                    // See https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=7283
                    var tetraMesh = new Ammo.btTriangleMesh();
                    impostor._pluginData.toDispose.push(tetraMesh);
                    var triangeCount = this._addMeshVerts(tetraMesh, object, object);
                    if (triangeCount == 0) {
                        returnValue = new Ammo.btCompoundShape();
                    }
                    else {
                        returnValue = new Ammo.btBvhTriangleMeshShape(tetraMesh);
                    }
                    break;
                }
            // Otherwise create convexHullImpostor
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].ConvexHullImpostor:
                var convexMesh = new Ammo.btConvexHullShape();
                var triangeCount = this._addHullVerts(convexMesh, object, object);
                if (triangeCount == 0) {
                    // Cleanup Unused Convex Hull Shape
                    impostor._pluginData.toDispose.push(convexMesh);
                    returnValue = new Ammo.btCompoundShape();
                }
                else {
                    returnValue = convexMesh;
                }
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].NoImpostor:
                // Fill with sphere but collision is disabled on the rigid body in generatePhysicsBody, using an empty shape caused unexpected movement with joints
                returnValue = new Ammo.btSphereShape(extendSize.x / 2);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].SoftbodyImpostor:
                // Only usable with a mesh that has sufficient and shared vertices
                returnValue = this._createSoftbody(impostor);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].ClothImpostor:
                // Only usable with a ground mesh that has sufficient and shared vertices
                returnValue = this._createCloth(impostor);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].RopeImpostor:
                // Only usable with a line mesh or an extruded mesh that is updatable
                returnValue = this._createRope(impostor);
                break;
            default:
                _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("The impostor type is not currently supported by the ammo plugin.");
                break;
        }
        return returnValue;
    };
    /**
     * Sets the physics body position/rotation from the babylon mesh's position/rotation
     * @param impostor imposter containing the physics body and babylon object
     */
    AmmoJSPlugin.prototype.setTransformationFromPhysicsBody = function (impostor) {
        impostor.physicsBody.getMotionState().getWorldTransform(this._tmpAmmoTransform);
        impostor.object.position.set(this._tmpAmmoTransform.getOrigin().x(), this._tmpAmmoTransform.getOrigin().y(), this._tmpAmmoTransform.getOrigin().z());
        if (!impostor.object.rotationQuaternion) {
            if (impostor.object.rotation) {
                this._tmpQuaternion.set(this._tmpAmmoTransform.getRotation().x(), this._tmpAmmoTransform.getRotation().y(), this._tmpAmmoTransform.getRotation().z(), this._tmpAmmoTransform.getRotation().w());
                this._tmpQuaternion.toEulerAnglesToRef(impostor.object.rotation);
            }
        }
        else {
            impostor.object.rotationQuaternion.set(this._tmpAmmoTransform.getRotation().x(), this._tmpAmmoTransform.getRotation().y(), this._tmpAmmoTransform.getRotation().z(), this._tmpAmmoTransform.getRotation().w());
        }
    };
    /**
     * Sets the babylon object's position/rotation from the physics body's position/rotation
     * @param impostor imposter containing the physics body and babylon object
     * @param newPosition new position
     * @param newRotation new rotation
     */
    AmmoJSPlugin.prototype.setPhysicsBodyTransformation = function (impostor, newPosition, newRotation) {
        var trans = impostor.physicsBody.getWorldTransform();
        // If rotation/position has changed update and activate riged body
        if (trans.getOrigin().x() != newPosition.x ||
            trans.getOrigin().y() != newPosition.y ||
            trans.getOrigin().z() != newPosition.z ||
            trans.getRotation().x() != newRotation.x ||
            trans.getRotation().y() != newRotation.y ||
            trans.getRotation().z() != newRotation.z ||
            trans.getRotation().w() != newRotation.w) {
            this._tmpAmmoVectorA.setValue(newPosition.x, newPosition.y, newPosition.z);
            trans.setOrigin(this._tmpAmmoVectorA);
            this._tmpAmmoQuaternion.setValue(newRotation.x, newRotation.y, newRotation.z, newRotation.w);
            trans.setRotation(this._tmpAmmoQuaternion);
            impostor.physicsBody.setWorldTransform(trans);
            if (impostor.mass == 0) {
                // Kinematic objects must be updated using motion state
                var motionState = impostor.physicsBody.getMotionState();
                if (motionState) {
                    motionState.setWorldTransform(trans);
                }
            }
            else {
                impostor.physicsBody.activate();
            }
        }
    };
    /**
     * If this plugin is supported
     * @returns true if its supported
     */
    AmmoJSPlugin.prototype.isSupported = function () {
        return this.bjsAMMO !== undefined;
    };
    /**
     * Sets the linear velocity of the physics body
     * @param impostor imposter to set the velocity on
     * @param velocity velocity to set
     */
    AmmoJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
        this._tmpAmmoVectorA.setValue(velocity.x, velocity.y, velocity.z);
        if (impostor.soft) {
            impostor.physicsBody.linearVelocity(this._tmpAmmoVectorA);
        }
        else {
            impostor.physicsBody.setLinearVelocity(this._tmpAmmoVectorA);
        }
    };
    /**
     * Sets the angular velocity of the physics body
     * @param impostor imposter to set the velocity on
     * @param velocity velocity to set
     */
    AmmoJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
        this._tmpAmmoVectorA.setValue(velocity.x, velocity.y, velocity.z);
        if (impostor.soft) {
            impostor.physicsBody.angularVelocity(this._tmpAmmoVectorA);
        }
        else {
            impostor.physicsBody.setAngularVelocity(this._tmpAmmoVectorA);
        }
    };
    /**
     * gets the linear velocity
     * @param impostor imposter to get linear velocity from
     * @returns linear velocity
     */
    AmmoJSPlugin.prototype.getLinearVelocity = function (impostor) {
        if (impostor.soft) {
            var v = impostor.physicsBody.linearVelocity();
        }
        else {
            var v = impostor.physicsBody.getLinearVelocity();
        }
        if (!v) {
            return null;
        }
        var result = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](v.x(), v.y(), v.z());
        Ammo.destroy(v);
        return result;
    };
    /**
     * gets the angular velocity
     * @param impostor imposter to get angular velocity from
     * @returns angular velocity
     */
    AmmoJSPlugin.prototype.getAngularVelocity = function (impostor) {
        if (impostor.soft) {
            var v = impostor.physicsBody.angularVelocity();
        }
        else {
            var v = impostor.physicsBody.getAngularVelocity();
        }
        if (!v) {
            return null;
        }
        var result = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](v.x(), v.y(), v.z());
        Ammo.destroy(v);
        return result;
    };
    /**
     * Sets the mass of physics body
     * @param impostor imposter to set the mass on
     * @param mass mass to set
     */
    AmmoJSPlugin.prototype.setBodyMass = function (impostor, mass) {
        if (impostor.soft) {
            impostor.physicsBody.setTotalMass(mass, false);
        }
        else {
            impostor.physicsBody.setMassProps(mass);
        }
        impostor._pluginData.mass = mass;
    };
    /**
     * Gets the mass of the physics body
     * @param impostor imposter to get the mass from
     * @returns mass
     */
    AmmoJSPlugin.prototype.getBodyMass = function (impostor) {
        return impostor._pluginData.mass || 0;
    };
    /**
     * Gets friction of the impostor
     * @param impostor impostor to get friction from
     * @returns friction value
     */
    AmmoJSPlugin.prototype.getBodyFriction = function (impostor) {
        return impostor._pluginData.friction || 0;
    };
    /**
     * Sets friction of the impostor
     * @param impostor impostor to set friction on
     * @param friction friction value
     */
    AmmoJSPlugin.prototype.setBodyFriction = function (impostor, friction) {
        if (impostor.soft) {
            impostor.physicsBody.get_m_cfg().set_kDF(friction);
        }
        else {
            impostor.physicsBody.setFriction(friction);
        }
        impostor._pluginData.friction = friction;
    };
    /**
     * Gets restitution of the impostor
     * @param impostor impostor to get restitution from
     * @returns restitution value
     */
    AmmoJSPlugin.prototype.getBodyRestitution = function (impostor) {
        return impostor._pluginData.restitution || 0;
    };
    /**
     * Sets resitution of the impostor
     * @param impostor impostor to set resitution on
     * @param restitution resitution value
     */
    AmmoJSPlugin.prototype.setBodyRestitution = function (impostor, restitution) {
        impostor.physicsBody.setRestitution(restitution);
        impostor._pluginData.restitution = restitution;
    };
    /**
     * Gets pressure inside the impostor
     * @param impostor impostor to get pressure from
     * @returns pressure value
     */
    AmmoJSPlugin.prototype.getBodyPressure = function (impostor) {
        if (!impostor.soft) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Pressure is not a property of a rigid body");
            return 0;
        }
        return impostor._pluginData.pressure || 0;
    };
    /**
     * Sets pressure inside a soft body impostor
     * Cloth and rope must remain 0 pressure
     * @param impostor impostor to set pressure on
     * @param pressure pressure value
     */
    AmmoJSPlugin.prototype.setBodyPressure = function (impostor, pressure) {
        if (impostor.soft) {
            if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_2__["PhysicsImpostor"].SoftbodyImpostor) {
                impostor.physicsBody.get_m_cfg().set_kPR(pressure);
                impostor._pluginData.pressure = pressure;
            }
            else {
                impostor.physicsBody.get_m_cfg().set_kPR(0);
                impostor._pluginData.pressure = 0;
            }
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Pressure can only be applied to a softbody");
        }
    };
    /**
     * Gets stiffness of the impostor
     * @param impostor impostor to get stiffness from
     * @returns pressure value
     */
    AmmoJSPlugin.prototype.getBodyStiffness = function (impostor) {
        if (!impostor.soft) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Stiffness is not a property of a rigid body");
            return 0;
        }
        return impostor._pluginData.stiffness || 0;
    };
    /**
     * Sets stiffness of the impostor
     * @param impostor impostor to set stiffness on
     * @param stiffness stiffness value from 0 to 1
     */
    AmmoJSPlugin.prototype.setBodyStiffness = function (impostor, stiffness) {
        if (impostor.soft) {
            stiffness = stiffness < 0 ? 0 : stiffness;
            stiffness = stiffness > 1 ? 1 : stiffness;
            impostor.physicsBody.get_m_materials().at(0).set_m_kLST(stiffness);
            impostor._pluginData.stiffness = stiffness;
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Stiffness cannot be applied to a rigid body");
        }
    };
    /**
     * Gets velocityIterations of the impostor
     * @param impostor impostor to get velocity iterations from
     * @returns velocityIterations value
     */
    AmmoJSPlugin.prototype.getBodyVelocityIterations = function (impostor) {
        if (!impostor.soft) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Velocity iterations is not a property of a rigid body");
            return 0;
        }
        return impostor._pluginData.velocityIterations || 0;
    };
    /**
     * Sets velocityIterations of the impostor
     * @param impostor impostor to set velocity iterations on
     * @param velocityIterations velocityIterations value
     */
    AmmoJSPlugin.prototype.setBodyVelocityIterations = function (impostor, velocityIterations) {
        if (impostor.soft) {
            velocityIterations = velocityIterations < 0 ? 0 : velocityIterations;
            impostor.physicsBody.get_m_cfg().set_viterations(velocityIterations);
            impostor._pluginData.velocityIterations = velocityIterations;
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Velocity iterations cannot be applied to a rigid body");
        }
    };
    /**
     * Gets positionIterations of the impostor
     * @param impostor impostor to get position iterations from
     * @returns positionIterations value
     */
    AmmoJSPlugin.prototype.getBodyPositionIterations = function (impostor) {
        if (!impostor.soft) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Position iterations is not a property of a rigid body");
            return 0;
        }
        return impostor._pluginData.positionIterations || 0;
    };
    /**
     * Sets positionIterations of the impostor
     * @param impostor impostor to set position on
     * @param positionIterations positionIterations value
     */
    AmmoJSPlugin.prototype.setBodyPositionIterations = function (impostor, positionIterations) {
        if (impostor.soft) {
            positionIterations = positionIterations < 0 ? 0 : positionIterations;
            impostor.physicsBody.get_m_cfg().set_piterations(positionIterations);
            impostor._pluginData.positionIterations = positionIterations;
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Position iterations cannot be applied to a rigid body");
        }
    };
    /**
    * Append an anchor to a cloth object
    * @param impostor is the cloth impostor to add anchor to
    * @param otherImpostor is the rigid impostor to anchor to
    * @param width ratio across width from 0 to 1
    * @param height ratio up height from 0 to 1
    * @param influence the elasticity between cloth impostor and anchor from 0, very stretchy to 1, little strech
    * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false
    */
    AmmoJSPlugin.prototype.appendAnchor = function (impostor, otherImpostor, width, height, influence, noCollisionBetweenLinkedBodies) {
        if (influence === void 0) { influence = 1; }
        if (noCollisionBetweenLinkedBodies === void 0) { noCollisionBetweenLinkedBodies = false; }
        var segs = impostor.segments;
        var nbAcross = Math.round((segs - 1) * width);
        var nbUp = Math.round((segs - 1) * height);
        var nbDown = segs - 1 - nbUp;
        var node = nbAcross + segs * nbDown;
        impostor.physicsBody.appendAnchor(node, otherImpostor.physicsBody, noCollisionBetweenLinkedBodies, influence);
    };
    /**
     * Append an hook to a rope object
     * @param impostor is the rope impostor to add hook to
     * @param otherImpostor is the rigid impostor to hook to
     * @param length ratio along the rope from 0 to 1
     * @param influence the elasticity between soft impostor and anchor from 0, very stretchy to 1, little strech
     * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false
     */
    AmmoJSPlugin.prototype.appendHook = function (impostor, otherImpostor, length, influence, noCollisionBetweenLinkedBodies) {
        if (influence === void 0) { influence = 1; }
        if (noCollisionBetweenLinkedBodies === void 0) { noCollisionBetweenLinkedBodies = false; }
        var node = Math.round(impostor.segments * length);
        impostor.physicsBody.appendAnchor(node, otherImpostor.physicsBody, noCollisionBetweenLinkedBodies, influence);
    };
    /**
     * Sleeps the physics body and stops it from being active
     * @param impostor impostor to sleep
     */
    AmmoJSPlugin.prototype.sleepBody = function (impostor) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("sleepBody is not currently supported by the Ammo physics plugin");
    };
    /**
     * Activates the physics body
     * @param impostor impostor to activate
     */
    AmmoJSPlugin.prototype.wakeUpBody = function (impostor) {
        impostor.physicsBody.activate();
    };
    /**
     * Updates the distance parameters of the joint
     * @param joint joint to update
     * @param maxDistance maximum distance of the joint
     * @param minDistance minimum distance of the joint
     */
    AmmoJSPlugin.prototype.updateDistanceJoint = function (joint, maxDistance, minDistance) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("updateDistanceJoint is not currently supported by the Ammo physics plugin");
    };
    /**
     * Sets a motor on the joint
     * @param joint joint to set motor on
     * @param speed speed of the motor
     * @param maxForce maximum force of the motor
     * @param motorIndex index of the motor
     */
    AmmoJSPlugin.prototype.setMotor = function (joint, speed, maxForce, motorIndex) {
        joint.physicsJoint.enableAngularMotor(true, speed, maxForce);
    };
    /**
     * Sets the motors limit
     * @param joint joint to set limit on
     * @param upperLimit upper limit
     * @param lowerLimit lower limit
     */
    AmmoJSPlugin.prototype.setLimit = function (joint, upperLimit, lowerLimit) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("setLimit is not currently supported by the Ammo physics plugin");
    };
    /**
     * Syncs the position and rotation of a mesh with the impostor
     * @param mesh mesh to sync
     * @param impostor impostor to update the mesh with
     */
    AmmoJSPlugin.prototype.syncMeshWithImpostor = function (mesh, impostor) {
        var body = impostor.physicsBody;
        body.getMotionState().getWorldTransform(this._tmpAmmoTransform);
        mesh.position.x = this._tmpAmmoTransform.getOrigin().x();
        mesh.position.y = this._tmpAmmoTransform.getOrigin().y();
        mesh.position.z = this._tmpAmmoTransform.getOrigin().z();
        if (mesh.rotationQuaternion) {
            mesh.rotationQuaternion.x = this._tmpAmmoTransform.getRotation().x();
            mesh.rotationQuaternion.y = this._tmpAmmoTransform.getRotation().y();
            mesh.rotationQuaternion.z = this._tmpAmmoTransform.getRotation().z();
            mesh.rotationQuaternion.w = this._tmpAmmoTransform.getRotation().w();
        }
    };
    /**
     * Gets the radius of the impostor
     * @param impostor impostor to get radius from
     * @returns the radius
     */
    AmmoJSPlugin.prototype.getRadius = function (impostor) {
        var exntend = impostor.getObjectExtendSize();
        return exntend.x / 2;
    };
    /**
     * Gets the box size of the impostor
     * @param impostor impostor to get box size from
     * @param result the resulting box size
     */
    AmmoJSPlugin.prototype.getBoxSizeToRef = function (impostor, result) {
        var exntend = impostor.getObjectExtendSize();
        result.x = exntend.x;
        result.y = exntend.y;
        result.z = exntend.z;
    };
    /**
     * Disposes of the impostor
     */
    AmmoJSPlugin.prototype.dispose = function () {
        // Dispose of world
        Ammo.destroy(this.world);
        Ammo.destroy(this._solver);
        Ammo.destroy(this._overlappingPairCache);
        Ammo.destroy(this._dispatcher);
        Ammo.destroy(this._collisionConfiguration);
        // Dispose of tmp variables
        Ammo.destroy(this._tmpAmmoVectorA);
        Ammo.destroy(this._tmpAmmoVectorB);
        Ammo.destroy(this._tmpAmmoVectorC);
        Ammo.destroy(this._tmpAmmoTransform);
        Ammo.destroy(this._tmpAmmoQuaternion);
        Ammo.destroy(this._tmpAmmoConcreteContactResultCallback);
        this.world = null;
    };
    /**
     * Does a raycast in the physics world
     * @param from when should the ray start?
     * @param to when should the ray end?
     * @returns PhysicsRaycastResult
     */
    AmmoJSPlugin.prototype.raycast = function (from, to) {
        this._tmpAmmoVectorRCA = new this.bjsAMMO.btVector3(from.x, from.y, from.z);
        this._tmpAmmoVectorRCB = new this.bjsAMMO.btVector3(to.x, to.y, to.z);
        var rayCallback = new this.bjsAMMO.ClosestRayResultCallback(this._tmpAmmoVectorRCA, this._tmpAmmoVectorRCB);
        this.world.rayTest(this._tmpAmmoVectorRCA, this._tmpAmmoVectorRCB, rayCallback);
        this._raycastResult.reset(from, to);
        if (rayCallback.hasHit()) {
            // TODO: do we want/need the body? If so, set all the data
            /*
            var rigidBody = this.bjsAMMO.btRigidBody.prototype.upcast(
                rayCallback.get_m_collisionObject()
            );
            var body = {};
            */
            this._raycastResult.setHitData({
                x: rayCallback.get_m_hitNormalWorld().x(),
                y: rayCallback.get_m_hitNormalWorld().y(),
                z: rayCallback.get_m_hitNormalWorld().z(),
            }, {
                x: rayCallback.get_m_hitPointWorld().x(),
                y: rayCallback.get_m_hitPointWorld().y(),
                z: rayCallback.get_m_hitPointWorld().z(),
            });
            this._raycastResult.calculateHitDistance();
        }
        Ammo.destroy(rayCallback);
        Ammo.destroy(this._tmpAmmoVectorRCA);
        Ammo.destroy(this._tmpAmmoVectorRCB);
        return this._raycastResult;
    };
    AmmoJSPlugin.DISABLE_COLLISION_FLAG = 4;
    AmmoJSPlugin.KINEMATIC_FLAG = 2;
    AmmoJSPlugin.DISABLE_DEACTIVATION_FLAG = 4;
    return AmmoJSPlugin;
}());



/***/ }),

/***/ "./Physics/Plugins/cannonJSPlugin.ts":
/*!*******************************************!*\
  !*** ./Physics/Plugins/cannonJSPlugin.ts ***!
  \*******************************************/
/*! exports provided: CannonJSPlugin */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CannonJSPlugin", function() { return CannonJSPlugin; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Physics/physicsImpostor */ "./Physics/physicsImpostor.ts");
/* harmony import */ var _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Physics/physicsJoint */ "./Physics/physicsJoint.ts");
/* harmony import */ var _Physics_physicsEngine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../Physics/physicsEngine */ "./Physics/physicsEngine.ts");
/* harmony import */ var _physicsRaycastResult__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../physicsRaycastResult */ "./Physics/physicsRaycastResult.ts");







/** @hidden */
var CannonJSPlugin = /** @class */ (function () {
    function CannonJSPlugin(_useDeltaForWorldStep, iterations, cannonInjection) {
        if (_useDeltaForWorldStep === void 0) { _useDeltaForWorldStep = true; }
        if (iterations === void 0) { iterations = 10; }
        if (cannonInjection === void 0) { cannonInjection = CANNON; }
        this._useDeltaForWorldStep = _useDeltaForWorldStep;
        this.name = "CannonJSPlugin";
        this._physicsMaterials = new Array();
        this._fixedTimeStep = 1 / 60;
        this._physicsBodysToRemoveAfterStep = new Array();
        this._minus90X = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"](-0.7071067811865475, 0, 0, 0.7071067811865475);
        this._plus90X = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"](0.7071067811865475, 0, 0, 0.7071067811865475);
        this._tmpPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this._tmpDeltaPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        this._tmpUnityRotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"]();
        this.BJSCANNON = cannonInjection;
        if (!this.isSupported()) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("CannonJS is not available. Please make sure you included the js file.");
            return;
        }
        this._extendNamespace();
        this.world = new this.BJSCANNON.World();
        this.world.broadphase = new this.BJSCANNON.NaiveBroadphase();
        this.world.solver.iterations = iterations;
        this._cannonRaycastResult = new this.BJSCANNON.RaycastResult();
        this._raycastResult = new _physicsRaycastResult__WEBPACK_IMPORTED_MODULE_6__["PhysicsRaycastResult"]();
    }
    CannonJSPlugin.prototype.setGravity = function (gravity) {
        this.world.gravity.copy(gravity);
    };
    CannonJSPlugin.prototype.setTimeStep = function (timeStep) {
        this._fixedTimeStep = timeStep;
    };
    CannonJSPlugin.prototype.getTimeStep = function () {
        return this._fixedTimeStep;
    };
    CannonJSPlugin.prototype.executeStep = function (delta) {
        this.world.step(this._fixedTimeStep, this._useDeltaForWorldStep ? delta : 0, 3);
        this._removeMarkedPhysicsBodiesFromWorld();
    };
    CannonJSPlugin.prototype._removeMarkedPhysicsBodiesFromWorld = function () {
        var _this = this;
        if (this._physicsBodysToRemoveAfterStep.length > 0) {
            this._physicsBodysToRemoveAfterStep.forEach(function (physicsBody) {
                _this.world.remove(physicsBody);
            });
            this._physicsBodysToRemoveAfterStep = [];
        }
    };
    CannonJSPlugin.prototype.applyImpulse = function (impostor, force, contactPoint) {
        var worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
        var impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);
        impostor.physicsBody.applyImpulse(impulse, worldPoint);
    };
    CannonJSPlugin.prototype.applyForce = function (impostor, force, contactPoint) {
        var worldPoint = new this.BJSCANNON.Vec3(contactPoint.x, contactPoint.y, contactPoint.z);
        var impulse = new this.BJSCANNON.Vec3(force.x, force.y, force.z);
        impostor.physicsBody.applyForce(impulse, worldPoint);
    };
    CannonJSPlugin.prototype.generatePhysicsBody = function (impostor) {
        // When calling forceUpdate generatePhysicsBody is called again, ensure that the updated body does not instantly collide with removed body
        this._removeMarkedPhysicsBodiesFromWorld();
        //parent-child relationship. Does this impostor has a parent impostor?
        if (impostor.parent) {
            if (impostor.physicsBody) {
                this.removePhysicsBody(impostor);
                //TODO is that needed?
                impostor.forceUpdate();
            }
            return;
        }
        //should a new body be created for this impostor?
        if (impostor.isBodyInitRequired()) {
            var shape = this._createShape(impostor);
            //unregister events, if body is being changed
            var oldBody = impostor.physicsBody;
            if (oldBody) {
                this.removePhysicsBody(impostor);
            }
            //create the body and material
            var material = this._addMaterial("mat-" + impostor.uniqueId, impostor.getParam("friction"), impostor.getParam("restitution"));
            var bodyCreationObject = {
                mass: impostor.getParam("mass"),
                material: material
            };
            // A simple extend, in case native options were used.
            var nativeOptions = impostor.getParam("nativeOptions");
            for (var key in nativeOptions) {
                if (nativeOptions.hasOwnProperty(key)) {
                    bodyCreationObject[key] = nativeOptions[key];
                }
            }
            impostor.physicsBody = new this.BJSCANNON.Body(bodyCreationObject);
            impostor.physicsBody.addEventListener("collide", impostor.onCollide);
            this.world.addEventListener("preStep", impostor.beforeStep);
            this.world.addEventListener("postStep", impostor.afterStep);
            impostor.physicsBody.addShape(shape);
            this.world.add(impostor.physicsBody);
            //try to keep the body moving in the right direction by taking old properties.
            //Should be tested!
            if (oldBody) {
                ['force', 'torque', 'velocity', 'angularVelocity'].forEach(function (param) {
                    impostor.physicsBody[param].copy(oldBody[param]);
                });
            }
            this._processChildMeshes(impostor);
        }
        //now update the body's transformation
        this._updatePhysicsBodyTransformation(impostor);
    };
    CannonJSPlugin.prototype._processChildMeshes = function (mainImpostor) {
        var _this = this;
        var meshChildren = mainImpostor.object.getChildMeshes ? mainImpostor.object.getChildMeshes(true) : [];
        var currentRotation = mainImpostor.object.rotationQuaternion;
        if (meshChildren.length) {
            var processMesh = function (localPosition, mesh) {
                if (!currentRotation || !mesh.rotationQuaternion) {
                    return;
                }
                var childImpostor = mesh.getPhysicsImpostor();
                if (childImpostor) {
                    var parent = childImpostor.parent;
                    if (parent !== mainImpostor) {
                        var pPosition = mesh.getAbsolutePosition().subtract(mainImpostor.object.getAbsolutePosition());
                        var localRotation = mesh.rotationQuaternion.multiply(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Quaternion"].Inverse(currentRotation));
                        if (childImpostor.physicsBody) {
                            _this.removePhysicsBody(childImpostor);
                            childImpostor.physicsBody = null;
                        }
                        childImpostor.parent = mainImpostor;
                        childImpostor.resetUpdateFlags();
                        mainImpostor.physicsBody.addShape(_this._createShape(childImpostor), new _this.BJSCANNON.Vec3(pPosition.x, pPosition.y, pPosition.z), new _this.BJSCANNON.Quaternion(localRotation.x, localRotation.y, localRotation.z, localRotation.w));
                        //Add the mass of the children.
                        mainImpostor.physicsBody.mass += childImpostor.getParam("mass");
                    }
                }
                currentRotation.multiplyInPlace(mesh.rotationQuaternion);
                mesh.getChildMeshes(true).filter(function (m) { return !!m.physicsImpostor; }).forEach(processMesh.bind(_this, mesh.getAbsolutePosition()));
            };
            meshChildren.filter(function (m) { return !!m.physicsImpostor; }).forEach(processMesh.bind(this, mainImpostor.object.getAbsolutePosition()));
        }
    };
    CannonJSPlugin.prototype.removePhysicsBody = function (impostor) {
        impostor.physicsBody.removeEventListener("collide", impostor.onCollide);
        this.world.removeEventListener("preStep", impostor.beforeStep);
        this.world.removeEventListener("postStep", impostor.afterStep);
        // Only remove the physics body after the physics step to avoid disrupting cannon's internal state
        if (this._physicsBodysToRemoveAfterStep.indexOf(impostor.physicsBody) === -1) {
            this._physicsBodysToRemoveAfterStep.push(impostor.physicsBody);
        }
    };
    CannonJSPlugin.prototype.generateJoint = function (impostorJoint) {
        var mainBody = impostorJoint.mainImpostor.physicsBody;
        var connectedBody = impostorJoint.connectedImpostor.physicsBody;
        if (!mainBody || !connectedBody) {
            return;
        }
        var constraint;
        var jointData = impostorJoint.joint.jointData;
        //TODO - https://github.com/schteppe/this.BJSCANNON.js/blob/gh-pages/demos/collisionFilter.html
        var constraintData = {
            pivotA: jointData.mainPivot ? new this.BJSCANNON.Vec3().copy(jointData.mainPivot) : null,
            pivotB: jointData.connectedPivot ? new this.BJSCANNON.Vec3().copy(jointData.connectedPivot) : null,
            axisA: jointData.mainAxis ? new this.BJSCANNON.Vec3().copy(jointData.mainAxis) : null,
            axisB: jointData.connectedAxis ? new this.BJSCANNON.Vec3().copy(jointData.connectedAxis) : null,
            maxForce: jointData.nativeParams.maxForce,
            collideConnected: !!jointData.collision
        };
        switch (impostorJoint.joint.type) {
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].HingeJoint:
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].Hinge2Joint:
                constraint = new this.BJSCANNON.HingeConstraint(mainBody, connectedBody, constraintData);
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].DistanceJoint:
                constraint = new this.BJSCANNON.DistanceConstraint(mainBody, connectedBody, jointData.maxDistance || 2);
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].SpringJoint:
                var springData = jointData;
                constraint = new this.BJSCANNON.Spring(mainBody, connectedBody, {
                    restLength: springData.length,
                    stiffness: springData.stiffness,
                    damping: springData.damping,
                    localAnchorA: constraintData.pivotA,
                    localAnchorB: constraintData.pivotB
                });
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].LockJoint:
                constraint = new this.BJSCANNON.LockConstraint(mainBody, connectedBody, constraintData);
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].PointToPointJoint:
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].BallAndSocketJoint:
            default:
                constraint = new this.BJSCANNON.PointToPointConstraint(mainBody, constraintData.pivotA, connectedBody, constraintData.pivotB, constraintData.maxForce);
                break;
        }
        //set the collideConnected flag after the creation, since DistanceJoint ignores it.
        constraint.collideConnected = !!jointData.collision;
        impostorJoint.joint.physicsJoint = constraint;
        //don't add spring as constraint, as it is not one.
        if (impostorJoint.joint.type !== _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].SpringJoint) {
            this.world.addConstraint(constraint);
        }
        else {
            impostorJoint.joint.jointData.forceApplicationCallback = impostorJoint.joint.jointData.forceApplicationCallback || function () {
                constraint.applyForce();
            };
            impostorJoint.mainImpostor.registerAfterPhysicsStep(impostorJoint.joint.jointData.forceApplicationCallback);
        }
    };
    CannonJSPlugin.prototype.removeJoint = function (impostorJoint) {
        if (impostorJoint.joint.type !== _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"].SpringJoint) {
            this.world.removeConstraint(impostorJoint.joint.physicsJoint);
        }
        else {
            impostorJoint.mainImpostor.unregisterAfterPhysicsStep(impostorJoint.joint.jointData.forceApplicationCallback);
        }
    };
    CannonJSPlugin.prototype._addMaterial = function (name, friction, restitution) {
        var index;
        var mat;
        for (index = 0; index < this._physicsMaterials.length; index++) {
            mat = this._physicsMaterials[index];
            if (mat.friction === friction && mat.restitution === restitution) {
                return mat;
            }
        }
        var currentMat = new this.BJSCANNON.Material(name);
        currentMat.friction = friction;
        currentMat.restitution = restitution;
        this._physicsMaterials.push(currentMat);
        return currentMat;
    };
    CannonJSPlugin.prototype._checkWithEpsilon = function (value) {
        return value < _Physics_physicsEngine__WEBPACK_IMPORTED_MODULE_5__["PhysicsEngine"].Epsilon ? _Physics_physicsEngine__WEBPACK_IMPORTED_MODULE_5__["PhysicsEngine"].Epsilon : value;
    };
    CannonJSPlugin.prototype._createShape = function (impostor) {
        var object = impostor.object;
        var returnValue;
        var extendSize = impostor.getObjectExtendSize();
        switch (impostor.type) {
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].SphereImpostor:
                var radiusX = extendSize.x;
                var radiusY = extendSize.y;
                var radiusZ = extendSize.z;
                returnValue = new this.BJSCANNON.Sphere(Math.max(this._checkWithEpsilon(radiusX), this._checkWithEpsilon(radiusY), this._checkWithEpsilon(radiusZ)) / 2);
                break;
            //TMP also for cylinder - TODO Cannon supports cylinder natively.
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].CylinderImpostor:
                var nativeParams = impostor.getParam("nativeOptions");
                if (!nativeParams) {
                    nativeParams = {};
                }
                var radiusTop = nativeParams.radiusTop !== undefined ? nativeParams.radiusTop : this._checkWithEpsilon(extendSize.x) / 2;
                var radiusBottom = nativeParams.radiusBottom !== undefined ? nativeParams.radiusBottom : this._checkWithEpsilon(extendSize.x) / 2;
                var height = nativeParams.height !== undefined ? nativeParams.height : this._checkWithEpsilon(extendSize.y);
                var numSegments = nativeParams.numSegments !== undefined ? nativeParams.numSegments : 16;
                returnValue = new this.BJSCANNON.Cylinder(radiusTop, radiusBottom, height, numSegments);
                // Rotate 90 degrees as this shape is horizontal in cannon
                var quat = new this.BJSCANNON.Quaternion();
                quat.setFromAxisAngle(new this.BJSCANNON.Vec3(1, 0, 0), -Math.PI / 2);
                var translation = new this.BJSCANNON.Vec3(0, 0, 0);
                returnValue.transformAllPoints(translation, quat);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].BoxImpostor:
                var box = extendSize.scale(0.5);
                returnValue = new this.BJSCANNON.Box(new this.BJSCANNON.Vec3(this._checkWithEpsilon(box.x), this._checkWithEpsilon(box.y), this._checkWithEpsilon(box.z)));
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].PlaneImpostor:
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Attention, PlaneImposter might not behave as you expect. Consider using BoxImposter instead");
                returnValue = new this.BJSCANNON.Plane();
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].MeshImpostor:
                // should transform the vertex data to world coordinates!!
                var rawVerts = object.getVerticesData ? object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind) : [];
                var rawFaces = object.getIndices ? object.getIndices() : [];
                if (!rawVerts) {
                    return;
                }
                // get only scale! so the object could transform correctly.
                var oldPosition = object.position.clone();
                var oldRotation = object.rotation && object.rotation.clone();
                var oldQuaternion = object.rotationQuaternion && object.rotationQuaternion.clone();
                object.position.copyFromFloats(0, 0, 0);
                object.rotation && object.rotation.copyFromFloats(0, 0, 0);
                object.rotationQuaternion && object.rotationQuaternion.copyFrom(impostor.getParentsRotation());
                object.rotationQuaternion && object.parent && object.rotationQuaternion.conjugateInPlace();
                var transform = object.computeWorldMatrix(true);
                // convert rawVerts to object space
                var temp = new Array();
                var index;
                for (index = 0; index < rawVerts.length; index += 3) {
                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinates(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(rawVerts, index), transform).toArray(temp, index);
                }
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("MeshImpostor only collides against spheres.");
                returnValue = new this.BJSCANNON.Trimesh(temp, rawFaces);
                //now set back the transformation!
                object.position.copyFrom(oldPosition);
                oldRotation && object.rotation && object.rotation.copyFrom(oldRotation);
                oldQuaternion && object.rotationQuaternion && object.rotationQuaternion.copyFrom(oldQuaternion);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].HeightmapImpostor:
                var oldPosition2 = object.position.clone();
                var oldRotation2 = object.rotation && object.rotation.clone();
                var oldQuaternion2 = object.rotationQuaternion && object.rotationQuaternion.clone();
                object.position.copyFromFloats(0, 0, 0);
                object.rotation && object.rotation.copyFromFloats(0, 0, 0);
                object.rotationQuaternion && object.rotationQuaternion.copyFrom(impostor.getParentsRotation());
                object.rotationQuaternion && object.parent && object.rotationQuaternion.conjugateInPlace();
                object.rotationQuaternion && object.rotationQuaternion.multiplyInPlace(this._minus90X);
                returnValue = this._createHeightmap(object);
                object.position.copyFrom(oldPosition2);
                oldRotation2 && object.rotation && object.rotation.copyFrom(oldRotation2);
                oldQuaternion2 && object.rotationQuaternion && object.rotationQuaternion.copyFrom(oldQuaternion2);
                object.computeWorldMatrix(true);
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].ParticleImpostor:
                returnValue = new this.BJSCANNON.Particle();
                break;
            case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].NoImpostor:
                returnValue = new this.BJSCANNON.Box(new this.BJSCANNON.Vec3(0, 0, 0));
                break;
        }
        return returnValue;
    };
    CannonJSPlugin.prototype._createHeightmap = function (object, pointDepth) {
        var pos = (object.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind));
        var transform = object.computeWorldMatrix(true);
        // convert rawVerts to object space
        var temp = new Array();
        var index;
        for (index = 0; index < pos.length; index += 3) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinates(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(pos, index), transform).toArray(temp, index);
        }
        pos = temp;
        var matrix = new Array();
        //For now pointDepth will not be used and will be automatically calculated.
        //Future reference - try and find the best place to add a reference to the pointDepth variable.
        var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
        var boundingInfo = object.getBoundingInfo();
        var dim = Math.min(boundingInfo.boundingBox.extendSizeWorld.x, boundingInfo.boundingBox.extendSizeWorld.y);
        var minY = boundingInfo.boundingBox.extendSizeWorld.z;
        var elementSize = dim * 2 / arraySize;
        for (var i = 0; i < pos.length; i = i + 3) {
            var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
            var z = Math.round(((pos[i + 1]) / elementSize - arraySize / 2) * -1);
            var y = -pos[i + 2] + minY;
            if (!matrix[x]) {
                matrix[x] = [];
            }
            if (!matrix[x][z]) {
                matrix[x][z] = y;
            }
            matrix[x][z] = Math.max(y, matrix[x][z]);
        }
        for (var x = 0; x <= arraySize; ++x) {
            if (!matrix[x]) {
                var loc = 1;
                while (!matrix[(x + loc) % arraySize]) {
                    loc++;
                }
                matrix[x] = matrix[(x + loc) % arraySize].slice();
                //console.log("missing x", x);
            }
            for (var z = 0; z <= arraySize; ++z) {
                if (!matrix[x][z]) {
                    var loc = 1;
                    var newValue;
                    while (newValue === undefined) {
                        newValue = matrix[x][(z + loc++) % arraySize];
                    }
                    matrix[x][z] = newValue;
                }
            }
        }
        var shape = new this.BJSCANNON.Heightfield(matrix, {
            elementSize: elementSize
        });
        //For future reference, needed for body transformation
        shape.minY = minY;
        return shape;
    };
    CannonJSPlugin.prototype._updatePhysicsBodyTransformation = function (impostor) {
        var object = impostor.object;
        //make sure it is updated...
        object.computeWorldMatrix && object.computeWorldMatrix(true);
        // The delta between the mesh position and the mesh bounding box center
        var bInfo = object.getBoundingInfo();
        if (!bInfo) {
            return;
        }
        var center = impostor.getObjectCenter();
        //m.getAbsolutePosition().subtract(m.getBoundingInfo().boundingBox.centerWorld)
        this._tmpDeltaPosition.copyFrom(object.getAbsolutePivotPoint().subtract(center));
        this._tmpDeltaPosition.divideInPlace(impostor.object.scaling);
        this._tmpPosition.copyFrom(center);
        var quaternion = object.rotationQuaternion;
        if (!quaternion) {
            return;
        }
        //is shape is a plane or a heightmap, it must be rotated 90 degs in the X axis.
        //ideally these would be rotated at time of creation like cylinder but they dont extend ConvexPolyhedron
        if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].PlaneImpostor || impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].HeightmapImpostor) {
            //-90 DEG in X, precalculated
            quaternion = quaternion.multiply(this._minus90X);
            //Invert! (Precalculated, 90 deg in X)
            //No need to clone. this will never change.
            impostor.setDeltaRotation(this._plus90X);
        }
        //If it is a heightfield, if should be centered.
        if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].HeightmapImpostor) {
            var mesh = object;
            var boundingInfo = mesh.getBoundingInfo();
            //calculate the correct body position:
            var rotationQuaternion = mesh.rotationQuaternion;
            mesh.rotationQuaternion = this._tmpUnityRotation;
            mesh.computeWorldMatrix(true);
            //get original center with no rotation
            var c = center.clone();
            var oldPivot = mesh.getPivotMatrix();
            if (oldPivot) {
                // create a copy the pivot Matrix as it is modified in place
                oldPivot = oldPivot.clone();
            }
            else {
                oldPivot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
            }
            //calculate the new center using a pivot (since this.BJSCANNON.js doesn't center height maps)
            var p = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Translation(boundingInfo.boundingBox.extendSizeWorld.x, 0, -boundingInfo.boundingBox.extendSizeWorld.z);
            mesh.setPreTransformMatrix(p);
            mesh.computeWorldMatrix(true);
            //calculate the translation
            var translation = boundingInfo.boundingBox.centerWorld.subtract(center).subtract(mesh.position).negate();
            this._tmpPosition.copyFromFloats(translation.x, translation.y - boundingInfo.boundingBox.extendSizeWorld.y, translation.z);
            //add it inverted to the delta
            this._tmpDeltaPosition.copyFrom(boundingInfo.boundingBox.centerWorld.subtract(c));
            this._tmpDeltaPosition.y += boundingInfo.boundingBox.extendSizeWorld.y;
            //rotation is back
            mesh.rotationQuaternion = rotationQuaternion;
            mesh.setPreTransformMatrix(oldPivot);
            mesh.computeWorldMatrix(true);
        }
        else if (impostor.type === _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"].MeshImpostor) {
            this._tmpDeltaPosition.copyFromFloats(0, 0, 0);
            //this._tmpPosition.copyFrom(object.position);
        }
        impostor.setDeltaPosition(this._tmpDeltaPosition);
        //Now update the impostor object
        impostor.physicsBody.position.copy(this._tmpPosition);
        impostor.physicsBody.quaternion.copy(quaternion);
    };
    CannonJSPlugin.prototype.setTransformationFromPhysicsBody = function (impostor) {
        impostor.object.position.copyFrom(impostor.physicsBody.position);
        if (impostor.object.rotationQuaternion) {
            impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.quaternion);
        }
    };
    CannonJSPlugin.prototype.setPhysicsBodyTransformation = function (impostor, newPosition, newRotation) {
        impostor.physicsBody.position.copy(newPosition);
        impostor.physicsBody.quaternion.copy(newRotation);
    };
    CannonJSPlugin.prototype.isSupported = function () {
        return this.BJSCANNON !== undefined;
    };
    CannonJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
        impostor.physicsBody.velocity.copy(velocity);
    };
    CannonJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
        impostor.physicsBody.angularVelocity.copy(velocity);
    };
    CannonJSPlugin.prototype.getLinearVelocity = function (impostor) {
        var v = impostor.physicsBody.velocity;
        if (!v) {
            return null;
        }
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](v.x, v.y, v.z);
    };
    CannonJSPlugin.prototype.getAngularVelocity = function (impostor) {
        var v = impostor.physicsBody.angularVelocity;
        if (!v) {
            return null;
        }
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](v.x, v.y, v.z);
    };
    CannonJSPlugin.prototype.setBodyMass = function (impostor, mass) {
        impostor.physicsBody.mass = mass;
        impostor.physicsBody.updateMassProperties();
    };
    CannonJSPlugin.prototype.getBodyMass = function (impostor) {
        return impostor.physicsBody.mass;
    };
    CannonJSPlugin.prototype.getBodyFriction = function (impostor) {
        return impostor.physicsBody.material.friction;
    };
    CannonJSPlugin.prototype.setBodyFriction = function (impostor, friction) {
        impostor.physicsBody.material.friction = friction;
    };
    CannonJSPlugin.prototype.getBodyRestitution = function (impostor) {
        return impostor.physicsBody.material.restitution;
    };
    CannonJSPlugin.prototype.setBodyRestitution = function (impostor, restitution) {
        impostor.physicsBody.material.restitution = restitution;
    };
    CannonJSPlugin.prototype.sleepBody = function (impostor) {
        impostor.physicsBody.sleep();
    };
    CannonJSPlugin.prototype.wakeUpBody = function (impostor) {
        impostor.physicsBody.wakeUp();
    };
    CannonJSPlugin.prototype.updateDistanceJoint = function (joint, maxDistance) {
        joint.physicsJoint.distance = maxDistance;
    };
    // private enableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
    //     if (!motorIndex) {
    //         joint.physicsJoint.enableMotor();
    //     }
    // }
    // private disableMotor(joint: IMotorEnabledJoint, motorIndex?: number) {
    //     if (!motorIndex) {
    //         joint.physicsJoint.disableMotor();
    //     }
    // }
    CannonJSPlugin.prototype.setMotor = function (joint, speed, maxForce, motorIndex) {
        if (!motorIndex) {
            joint.physicsJoint.enableMotor();
            joint.physicsJoint.setMotorSpeed(speed);
            if (maxForce) {
                this.setLimit(joint, maxForce);
            }
        }
    };
    CannonJSPlugin.prototype.setLimit = function (joint, upperLimit, lowerLimit) {
        joint.physicsJoint.motorEquation.maxForce = upperLimit;
        joint.physicsJoint.motorEquation.minForce = lowerLimit === void 0 ? -upperLimit : lowerLimit;
    };
    CannonJSPlugin.prototype.syncMeshWithImpostor = function (mesh, impostor) {
        var body = impostor.physicsBody;
        mesh.position.x = body.position.x;
        mesh.position.y = body.position.y;
        mesh.position.z = body.position.z;
        if (mesh.rotationQuaternion) {
            mesh.rotationQuaternion.x = body.quaternion.x;
            mesh.rotationQuaternion.y = body.quaternion.y;
            mesh.rotationQuaternion.z = body.quaternion.z;
            mesh.rotationQuaternion.w = body.quaternion.w;
        }
    };
    CannonJSPlugin.prototype.getRadius = function (impostor) {
        var shape = impostor.physicsBody.shapes[0];
        return shape.boundingSphereRadius;
    };
    CannonJSPlugin.prototype.getBoxSizeToRef = function (impostor, result) {
        var shape = impostor.physicsBody.shapes[0];
        result.x = shape.halfExtents.x * 2;
        result.y = shape.halfExtents.y * 2;
        result.z = shape.halfExtents.z * 2;
    };
    CannonJSPlugin.prototype.dispose = function () {
    };
    CannonJSPlugin.prototype._extendNamespace = function () {
        //this will force cannon to execute at least one step when using interpolation
        var step_tmp1 = new this.BJSCANNON.Vec3();
        var Engine = this.BJSCANNON;
        this.BJSCANNON.World.prototype.step = function (dt, timeSinceLastCalled, maxSubSteps) {
            maxSubSteps = maxSubSteps || 10;
            timeSinceLastCalled = timeSinceLastCalled || 0;
            if (timeSinceLastCalled === 0) {
                this.internalStep(dt);
                this.time += dt;
            }
            else {
                var internalSteps = Math.floor((this.time + timeSinceLastCalled) / dt) - Math.floor(this.time / dt);
                internalSteps = Math.min(internalSteps, maxSubSteps) || 1;
                var t0 = performance.now();
                for (var i = 0; i !== internalSteps; i++) {
                    this.internalStep(dt);
                    if (performance.now() - t0 > dt * 1000) {
                        break;
                    }
                }
                this.time += timeSinceLastCalled;
                var h = this.time % dt;
                var h_div_dt = h / dt;
                var interpvelo = step_tmp1;
                var bodies = this.bodies;
                for (var j = 0; j !== bodies.length; j++) {
                    var b = bodies[j];
                    if (b.type !== Engine.Body.STATIC && b.sleepState !== Engine.Body.SLEEPING) {
                        b.position.vsub(b.previousPosition, interpvelo);
                        interpvelo.scale(h_div_dt, interpvelo);
                        b.position.vadd(interpvelo, b.interpolatedPosition);
                    }
                    else {
                        b.interpolatedPosition.copy(b.position);
                        b.interpolatedQuaternion.copy(b.quaternion);
                    }
                }
            }
        };
    };
    /**
     * Does a raycast in the physics world
     * @param from when should the ray start?
     * @param to when should the ray end?
     * @returns PhysicsRaycastResult
     */
    CannonJSPlugin.prototype.raycast = function (from, to) {
        this._cannonRaycastResult.reset();
        this.world.raycastClosest(from, to, {}, this._cannonRaycastResult);
        this._raycastResult.reset(from, to);
        if (this._cannonRaycastResult.hasHit) {
            // TODO: do we also want to get the body it hit?
            this._raycastResult.setHitData({
                x: this._cannonRaycastResult.hitNormalWorld.x,
                y: this._cannonRaycastResult.hitNormalWorld.y,
                z: this._cannonRaycastResult.hitNormalWorld.z,
            }, {
                x: this._cannonRaycastResult.hitPointWorld.x,
                y: this._cannonRaycastResult.hitPointWorld.y,
                z: this._cannonRaycastResult.hitPointWorld.z,
            });
            this._raycastResult.setHitDistance(this._cannonRaycastResult.distance);
        }
        return this._raycastResult;
    };
    return CannonJSPlugin;
}());

_Physics_physicsEngine__WEBPACK_IMPORTED_MODULE_5__["PhysicsEngine"].DefaultPluginFactory = function () { return new CannonJSPlugin(); };


/***/ }),

/***/ "./Physics/Plugins/index.ts":
/*!**********************************!*\
  !*** ./Physics/Plugins/index.ts ***!
  \**********************************/
/*! exports provided: CannonJSPlugin, AmmoJSPlugin, OimoJSPlugin */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _cannonJSPlugin__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./cannonJSPlugin */ "./Physics/Plugins/cannonJSPlugin.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CannonJSPlugin", function() { return _cannonJSPlugin__WEBPACK_IMPORTED_MODULE_0__["CannonJSPlugin"]; });

/* harmony import */ var _ammoJSPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ammoJSPlugin */ "./Physics/Plugins/ammoJSPlugin.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AmmoJSPlugin", function() { return _ammoJSPlugin__WEBPACK_IMPORTED_MODULE_1__["AmmoJSPlugin"]; });

/* harmony import */ var _oimoJSPlugin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./oimoJSPlugin */ "./Physics/Plugins/oimoJSPlugin.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OimoJSPlugin", function() { return _oimoJSPlugin__WEBPACK_IMPORTED_MODULE_2__["OimoJSPlugin"]; });






/***/ }),

/***/ "./Physics/Plugins/oimoJSPlugin.ts":
/*!*****************************************!*\
  !*** ./Physics/Plugins/oimoJSPlugin.ts ***!
  \*****************************************/
/*! exports provided: OimoJSPlugin */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OimoJSPlugin", function() { return OimoJSPlugin; });
/* harmony import */ var _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Physics/physicsImpostor */ "./Physics/physicsImpostor.ts");
/* harmony import */ var _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Physics/physicsJoint */ "./Physics/physicsJoint.ts");
/* harmony import */ var _Physics_physicsEngine__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Physics/physicsEngine */ "./Physics/physicsEngine.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _physicsRaycastResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../physicsRaycastResult */ "./Physics/physicsRaycastResult.ts");






/** @hidden */
var OimoJSPlugin = /** @class */ (function () {
    function OimoJSPlugin(iterations, oimoInjection) {
        if (oimoInjection === void 0) { oimoInjection = OIMO; }
        this.name = "OimoJSPlugin";
        this._tmpImpostorsArray = [];
        this._tmpPositionVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this.BJSOIMO = oimoInjection;
        this.world = new this.BJSOIMO.World({
            iterations: iterations
        });
        this.world.clear();
        this._raycastResult = new _physicsRaycastResult__WEBPACK_IMPORTED_MODULE_5__["PhysicsRaycastResult"]();
    }
    OimoJSPlugin.prototype.setGravity = function (gravity) {
        this.world.gravity.copy(gravity);
    };
    OimoJSPlugin.prototype.setTimeStep = function (timeStep) {
        this.world.timeStep = timeStep;
    };
    OimoJSPlugin.prototype.getTimeStep = function () {
        return this.world.timeStep;
    };
    OimoJSPlugin.prototype.executeStep = function (delta, impostors) {
        var _this = this;
        impostors.forEach(function (impostor) {
            impostor.beforeStep();
        });
        this.world.step();
        impostors.forEach(function (impostor) {
            impostor.afterStep();
            //update the ordered impostors array
            _this._tmpImpostorsArray[impostor.uniqueId] = impostor;
        });
        //check for collisions
        var contact = this.world.contacts;
        while (contact !== null) {
            if (contact.touching && !contact.body1.sleeping && !contact.body2.sleeping) {
                contact = contact.next;
                continue;
            }
            //is this body colliding with any other? get the impostor
            var mainImpostor = this._tmpImpostorsArray[+contact.body1.name];
            var collidingImpostor = this._tmpImpostorsArray[+contact.body2.name];
            if (!mainImpostor || !collidingImpostor) {
                contact = contact.next;
                continue;
            }
            mainImpostor.onCollide({ body: collidingImpostor.physicsBody });
            collidingImpostor.onCollide({ body: mainImpostor.physicsBody });
            contact = contact.next;
        }
    };
    OimoJSPlugin.prototype.applyImpulse = function (impostor, force, contactPoint) {
        var mass = impostor.physicsBody.mass;
        impostor.physicsBody.applyImpulse(contactPoint.scale(this.world.invScale), force.scale(this.world.invScale * mass));
    };
    OimoJSPlugin.prototype.applyForce = function (impostor, force, contactPoint) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Warn("Oimo doesn't support applying force. Using impule instead.");
        this.applyImpulse(impostor, force, contactPoint);
    };
    OimoJSPlugin.prototype.generatePhysicsBody = function (impostor) {
        var _this = this;
        //parent-child relationship. Does this impostor has a parent impostor?
        if (impostor.parent) {
            if (impostor.physicsBody) {
                this.removePhysicsBody(impostor);
                //TODO is that needed?
                impostor.forceUpdate();
            }
            return;
        }
        if (impostor.isBodyInitRequired()) {
            var bodyConfig = {
                name: impostor.uniqueId,
                //Oimo must have mass, also for static objects.
                config: [impostor.getParam("mass") || 1, impostor.getParam("friction"), impostor.getParam("restitution")],
                size: [],
                type: [],
                pos: [],
                posShape: [],
                rot: [],
                rotShape: [],
                move: impostor.getParam("mass") !== 0,
                density: impostor.getParam("mass"),
                friction: impostor.getParam("friction"),
                restitution: impostor.getParam("restitution"),
                //Supporting older versions of Oimo
                world: this.world
            };
            var impostors = [impostor];
            var addToArray = function (parent) {
                if (!parent.getChildMeshes) {
                    return;
                }
                parent.getChildMeshes().forEach(function (m) {
                    if (m.physicsImpostor) {
                        impostors.push(m.physicsImpostor);
                        //m.physicsImpostor._init();
                    }
                });
            };
            addToArray(impostor.object);
            var checkWithEpsilon_1 = function (value) {
                return Math.max(value, _Physics_physicsEngine__WEBPACK_IMPORTED_MODULE_2__["PhysicsEngine"].Epsilon);
            };
            var globalQuaternion_1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Quaternion"]();
            impostors.forEach(function (i) {
                if (!i.object.rotationQuaternion) {
                    return;
                }
                //get the correct bounding box
                var oldQuaternion = i.object.rotationQuaternion;
                globalQuaternion_1 = oldQuaternion.clone();
                var rot = oldQuaternion.toEulerAngles();
                var extendSize = i.getObjectExtendSize();
                var radToDeg = 57.295779513082320876;
                if (i === impostor) {
                    var center = impostor.getObjectCenter();
                    impostor.object.getAbsolutePivotPoint().subtractToRef(center, _this._tmpPositionVector);
                    _this._tmpPositionVector.divideInPlace(impostor.object.scaling);
                    //Can also use Array.prototype.push.apply
                    bodyConfig.pos.push(center.x);
                    bodyConfig.pos.push(center.y);
                    bodyConfig.pos.push(center.z);
                    bodyConfig.posShape.push(0, 0, 0);
                    bodyConfig.rotShape.push(0, 0, 0);
                }
                else {
                    var localPosition = i.object.getAbsolutePosition().subtract(impostor.object.getAbsolutePosition());
                    bodyConfig.posShape.push(localPosition.x);
                    bodyConfig.posShape.push(localPosition.y);
                    bodyConfig.posShape.push(localPosition.z);
                    bodyConfig.pos.push(0, 0, 0);
                    bodyConfig.rotShape.push(rot.x * radToDeg);
                    bodyConfig.rotShape.push(rot.y * radToDeg);
                    bodyConfig.rotShape.push(rot.z * radToDeg);
                }
                // register mesh
                switch (i.type) {
                    case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_0__["PhysicsImpostor"].ParticleImpostor:
                        _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Warn("No Particle support in OIMO.js. using SphereImpostor instead");
                    case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_0__["PhysicsImpostor"].SphereImpostor:
                        var radiusX = extendSize.x;
                        var radiusY = extendSize.y;
                        var radiusZ = extendSize.z;
                        var size = Math.max(checkWithEpsilon_1(radiusX), checkWithEpsilon_1(radiusY), checkWithEpsilon_1(radiusZ)) / 2;
                        bodyConfig.type.push('sphere');
                        //due to the way oimo works with compounds, add 3 times
                        bodyConfig.size.push(size);
                        bodyConfig.size.push(size);
                        bodyConfig.size.push(size);
                        break;
                    case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_0__["PhysicsImpostor"].CylinderImpostor:
                        var sizeX = checkWithEpsilon_1(extendSize.x) / 2;
                        var sizeY = checkWithEpsilon_1(extendSize.y);
                        bodyConfig.type.push('cylinder');
                        bodyConfig.size.push(sizeX);
                        bodyConfig.size.push(sizeY);
                        //due to the way oimo works with compounds, add one more value.
                        bodyConfig.size.push(sizeY);
                        break;
                    case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_0__["PhysicsImpostor"].PlaneImpostor:
                    case _Physics_physicsImpostor__WEBPACK_IMPORTED_MODULE_0__["PhysicsImpostor"].BoxImpostor:
                    default:
                        var sizeX = checkWithEpsilon_1(extendSize.x);
                        var sizeY = checkWithEpsilon_1(extendSize.y);
                        var sizeZ = checkWithEpsilon_1(extendSize.z);
                        bodyConfig.type.push('box');
                        //if (i === impostor) {
                        bodyConfig.size.push(sizeX);
                        bodyConfig.size.push(sizeY);
                        bodyConfig.size.push(sizeZ);
                        //} else {
                        //    bodyConfig.size.push(0,0,0);
                        //}
                        break;
                }
                //actually not needed, but hey...
                i.object.rotationQuaternion = oldQuaternion;
            });
            impostor.physicsBody = this.world.add(bodyConfig);
            // set the quaternion, ignoring the previously defined (euler) rotation
            impostor.physicsBody.resetQuaternion(globalQuaternion_1);
            // update with delta 0, so the body will reveive the new rotation.
            impostor.physicsBody.updatePosition(0);
        }
        else {
            this._tmpPositionVector.copyFromFloats(0, 0, 0);
        }
        impostor.setDeltaPosition(this._tmpPositionVector);
        //this._tmpPositionVector.addInPlace(impostor.mesh.getBoundingInfo().boundingBox.center);
        //this.setPhysicsBodyTransformation(impostor, this._tmpPositionVector, impostor.mesh.rotationQuaternion);
    };
    OimoJSPlugin.prototype.removePhysicsBody = function (impostor) {
        //impostor.physicsBody.dispose();
        //Same as : (older oimo versions)
        this.world.removeRigidBody(impostor.physicsBody);
    };
    OimoJSPlugin.prototype.generateJoint = function (impostorJoint) {
        var mainBody = impostorJoint.mainImpostor.physicsBody;
        var connectedBody = impostorJoint.connectedImpostor.physicsBody;
        if (!mainBody || !connectedBody) {
            return;
        }
        var jointData = impostorJoint.joint.jointData;
        var options = jointData.nativeParams || {};
        var type;
        var nativeJointData = {
            body1: mainBody,
            body2: connectedBody,
            axe1: options.axe1 || (jointData.mainAxis ? jointData.mainAxis.asArray() : null),
            axe2: options.axe2 || (jointData.connectedAxis ? jointData.connectedAxis.asArray() : null),
            pos1: options.pos1 || (jointData.mainPivot ? jointData.mainPivot.asArray() : null),
            pos2: options.pos2 || (jointData.connectedPivot ? jointData.connectedPivot.asArray() : null),
            min: options.min,
            max: options.max,
            collision: options.collision || jointData.collision,
            spring: options.spring,
            //supporting older version of Oimo
            world: this.world
        };
        switch (impostorJoint.joint.type) {
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].BallAndSocketJoint:
                type = "jointBall";
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].SpringJoint:
                _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Warn("OIMO.js doesn't support Spring Constraint. Simulating using DistanceJoint instead");
                var springData = jointData;
                nativeJointData.min = springData.length || nativeJointData.min;
                //Max should also be set, just make sure it is at least min
                nativeJointData.max = Math.max(nativeJointData.min, nativeJointData.max);
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].DistanceJoint:
                type = "jointDistance";
                nativeJointData.max = jointData.maxDistance;
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].PrismaticJoint:
                type = "jointPrisme";
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].SliderJoint:
                type = "jointSlide";
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].WheelJoint:
                type = "jointWheel";
                break;
            case _Physics_physicsJoint__WEBPACK_IMPORTED_MODULE_1__["PhysicsJoint"].HingeJoint:
            default:
                type = "jointHinge";
                break;
        }
        nativeJointData.type = type;
        impostorJoint.joint.physicsJoint = this.world.add(nativeJointData);
    };
    OimoJSPlugin.prototype.removeJoint = function (impostorJoint) {
        //Bug in Oimo prevents us from disposing a joint in the playground
        //joint.joint.physicsJoint.dispose();
        //So we will bruteforce it!
        try {
            this.world.removeJoint(impostorJoint.joint.physicsJoint);
        }
        catch (e) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Warn(e);
        }
    };
    OimoJSPlugin.prototype.isSupported = function () {
        return this.BJSOIMO !== undefined;
    };
    OimoJSPlugin.prototype.setTransformationFromPhysicsBody = function (impostor) {
        if (!impostor.physicsBody.sleeping) {
            //TODO check that
            /*if (impostor.physicsBody.shapes.next) {
                var parentShape = this._getLastShape(impostor.physicsBody);
                impostor.object.position.copyFrom(parentShape.position);
                console.log(parentShape.position);
            } else {*/
            impostor.object.position.copyFrom(impostor.physicsBody.getPosition());
            //}
            if (impostor.object.rotationQuaternion) {
                impostor.object.rotationQuaternion.copyFrom(impostor.physicsBody.getQuaternion());
            }
        }
    };
    OimoJSPlugin.prototype.setPhysicsBodyTransformation = function (impostor, newPosition, newRotation) {
        var body = impostor.physicsBody;
        body.position.copy(newPosition);
        body.orientation.copy(newRotation);
        body.syncShapes();
        body.awake();
    };
    /*private _getLastShape(body: any): any {
        var lastShape = body.shapes;
        while (lastShape.next) {
            lastShape = lastShape.next;
        }
        return lastShape;
    }*/
    OimoJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
        impostor.physicsBody.linearVelocity.copy(velocity);
    };
    OimoJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
        impostor.physicsBody.angularVelocity.copy(velocity);
    };
    OimoJSPlugin.prototype.getLinearVelocity = function (impostor) {
        var v = impostor.physicsBody.linearVelocity;
        if (!v) {
            return null;
        }
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](v.x, v.y, v.z);
    };
    OimoJSPlugin.prototype.getAngularVelocity = function (impostor) {
        var v = impostor.physicsBody.angularVelocity;
        if (!v) {
            return null;
        }
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](v.x, v.y, v.z);
    };
    OimoJSPlugin.prototype.setBodyMass = function (impostor, mass) {
        var staticBody = mass === 0;
        //this will actually set the body's density and not its mass.
        //But this is how oimo treats the mass variable.
        impostor.physicsBody.shapes.density = staticBody ? 1 : mass;
        impostor.physicsBody.setupMass(staticBody ? 0x2 : 0x1);
    };
    OimoJSPlugin.prototype.getBodyMass = function (impostor) {
        return impostor.physicsBody.shapes.density;
    };
    OimoJSPlugin.prototype.getBodyFriction = function (impostor) {
        return impostor.physicsBody.shapes.friction;
    };
    OimoJSPlugin.prototype.setBodyFriction = function (impostor, friction) {
        impostor.physicsBody.shapes.friction = friction;
    };
    OimoJSPlugin.prototype.getBodyRestitution = function (impostor) {
        return impostor.physicsBody.shapes.restitution;
    };
    OimoJSPlugin.prototype.setBodyRestitution = function (impostor, restitution) {
        impostor.physicsBody.shapes.restitution = restitution;
    };
    OimoJSPlugin.prototype.sleepBody = function (impostor) {
        impostor.physicsBody.sleep();
    };
    OimoJSPlugin.prototype.wakeUpBody = function (impostor) {
        impostor.physicsBody.awake();
    };
    OimoJSPlugin.prototype.updateDistanceJoint = function (joint, maxDistance, minDistance) {
        joint.physicsJoint.limitMotor.upperLimit = maxDistance;
        if (minDistance !== void 0) {
            joint.physicsJoint.limitMotor.lowerLimit = minDistance;
        }
    };
    OimoJSPlugin.prototype.setMotor = function (joint, speed, force, motorIndex) {
        if (force !== undefined) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Warn("OimoJS plugin currently has unexpected behavior when using setMotor with force parameter");
        }
        else {
            force = 1e6;
        }
        speed *= -1;
        //TODO separate rotational and transational motors.
        var motor = motorIndex ? joint.physicsJoint.rotationalLimitMotor2 : joint.physicsJoint.rotationalLimitMotor1 || joint.physicsJoint.rotationalLimitMotor || joint.physicsJoint.limitMotor;
        if (motor) {
            motor.setMotor(speed, force);
        }
    };
    OimoJSPlugin.prototype.setLimit = function (joint, upperLimit, lowerLimit, motorIndex) {
        //TODO separate rotational and transational motors.
        var motor = motorIndex ? joint.physicsJoint.rotationalLimitMotor2 : joint.physicsJoint.rotationalLimitMotor1 || joint.physicsJoint.rotationalLimitMotor || joint.physicsJoint.limitMotor;
        if (motor) {
            motor.setLimit(upperLimit, lowerLimit === void 0 ? -upperLimit : lowerLimit);
        }
    };
    OimoJSPlugin.prototype.syncMeshWithImpostor = function (mesh, impostor) {
        var body = impostor.physicsBody;
        mesh.position.x = body.position.x;
        mesh.position.y = body.position.y;
        mesh.position.z = body.position.z;
        if (mesh.rotationQuaternion) {
            mesh.rotationQuaternion.x = body.orientation.x;
            mesh.rotationQuaternion.y = body.orientation.y;
            mesh.rotationQuaternion.z = body.orientation.z;
            mesh.rotationQuaternion.w = body.orientation.s;
        }
    };
    OimoJSPlugin.prototype.getRadius = function (impostor) {
        return impostor.physicsBody.shapes.radius;
    };
    OimoJSPlugin.prototype.getBoxSizeToRef = function (impostor, result) {
        var shape = impostor.physicsBody.shapes;
        result.x = shape.halfWidth * 2;
        result.y = shape.halfHeight * 2;
        result.z = shape.halfDepth * 2;
    };
    OimoJSPlugin.prototype.dispose = function () {
        this.world.clear();
    };
    /**
     * Does a raycast in the physics world
     * @param from when should the ray start?
     * @param to when should the ray end?
     * @returns PhysicsRaycastResult
     */
    OimoJSPlugin.prototype.raycast = function (from, to) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_4__["Logger"].Warn("raycast is not currently supported by the Oimo physics plugin");
        this._raycastResult.reset(from, to);
        return this._raycastResult;
    };
    return OimoJSPlugin;
}());



/***/ }),

/***/ "./Physics/index.ts":
/*!**************************!*\
  !*** ./Physics/index.ts ***!
  \**************************/
/*! exports provided: PhysicsEngine, PhysicsEngineSceneComponent, PhysicsHelper, PhysicsRadialExplosionEventOptions, PhysicsUpdraftEventOptions, PhysicsVortexEventOptions, PhysicsRadialImpulseFalloff, PhysicsUpdraftMode, PhysicsImpostor, PhysicsJoint, DistanceJoint, MotorEnabledJoint, HingeJoint, Hinge2Joint, CannonJSPlugin, AmmoJSPlugin, OimoJSPlugin */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _physicsEngine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./physicsEngine */ "./Physics/physicsEngine.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngine", function() { return _physicsEngine__WEBPACK_IMPORTED_MODULE_0__["PhysicsEngine"]; });

/* harmony import */ var _physicsEngineComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./physicsEngineComponent */ "./Physics/physicsEngineComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngineSceneComponent", function() { return _physicsEngineComponent__WEBPACK_IMPORTED_MODULE_1__["PhysicsEngineSceneComponent"]; });

/* harmony import */ var _physicsHelper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./physicsHelper */ "./Physics/physicsHelper.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsHelper", function() { return _physicsHelper__WEBPACK_IMPORTED_MODULE_2__["PhysicsHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialExplosionEventOptions", function() { return _physicsHelper__WEBPACK_IMPORTED_MODULE_2__["PhysicsRadialExplosionEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftEventOptions", function() { return _physicsHelper__WEBPACK_IMPORTED_MODULE_2__["PhysicsUpdraftEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsVortexEventOptions", function() { return _physicsHelper__WEBPACK_IMPORTED_MODULE_2__["PhysicsVortexEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialImpulseFalloff", function() { return _physicsHelper__WEBPACK_IMPORTED_MODULE_2__["PhysicsRadialImpulseFalloff"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftMode", function() { return _physicsHelper__WEBPACK_IMPORTED_MODULE_2__["PhysicsUpdraftMode"]; });

/* harmony import */ var _physicsImpostor__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./physicsImpostor */ "./Physics/physicsImpostor.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsImpostor", function() { return _physicsImpostor__WEBPACK_IMPORTED_MODULE_3__["PhysicsImpostor"]; });

/* harmony import */ var _physicsJoint__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./physicsJoint */ "./Physics/physicsJoint.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsJoint", function() { return _physicsJoint__WEBPACK_IMPORTED_MODULE_4__["PhysicsJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DistanceJoint", function() { return _physicsJoint__WEBPACK_IMPORTED_MODULE_4__["DistanceJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotorEnabledJoint", function() { return _physicsJoint__WEBPACK_IMPORTED_MODULE_4__["MotorEnabledJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HingeJoint", function() { return _physicsJoint__WEBPACK_IMPORTED_MODULE_4__["HingeJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Hinge2Joint", function() { return _physicsJoint__WEBPACK_IMPORTED_MODULE_4__["Hinge2Joint"]; });

/* harmony import */ var _Plugins_index__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Plugins/index */ "./Physics/Plugins/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CannonJSPlugin", function() { return _Plugins_index__WEBPACK_IMPORTED_MODULE_5__["CannonJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AmmoJSPlugin", function() { return _Plugins_index__WEBPACK_IMPORTED_MODULE_5__["AmmoJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OimoJSPlugin", function() { return _Plugins_index__WEBPACK_IMPORTED_MODULE_5__["OimoJSPlugin"]; });









/***/ }),

/***/ "./Physics/physicsEngine.ts":
/*!**********************************!*\
  !*** ./Physics/physicsEngine.ts ***!
  \**********************************/
/*! exports provided: PhysicsEngine */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngine", function() { return PhysicsEngine; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");


/**
 * Class used to control physics engine
 * @see http://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var PhysicsEngine = /** @class */ (function () {
    /**
     * Creates a new Physics Engine
     * @param gravity defines the gravity vector used by the simulation
     * @param _physicsPlugin defines the plugin to use (CannonJS by default)
     */
    function PhysicsEngine(gravity, _physicsPlugin) {
        if (_physicsPlugin === void 0) { _physicsPlugin = PhysicsEngine.DefaultPluginFactory(); }
        this._physicsPlugin = _physicsPlugin;
        this._impostors = [];
        this._joints = [];
        if (!this._physicsPlugin.isSupported()) {
            throw new Error("Physics Engine " + this._physicsPlugin.name + " cannot be found. "
                + "Please make sure it is included.");
        }
        gravity = gravity || new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -9.807, 0);
        this.setGravity(gravity);
        this.setTimeStep();
    }
    /**
     * Factory used to create the default physics plugin.
     * @returns The default physics plugin
     */
    PhysicsEngine.DefaultPluginFactory = function () {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_1__["_DevTools"].WarnImport("CannonJSPlugin");
    };
    /**
     * Sets the gravity vector used by the simulation
     * @param gravity defines the gravity vector to use
     */
    PhysicsEngine.prototype.setGravity = function (gravity) {
        this.gravity = gravity;
        this._physicsPlugin.setGravity(this.gravity);
    };
    /**
     * Set the time step of the physics engine.
     * Default is 1/60.
     * To slow it down, enter 1/600 for example.
     * To speed it up, 1/30
     * @param newTimeStep defines the new timestep to apply to this world.
     */
    PhysicsEngine.prototype.setTimeStep = function (newTimeStep) {
        if (newTimeStep === void 0) { newTimeStep = 1 / 60; }
        this._physicsPlugin.setTimeStep(newTimeStep);
    };
    /**
     * Get the time step of the physics engine.
     * @returns the current time step
     */
    PhysicsEngine.prototype.getTimeStep = function () {
        return this._physicsPlugin.getTimeStep();
    };
    /**
     * Release all resources
     */
    PhysicsEngine.prototype.dispose = function () {
        this._impostors.forEach(function (impostor) {
            impostor.dispose();
        });
        this._physicsPlugin.dispose();
    };
    /**
     * Gets the name of the current physics plugin
     * @returns the name of the plugin
     */
    PhysicsEngine.prototype.getPhysicsPluginName = function () {
        return this._physicsPlugin.name;
    };
    /**
     * Adding a new impostor for the impostor tracking.
     * This will be done by the impostor itself.
     * @param impostor the impostor to add
     */
    PhysicsEngine.prototype.addImpostor = function (impostor) {
        impostor.uniqueId = this._impostors.push(impostor);
        //if no parent, generate the body
        if (!impostor.parent) {
            this._physicsPlugin.generatePhysicsBody(impostor);
        }
    };
    /**
     * Remove an impostor from the engine.
     * This impostor and its mesh will not longer be updated by the physics engine.
     * @param impostor the impostor to remove
     */
    PhysicsEngine.prototype.removeImpostor = function (impostor) {
        var index = this._impostors.indexOf(impostor);
        if (index > -1) {
            var removed = this._impostors.splice(index, 1);
            //Is it needed?
            if (removed.length) {
                this.getPhysicsPlugin().removePhysicsBody(impostor);
            }
        }
    };
    /**
     * Add a joint to the physics engine
     * @param mainImpostor defines the main impostor to which the joint is added.
     * @param connectedImpostor defines the impostor that is connected to the main impostor using this joint
     * @param joint defines the joint that will connect both impostors.
     */
    PhysicsEngine.prototype.addJoint = function (mainImpostor, connectedImpostor, joint) {
        var impostorJoint = {
            mainImpostor: mainImpostor,
            connectedImpostor: connectedImpostor,
            joint: joint
        };
        joint.physicsPlugin = this._physicsPlugin;
        this._joints.push(impostorJoint);
        this._physicsPlugin.generateJoint(impostorJoint);
    };
    /**
     * Removes a joint from the simulation
     * @param mainImpostor defines the impostor used with the joint
     * @param connectedImpostor defines the other impostor connected to the main one by the joint
     * @param joint defines the joint to remove
     */
    PhysicsEngine.prototype.removeJoint = function (mainImpostor, connectedImpostor, joint) {
        var matchingJoints = this._joints.filter(function (impostorJoint) {
            return (impostorJoint.connectedImpostor === connectedImpostor
                && impostorJoint.joint === joint
                && impostorJoint.mainImpostor === mainImpostor);
        });
        if (matchingJoints.length) {
            this._physicsPlugin.removeJoint(matchingJoints[0]);
            //TODO remove it from the list as well
        }
    };
    /**
     * Called by the scene. No need to call it.
     * @param delta defines the timespam between frames
     */
    PhysicsEngine.prototype._step = function (delta) {
        var _this = this;
        //check if any mesh has no body / requires an update
        this._impostors.forEach(function (impostor) {
            if (impostor.isBodyInitRequired()) {
                _this._physicsPlugin.generatePhysicsBody(impostor);
            }
        });
        if (delta > 0.1) {
            delta = 0.1;
        }
        else if (delta <= 0) {
            delta = 1.0 / 60.0;
        }
        this._physicsPlugin.executeStep(delta, this._impostors);
    };
    /**
     * Gets the current plugin used to run the simulation
     * @returns current plugin
     */
    PhysicsEngine.prototype.getPhysicsPlugin = function () {
        return this._physicsPlugin;
    };
    /**
     * Gets the list of physic impostors
     * @returns an array of PhysicsImpostor
     */
    PhysicsEngine.prototype.getImpostors = function () {
        return this._impostors;
    };
    /**
     * Gets the impostor for a physics enabled object
     * @param object defines the object impersonated by the impostor
     * @returns the PhysicsImpostor or null if not found
     */
    PhysicsEngine.prototype.getImpostorForPhysicsObject = function (object) {
        for (var i = 0; i < this._impostors.length; ++i) {
            if (this._impostors[i].object === object) {
                return this._impostors[i];
            }
        }
        return null;
    };
    /**
     * Gets the impostor for a physics body object
     * @param body defines physics body used by the impostor
     * @returns the PhysicsImpostor or null if not found
     */
    PhysicsEngine.prototype.getImpostorWithPhysicsBody = function (body) {
        for (var i = 0; i < this._impostors.length; ++i) {
            if (this._impostors[i].physicsBody === body) {
                return this._impostors[i];
            }
        }
        return null;
    };
    /**
     * Does a raycast in the physics world
     * @param from when should the ray start?
     * @param to when should the ray end?
     * @returns PhysicsRaycastResult
     */
    PhysicsEngine.prototype.raycast = function (from, to) {
        return this._physicsPlugin.raycast(from, to);
    };
    /**
     * Global value used to control the smallest number supported by the simulation
     */
    PhysicsEngine.Epsilon = 0.001;
    return PhysicsEngine;
}());



/***/ }),

/***/ "./Physics/physicsEngineComponent.ts":
/*!*******************************************!*\
  !*** ./Physics/physicsEngineComponent.ts ***!
  \*******************************************/
/*! exports provided: PhysicsEngineSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngineSceneComponent", function() { return PhysicsEngineSceneComponent; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _physicsEngine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./physicsEngine */ "./Physics/physicsEngine.ts");
/* harmony import */ var _physicsJoint__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./physicsJoint */ "./Physics/physicsJoint.ts");







/**
 * Gets the current physics engine
 * @returns a IPhysicsEngine or null if none attached
 */
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.getPhysicsEngine = function () {
    return this._physicsEngine;
};
/**
 * Enables physics to the current scene
 * @param gravity defines the scene's gravity for the physics engine
 * @param plugin defines the physics engine to be used. defaults to OimoJS.
 * @return a boolean indicating if the physics engine was initialized
 */
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.enablePhysics = function (gravity, plugin) {
    if (gravity === void 0) { gravity = null; }
    if (this._physicsEngine) {
        return true;
    }
    // Register the component to the scene
    var component = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].NAME_PHYSICSENGINE);
    if (!component) {
        component = new PhysicsEngineSceneComponent(this);
        this._addComponent(component);
    }
    try {
        this._physicsEngine = new _physicsEngine__WEBPACK_IMPORTED_MODULE_5__["PhysicsEngine"](gravity, plugin);
        return true;
    }
    catch (e) {
        _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error(e.message);
        return false;
    }
};
/**
 * Disables and disposes the physics engine associated with the scene
 */
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.disablePhysicsEngine = function () {
    if (!this._physicsEngine) {
        return;
    }
    this._physicsEngine.dispose();
    this._physicsEngine = null;
};
/**
 * Gets a boolean indicating if there is an active physics engine
 * @returns a boolean indicating if there is an active physics engine
 */
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.isPhysicsEnabled = function () {
    return this._physicsEngine !== undefined;
};
/**
 * Deletes a physics compound impostor
 * @param compound defines the compound to delete
 */
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype.deleteCompoundImpostor = function (compound) {
    var mesh = compound.parts[0].mesh;
    if (mesh.physicsImpostor) {
        mesh.physicsImpostor.dispose( /*true*/);
        mesh.physicsImpostor = null;
    }
};
/** @hidden */
_scene__WEBPACK_IMPORTED_MODULE_4__["Scene"].prototype._advancePhysicsEngineStep = function (step) {
    if (this._physicsEngine) {
        this.onBeforePhysicsObservable.notifyObservers(this);
        this._physicsEngine._step(step / 1000);
        this.onAfterPhysicsObservable.notifyObservers(this);
    }
};
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype, "physicsImpostor", {
    get: function () {
        return this._physicsImpostor;
    },
    set: function (value) {
        var _this = this;
        if (this._physicsImpostor === value) {
            return;
        }
        if (this._disposePhysicsObserver) {
            this.onDisposeObservable.remove(this._disposePhysicsObserver);
        }
        this._physicsImpostor = value;
        if (value) {
            this._disposePhysicsObserver = this.onDisposeObservable.add(function () {
                // Physics
                if (_this.physicsImpostor) {
                    _this.physicsImpostor.dispose( /*!doNotRecurse*/);
                    _this.physicsImpostor = null;
                }
            });
        }
    },
    enumerable: true,
    configurable: true
});
/**
 * Gets the current physics impostor
 * @see http://doc.babylonjs.com/features/physics_engine
 * @returns a physics impostor or null
 */
_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype.getPhysicsImpostor = function () {
    return this.physicsImpostor;
};
/**
 * Apply a physic impulse to the mesh
 * @param force defines the force to apply
 * @param contactPoint defines where to apply the force
 * @returns the current mesh
 * @see http://doc.babylonjs.com/how_to/using_the_physics_engine
 */
_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype.applyImpulse = function (force, contactPoint) {
    if (!this.physicsImpostor) {
        return this;
    }
    this.physicsImpostor.applyImpulse(force, contactPoint);
    return this;
};
/**
 * Creates a physic joint between two meshes
 * @param otherMesh defines the other mesh to use
 * @param pivot1 defines the pivot to use on this mesh
 * @param pivot2 defines the pivot to use on the other mesh
 * @param options defines additional options (can be plugin dependent)
 * @returns the current mesh
 * @see https://www.babylonjs-playground.com/#0BS5U0#0
 */
_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype.setPhysicsLinkWith = function (otherMesh, pivot1, pivot2, options) {
    if (!this.physicsImpostor || !otherMesh.physicsImpostor) {
        return this;
    }
    this.physicsImpostor.createJoint(otherMesh.physicsImpostor, _physicsJoint__WEBPACK_IMPORTED_MODULE_6__["PhysicsJoint"].HingeJoint, {
        mainPivot: pivot1,
        connectedPivot: pivot2,
        nativeParams: options
    });
    return this;
};
/**
 * Defines the physics engine scene component responsible to manage a physics engine
 */
var PhysicsEngineSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function PhysicsEngineSceneComponent(scene) {
        var _this = this;
        /**
         * The component name helpful to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].NAME_PHYSICSENGINE;
        this.scene = scene;
        this.scene.onBeforePhysicsObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this.scene.onAfterPhysicsObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        // Replace the function used to get the deterministic frame time
        this.scene.getDeterministicFrameTime = function () {
            if (_this.scene._physicsEngine) {
                return _this.scene._physicsEngine.getTimeStep() * 1000;
            }
            return 1000.0 / 60.0;
        };
    }
    /**
     * Registers the component in a given scene
     */
    PhysicsEngineSceneComponent.prototype.register = function () {
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    PhysicsEngineSceneComponent.prototype.rebuild = function () {
        // Nothing to do for this component
    };
    /**
     * Disposes the component and the associated ressources
     */
    PhysicsEngineSceneComponent.prototype.dispose = function () {
        this.scene.onBeforePhysicsObservable.clear();
        this.scene.onAfterPhysicsObservable.clear();
        if (this.scene._physicsEngine) {
            this.scene.disablePhysicsEngine();
        }
    };
    return PhysicsEngineSceneComponent;
}());



/***/ }),

/***/ "./Physics/physicsHelper.ts":
/*!**********************************!*\
  !*** ./Physics/physicsHelper.ts ***!
  \**********************************/
/*! exports provided: PhysicsHelper, PhysicsRadialExplosionEventOptions, PhysicsUpdraftEventOptions, PhysicsVortexEventOptions, PhysicsRadialImpulseFalloff, PhysicsUpdraftMode */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsHelper", function() { return PhysicsHelper; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialExplosionEventOptions", function() { return PhysicsRadialExplosionEventOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftEventOptions", function() { return PhysicsUpdraftEventOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsVortexEventOptions", function() { return PhysicsVortexEventOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialImpulseFalloff", function() { return PhysicsRadialImpulseFalloff; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftMode", function() { return PhysicsUpdraftMode; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/Builders/sphereBuilder */ "./Meshes/Builders/sphereBuilder.ts");
/* harmony import */ var _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/Builders/cylinderBuilder */ "./Meshes/Builders/cylinderBuilder.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Culling/ray */ "./Culling/ray.ts");






/**
 * A helper for physics simulations
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine#further-functionality-of-the-impostor-class
 */
var PhysicsHelper = /** @class */ (function () {
    /**
     * Initializes the Physics helper
     * @param scene Babylon.js scene
     */
    function PhysicsHelper(scene) {
        this._scene = scene;
        this._physicsEngine = this._scene.getPhysicsEngine();
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Physics engine not enabled. Please enable the physics before you can use the methods.');
            return;
        }
    }
    /**
     * Applies a radial explosion impulse
     * @param origin the origin of the explosion
     * @param radiusOrEventOptions the radius or the options of radial explosion
     * @param strength the explosion strength
     * @param falloff possible options: Constant & Linear. Defaults to Constant
     * @returns A physics radial explosion event, or null
     */
    PhysicsHelper.prototype.applyRadialExplosionImpulse = function (origin, radiusOrEventOptions, strength, falloff) {
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Physics engine not enabled. Please enable the physics before you call this method.');
            return null;
        }
        var impostors = this._physicsEngine.getImpostors();
        if (impostors.length === 0) {
            return null;
        }
        if (typeof radiusOrEventOptions === 'number') {
            radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();
            radiusOrEventOptions.radius = radiusOrEventOptions;
            radiusOrEventOptions.strength = strength || radiusOrEventOptions.strength;
            radiusOrEventOptions.falloff = falloff || radiusOrEventOptions.falloff;
        }
        var event = new PhysicsRadialExplosionEvent(this._scene, radiusOrEventOptions);
        var affectedImpostorsWithData = Array();
        impostors.forEach(function (impostor) {
            var impostorHitData = event.getImpostorHitData(impostor, origin);
            if (!impostorHitData) {
                return;
            }
            impostor.applyImpulse(impostorHitData.force, impostorHitData.contactPoint);
            affectedImpostorsWithData.push({
                impostor: impostor,
                hitData: impostorHitData,
            });
        });
        event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);
        event.dispose(false);
        return event;
    };
    /**
     * Applies a radial explosion force
     * @param origin the origin of the explosion
     * @param radiusOrEventOptions the radius or the options of radial explosion
     * @param strength the explosion strength
     * @param falloff possible options: Constant & Linear. Defaults to Constant
     * @returns A physics radial explosion event, or null
     */
    PhysicsHelper.prototype.applyRadialExplosionForce = function (origin, radiusOrEventOptions, strength, falloff) {
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.');
            return null;
        }
        var impostors = this._physicsEngine.getImpostors();
        if (impostors.length === 0) {
            return null;
        }
        if (typeof radiusOrEventOptions === 'number') {
            radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();
            radiusOrEventOptions.radius = radiusOrEventOptions;
            radiusOrEventOptions.strength = strength || radiusOrEventOptions.strength;
            radiusOrEventOptions.falloff = falloff || radiusOrEventOptions.falloff;
        }
        var event = new PhysicsRadialExplosionEvent(this._scene, radiusOrEventOptions);
        var affectedImpostorsWithData = Array();
        impostors.forEach(function (impostor) {
            var impostorHitData = event.getImpostorHitData(impostor, origin);
            if (!impostorHitData) {
                return;
            }
            impostor.applyForce(impostorHitData.force, impostorHitData.contactPoint);
            affectedImpostorsWithData.push({
                impostor: impostor,
                hitData: impostorHitData,
            });
        });
        event.triggerAffectedImpostorsCallback(affectedImpostorsWithData);
        event.dispose(false);
        return event;
    };
    /**
     * Creates a gravitational field
     * @param origin the origin of the explosion
     * @param radiusOrEventOptions the radius or the options of radial explosion
     * @param strength the explosion strength
     * @param falloff possible options: Constant & Linear. Defaults to Constant
     * @returns A physics gravitational field event, or null
     */
    PhysicsHelper.prototype.gravitationalField = function (origin, radiusOrEventOptions, strength, falloff) {
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.');
            return null;
        }
        var impostors = this._physicsEngine.getImpostors();
        if (impostors.length === 0) {
            return null;
        }
        if (typeof radiusOrEventOptions === 'number') {
            radiusOrEventOptions = new PhysicsRadialExplosionEventOptions();
            radiusOrEventOptions.radius = radiusOrEventOptions;
            radiusOrEventOptions.strength = strength || radiusOrEventOptions.strength;
            radiusOrEventOptions.falloff = falloff || radiusOrEventOptions.falloff;
        }
        var event = new PhysicsGravitationalFieldEvent(this, this._scene, origin, radiusOrEventOptions);
        event.dispose(false);
        return event;
    };
    /**
     * Creates a physics updraft event
     * @param origin the origin of the updraft
     * @param radiusOrEventOptions the radius or the options of the updraft
     * @param strength the strength of the updraft
     * @param height the height of the updraft
     * @param updraftMode possible options: Center & Perpendicular. Defaults to Center
     * @returns A physics updraft event, or null
     */
    PhysicsHelper.prototype.updraft = function (origin, radiusOrEventOptions, strength, height, updraftMode) {
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.');
            return null;
        }
        if (this._physicsEngine.getImpostors().length === 0) {
            return null;
        }
        if (typeof radiusOrEventOptions === 'number') {
            radiusOrEventOptions = new PhysicsUpdraftEventOptions();
            radiusOrEventOptions.radius = radiusOrEventOptions;
            radiusOrEventOptions.strength = strength || radiusOrEventOptions.strength;
            radiusOrEventOptions.height = height || radiusOrEventOptions.height;
            radiusOrEventOptions.updraftMode = updraftMode || radiusOrEventOptions.updraftMode;
        }
        var event = new PhysicsUpdraftEvent(this._scene, origin, radiusOrEventOptions);
        event.dispose(false);
        return event;
    };
    /**
     * Creates a physics vortex event
     * @param origin the of the vortex
     * @param radiusOrEventOptions the radius or the options of the vortex
     * @param strength the strength of the vortex
     * @param height   the height of the vortex
     * @returns a Physics vortex event, or null
     * A physics vortex event or null
     */
    PhysicsHelper.prototype.vortex = function (origin, radiusOrEventOptions, strength, height) {
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn('Physics engine not enabled. Please enable the physics before you call the PhysicsHelper.');
            return null;
        }
        if (this._physicsEngine.getImpostors().length === 0) {
            return null;
        }
        if (typeof radiusOrEventOptions === 'number') {
            radiusOrEventOptions = new PhysicsVortexEventOptions();
            radiusOrEventOptions.radius = radiusOrEventOptions;
            radiusOrEventOptions.strength = strength || radiusOrEventOptions.strength;
            radiusOrEventOptions.height = height || radiusOrEventOptions.height;
        }
        var event = new PhysicsVortexEvent(this._scene, origin, radiusOrEventOptions);
        event.dispose(false);
        return event;
    };
    return PhysicsHelper;
}());

/**
 * Represents a physics radial explosion event
 */
var PhysicsRadialExplosionEvent = /** @class */ (function () {
    /**
     * Initializes a radial explosioin event
     * @param _scene BabylonJS scene
     * @param _options The options for the vortex event
     */
    function PhysicsRadialExplosionEvent(_scene, _options) {
        this._scene = _scene;
        this._options = _options;
        this._dataFetched = false; // check if the data has been fetched. If not, do cleanup
        this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, (new PhysicsRadialExplosionEventOptions()), this._options);
    }
    /**
     * Returns the data related to the radial explosion event (sphere).
     * @returns The radial explosion event data
     */
    PhysicsRadialExplosionEvent.prototype.getData = function () {
        this._dataFetched = true;
        return {
            sphere: this._sphere,
        };
    };
    /**
     * Returns the force and contact point of the impostor or false, if the impostor is not affected by the force/impulse.
     * @param impostor A physics imposter
     * @param origin the origin of the explosion
     * @returns {Nullable<PhysicsHitData>} A physics force and contact point, or null
     */
    PhysicsRadialExplosionEvent.prototype.getImpostorHitData = function (impostor, origin) {
        if (impostor.mass === 0) {
            return null;
        }
        if (!this._intersectsWithSphere(impostor, origin, this._options.radius)) {
            return null;
        }
        if (impostor.object.getClassName() !== 'Mesh' && impostor.object.getClassName() !== 'InstancedMesh') {
            return null;
        }
        var impostorObjectCenter = impostor.getObjectCenter();
        var direction = impostorObjectCenter.subtract(origin);
        var ray = new _Culling_ray__WEBPACK_IMPORTED_MODULE_5__["Ray"](origin, direction, this._options.radius);
        var hit = ray.intersectsMesh(impostor.object);
        var contactPoint = hit.pickedPoint;
        if (!contactPoint) {
            return null;
        }
        var distanceFromOrigin = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Distance(origin, contactPoint);
        if (distanceFromOrigin > this._options.radius) {
            return null;
        }
        var multiplier = this._options.falloff === PhysicsRadialImpulseFalloff.Constant
            ? this._options.strength
            : this._options.strength * (1 - (distanceFromOrigin / this._options.radius));
        var force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
        return { force: force, contactPoint: contactPoint, distanceFromOrigin: distanceFromOrigin };
    };
    /**
     * Triggers affecterd impostors callbacks
     * @param affectedImpostorsWithData defines the list of affected impostors (including associated data)
     */
    PhysicsRadialExplosionEvent.prototype.triggerAffectedImpostorsCallback = function (affectedImpostorsWithData) {
        if (this._options.affectedImpostorsCallback) {
            this._options.affectedImpostorsCallback(affectedImpostorsWithData);
        }
    };
    /**
     * Disposes the sphere.
     * @param force Specifies if the sphere should be disposed by force
     */
    PhysicsRadialExplosionEvent.prototype.dispose = function (force) {
        var _this = this;
        if (force === void 0) { force = true; }
        if (force) {
            this._sphere.dispose();
        }
        else {
            setTimeout(function () {
                if (!_this._dataFetched) {
                    _this._sphere.dispose();
                }
            }, 0);
        }
    };
    /*** Helpers ***/
    PhysicsRadialExplosionEvent.prototype._prepareSphere = function () {
        if (!this._sphere) {
            this._sphere = _Meshes_Builders_sphereBuilder__WEBPACK_IMPORTED_MODULE_3__["SphereBuilder"].CreateSphere("radialExplosionEventSphere", this._options.sphere, this._scene);
            this._sphere.isVisible = false;
        }
    };
    PhysicsRadialExplosionEvent.prototype._intersectsWithSphere = function (impostor, origin, radius) {
        var impostorObject = impostor.object;
        this._prepareSphere();
        this._sphere.position = origin;
        this._sphere.scaling = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](radius * 2, radius * 2, radius * 2);
        this._sphere._updateBoundingInfo();
        this._sphere.computeWorldMatrix(true);
        return this._sphere.intersectsMesh(impostorObject, true);
    };
    return PhysicsRadialExplosionEvent;
}());
/**
 * Represents a gravitational field event
 */
var PhysicsGravitationalFieldEvent = /** @class */ (function () {
    /**
     * Initializes the physics gravitational field event
     * @param _physicsHelper A physics helper
     * @param _scene BabylonJS scene
     * @param _origin The origin position of the gravitational field event
     * @param _options The options for the vortex event
     */
    function PhysicsGravitationalFieldEvent(_physicsHelper, _scene, _origin, _options) {
        this._physicsHelper = _physicsHelper;
        this._scene = _scene;
        this._origin = _origin;
        this._options = _options;
        this._dataFetched = false; // check if the has been fetched the data. If not, do cleanup
        this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, (new PhysicsRadialExplosionEventOptions()), this._options);
        this._tickCallback = this._tick.bind(this);
        this._options.strength = this._options.strength * -1;
    }
    /**
     * Returns the data related to the gravitational field event (sphere).
     * @returns A gravitational field event
     */
    PhysicsGravitationalFieldEvent.prototype.getData = function () {
        this._dataFetched = true;
        return {
            sphere: this._sphere,
        };
    };
    /**
     * Enables the gravitational field.
     */
    PhysicsGravitationalFieldEvent.prototype.enable = function () {
        this._tickCallback.call(this);
        this._scene.registerBeforeRender(this._tickCallback);
    };
    /**
     * Disables the gravitational field.
     */
    PhysicsGravitationalFieldEvent.prototype.disable = function () {
        this._scene.unregisterBeforeRender(this._tickCallback);
    };
    /**
     * Disposes the sphere.
     * @param force The force to dispose from the gravitational field event
     */
    PhysicsGravitationalFieldEvent.prototype.dispose = function (force) {
        var _this = this;
        if (force === void 0) { force = true; }
        if (force) {
            this._sphere.dispose();
        }
        else {
            setTimeout(function () {
                if (!_this._dataFetched) {
                    _this._sphere.dispose();
                }
            }, 0);
        }
    };
    PhysicsGravitationalFieldEvent.prototype._tick = function () {
        // Since the params won't change, we fetch the event only once
        if (this._sphere) {
            this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);
        }
        else {
            var radialExplosionEvent = this._physicsHelper.applyRadialExplosionForce(this._origin, this._options);
            if (radialExplosionEvent) {
                this._sphere = radialExplosionEvent.getData().sphere.clone('radialExplosionEventSphereClone');
            }
        }
    };
    return PhysicsGravitationalFieldEvent;
}());
/**
 * Represents a physics updraft event
 */
var PhysicsUpdraftEvent = /** @class */ (function () {
    /**
     * Initializes the physics updraft event
     * @param _scene BabylonJS scene
     * @param _origin The origin position of the updraft
     * @param _options The options for the updraft event
     */
    function PhysicsUpdraftEvent(_scene, _origin, _options) {
        this._scene = _scene;
        this._origin = _origin;
        this._options = _options;
        this._originTop = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(); // the most upper part of the cylinder
        this._originDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(); // used if the updraftMode is perpendicular
        this._cylinderPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(); // to keep the cylinders position, because normally the origin is in the center and not on the bottom
        this._dataFetched = false; // check if the has been fetched the data. If not, do cleanup
        this._physicsEngine = this._scene.getPhysicsEngine();
        this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, (new PhysicsUpdraftEventOptions()), this._options);
        this._origin.addToRef(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, this._options.height / 2, 0), this._cylinderPosition);
        this._origin.addToRef(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, this._options.height, 0), this._originTop);
        if (this._options.updraftMode === PhysicsUpdraftMode.Perpendicular) {
            this._originDirection = this._origin.subtract(this._originTop).normalize();
        }
        this._tickCallback = this._tick.bind(this);
        this._prepareCylinder();
    }
    /**
     * Returns the data related to the updraft event (cylinder).
     * @returns A physics updraft event
     */
    PhysicsUpdraftEvent.prototype.getData = function () {
        this._dataFetched = true;
        return {
            cylinder: this._cylinder,
        };
    };
    /**
     * Enables the updraft.
     */
    PhysicsUpdraftEvent.prototype.enable = function () {
        this._tickCallback.call(this);
        this._scene.registerBeforeRender(this._tickCallback);
    };
    /**
     * Disables the updraft.
     */
    PhysicsUpdraftEvent.prototype.disable = function () {
        this._scene.unregisterBeforeRender(this._tickCallback);
    };
    /**
     * Disposes the cylinder.
     * @param force Specifies if the updraft should be disposed by force
     */
    PhysicsUpdraftEvent.prototype.dispose = function (force) {
        var _this = this;
        if (force === void 0) { force = true; }
        if (!this._cylinder) {
            return;
        }
        if (force) {
            this._cylinder.dispose();
        }
        else {
            setTimeout(function () {
                if (!_this._dataFetched) {
                    _this._cylinder.dispose();
                }
            }, 0);
        }
    };
    PhysicsUpdraftEvent.prototype.getImpostorHitData = function (impostor) {
        if (impostor.mass === 0) {
            return null;
        }
        if (!this._intersectsWithCylinder(impostor)) {
            return null;
        }
        var impostorObjectCenter = impostor.getObjectCenter();
        if (this._options.updraftMode === PhysicsUpdraftMode.Perpendicular) {
            var direction = this._originDirection;
        }
        else {
            var direction = impostorObjectCenter.subtract(this._originTop);
        }
        var distanceFromOrigin = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Distance(this._origin, impostorObjectCenter);
        var multiplier = this._options.strength * -1;
        var force = direction.multiplyByFloats(multiplier, multiplier, multiplier);
        return { force: force, contactPoint: impostorObjectCenter, distanceFromOrigin: distanceFromOrigin };
    };
    PhysicsUpdraftEvent.prototype._tick = function () {
        var _this = this;
        this._physicsEngine.getImpostors().forEach(function (impostor) {
            var impostorHitData = _this.getImpostorHitData(impostor);
            if (!impostorHitData) {
                return;
            }
            impostor.applyForce(impostorHitData.force, impostorHitData.contactPoint);
        });
    };
    /*** Helpers ***/
    PhysicsUpdraftEvent.prototype._prepareCylinder = function () {
        if (!this._cylinder) {
            this._cylinder = _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_4__["CylinderBuilder"].CreateCylinder("updraftEventCylinder", {
                height: this._options.height,
                diameter: this._options.radius * 2,
            }, this._scene);
            this._cylinder.isVisible = false;
        }
    };
    PhysicsUpdraftEvent.prototype._intersectsWithCylinder = function (impostor) {
        var impostorObject = impostor.object;
        this._cylinder.position = this._cylinderPosition;
        return this._cylinder.intersectsMesh(impostorObject, true);
    };
    return PhysicsUpdraftEvent;
}());
/**
 * Represents a physics vortex event
 */
var PhysicsVortexEvent = /** @class */ (function () {
    /**
     * Initializes the physics vortex event
     * @param _scene The BabylonJS scene
     * @param _origin The origin position of the vortex
     * @param _options The options for the vortex event
     */
    function PhysicsVortexEvent(_scene, _origin, _options) {
        this._scene = _scene;
        this._origin = _origin;
        this._options = _options;
        this._originTop = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(); // the most upper part of the cylinder
        this._cylinderPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero(); // to keep the cylinders position, because normally the origin is in the center and not on the bottom
        this._dataFetched = false; // check if the has been fetched the data. If not, do cleanup
        this._physicsEngine = this._scene.getPhysicsEngine();
        this._options = tslib__WEBPACK_IMPORTED_MODULE_0__["__assign"]({}, (new PhysicsVortexEventOptions()), this._options);
        this._origin.addToRef(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, this._options.height / 2, 0), this._cylinderPosition);
        this._origin.addToRef(new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](0, this._options.height, 0), this._originTop);
        this._tickCallback = this._tick.bind(this);
        this._prepareCylinder();
    }
    /**
     * Returns the data related to the vortex event (cylinder).
     * @returns The physics vortex event data
     */
    PhysicsVortexEvent.prototype.getData = function () {
        this._dataFetched = true;
        return {
            cylinder: this._cylinder,
        };
    };
    /**
     * Enables the vortex.
     */
    PhysicsVortexEvent.prototype.enable = function () {
        this._tickCallback.call(this);
        this._scene.registerBeforeRender(this._tickCallback);
    };
    /**
     * Disables the cortex.
     */
    PhysicsVortexEvent.prototype.disable = function () {
        this._scene.unregisterBeforeRender(this._tickCallback);
    };
    /**
     * Disposes the sphere.
     * @param force
     */
    PhysicsVortexEvent.prototype.dispose = function (force) {
        var _this = this;
        if (force === void 0) { force = true; }
        if (force) {
            this._cylinder.dispose();
        }
        else {
            setTimeout(function () {
                if (!_this._dataFetched) {
                    _this._cylinder.dispose();
                }
            }, 0);
        }
    };
    PhysicsVortexEvent.prototype.getImpostorHitData = function (impostor) {
        if (impostor.mass === 0) {
            return null;
        }
        if (!this._intersectsWithCylinder(impostor)) {
            return null;
        }
        if (impostor.object.getClassName() !== 'Mesh' && impostor.object.getClassName() !== 'InstancedMesh') {
            return null;
        }
        var impostorObjectCenter = impostor.getObjectCenter();
        var originOnPlane = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](this._origin.x, impostorObjectCenter.y, this._origin.z); // the distance to the origin as if both objects were on a plane (Y-axis)
        var originToImpostorDirection = impostorObjectCenter.subtract(originOnPlane);
        var ray = new _Culling_ray__WEBPACK_IMPORTED_MODULE_5__["Ray"](originOnPlane, originToImpostorDirection, this._options.radius);
        var hit = ray.intersectsMesh(impostor.object);
        var contactPoint = hit.pickedPoint;
        if (!contactPoint) {
            return null;
        }
        var absoluteDistanceFromOrigin = hit.distance / this._options.radius;
        var directionToOrigin = contactPoint.normalize();
        if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {
            directionToOrigin = directionToOrigin.negate();
        }
        if (absoluteDistanceFromOrigin > this._options.centripetalForceThreshold) {
            var forceX = directionToOrigin.x * this._options.centripetalForceMultiplier;
            var forceY = directionToOrigin.y * this._options.updraftForceMultiplier;
            var forceZ = directionToOrigin.z * this._options.centripetalForceMultiplier;
        }
        else {
            var perpendicularDirection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Cross(originOnPlane, impostorObjectCenter).normalize();
            var forceX = (perpendicularDirection.x + directionToOrigin.x) * this._options.centrifugalForceMultiplier;
            var forceY = this._originTop.y * this._options.updraftForceMultiplier;
            var forceZ = (perpendicularDirection.z + directionToOrigin.z) * this._options.centrifugalForceMultiplier;
        }
        var force = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](forceX, forceY, forceZ);
        force = force.multiplyByFloats(this._options.strength, this._options.strength, this._options.strength);
        return { force: force, contactPoint: impostorObjectCenter, distanceFromOrigin: absoluteDistanceFromOrigin };
    };
    PhysicsVortexEvent.prototype._tick = function () {
        var _this = this;
        this._physicsEngine.getImpostors().forEach(function (impostor) {
            var impostorHitData = _this.getImpostorHitData(impostor);
            if (!impostorHitData) {
                return;
            }
            impostor.applyForce(impostorHitData.force, impostorHitData.contactPoint);
        });
    };
    /*** Helpers ***/
    PhysicsVortexEvent.prototype._prepareCylinder = function () {
        if (!this._cylinder) {
            this._cylinder = _Meshes_Builders_cylinderBuilder__WEBPACK_IMPORTED_MODULE_4__["CylinderBuilder"].CreateCylinder("vortexEventCylinder", {
                height: this._options.height,
                diameter: this._options.radius * 2,
            }, this._scene);
            this._cylinder.isVisible = false;
        }
    };
    PhysicsVortexEvent.prototype._intersectsWithCylinder = function (impostor) {
        var impostorObject = impostor.object;
        this._cylinder.position = this._cylinderPosition;
        return this._cylinder.intersectsMesh(impostorObject, true);
    };
    return PhysicsVortexEvent;
}());
/**
 * Options fot the radial explosion event
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine#further-functionality-of-the-impostor-class
 */
var PhysicsRadialExplosionEventOptions = /** @class */ (function () {
    function PhysicsRadialExplosionEventOptions() {
        /**
         * The radius of the sphere for the radial explosion.
         */
        this.radius = 5;
        /**
         * The strenth of the explosion.
         */
        this.strength = 10;
        /**
         * The strenght of the force in correspondence to the distance of the affected object
         */
        this.falloff = PhysicsRadialImpulseFalloff.Constant;
        /**
         * Sphere options for the radial explosion.
         */
        this.sphere = { segments: 32, diameter: 1 };
    }
    return PhysicsRadialExplosionEventOptions;
}());

/**
 * Options fot the updraft event
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine#further-functionality-of-the-impostor-class
 */
var PhysicsUpdraftEventOptions = /** @class */ (function () {
    function PhysicsUpdraftEventOptions() {
        /**
         * The radius of the cylinder for the vortex
         */
        this.radius = 5;
        /**
         * The strenth of the updraft.
         */
        this.strength = 10;
        /**
         * The height of the cylinder for the updraft.
         */
        this.height = 10;
        /**
         * The mode for the the updraft.
         */
        this.updraftMode = PhysicsUpdraftMode.Center;
    }
    return PhysicsUpdraftEventOptions;
}());

/**
 * Options fot the vortex event
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine#further-functionality-of-the-impostor-class
 */
var PhysicsVortexEventOptions = /** @class */ (function () {
    function PhysicsVortexEventOptions() {
        /**
         * The radius of the cylinder for the vortex
         */
        this.radius = 5;
        /**
         * The strenth of the vortex.
         */
        this.strength = 10;
        /**
         * The height of the cylinder for the vortex.
         */
        this.height = 10;
        /**
         * At which distance, relative to the radius the centripetal forces should kick in? Range: 0-1
         */
        this.centripetalForceThreshold = 0.7;
        /**
         * This multiplier determines with how much force the objects will be pushed sideways/around the vortex, when below the treshold.
         */
        this.centripetalForceMultiplier = 5;
        /**
         * This multiplier determines with how much force the objects will be pushed sideways/around the vortex, when above the treshold.
         */
        this.centrifugalForceMultiplier = 0.5;
        /**
         * This multiplier determines with how much force the objects will be pushed upwards, when in the vortex.
         */
        this.updraftForceMultiplier = 0.02;
    }
    return PhysicsVortexEventOptions;
}());

/**
* The strenght of the force in correspondence to the distance of the affected object
* @see https://doc.babylonjs.com/how_to/using_the_physics_engine#further-functionality-of-the-impostor-class
*/
var PhysicsRadialImpulseFalloff;
(function (PhysicsRadialImpulseFalloff) {
    /** Defines that impulse is constant in strength across it's whole radius */
    PhysicsRadialImpulseFalloff[PhysicsRadialImpulseFalloff["Constant"] = 0] = "Constant";
    /** Defines that impulse gets weaker if it's further from the origin */
    PhysicsRadialImpulseFalloff[PhysicsRadialImpulseFalloff["Linear"] = 1] = "Linear";
})(PhysicsRadialImpulseFalloff || (PhysicsRadialImpulseFalloff = {}));
/**
 * The strength of the force in correspondence to the distance of the affected object
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine#further-functionality-of-the-impostor-class
 */
var PhysicsUpdraftMode;
(function (PhysicsUpdraftMode) {
    /** Defines that the upstream forces will pull towards the top center of the cylinder */
    PhysicsUpdraftMode[PhysicsUpdraftMode["Center"] = 0] = "Center";
    /** Defines that once a impostor is inside the cylinder, it will shoot out perpendicular from the ground of the cylinder */
    PhysicsUpdraftMode[PhysicsUpdraftMode["Perpendicular"] = 1] = "Perpendicular";
})(PhysicsUpdraftMode || (PhysicsUpdraftMode = {}));


/***/ }),

/***/ "./Physics/physicsImpostor.ts":
/*!************************************!*\
  !*** ./Physics/physicsImpostor.ts ***!
  \************************************/
/*! exports provided: PhysicsImpostor */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsImpostor", function() { return PhysicsImpostor; });
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/arrayTools */ "./Misc/arrayTools.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _physicsJoint__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./physicsJoint */ "./Physics/physicsJoint.ts");
/* harmony import */ var _Maths_math_axis__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Maths/math.axis */ "./Maths/math.axis.ts");







_Meshes_mesh__WEBPACK_IMPORTED_MODULE_4__["Mesh"]._PhysicsImpostorParser = function (scene, physicObject, jsonObject) {
    return new PhysicsImpostor(physicObject, jsonObject.physicsImpostor, {
        mass: jsonObject.physicsMass,
        friction: jsonObject.physicsFriction,
        restitution: jsonObject.physicsRestitution
    }, scene);
};
/**
 * Represents a physics imposter
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var PhysicsImpostor = /** @class */ (function () {
    /**
     * Initializes the physics imposter
     * @param object The physics-enabled object used as the physics imposter
     * @param type The type of the physics imposter
     * @param _options The options for the physics imposter
     * @param _scene The Babylon scene
     */
    function PhysicsImpostor(
    /**
     * The physics-enabled object used as the physics imposter
     */
    object,
    /**
     * The type of the physics imposter
     */
    type, _options, _scene) {
        var _this = this;
        if (_options === void 0) { _options = { mass: 0 }; }
        this.object = object;
        this.type = type;
        this._options = _options;
        this._scene = _scene;
        /** @hidden */
        this._pluginData = {};
        this._bodyUpdateRequired = false;
        this._onBeforePhysicsStepCallbacks = new Array();
        this._onAfterPhysicsStepCallbacks = new Array();
        /** @hidden */
        this._onPhysicsCollideCallbacks = [];
        this._deltaPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
        this._isDisposed = false;
        /**
         * @hidden
         */
        this.soft = false;
        /**
         * @hidden
         */
        this.segments = 0;
        //temp variables for parent rotation calculations
        //private _mats: Array<Matrix> = [new Matrix(), new Matrix()];
        this._tmpQuat = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        this._tmpQuat2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        /**
         * this function is executed by the physics engine.
         */
        this.beforeStep = function () {
            if (!_this._physicsEngine) {
                return;
            }
            _this.object.translate(_this._deltaPosition, -1);
            _this._deltaRotationConjugated && _this.object.rotationQuaternion && _this.object.rotationQuaternion.multiplyToRef(_this._deltaRotationConjugated, _this.object.rotationQuaternion);
            _this.object.computeWorldMatrix(false);
            if (_this.object.parent && _this.object.rotationQuaternion) {
                _this.getParentsRotation();
                _this._tmpQuat.multiplyToRef(_this.object.rotationQuaternion, _this._tmpQuat);
            }
            else {
                _this._tmpQuat.copyFrom(_this.object.rotationQuaternion || new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]());
            }
            if (!_this._options.disableBidirectionalTransformation) {
                _this.object.rotationQuaternion && _this._physicsEngine.getPhysicsPlugin().setPhysicsBodyTransformation(_this, /*bInfo.boundingBox.centerWorld*/ _this.object.getAbsolutePosition(), _this._tmpQuat);
            }
            _this._onBeforePhysicsStepCallbacks.forEach(function (func) {
                func(_this);
            });
        };
        /**
         * this function is executed by the physics engine
         */
        this.afterStep = function () {
            if (!_this._physicsEngine) {
                return;
            }
            _this._onAfterPhysicsStepCallbacks.forEach(function (func) {
                func(_this);
            });
            _this._physicsEngine.getPhysicsPlugin().setTransformationFromPhysicsBody(_this);
            // object has now its world rotation. needs to be converted to local.
            if (_this.object.parent && _this.object.rotationQuaternion) {
                _this.getParentsRotation();
                _this._tmpQuat.conjugateInPlace();
                _this._tmpQuat.multiplyToRef(_this.object.rotationQuaternion, _this.object.rotationQuaternion);
            }
            // take the position set and make it the absolute position of this object.
            _this.object.setAbsolutePosition(_this.object.position);
            _this._deltaRotation && _this.object.rotationQuaternion && _this.object.rotationQuaternion.multiplyToRef(_this._deltaRotation, _this.object.rotationQuaternion);
            _this.object.translate(_this._deltaPosition, 1);
        };
        /**
         * Legacy collision detection event support
         */
        this.onCollideEvent = null;
        /**
         * event and body object due to cannon's event-based architecture.
         */
        this.onCollide = function (e) {
            if (!_this._onPhysicsCollideCallbacks.length && !_this.onCollideEvent) {
                return;
            }
            if (!_this._physicsEngine) {
                return;
            }
            var otherImpostor = _this._physicsEngine.getImpostorWithPhysicsBody(e.body);
            if (otherImpostor) {
                // Legacy collision detection event support
                if (_this.onCollideEvent) {
                    _this.onCollideEvent(_this, otherImpostor);
                }
                _this._onPhysicsCollideCallbacks.filter(function (obj) {
                    return obj.otherImpostors.indexOf(otherImpostor) !== -1;
                }).forEach(function (obj) {
                    obj.callback(_this, otherImpostor);
                });
            }
        };
        //sanity check!
        if (!this.object) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("No object was provided. A physics object is obligatory");
            return;
        }
        if (this.object.parent && _options.mass !== 0) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("A physics impostor has been created for an object which has a parent. Babylon physics currently works in local space so unexpected issues may occur.");
        }
        // Legacy support for old syntax.
        if (!this._scene && object.getScene) {
            this._scene = object.getScene();
        }
        if (!this._scene) {
            return;
        }
        if (this.type > 100) {
            this.soft = true;
        }
        this._physicsEngine = this._scene.getPhysicsEngine();
        if (!this._physicsEngine) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Error("Physics not enabled. Please use scene.enablePhysics(...) before creating impostors.");
        }
        else {
            //set the object's quaternion, if not set
            if (!this.object.rotationQuaternion) {
                if (this.object.rotation) {
                    this.object.rotationQuaternion = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].RotationYawPitchRoll(this.object.rotation.y, this.object.rotation.x, this.object.rotation.z);
                }
                else {
                    this.object.rotationQuaternion = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
                }
            }
            //default options params
            this._options.mass = (_options.mass === void 0) ? 0 : _options.mass;
            this._options.friction = (_options.friction === void 0) ? 0.2 : _options.friction;
            this._options.restitution = (_options.restitution === void 0) ? 0.2 : _options.restitution;
            if (this.soft) {
                //softbody mass must be above 0;
                this._options.mass = this._options.mass > 0 ? this._options.mass : 1;
                this._options.pressure = (_options.pressure === void 0) ? 200 : _options.pressure;
                this._options.stiffness = (_options.stiffness === void 0) ? 1 : _options.stiffness;
                this._options.velocityIterations = (_options.velocityIterations === void 0) ? 20 : _options.velocityIterations;
                this._options.positionIterations = (_options.positionIterations === void 0) ? 20 : _options.positionIterations;
                this._options.fixedPoints = (_options.fixedPoints === void 0) ? 0 : _options.fixedPoints;
                this._options.margin = (_options.margin === void 0) ? 0 : _options.margin;
                this._options.damping = (_options.damping === void 0) ? 0 : _options.damping;
                this._options.path = (_options.path === void 0) ? null : _options.path;
                this._options.shape = (_options.shape === void 0) ? null : _options.shape;
            }
            this._joints = [];
            //If the mesh has a parent, don't initialize the physicsBody. Instead wait for the parent to do that.
            if (!this.object.parent || this._options.ignoreParent) {
                this._init();
            }
            else if (this.object.parent.physicsImpostor) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("You must affect impostors to children before affecting impostor to parent.");
            }
        }
    }
    Object.defineProperty(PhysicsImpostor.prototype, "isDisposed", {
        /**
         * Specifies if the physics imposter is disposed
         */
        get: function () {
            return this._isDisposed;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "mass", {
        /**
         * Gets the mass of the physics imposter
         */
        get: function () {
            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyMass(this) : 0;
        },
        set: function (value) {
            this.setMass(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "friction", {
        /**
         * Gets the coefficient of friction
         */
        get: function () {
            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyFriction(this) : 0;
        },
        /**
         * Sets the coefficient of friction
         */
        set: function (value) {
            if (!this._physicsEngine) {
                return;
            }
            this._physicsEngine.getPhysicsPlugin().setBodyFriction(this, value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "restitution", {
        /**
         * Gets the coefficient of restitution
         */
        get: function () {
            return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getBodyRestitution(this) : 0;
        },
        /**
         * Sets the coefficient of restitution
         */
        set: function (value) {
            if (!this._physicsEngine) {
                return;
            }
            this._physicsEngine.getPhysicsPlugin().setBodyRestitution(this, value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "pressure", {
        /**
         * Gets the pressure of a soft body; only supported by the AmmoJSPlugin
         */
        get: function () {
            if (!this._physicsEngine) {
                return 0;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.setBodyPressure) {
                return 0;
            }
            return plugin.getBodyPressure(this);
        },
        /**
         * Sets the pressure of a soft body; only supported by the AmmoJSPlugin
         */
        set: function (value) {
            if (!this._physicsEngine) {
                return;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.setBodyPressure) {
                return;
            }
            plugin.setBodyPressure(this, value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "stiffness", {
        /**
         * Gets the stiffness of a soft body; only supported by the AmmoJSPlugin
         */
        get: function () {
            if (!this._physicsEngine) {
                return 0;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.getBodyStiffness) {
                return 0;
            }
            return plugin.getBodyStiffness(this);
        },
        /**
         * Sets the stiffness of a soft body; only supported by the AmmoJSPlugin
         */
        set: function (value) {
            if (!this._physicsEngine) {
                return;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.setBodyStiffness) {
                return;
            }
            plugin.setBodyStiffness(this, value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "velocityIterations", {
        /**
         * Gets the velocityIterations of a soft body; only supported by the AmmoJSPlugin
         */
        get: function () {
            if (!this._physicsEngine) {
                return 0;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.getBodyVelocityIterations) {
                return 0;
            }
            return plugin.getBodyVelocityIterations(this);
        },
        /**
         * Sets the velocityIterations of a soft body; only supported by the AmmoJSPlugin
         */
        set: function (value) {
            if (!this._physicsEngine) {
                return;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.setBodyVelocityIterations) {
                return;
            }
            plugin.setBodyVelocityIterations(this, value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "positionIterations", {
        /**
         * Gets the positionIterations of a soft body; only supported by the AmmoJSPlugin
         */
        get: function () {
            if (!this._physicsEngine) {
                return 0;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.getBodyPositionIterations) {
                return 0;
            }
            return plugin.getBodyPositionIterations(this);
        },
        /**
         * Sets the positionIterations of a soft body; only supported by the AmmoJSPlugin
         */
        set: function (value) {
            if (!this._physicsEngine) {
                return;
            }
            var plugin = this._physicsEngine.getPhysicsPlugin();
            if (!plugin.setBodyPositionIterations) {
                return;
            }
            plugin.setBodyPositionIterations(this, value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * This function will completly initialize this impostor.
     * It will create a new body - but only if this mesh has no parent.
     * If it has, this impostor will not be used other than to define the impostor
     * of the child mesh.
     * @hidden
     */
    PhysicsImpostor.prototype._init = function () {
        if (!this._physicsEngine) {
            return;
        }
        this._physicsEngine.removeImpostor(this);
        this.physicsBody = null;
        this._parent = this._parent || this._getPhysicsParent();
        if (!this._isDisposed && (!this.parent || this._options.ignoreParent)) {
            this._physicsEngine.addImpostor(this);
        }
    };
    PhysicsImpostor.prototype._getPhysicsParent = function () {
        if (this.object.parent instanceof _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_3__["AbstractMesh"]) {
            var parentMesh = this.object.parent;
            return parentMesh.physicsImpostor;
        }
        return null;
    };
    /**
     * Should a new body be generated.
     * @returns boolean specifying if body initialization is required
     */
    PhysicsImpostor.prototype.isBodyInitRequired = function () {
        return this._bodyUpdateRequired || (!this._physicsBody && !this._parent);
    };
    /**
     * Sets the updated scaling
     * @param updated Specifies if the scaling is updated
     */
    PhysicsImpostor.prototype.setScalingUpdated = function () {
        this.forceUpdate();
    };
    /**
     * Force a regeneration of this or the parent's impostor's body.
     * Use under cautious - This will remove all joints already implemented.
     */
    PhysicsImpostor.prototype.forceUpdate = function () {
        this._init();
        if (this.parent && !this._options.ignoreParent) {
            this.parent.forceUpdate();
        }
    };
    Object.defineProperty(PhysicsImpostor.prototype, "physicsBody", {
        /*public get mesh(): AbstractMesh {
            return this._mesh;
        }*/
        /**
         * Gets the body that holds this impostor. Either its own, or its parent.
         */
        get: function () {
            return (this._parent && !this._options.ignoreParent) ? this._parent.physicsBody : this._physicsBody;
        },
        /**
         * Set the physics body. Used mainly by the physics engine/plugin
         */
        set: function (physicsBody) {
            if (this._physicsBody && this._physicsEngine) {
                this._physicsEngine.getPhysicsPlugin().removePhysicsBody(this);
            }
            this._physicsBody = physicsBody;
            this.resetUpdateFlags();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsImpostor.prototype, "parent", {
        /**
         * Get the parent of the physics imposter
         * @returns Physics imposter or null
         */
        get: function () {
            return !this._options.ignoreParent && this._parent ? this._parent : null;
        },
        /**
         * Sets the parent of the physics imposter
         */
        set: function (value) {
            this._parent = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resets the update flags
     */
    PhysicsImpostor.prototype.resetUpdateFlags = function () {
        this._bodyUpdateRequired = false;
    };
    /**
     * Gets the object extend size
     * @returns the object extend size
     */
    PhysicsImpostor.prototype.getObjectExtendSize = function () {
        if (this.object.getBoundingInfo) {
            var q = this.object.rotationQuaternion;
            //reset rotation
            this.object.rotationQuaternion = PhysicsImpostor.IDENTITY_QUATERNION;
            //calculate the world matrix with no rotation
            this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
            var boundingInfo = this.object.getBoundingInfo();
            var size = boundingInfo.boundingBox.extendSizeWorld.scale(2);
            //bring back the rotation
            this.object.rotationQuaternion = q;
            //calculate the world matrix with the new rotation
            this.object.computeWorldMatrix && this.object.computeWorldMatrix(true);
            return size;
        }
        else {
            return PhysicsImpostor.DEFAULT_OBJECT_SIZE;
        }
    };
    /**
     * Gets the object center
     * @returns The object center
     */
    PhysicsImpostor.prototype.getObjectCenter = function () {
        if (this.object.getBoundingInfo) {
            var boundingInfo = this.object.getBoundingInfo();
            return boundingInfo.boundingBox.centerWorld;
        }
        else {
            return this.object.position;
        }
    };
    /**
     * Get a specific parametes from the options parameter
     * @param paramName The object parameter name
     * @returns The object parameter
     */
    PhysicsImpostor.prototype.getParam = function (paramName) {
        return this._options[paramName];
    };
    /**
     * Sets a specific parameter in the options given to the physics plugin
     * @param paramName The parameter name
     * @param value The value of the parameter
     */
    PhysicsImpostor.prototype.setParam = function (paramName, value) {
        this._options[paramName] = value;
        this._bodyUpdateRequired = true;
    };
    /**
     * Specifically change the body's mass option. Won't recreate the physics body object
     * @param mass The mass of the physics imposter
     */
    PhysicsImpostor.prototype.setMass = function (mass) {
        if (this.getParam("mass") !== mass) {
            this.setParam("mass", mass);
        }
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().setBodyMass(this, mass);
        }
    };
    /**
     * Gets the linear velocity
     * @returns  linear velocity or null
     */
    PhysicsImpostor.prototype.getLinearVelocity = function () {
        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getLinearVelocity(this) : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
    };
    /**
     * Sets the linear velocity
     * @param velocity  linear velocity or null
     */
    PhysicsImpostor.prototype.setLinearVelocity = function (velocity) {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
        }
    };
    /**
     * Gets the angular velocity
     * @returns angular velocity or null
     */
    PhysicsImpostor.prototype.getAngularVelocity = function () {
        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getAngularVelocity(this) : _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero();
    };
    /**
     * Sets the angular velocity
     * @param velocity The velocity or null
     */
    PhysicsImpostor.prototype.setAngularVelocity = function (velocity) {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
        }
    };
    /**
     * Execute a function with the physics plugin native code
     * Provide a function the will have two variables - the world object and the physics body object
     * @param func The function to execute with the physics plugin native code
     */
    PhysicsImpostor.prototype.executeNativeFunction = function (func) {
        if (this._physicsEngine) {
            func(this._physicsEngine.getPhysicsPlugin().world, this.physicsBody);
        }
    };
    /**
     * Register a function that will be executed before the physics world is stepping forward
     * @param func The function to execute before the physics world is stepped forward
     */
    PhysicsImpostor.prototype.registerBeforePhysicsStep = function (func) {
        this._onBeforePhysicsStepCallbacks.push(func);
    };
    /**
     * Unregister a function that will be executed before the physics world is stepping forward
     * @param func The function to execute before the physics world is stepped forward
     */
    PhysicsImpostor.prototype.unregisterBeforePhysicsStep = function (func) {
        var index = this._onBeforePhysicsStepCallbacks.indexOf(func);
        if (index > -1) {
            this._onBeforePhysicsStepCallbacks.splice(index, 1);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Function to remove was not found");
        }
    };
    /**
     * Register a function that will be executed after the physics step
     * @param func The function to execute after physics step
     */
    PhysicsImpostor.prototype.registerAfterPhysicsStep = function (func) {
        this._onAfterPhysicsStepCallbacks.push(func);
    };
    /**
     * Unregisters a function that will be executed after the physics step
     * @param func The function to execute after physics step
     */
    PhysicsImpostor.prototype.unregisterAfterPhysicsStep = function (func) {
        var index = this._onAfterPhysicsStepCallbacks.indexOf(func);
        if (index > -1) {
            this._onAfterPhysicsStepCallbacks.splice(index, 1);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Function to remove was not found");
        }
    };
    /**
     * register a function that will be executed when this impostor collides against a different body
     * @param collideAgainst Physics imposter, or array of physics imposters to collide against
     * @param func Callback that is executed on collision
     */
    PhysicsImpostor.prototype.registerOnPhysicsCollide = function (collideAgainst, func) {
        var collidedAgainstList = collideAgainst instanceof Array ? collideAgainst : [collideAgainst];
        this._onPhysicsCollideCallbacks.push({ callback: func, otherImpostors: collidedAgainstList });
    };
    /**
     * Unregisters the physics imposter on contact
     * @param collideAgainst The physics object to collide against
     * @param func Callback to execute on collision
     */
    PhysicsImpostor.prototype.unregisterOnPhysicsCollide = function (collideAgainst, func) {
        var collidedAgainstList = collideAgainst instanceof Array ? collideAgainst : [collideAgainst];
        var index = -1;
        var found = this._onPhysicsCollideCallbacks.some(function (cbDef, idx) {
            if (cbDef.callback === func && cbDef.otherImpostors.length === collidedAgainstList.length) {
                // chcek the arrays match
                var sameList = cbDef.otherImpostors.every(function (impostor) {
                    return collidedAgainstList.indexOf(impostor) > -1;
                });
                if (sameList) {
                    index = idx;
                }
                return sameList;
            }
            return false;
        });
        if (found) {
            this._onPhysicsCollideCallbacks.splice(index, 1);
        }
        else {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("Function to remove was not found");
        }
    };
    /**
     * Get the parent rotation
     * @returns The parent rotation
     */
    PhysicsImpostor.prototype.getParentsRotation = function () {
        var parent = this.object.parent;
        this._tmpQuat.copyFromFloats(0, 0, 0, 1);
        while (parent) {
            if (parent.rotationQuaternion) {
                this._tmpQuat2.copyFrom(parent.rotationQuaternion);
            }
            else {
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].RotationYawPitchRollToRef(parent.rotation.y, parent.rotation.x, parent.rotation.z, this._tmpQuat2);
            }
            this._tmpQuat.multiplyToRef(this._tmpQuat2, this._tmpQuat);
            parent = parent.parent;
        }
        return this._tmpQuat;
    };
    /**
     * Apply a force
     * @param force The force to apply
     * @param contactPoint The contact point for the force
     * @returns The physics imposter
     */
    PhysicsImpostor.prototype.applyForce = function (force, contactPoint) {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().applyForce(this, force, contactPoint);
        }
        return this;
    };
    /**
     * Apply an impulse
     * @param force The impulse force
     * @param contactPoint The contact point for the impulse force
     * @returns The physics imposter
     */
    PhysicsImpostor.prototype.applyImpulse = function (force, contactPoint) {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().applyImpulse(this, force, contactPoint);
        }
        return this;
    };
    /**
     * A help function to create a joint
     * @param otherImpostor A physics imposter used to create a joint
     * @param jointType The type of joint
     * @param jointData The data for the joint
     * @returns The physics imposter
     */
    PhysicsImpostor.prototype.createJoint = function (otherImpostor, jointType, jointData) {
        var joint = new _physicsJoint__WEBPACK_IMPORTED_MODULE_5__["PhysicsJoint"](jointType, jointData);
        this.addJoint(otherImpostor, joint);
        return this;
    };
    /**
     * Add a joint to this impostor with a different impostor
     * @param otherImpostor A physics imposter used to add a joint
     * @param joint The joint to add
     * @returns The physics imposter
     */
    PhysicsImpostor.prototype.addJoint = function (otherImpostor, joint) {
        this._joints.push({
            otherImpostor: otherImpostor,
            joint: joint
        });
        if (this._physicsEngine) {
            this._physicsEngine.addJoint(this, otherImpostor, joint);
        }
        return this;
    };
    /**
     * Add an anchor to a cloth impostor
     * @param otherImpostor rigid impostor to anchor to
     * @param width ratio across width from 0 to 1
     * @param height ratio up height from 0 to 1
     * @param influence the elasticity between cloth impostor and anchor from 0, very stretchy to 1, little strech
     * @param noCollisionBetweenLinkedBodies when true collisions between cloth impostor and anchor are ignored; default false
     * @returns impostor the soft imposter
     */
    PhysicsImpostor.prototype.addAnchor = function (otherImpostor, width, height, influence, noCollisionBetweenLinkedBodies) {
        if (!this._physicsEngine) {
            return this;
        }
        var plugin = this._physicsEngine.getPhysicsPlugin();
        if (!plugin.appendAnchor) {
            return this;
        }
        if (this._physicsEngine) {
            plugin.appendAnchor(this, otherImpostor, width, height, influence, noCollisionBetweenLinkedBodies);
        }
        return this;
    };
    /**
     * Add a hook to a rope impostor
     * @param otherImpostor rigid impostor to anchor to
     * @param length ratio across rope from 0 to 1
     * @param influence the elasticity between rope impostor and anchor from 0, very stretchy to 1, little strech
     * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false
     * @returns impostor the rope imposter
     */
    PhysicsImpostor.prototype.addHook = function (otherImpostor, length, influence, noCollisionBetweenLinkedBodies) {
        if (!this._physicsEngine) {
            return this;
        }
        var plugin = this._physicsEngine.getPhysicsPlugin();
        if (!plugin.appendAnchor) {
            return this;
        }
        if (this._physicsEngine) {
            plugin.appendHook(this, otherImpostor, length, influence, noCollisionBetweenLinkedBodies);
        }
        return this;
    };
    /**
     * Will keep this body still, in a sleep mode.
     * @returns the physics imposter
     */
    PhysicsImpostor.prototype.sleep = function () {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().sleepBody(this);
        }
        return this;
    };
    /**
     * Wake the body up.
     * @returns The physics imposter
     */
    PhysicsImpostor.prototype.wakeUp = function () {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().wakeUpBody(this);
        }
        return this;
    };
    /**
     * Clones the physics imposter
     * @param newObject The physics imposter clones to this physics-enabled object
     * @returns A nullable physics imposter
     */
    PhysicsImpostor.prototype.clone = function (newObject) {
        if (!newObject) {
            return null;
        }
        return new PhysicsImpostor(newObject, this.type, this._options, this._scene);
    };
    /**
     * Disposes the physics imposter
     */
    PhysicsImpostor.prototype.dispose = function ( /*disposeChildren: boolean = true*/) {
        var _this = this;
        //no dispose if no physics engine is available.
        if (!this._physicsEngine) {
            return;
        }
        this._joints.forEach(function (j) {
            if (_this._physicsEngine) {
                _this._physicsEngine.removeJoint(_this, j.otherImpostor, j.joint);
            }
        });
        //dispose the physics body
        this._physicsEngine.removeImpostor(this);
        if (this.parent) {
            this.parent.forceUpdate();
        }
        else {
            /*this._object.getChildMeshes().forEach(function(mesh) {
                if (mesh.physicsImpostor) {
                    if (disposeChildren) {
                        mesh.physicsImpostor.dispose();
                        mesh.physicsImpostor = null;
                    }
                }
            })*/
        }
        this._isDisposed = true;
    };
    /**
     * Sets the delta position
     * @param position The delta position amount
     */
    PhysicsImpostor.prototype.setDeltaPosition = function (position) {
        this._deltaPosition.copyFrom(position);
    };
    /**
     * Sets the delta rotation
     * @param rotation The delta rotation amount
     */
    PhysicsImpostor.prototype.setDeltaRotation = function (rotation) {
        if (!this._deltaRotation) {
            this._deltaRotation = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"]();
        }
        this._deltaRotation.copyFrom(rotation);
        this._deltaRotationConjugated = this._deltaRotation.conjugate();
    };
    /**
     * Gets the box size of the physics imposter and stores the result in the input parameter
     * @param result Stores the box size
     * @returns The physics imposter
     */
    PhysicsImpostor.prototype.getBoxSizeToRef = function (result) {
        if (this._physicsEngine) {
            this._physicsEngine.getPhysicsPlugin().getBoxSizeToRef(this, result);
        }
        return this;
    };
    /**
     * Gets the radius of the physics imposter
     * @returns Radius of the physics imposter
     */
    PhysicsImpostor.prototype.getRadius = function () {
        return this._physicsEngine ? this._physicsEngine.getPhysicsPlugin().getRadius(this) : 0;
    };
    /**
     * Sync a bone with this impostor
     * @param bone The bone to sync to the impostor.
     * @param boneMesh The mesh that the bone is influencing.
     * @param jointPivot The pivot of the joint / bone in local space.
     * @param distToJoint Optional distance from the impostor to the joint.
     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.
     */
    PhysicsImpostor.prototype.syncBoneWithImpostor = function (bone, boneMesh, jointPivot, distToJoint, adjustRotation) {
        var tempVec = PhysicsImpostor._tmpVecs[0];
        var mesh = this.object;
        if (mesh.rotationQuaternion) {
            if (adjustRotation) {
                var tempQuat = PhysicsImpostor._tmpQuat;
                mesh.rotationQuaternion.multiplyToRef(adjustRotation, tempQuat);
                bone.setRotationQuaternion(tempQuat, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_6__["Space"].WORLD, boneMesh);
            }
            else {
                bone.setRotationQuaternion(mesh.rotationQuaternion, _Maths_math_axis__WEBPACK_IMPORTED_MODULE_6__["Space"].WORLD, boneMesh);
            }
        }
        tempVec.x = 0;
        tempVec.y = 0;
        tempVec.z = 0;
        if (jointPivot) {
            tempVec.x = jointPivot.x;
            tempVec.y = jointPivot.y;
            tempVec.z = jointPivot.z;
            bone.getDirectionToRef(tempVec, boneMesh, tempVec);
            if (distToJoint === undefined || distToJoint === null) {
                distToJoint = jointPivot.length();
            }
            tempVec.x *= distToJoint;
            tempVec.y *= distToJoint;
            tempVec.z *= distToJoint;
        }
        if (bone.getParent()) {
            tempVec.addInPlace(mesh.getAbsolutePosition());
            bone.setAbsolutePosition(tempVec, boneMesh);
        }
        else {
            boneMesh.setAbsolutePosition(mesh.getAbsolutePosition());
            boneMesh.position.x -= tempVec.x;
            boneMesh.position.y -= tempVec.y;
            boneMesh.position.z -= tempVec.z;
        }
    };
    /**
     * Sync impostor to a bone
     * @param bone The bone that the impostor will be synced to.
     * @param boneMesh The mesh that the bone is influencing.
     * @param jointPivot The pivot of the joint / bone in local space.
     * @param distToJoint Optional distance from the impostor to the joint.
     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.
     * @param boneAxis Optional vector3 axis the bone is aligned with
     */
    PhysicsImpostor.prototype.syncImpostorWithBone = function (bone, boneMesh, jointPivot, distToJoint, adjustRotation, boneAxis) {
        var mesh = this.object;
        if (mesh.rotationQuaternion) {
            if (adjustRotation) {
                var tempQuat = PhysicsImpostor._tmpQuat;
                bone.getRotationQuaternionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_6__["Space"].WORLD, boneMesh, tempQuat);
                tempQuat.multiplyToRef(adjustRotation, mesh.rotationQuaternion);
            }
            else {
                bone.getRotationQuaternionToRef(_Maths_math_axis__WEBPACK_IMPORTED_MODULE_6__["Space"].WORLD, boneMesh, mesh.rotationQuaternion);
            }
        }
        var pos = PhysicsImpostor._tmpVecs[0];
        var boneDir = PhysicsImpostor._tmpVecs[1];
        if (!boneAxis) {
            boneAxis = PhysicsImpostor._tmpVecs[2];
            boneAxis.x = 0;
            boneAxis.y = 1;
            boneAxis.z = 0;
        }
        bone.getDirectionToRef(boneAxis, boneMesh, boneDir);
        bone.getAbsolutePositionToRef(boneMesh, pos);
        if ((distToJoint === undefined || distToJoint === null) && jointPivot) {
            distToJoint = jointPivot.length();
        }
        if (distToJoint !== undefined && distToJoint !== null) {
            pos.x += boneDir.x * distToJoint;
            pos.y += boneDir.y * distToJoint;
            pos.z += boneDir.z * distToJoint;
        }
        mesh.setAbsolutePosition(pos);
    };
    /**
     * The default object size of the imposter
     */
    PhysicsImpostor.DEFAULT_OBJECT_SIZE = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"](1, 1, 1);
    /**
     * The identity quaternion of the imposter
     */
    PhysicsImpostor.IDENTITY_QUATERNION = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].Identity();
    PhysicsImpostor._tmpVecs = _Misc_arrayTools__WEBPACK_IMPORTED_MODULE_1__["ArrayTools"].BuildArray(3, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector3"].Zero);
    PhysicsImpostor._tmpQuat = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Quaternion"].Identity();
    //Impostor types
    /**
     * No-Imposter type
     */
    PhysicsImpostor.NoImpostor = 0;
    /**
     * Sphere-Imposter type
     */
    PhysicsImpostor.SphereImpostor = 1;
    /**
     * Box-Imposter type
     */
    PhysicsImpostor.BoxImpostor = 2;
    /**
     * Plane-Imposter type
     */
    PhysicsImpostor.PlaneImpostor = 3;
    /**
     * Mesh-imposter type
     */
    PhysicsImpostor.MeshImpostor = 4;
    /**
     * Capsule-Impostor type (Ammo.js plugin only)
     */
    PhysicsImpostor.CapsuleImpostor = 6;
    /**
     * Cylinder-Imposter type
     */
    PhysicsImpostor.CylinderImpostor = 7;
    /**
     * Particle-Imposter type
     */
    PhysicsImpostor.ParticleImpostor = 8;
    /**
     * Heightmap-Imposter type
     */
    PhysicsImpostor.HeightmapImpostor = 9;
    /**
     * ConvexHull-Impostor type (Ammo.js plugin only)
     */
    PhysicsImpostor.ConvexHullImpostor = 10;
    /**
     * Rope-Imposter type
     */
    PhysicsImpostor.RopeImpostor = 101;
    /**
     * Cloth-Imposter type
     */
    PhysicsImpostor.ClothImpostor = 102;
    /**
     * Softbody-Imposter type
     */
    PhysicsImpostor.SoftbodyImpostor = 103;
    return PhysicsImpostor;
}());



/***/ }),

/***/ "./Physics/physicsJoint.ts":
/*!*********************************!*\
  !*** ./Physics/physicsJoint.ts ***!
  \*********************************/
/*! exports provided: PhysicsJoint, DistanceJoint, MotorEnabledJoint, HingeJoint, Hinge2Joint */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsJoint", function() { return PhysicsJoint; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DistanceJoint", function() { return DistanceJoint; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MotorEnabledJoint", function() { return MotorEnabledJoint; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HingeJoint", function() { return HingeJoint; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Hinge2Joint", function() { return Hinge2Joint; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");

/**
 * This is a holder class for the physics joint created by the physics plugin
 * It holds a set of functions to control the underlying joint
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var PhysicsJoint = /** @class */ (function () {
    /**
     * Initializes the physics joint
     * @param type The type of the physics joint
     * @param jointData The data for the physics joint
     */
    function PhysicsJoint(
    /**
     * The type of the physics joint
     */
    type,
    /**
     * The data for the physics joint
     */
    jointData) {
        this.type = type;
        this.jointData = jointData;
        jointData.nativeParams = jointData.nativeParams || {};
    }
    Object.defineProperty(PhysicsJoint.prototype, "physicsJoint", {
        /**
         * Gets the physics joint
         */
        get: function () {
            return this._physicsJoint;
        },
        /**
         * Sets the physics joint
         */
        set: function (newJoint) {
            if (this._physicsJoint) {
                //remove from the wolrd
            }
            this._physicsJoint = newJoint;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsJoint.prototype, "physicsPlugin", {
        /**
         * Sets the physics plugin
         */
        set: function (physicsPlugin) {
            this._physicsPlugin = physicsPlugin;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Execute a function that is physics-plugin specific.
     * @param {Function} func the function that will be executed.
     *                        It accepts two parameters: the physics world and the physics joint
     */
    PhysicsJoint.prototype.executeNativeFunction = function (func) {
        func(this._physicsPlugin.world, this._physicsJoint);
    };
    //TODO check if the native joints are the same
    //Joint Types
    /**
     * Distance-Joint type
     */
    PhysicsJoint.DistanceJoint = 0;
    /**
     * Hinge-Joint type
     */
    PhysicsJoint.HingeJoint = 1;
    /**
     * Ball-and-Socket joint type
     */
    PhysicsJoint.BallAndSocketJoint = 2;
    /**
     * Wheel-Joint type
     */
    PhysicsJoint.WheelJoint = 3;
    /**
     * Slider-Joint type
     */
    PhysicsJoint.SliderJoint = 4;
    //OIMO
    /**
     * Prismatic-Joint type
     */
    PhysicsJoint.PrismaticJoint = 5;
    //
    /**
     * Universal-Joint type
     * ENERGY FTW! (compare with this - @see http://ode-wiki.org/wiki/index.php?title=Manual:_Joint_Types_and_Functions)
     */
    PhysicsJoint.UniversalJoint = 6;
    /**
     * Hinge-Joint 2 type
     */
    PhysicsJoint.Hinge2Joint = PhysicsJoint.WheelJoint;
    //Cannon
    /**
     * Point to Point Joint type.  Similar to a Ball-Joint.  Different in parameters
     */
    PhysicsJoint.PointToPointJoint = 8;
    //Cannon only at the moment
    /**
     * Spring-Joint type
     */
    PhysicsJoint.SpringJoint = 9;
    /**
     * Lock-Joint type
     */
    PhysicsJoint.LockJoint = 10;
    return PhysicsJoint;
}());

/**
 * A class representing a physics distance joint
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var DistanceJoint = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistanceJoint, _super);
    /**
     *
     * @param jointData The data for the Distance-Joint
     */
    function DistanceJoint(jointData) {
        return _super.call(this, PhysicsJoint.DistanceJoint, jointData) || this;
    }
    /**
     * Update the predefined distance.
     * @param maxDistance The maximum preferred distance
     * @param minDistance The minimum preferred distance
     */
    DistanceJoint.prototype.updateDistance = function (maxDistance, minDistance) {
        this._physicsPlugin.updateDistanceJoint(this, maxDistance, minDistance);
    };
    return DistanceJoint;
}(PhysicsJoint));

/**
 * Represents a Motor-Enabled Joint
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var MotorEnabledJoint = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MotorEnabledJoint, _super);
    /**
     * Initializes the Motor-Enabled Joint
     * @param type The type of the joint
     * @param jointData The physica joint data for the joint
     */
    function MotorEnabledJoint(type, jointData) {
        return _super.call(this, type, jointData) || this;
    }
    /**
     * Set the motor values.
     * Attention, this function is plugin specific. Engines won't react 100% the same.
     * @param force the force to apply
     * @param maxForce max force for this motor.
     */
    MotorEnabledJoint.prototype.setMotor = function (force, maxForce) {
        this._physicsPlugin.setMotor(this, force || 0, maxForce);
    };
    /**
     * Set the motor's limits.
     * Attention, this function is plugin specific. Engines won't react 100% the same.
     * @param upperLimit The upper limit of the motor
     * @param lowerLimit The lower limit of the motor
     */
    MotorEnabledJoint.prototype.setLimit = function (upperLimit, lowerLimit) {
        this._physicsPlugin.setLimit(this, upperLimit, lowerLimit);
    };
    return MotorEnabledJoint;
}(PhysicsJoint));

/**
 * This class represents a single physics Hinge-Joint
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var HingeJoint = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HingeJoint, _super);
    /**
     * Initializes the Hinge-Joint
     * @param jointData The joint data for the Hinge-Joint
     */
    function HingeJoint(jointData) {
        return _super.call(this, PhysicsJoint.HingeJoint, jointData) || this;
    }
    /**
     * Set the motor values.
     * Attention, this function is plugin specific. Engines won't react 100% the same.
     * @param {number} force the force to apply
     * @param {number} maxForce max force for this motor.
     */
    HingeJoint.prototype.setMotor = function (force, maxForce) {
        this._physicsPlugin.setMotor(this, force || 0, maxForce);
    };
    /**
     * Set the motor's limits.
     * Attention, this function is plugin specific. Engines won't react 100% the same.
     * @param upperLimit The upper limit of the motor
     * @param lowerLimit The lower limit of the motor
     */
    HingeJoint.prototype.setLimit = function (upperLimit, lowerLimit) {
        this._physicsPlugin.setLimit(this, upperLimit, lowerLimit);
    };
    return HingeJoint;
}(MotorEnabledJoint));

/**
 * This class represents a dual hinge physics joint (same as wheel joint)
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var Hinge2Joint = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Hinge2Joint, _super);
    /**
     * Initializes the Hinge2-Joint
     * @param jointData The joint data for the Hinge2-Joint
     */
    function Hinge2Joint(jointData) {
        return _super.call(this, PhysicsJoint.Hinge2Joint, jointData) || this;
    }
    /**
    * Set the motor values.
    * Attention, this function is plugin specific. Engines won't react 100% the same.
    * @param {number} targetSpeed the speed the motor is to reach
    * @param {number} maxForce max force for this motor.
    * @param {motorIndex} the motor's index, 0 or 1.
    */
    Hinge2Joint.prototype.setMotor = function (targetSpeed, maxForce, motorIndex) {
        if (motorIndex === void 0) { motorIndex = 0; }
        this._physicsPlugin.setMotor(this, targetSpeed || 0, maxForce, motorIndex);
    };
    /**
     * Set the motor limits.
     * Attention, this function is plugin specific. Engines won't react 100% the same.
     * @param {number} upperLimit the upper limit
     * @param {number} lowerLimit lower limit
     * @param {motorIndex} the motor's index, 0 or 1.
     */
    Hinge2Joint.prototype.setLimit = function (upperLimit, lowerLimit, motorIndex) {
        if (motorIndex === void 0) { motorIndex = 0; }
        this._physicsPlugin.setLimit(this, upperLimit, lowerLimit, motorIndex);
    };
    return Hinge2Joint;
}(MotorEnabledJoint));



/***/ }),

/***/ "./Physics/physicsRaycastResult.ts":
/*!*****************************************!*\
  !*** ./Physics/physicsRaycastResult.ts ***!
  \*****************************************/
/*! exports provided: PhysicsRaycastResult */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsRaycastResult", function() { return PhysicsRaycastResult; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");

/**
 * Holds the data for the raycast result
 * @see https://doc.babylonjs.com/how_to/using_the_physics_engine
 */
var PhysicsRaycastResult = /** @class */ (function () {
    function PhysicsRaycastResult() {
        this._hasHit = false;
        this._hitDistance = 0;
        this._hitNormalWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._hitPointWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._rayFromWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._rayToWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    }
    Object.defineProperty(PhysicsRaycastResult.prototype, "hasHit", {
        /**
         * Gets if there was a hit
         */
        get: function () {
            return this._hasHit;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsRaycastResult.prototype, "hitDistance", {
        /**
         * Gets the distance from the hit
         */
        get: function () {
            return this._hitDistance;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsRaycastResult.prototype, "hitNormalWorld", {
        /**
         * Gets the hit normal/direction in the world
         */
        get: function () {
            return this._hitNormalWorld;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsRaycastResult.prototype, "hitPointWorld", {
        /**
         * Gets the hit point in the world
         */
        get: function () {
            return this._hitPointWorld;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsRaycastResult.prototype, "rayFromWorld", {
        /**
         * Gets the ray "start point" of the ray in the world
         */
        get: function () {
            return this._rayFromWorld;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PhysicsRaycastResult.prototype, "rayToWorld", {
        /**
         * Gets the ray "end point" of the ray in the world
         */
        get: function () {
            return this._rayToWorld;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets the hit data (normal & point in world space)
     * @param hitNormalWorld defines the normal in world space
     * @param hitPointWorld defines the point in world space
     */
    PhysicsRaycastResult.prototype.setHitData = function (hitNormalWorld, hitPointWorld) {
        this._hasHit = true;
        this._hitNormalWorld = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](hitNormalWorld.x, hitNormalWorld.y, hitNormalWorld.z);
        this._hitPointWorld = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"](hitPointWorld.x, hitPointWorld.y, hitPointWorld.z);
    };
    /**
     * Sets the distance from the start point to the hit point
     * @param distance
     */
    PhysicsRaycastResult.prototype.setHitDistance = function (distance) {
        this._hitDistance = distance;
    };
    /**
     * Calculates the distance manually
     */
    PhysicsRaycastResult.prototype.calculateHitDistance = function () {
        this._hitDistance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Distance(this._rayFromWorld, this._hitPointWorld);
    };
    /**
     * Resets all the values to default
     * @param from The from point on world space
     * @param to The to point on world space
     */
    PhysicsRaycastResult.prototype.reset = function (from, to) {
        if (from === void 0) { from = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(); }
        if (to === void 0) { to = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero(); }
        this._rayFromWorld = from;
        this._rayToWorld = to;
        this._hasHit = false;
        this._hitDistance = 0;
        this._hitNormalWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
        this._hitPointWorld = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    };
    return PhysicsRaycastResult;
}());



/***/ }),

/***/ "./PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts":
/*!****************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts ***!
  \****************************************************************************/
/*! exports provided: DefaultRenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DefaultRenderingPipeline", function() { return DefaultRenderingPipeline; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Layers_glowLayer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../Layers/glowLayer */ "./Layers/glowLayer.ts");
/* harmony import */ var _PostProcesses_sharpenPostProcess__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../PostProcesses/sharpenPostProcess */ "./PostProcesses/sharpenPostProcess.ts");
/* harmony import */ var _PostProcesses_imageProcessingPostProcess__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../PostProcesses/imageProcessingPostProcess */ "./PostProcesses/imageProcessingPostProcess.ts");
/* harmony import */ var _PostProcesses_chromaticAberrationPostProcess__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../PostProcesses/chromaticAberrationPostProcess */ "./PostProcesses/chromaticAberrationPostProcess.ts");
/* harmony import */ var _PostProcesses_grainPostProcess__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../PostProcesses/grainPostProcess */ "./PostProcesses/grainPostProcess.ts");
/* harmony import */ var _PostProcesses_fxaaPostProcess__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../PostProcesses/fxaaPostProcess */ "./PostProcesses/fxaaPostProcess.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipeline */ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _PostProcesses_depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../../PostProcesses/depthOfFieldEffect */ "./PostProcesses/depthOfFieldEffect.ts");
/* harmony import */ var _PostProcesses_bloomEffect__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../../PostProcesses/bloomEffect */ "./PostProcesses/bloomEffect.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../../../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts");


















/**
 * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.
 * See https://doc.babylonjs.com/how_to/using_default_rendering_pipeline
 */
var DefaultRenderingPipeline = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DefaultRenderingPipeline, _super);
    /**
     * @constructor
     * @param name - The rendering pipeline name (default: "")
     * @param hdr - If high dynamic range textures should be used (default: true)
     * @param scene - The scene linked to this pipeline (default: the last created scene)
     * @param cameras - The array of cameras that the rendering pipeline will be attached to (default: scene.cameras)
     * @param automaticBuild - if false, you will have to manually call prepare() to update the pipeline (default: true)
     */
    function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
        if (name === void 0) { name = ""; }
        if (hdr === void 0) { hdr = true; }
        if (scene === void 0) { scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_16__["EngineStore"].LastCreatedScene; }
        if (automaticBuild === void 0) { automaticBuild = true; }
        var _this = _super.call(this, scene.getEngine(), name) || this;
        _this._camerasToBeAttached = [];
        /**
         * ID of the sharpen post process,
         */
        _this.SharpenPostProcessId = "SharpenPostProcessEffect";
        /**
         * @ignore
         * ID of the image processing post process;
         */
        _this.ImageProcessingPostProcessId = "ImageProcessingPostProcessEffect";
        /**
         * @ignore
         * ID of the Fast Approximate Anti-Aliasing post process;
         */
        _this.FxaaPostProcessId = "FxaaPostProcessEffect";
        /**
         * ID of the chromatic aberration post process,
         */
        _this.ChromaticAberrationPostProcessId = "ChromaticAberrationPostProcessEffect";
        /**
         * ID of the grain post process
         */
        _this.GrainPostProcessId = "GrainPostProcessEffect";
        /**
         * Glow post process which adds a glow to emissive areas of the image
         */
        _this._glowLayer = null;
        /**
         * Animations which can be used to tweak settings over a period of time
         */
        _this.animations = [];
        _this._imageProcessingConfigurationObserver = null;
        // Values
        _this._sharpenEnabled = false;
        _this._bloomEnabled = false;
        _this._depthOfFieldEnabled = false;
        _this._depthOfFieldBlurLevel = _PostProcesses_depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_13__["DepthOfFieldEffectBlurLevel"].Low;
        _this._fxaaEnabled = false;
        _this._imageProcessingEnabled = true;
        _this._bloomScale = 0.5;
        _this._chromaticAberrationEnabled = false;
        _this._grainEnabled = false;
        _this._buildAllowed = true;
        _this._resizeObserver = null;
        _this._hardwareScaleLevel = 1.0;
        _this._bloomKernel = 64;
        /**
         * Specifies the weight of the bloom in the final rendering
         */
        _this._bloomWeight = 0.15;
        /**
         * Specifies the luma threshold for the area that will be blurred by the bloom
         */
        _this._bloomThreshold = 0.9;
        _this._samples = 1;
        _this._hasCleared = false;
        _this._prevPostProcess = null;
        _this._prevPrevPostProcess = null;
        _this._depthOfFieldSceneObserver = null;
        _this._cameras = cameras || scene.cameras;
        _this._cameras = _this._cameras.slice();
        _this._camerasToBeAttached = _this._cameras.slice();
        _this._buildAllowed = automaticBuild;
        // Initialize
        _this._scene = scene;
        var caps = _this._scene.getEngine().getCaps();
        _this._hdr = hdr && (caps.textureHalfFloatRender || caps.textureFloatRender);
        // Misc
        if (_this._hdr) {
            if (caps.textureHalfFloatRender) {
                _this._defaultPipelineTextureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].TEXTURETYPE_HALF_FLOAT;
            }
            else if (caps.textureFloatRender) {
                _this._defaultPipelineTextureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].TEXTURETYPE_FLOAT;
            }
        }
        else {
            _this._defaultPipelineTextureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].TEXTURETYPE_UNSIGNED_INT;
        }
        // Attach
        scene.postProcessRenderPipelineManager.addPipeline(_this);
        var engine = _this._scene.getEngine();
        // Create post processes before hand so they can be modified before enabled.
        // Block compilation flag is set to true to avoid compilation prior to use, these will be updated on first use in build pipeline.
        _this.sharpen = new _PostProcesses_sharpenPostProcess__WEBPACK_IMPORTED_MODULE_6__["SharpenPostProcess"]("sharpen", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType, true);
        _this._sharpenEffect = new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_12__["PostProcessRenderEffect"](engine, _this.SharpenPostProcessId, function () { return _this.sharpen; }, true);
        _this.depthOfField = new _PostProcesses_depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_13__["DepthOfFieldEffect"](_this._scene, null, _this._depthOfFieldBlurLevel, _this._defaultPipelineTextureType, true);
        _this.bloom = new _PostProcesses_bloomEffect__WEBPACK_IMPORTED_MODULE_14__["BloomEffect"](_this._scene, _this._bloomScale, _this._bloomWeight, _this.bloomKernel, _this._defaultPipelineTextureType, true);
        _this.chromaticAberration = new _PostProcesses_chromaticAberrationPostProcess__WEBPACK_IMPORTED_MODULE_8__["ChromaticAberrationPostProcess"]("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType, true);
        _this._chromaticAberrationEffect = new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_12__["PostProcessRenderEffect"](engine, _this.ChromaticAberrationPostProcessId, function () { return _this.chromaticAberration; }, true);
        _this.grain = new _PostProcesses_grainPostProcess__WEBPACK_IMPORTED_MODULE_9__["GrainPostProcess"]("Grain", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, _this._defaultPipelineTextureType, true);
        _this._grainEffect = new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_12__["PostProcessRenderEffect"](engine, _this.GrainPostProcessId, function () { return _this.grain; }, true);
        _this._resizeObserver = engine.onResizeObservable.add(function () {
            _this._hardwareScaleLevel = engine.getHardwareScalingLevel();
            _this.bloomKernel = _this.bloomKernel;
        });
        _this._imageProcessingConfigurationObserver = _this._scene.imageProcessingConfiguration.onUpdateParameters.add(function () {
            _this.bloom._downscale._exposure = _this._scene.imageProcessingConfiguration.exposure;
        });
        _this._buildPipeline();
        return _this;
    }
    Object.defineProperty(DefaultRenderingPipeline.prototype, "scene", {
        /**
         * Gets active scene
         */
        get: function () {
            return this._scene;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "sharpenEnabled", {
        get: function () {
            return this._sharpenEnabled;
        },
        /**
         * Enable or disable the sharpen process from the pipeline
         */
        set: function (enabled) {
            if (this._sharpenEnabled === enabled) {
                return;
            }
            this._sharpenEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "bloomKernel", {
        /**
         * Specifies the size of the bloom blur kernel, relative to the final output size
         */
        get: function () {
            return this._bloomKernel;
        },
        set: function (value) {
            this._bloomKernel = value;
            this.bloom.kernel = value / this._hardwareScaleLevel;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "bloomWeight", {
        get: function () {
            return this._bloomWeight;
        },
        /**
         * The strength of the bloom.
         */
        set: function (value) {
            if (this._bloomWeight === value) {
                return;
            }
            this.bloom.weight = value;
            this._bloomWeight = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "bloomThreshold", {
        get: function () {
            return this._bloomThreshold;
        },
        /**
         * The strength of the bloom.
         */
        set: function (value) {
            if (this._bloomThreshold === value) {
                return;
            }
            this.bloom.threshold = value;
            this._bloomThreshold = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "bloomScale", {
        get: function () {
            return this._bloomScale;
        },
        /**
         * The scale of the bloom, lower value will provide better performance.
         */
        set: function (value) {
            if (this._bloomScale === value) {
                return;
            }
            this._bloomScale = value;
            // recreate bloom and dispose old as this setting is not dynamic
            this._rebuildBloom();
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "bloomEnabled", {
        get: function () {
            return this._bloomEnabled;
        },
        /**
         * Enable or disable the bloom from the pipeline
         */
        set: function (enabled) {
            if (this._bloomEnabled === enabled) {
                return;
            }
            this._bloomEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    DefaultRenderingPipeline.prototype._rebuildBloom = function () {
        // recreate bloom and dispose old as this setting is not dynamic
        var oldBloom = this.bloom;
        this.bloom = new _PostProcesses_bloomEffect__WEBPACK_IMPORTED_MODULE_14__["BloomEffect"](this._scene, this.bloomScale, this._bloomWeight, this.bloomKernel, this._defaultPipelineTextureType, false);
        this.bloom.threshold = oldBloom.threshold;
        for (var i = 0; i < this._cameras.length; i++) {
            oldBloom.disposeEffects(this._cameras[i]);
        }
    };
    Object.defineProperty(DefaultRenderingPipeline.prototype, "depthOfFieldEnabled", {
        /**
         * If the depth of field is enabled.
         */
        get: function () {
            return this._depthOfFieldEnabled;
        },
        set: function (enabled) {
            if (this._depthOfFieldEnabled === enabled) {
                return;
            }
            this._depthOfFieldEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "depthOfFieldBlurLevel", {
        /**
         * Blur level of the depth of field effect. (Higher blur will effect performance)
         */
        get: function () {
            return this._depthOfFieldBlurLevel;
        },
        set: function (value) {
            if (this._depthOfFieldBlurLevel === value) {
                return;
            }
            this._depthOfFieldBlurLevel = value;
            // recreate dof and dispose old as this setting is not dynamic
            var oldDof = this.depthOfField;
            this.depthOfField = new _PostProcesses_depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_13__["DepthOfFieldEffect"](this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false);
            this.depthOfField.focalLength = oldDof.focalLength;
            this.depthOfField.focusDistance = oldDof.focusDistance;
            this.depthOfField.fStop = oldDof.fStop;
            this.depthOfField.lensSize = oldDof.lensSize;
            for (var i = 0; i < this._cameras.length; i++) {
                oldDof.disposeEffects(this._cameras[i]);
            }
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "fxaaEnabled", {
        get: function () {
            return this._fxaaEnabled;
        },
        /**
         * If the anti aliasing is enabled.
         */
        set: function (enabled) {
            if (this._fxaaEnabled === enabled) {
                return;
            }
            this._fxaaEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "samples", {
        get: function () {
            return this._samples;
        },
        /**
         * MSAA sample count, setting this to 4 will provide 4x anti aliasing. (default: 1)
         */
        set: function (sampleCount) {
            if (this._samples === sampleCount) {
                return;
            }
            this._samples = sampleCount;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "imageProcessingEnabled", {
        get: function () {
            return this._imageProcessingEnabled;
        },
        /**
         * If image processing is enabled.
         */
        set: function (enabled) {
            if (this._imageProcessingEnabled === enabled) {
                return;
            }
            this._imageProcessingEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "glowLayerEnabled", {
        get: function () {
            return this._glowLayer != null;
        },
        /**
         * If glow layer is enabled. (Adds a glow effect to emmissive materials)
         */
        set: function (enabled) {
            if (enabled && !this._glowLayer) {
                this._glowLayer = new _Layers_glowLayer__WEBPACK_IMPORTED_MODULE_5__["GlowLayer"]("", this._scene);
            }
            else if (!enabled && this._glowLayer) {
                this._glowLayer.dispose();
                this._glowLayer = null;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "glowLayer", {
        /**
         * Gets the glow layer (or null if not defined)
         */
        get: function () {
            return this._glowLayer;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "chromaticAberrationEnabled", {
        get: function () {
            return this._chromaticAberrationEnabled;
        },
        /**
         * Enable or disable the chromaticAberration process from the pipeline
         */
        set: function (enabled) {
            if (this._chromaticAberrationEnabled === enabled) {
                return;
            }
            this._chromaticAberrationEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DefaultRenderingPipeline.prototype, "grainEnabled", {
        get: function () {
            return this._grainEnabled;
        },
        /**
         * Enable or disable the grain process from the pipeline
         */
        set: function (enabled) {
            if (this._grainEnabled === enabled) {
                return;
            }
            this._grainEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get the class name
     * @returns "DefaultRenderingPipeline"
     */
    DefaultRenderingPipeline.prototype.getClassName = function () {
        return "DefaultRenderingPipeline";
    };
    /**
     * Force the compilation of the entire pipeline.
     */
    DefaultRenderingPipeline.prototype.prepare = function () {
        var previousState = this._buildAllowed;
        this._buildAllowed = true;
        this._buildPipeline();
        this._buildAllowed = previousState;
    };
    DefaultRenderingPipeline.prototype._setAutoClearAndTextureSharing = function (postProcess, skipTextureSharing) {
        if (skipTextureSharing === void 0) { skipTextureSharing = false; }
        if (this._hasCleared) {
            postProcess.autoClear = false;
        }
        else {
            postProcess.autoClear = true;
            this._scene.autoClear = false;
            this._hasCleared = true;
        }
        if (!skipTextureSharing) {
            if (this._prevPrevPostProcess) {
                postProcess.shareOutputWith(this._prevPrevPostProcess);
            }
            else {
                postProcess.useOwnOutput();
            }
            if (this._prevPostProcess) {
                this._prevPrevPostProcess = this._prevPostProcess;
            }
            this._prevPostProcess = postProcess;
        }
    };
    DefaultRenderingPipeline.prototype._buildPipeline = function () {
        var _this = this;
        if (!this._buildAllowed) {
            return;
        }
        this._scene.autoClear = true;
        var engine = this._scene.getEngine();
        this._disposePostProcesses();
        if (this._cameras !== null) {
            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
            // get back cameras to be used to reattach pipeline
            this._cameras = this._camerasToBeAttached.slice();
        }
        this._reset();
        this._prevPostProcess = null;
        this._prevPrevPostProcess = null;
        this._hasCleared = false;
        if (this.depthOfFieldEnabled) {
            // Multi camera suport
            if (this._cameras.length > 1) {
                for (var _i = 0, _a = this._cameras; _i < _a.length; _i++) {
                    var camera = _a[_i];
                    var depthRenderer = this._scene.enableDepthRenderer(camera);
                    depthRenderer.useOnlyInActiveCamera = true;
                }
                this._depthOfFieldSceneObserver = this._scene.onAfterRenderTargetsRenderObservable.add(function (scene) {
                    if (_this._cameras.indexOf(scene.activeCamera) > -1) {
                        _this.depthOfField.depthTexture = scene.enableDepthRenderer(scene.activeCamera).getDepthMap();
                    }
                });
            }
            else {
                this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
                var depthRenderer = this._scene.enableDepthRenderer(this._cameras[0]);
                this.depthOfField.depthTexture = depthRenderer.getDepthMap();
            }
            if (!this.depthOfField._isReady()) {
                this.depthOfField._updateEffects();
            }
            this.addEffect(this.depthOfField);
            this._setAutoClearAndTextureSharing(this.depthOfField._effects[0], true);
        }
        else {
            this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
        }
        if (this.bloomEnabled) {
            if (!this.bloom._isReady()) {
                this.bloom._updateEffects();
            }
            this.addEffect(this.bloom);
            this._setAutoClearAndTextureSharing(this.bloom._effects[0], true);
        }
        if (this._imageProcessingEnabled) {
            this.imageProcessing = new _PostProcesses_imageProcessingPostProcess__WEBPACK_IMPORTED_MODULE_7__["ImageProcessingPostProcess"]("imageProcessing", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
            if (this._hdr) {
                this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_12__["PostProcessRenderEffect"](engine, this.ImageProcessingPostProcessId, function () { return _this.imageProcessing; }, true));
                this._setAutoClearAndTextureSharing(this.imageProcessing);
            }
            else {
                this._scene.imageProcessingConfiguration.applyByPostProcess = false;
            }
        }
        if (this.sharpenEnabled) {
            if (!this.sharpen.isReady()) {
                this.sharpen.updateEffect();
            }
            this.addEffect(this._sharpenEffect);
            this._setAutoClearAndTextureSharing(this.sharpen);
        }
        if (this.grainEnabled) {
            if (!this.grain.isReady()) {
                this.grain.updateEffect();
            }
            this.addEffect(this._grainEffect);
            this._setAutoClearAndTextureSharing(this.grain);
        }
        if (this.chromaticAberrationEnabled) {
            if (!this.chromaticAberration.isReady()) {
                this.chromaticAberration.updateEffect();
            }
            this.addEffect(this._chromaticAberrationEffect);
            this._setAutoClearAndTextureSharing(this.chromaticAberration);
        }
        if (this.fxaaEnabled) {
            this.fxaa = new _PostProcesses_fxaaPostProcess__WEBPACK_IMPORTED_MODULE_10__["FxaaPostProcess"]("fxaa", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_12__["PostProcessRenderEffect"](engine, this.FxaaPostProcessId, function () { return _this.fxaa; }, true));
            this._setAutoClearAndTextureSharing(this.fxaa, true);
        }
        if (this._cameras !== null) {
            this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
        }
        // In multicamera mode, the scene needs to autoclear in between cameras.
        if (this._scene.activeCameras && this._scene.activeCameras.length > 1) {
            this._scene.autoClear = true;
        }
        if (!this._enableMSAAOnFirstPostProcess(this.samples) && this.samples > 1) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0");
        }
    };
    DefaultRenderingPipeline.prototype._disposePostProcesses = function (disposeNonRecreated) {
        if (disposeNonRecreated === void 0) { disposeNonRecreated = false; }
        for (var i = 0; i < this._cameras.length; i++) {
            var camera = this._cameras[i];
            if (this.imageProcessing) {
                this.imageProcessing.dispose(camera);
            }
            if (this.fxaa) {
                this.fxaa.dispose(camera);
            }
            // These are created in the constructor and should not be disposed on every pipeline change
            if (disposeNonRecreated) {
                if (this.sharpen) {
                    this.sharpen.dispose(camera);
                }
                if (this.depthOfField) {
                    this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
                    this.depthOfField.disposeEffects(camera);
                }
                if (this.bloom) {
                    this.bloom.disposeEffects(camera);
                }
                if (this.chromaticAberration) {
                    this.chromaticAberration.dispose(camera);
                }
                if (this.grain) {
                    this.grain.dispose(camera);
                }
                if (this._glowLayer) {
                    this._glowLayer.dispose();
                }
            }
        }
        this.imageProcessing = null;
        this.fxaa = null;
        if (disposeNonRecreated) {
            this.sharpen = null;
            this._sharpenEffect = null;
            this.depthOfField = null;
            this.bloom = null;
            this.chromaticAberration = null;
            this._chromaticAberrationEffect = null;
            this.grain = null;
            this._grainEffect = null;
            this._glowLayer = null;
        }
    };
    /**
     * Adds a camera to the pipeline
     * @param camera the camera to be added
     */
    DefaultRenderingPipeline.prototype.addCamera = function (camera) {
        this._camerasToBeAttached.push(camera);
        this._buildPipeline();
    };
    /**
     * Removes a camera from the pipeline
     * @param camera the camera to remove
     */
    DefaultRenderingPipeline.prototype.removeCamera = function (camera) {
        var index = this._camerasToBeAttached.indexOf(camera);
        this._camerasToBeAttached.splice(index, 1);
        this._buildPipeline();
    };
    /**
     * Dispose of the pipeline and stop all post processes
     */
    DefaultRenderingPipeline.prototype.dispose = function () {
        this._disposePostProcesses(true);
        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
        this._scene.autoClear = true;
        if (this._resizeObserver) {
            this._scene.getEngine().onResizeObservable.remove(this._resizeObserver);
            this._resizeObserver = null;
        }
        this._scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigurationObserver);
        _super.prototype.dispose.call(this);
    };
    /**
     * Serialize the rendering pipeline (Used when exporting)
     * @returns the serialized object
     */
    DefaultRenderingPipeline.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "DefaultRenderingPipeline";
        return serializationObject;
    };
    /**
     * Parse the serialized pipeline
     * @param source Source pipeline.
     * @param scene The scene to load the pipeline to.
     * @param rootUrl The URL of the serialized pipeline.
     * @returns An instantiated pipeline from the serialized object.
     */
    DefaultRenderingPipeline.Parse = function (source, scene, rootUrl) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new DefaultRenderingPipeline(source._name, source._name._hdr, scene); }, source, scene, rootUrl);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "sharpenEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "bloomKernel", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "_bloomWeight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "_bloomThreshold", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "_hdr", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "bloomWeight", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "bloomThreshold", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "bloomScale", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "bloomEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "depthOfFieldEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "depthOfFieldBlurLevel", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "fxaaEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "samples", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "imageProcessingEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "glowLayerEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "chromaticAberrationEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], DefaultRenderingPipeline.prototype, "grainEnabled", null);
    return DefaultRenderingPipeline;
}(_PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_11__["PostProcessRenderPipeline"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_15__["_TypeStore"].RegisteredTypes["BABYLON.DefaultRenderingPipeline"] = DefaultRenderingPipeline;


/***/ }),

/***/ "./PostProcesses/RenderPipeline/Pipelines/index.ts":
/*!*********************************************************!*\
  !*** ./PostProcesses/RenderPipeline/Pipelines/index.ts ***!
  \*********************************************************/
/*! exports provided: DefaultRenderingPipeline, LensRenderingPipeline, SSAO2RenderingPipeline, SSAORenderingPipeline, StandardRenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _defaultRenderingPipeline__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./defaultRenderingPipeline */ "./PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultRenderingPipeline", function() { return _defaultRenderingPipeline__WEBPACK_IMPORTED_MODULE_0__["DefaultRenderingPipeline"]; });

/* harmony import */ var _lensRenderingPipeline__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lensRenderingPipeline */ "./PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensRenderingPipeline", function() { return _lensRenderingPipeline__WEBPACK_IMPORTED_MODULE_1__["LensRenderingPipeline"]; });

/* harmony import */ var _ssao2RenderingPipeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ssao2RenderingPipeline */ "./PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAO2RenderingPipeline", function() { return _ssao2RenderingPipeline__WEBPACK_IMPORTED_MODULE_2__["SSAO2RenderingPipeline"]; });

/* harmony import */ var _ssaoRenderingPipeline__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ssaoRenderingPipeline */ "./PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAORenderingPipeline", function() { return _ssaoRenderingPipeline__WEBPACK_IMPORTED_MODULE_3__["SSAORenderingPipeline"]; });

/* harmony import */ var _standardRenderingPipeline__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./standardRenderingPipeline */ "./PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardRenderingPipeline", function() { return _standardRenderingPipeline__WEBPACK_IMPORTED_MODULE_4__["StandardRenderingPipeline"]; });








/***/ }),

/***/ "./PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.ts":
/*!*************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/Pipelines/lensRenderingPipeline.ts ***!
  \*************************************************************************/
/*! exports provided: LensRenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LensRenderingPipeline", function() { return LensRenderingPipeline; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Materials/Textures/dynamicTexture */ "./Materials/Textures/dynamicTexture.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipeline */ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts");
/* harmony import */ var _Shaders_chromaticAberration_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../Shaders/chromaticAberration.fragment */ "./Shaders/chromaticAberration.fragment.ts");
/* harmony import */ var _Shaders_lensHighlights_fragment__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../Shaders/lensHighlights.fragment */ "./Shaders/lensHighlights.fragment.ts");
/* harmony import */ var _Shaders_depthOfField_fragment__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../Shaders/depthOfField.fragment */ "./Shaders/depthOfField.fragment.ts");










/**
 * BABYLON.JS Chromatic Aberration GLSL Shader
 * Author: Olivier Guyot
 * Separates very slightly R, G and B colors on the edges of the screen
 * Inspired by Francois Tarlier & Martins Upitis
 */
var LensRenderingPipeline = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LensRenderingPipeline, _super);
    /**
     * @constructor
     *
     * Effect parameters are as follow:
     * {
     *      chromatic_aberration: number;       // from 0 to x (1 for realism)
     *      edge_blur: number;                  // from 0 to x (1 for realism)
     *      distortion: number;                 // from 0 to x (1 for realism)
     *      grain_amount: number;               // from 0 to 1
     *      grain_texture: BABYLON.Texture;     // texture to use for grain effect; if unset, use random B&W noise
     *      dof_focus_distance: number;         // depth-of-field: focus distance; unset to disable (disabled by default)
     *      dof_aperture: number;               // depth-of-field: focus blur bias (default: 1)
     *      dof_darken: number;                 // depth-of-field: darken that which is out of focus (from 0 to 1, disabled by default)
     *      dof_pentagon: boolean;              // depth-of-field: makes a pentagon-like "bokeh" effect
     *      dof_gain: number;                   // depth-of-field: highlights gain; unset to disable (disabled by default)
     *      dof_threshold: number;              // depth-of-field: highlights threshold (default: 1)
     *      blur_noise: boolean;                // add a little bit of noise to the blur (default: true)
     * }
     * Note: if an effect parameter is unset, effect is disabled
     *
     * @param name The rendering pipeline name
     * @param parameters - An object containing all parameters (see above)
     * @param scene The scene linked to this pipeline
     * @param ratio The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)
     * @param cameras The array of cameras that the rendering pipeline will be attached to
     */
    function LensRenderingPipeline(name, parameters, scene, ratio, cameras) {
        if (ratio === void 0) { ratio = 1.0; }
        var _this = _super.call(this, scene.getEngine(), name) || this;
        // Lens effects can be of the following:
        // - chromatic aberration (slight shift of RGB colors)
        // - blur on the edge of the lens
        // - lens distortion
        // - depth-of-field blur & highlights enhancing
        // - depth-of-field 'bokeh' effect (shapes appearing in blurred areas)
        // - grain effect (noise or custom texture)
        // Two additional texture samplers are needed:
        // - depth map (for depth-of-field)
        // - grain texture
        /**
         * @ignore
         * The chromatic aberration PostProcess id in the pipeline
         */
        _this.LensChromaticAberrationEffect = "LensChromaticAberrationEffect";
        /**
         * @ignore
         * The highlights enhancing PostProcess id in the pipeline
         */
        _this.HighlightsEnhancingEffect = "HighlightsEnhancingEffect";
        /**
         * @ignore
        * The depth-of-field PostProcess id in the pipeline
        */
        _this.LensDepthOfFieldEffect = "LensDepthOfFieldEffect";
        _this._pentagonBokehIsEnabled = false;
        _this._scene = scene;
        // Fetch texture samplers
        _this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on"
        if (parameters.grain_texture) {
            _this._grainTexture = parameters.grain_texture;
        }
        else {
            _this._createGrainTexture();
        }
        // save parameters
        _this._edgeBlur = parameters.edge_blur ? parameters.edge_blur : 0;
        _this._grainAmount = parameters.grain_amount ? parameters.grain_amount : 0;
        _this._chromaticAberration = parameters.chromatic_aberration ? parameters.chromatic_aberration : 0;
        _this._distortion = parameters.distortion ? parameters.distortion : 0;
        _this._highlightsGain = parameters.dof_gain !== undefined ? parameters.dof_gain : -1;
        _this._highlightsThreshold = parameters.dof_threshold ? parameters.dof_threshold : 1;
        _this._dofDistance = parameters.dof_focus_distance !== undefined ? parameters.dof_focus_distance : -1;
        _this._dofAperture = parameters.dof_aperture ? parameters.dof_aperture : 1;
        _this._dofDarken = parameters.dof_darken ? parameters.dof_darken : 0;
        _this._dofPentagon = parameters.dof_pentagon !== undefined ? parameters.dof_pentagon : true;
        _this._blurNoise = parameters.blur_noise !== undefined ? parameters.blur_noise : true;
        // Create effects
        _this._createChromaticAberrationPostProcess(ratio);
        _this._createHighlightsPostProcess(ratio);
        _this._createDepthOfFieldPostProcess(ratio / 4);
        // Set up pipeline
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_5__["PostProcessRenderEffect"](scene.getEngine(), _this.LensChromaticAberrationEffect, function () { return _this._chromaticAberrationPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_5__["PostProcessRenderEffect"](scene.getEngine(), _this.HighlightsEnhancingEffect, function () { return _this._highlightsPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_5__["PostProcessRenderEffect"](scene.getEngine(), _this.LensDepthOfFieldEffect, function () { return _this._depthOfFieldPostProcess; }, true));
        if (_this._highlightsGain === -1) {
            _this._disableEffect(_this.HighlightsEnhancingEffect, null);
        }
        // Finish
        scene.postProcessRenderPipelineManager.addPipeline(_this);
        if (cameras) {
            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
        }
        return _this;
    }
    /**
     * Get the class name
     * @returns "LensRenderingPipeline"
     */
    LensRenderingPipeline.prototype.getClassName = function () {
        return "LensRenderingPipeline";
    };
    Object.defineProperty(LensRenderingPipeline.prototype, "scene", {
        // Properties
        /**
         * Gets associated scene
         */
        get: function () {
            return this._scene;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "edgeBlur", {
        /**
         * Gets or sets the edge blur
         */
        get: function () {
            return this._edgeBlur;
        },
        set: function (value) {
            this.setEdgeBlur(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "grainAmount", {
        /**
         * Gets or sets the grain amount
         */
        get: function () {
            return this._grainAmount;
        },
        set: function (value) {
            this.setGrainAmount(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "chromaticAberration", {
        /**
         * Gets or sets the chromatic aberration amount
         */
        get: function () {
            return this._chromaticAberration;
        },
        set: function (value) {
            this.setChromaticAberration(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "dofAperture", {
        /**
         * Gets or sets the depth of field aperture
         */
        get: function () {
            return this._dofAperture;
        },
        set: function (value) {
            this.setAperture(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "edgeDistortion", {
        /**
         * Gets or sets the edge distortion
         */
        get: function () {
            return this._distortion;
        },
        set: function (value) {
            this.setEdgeDistortion(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "dofDistortion", {
        /**
         * Gets or sets the depth of field distortion
         */
        get: function () {
            return this._dofDistance;
        },
        set: function (value) {
            this.setFocusDistance(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "darkenOutOfFocus", {
        /**
         * Gets or sets the darken out of focus amount
         */
        get: function () {
            return this._dofDarken;
        },
        set: function (value) {
            this.setDarkenOutOfFocus(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "blurNoise", {
        /**
         * Gets or sets a boolean indicating if blur noise is enabled
         */
        get: function () {
            return this._blurNoise;
        },
        set: function (value) {
            this._blurNoise = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "pentagonBokeh", {
        /**
         * Gets or sets a boolean indicating if pentagon bokeh is enabled
         */
        get: function () {
            return this._pentagonBokehIsEnabled;
        },
        set: function (value) {
            if (value) {
                this.enablePentagonBokeh();
            }
            else {
                this.disablePentagonBokeh();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "highlightsGain", {
        /**
         * Gets or sets the highlight grain amount
         */
        get: function () {
            return this._highlightsGain;
        },
        set: function (value) {
            this.setHighlightsGain(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(LensRenderingPipeline.prototype, "highlightsThreshold", {
        /**
         * Gets or sets the highlight threshold
         */
        get: function () {
            return this._highlightsThreshold;
        },
        set: function (value) {
            this.setHighlightsThreshold(value);
        },
        enumerable: true,
        configurable: true
    });
    // public methods (self explanatory)
    /**
     * Sets the amount of blur at the edges
     * @param amount blur amount
     */
    LensRenderingPipeline.prototype.setEdgeBlur = function (amount) { this._edgeBlur = amount; };
    /**
     * Sets edge blur to 0
     */
    LensRenderingPipeline.prototype.disableEdgeBlur = function () { this._edgeBlur = 0; };
    /**
     * Sets the amout of grain
     * @param amount Amount of grain
     */
    LensRenderingPipeline.prototype.setGrainAmount = function (amount) { this._grainAmount = amount; };
    /**
     * Set grain amount to 0
     */
    LensRenderingPipeline.prototype.disableGrain = function () { this._grainAmount = 0; };
    /**
     * Sets the chromatic aberration amount
     * @param amount amount of chromatic aberration
     */
    LensRenderingPipeline.prototype.setChromaticAberration = function (amount) { this._chromaticAberration = amount; };
    /**
     * Sets chromatic aberration amount to 0
     */
    LensRenderingPipeline.prototype.disableChromaticAberration = function () { this._chromaticAberration = 0; };
    /**
     * Sets the EdgeDistortion amount
     * @param amount amount of EdgeDistortion
     */
    LensRenderingPipeline.prototype.setEdgeDistortion = function (amount) { this._distortion = amount; };
    /**
     * Sets edge distortion to 0
     */
    LensRenderingPipeline.prototype.disableEdgeDistortion = function () { this._distortion = 0; };
    /**
     * Sets the FocusDistance amount
     * @param amount amount of FocusDistance
     */
    LensRenderingPipeline.prototype.setFocusDistance = function (amount) { this._dofDistance = amount; };
    /**
    * Disables depth of field
    */
    LensRenderingPipeline.prototype.disableDepthOfField = function () { this._dofDistance = -1; };
    /**
     * Sets the Aperture amount
     * @param amount amount of Aperture
     */
    LensRenderingPipeline.prototype.setAperture = function (amount) { this._dofAperture = amount; };
    /**
     * Sets the DarkenOutOfFocus amount
     * @param amount amount of DarkenOutOfFocus
     */
    LensRenderingPipeline.prototype.setDarkenOutOfFocus = function (amount) { this._dofDarken = amount; };
    /**
     * Creates a pentagon bokeh effect
     */
    LensRenderingPipeline.prototype.enablePentagonBokeh = function () {
        this._highlightsPostProcess.updateEffect("#define PENTAGON\n");
        this._pentagonBokehIsEnabled = true;
    };
    /**
     * Disables the pentagon bokeh effect
     */
    LensRenderingPipeline.prototype.disablePentagonBokeh = function () {
        this._pentagonBokehIsEnabled = false;
        this._highlightsPostProcess.updateEffect();
    };
    /**
     * Enables noise blur
     */
    LensRenderingPipeline.prototype.enableNoiseBlur = function () { this._blurNoise = true; };
    /**
     * Disables noise blur
     */
    LensRenderingPipeline.prototype.disableNoiseBlur = function () { this._blurNoise = false; };
    /**
     * Sets the HighlightsGain amount
     * @param amount amount of HighlightsGain
     */
    LensRenderingPipeline.prototype.setHighlightsGain = function (amount) {
        this._highlightsGain = amount;
    };
    /**
     * Sets the HighlightsThreshold amount
     * @param amount amount of HighlightsThreshold
     */
    LensRenderingPipeline.prototype.setHighlightsThreshold = function (amount) {
        if (this._highlightsGain === -1) {
            this._highlightsGain = 1.0;
        }
        this._highlightsThreshold = amount;
    };
    /**
     * Disables highlights
     */
    LensRenderingPipeline.prototype.disableHighlights = function () {
        this._highlightsGain = -1;
    };
    /**
     * Removes the internal pipeline assets and detaches the pipeline from the scene cameras
     * @param disableDepthRender If the scens depth rendering should be disabled (default: false)
     */
    LensRenderingPipeline.prototype.dispose = function (disableDepthRender) {
        if (disableDepthRender === void 0) { disableDepthRender = false; }
        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
        this._chromaticAberrationPostProcess = null;
        this._highlightsPostProcess = null;
        this._depthOfFieldPostProcess = null;
        this._grainTexture.dispose();
        if (disableDepthRender) {
            this._scene.disableDepthRenderer();
        }
    };
    // colors shifting and distortion
    LensRenderingPipeline.prototype._createChromaticAberrationPostProcess = function (ratio) {
        var _this = this;
        this._chromaticAberrationPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_3__["PostProcess"]("LensChromaticAberration", "chromaticAberration", ["chromatic_aberration", "screen_width", "screen_height", "direction", "radialIntensity", "centerPosition"], // uniforms
        [], // samplers
        ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false);
        this._chromaticAberrationPostProcess.onApply = function (effect) {
            effect.setFloat('chromatic_aberration', _this._chromaticAberration);
            effect.setFloat('screen_width', _this._scene.getEngine().getRenderWidth());
            effect.setFloat('screen_height', _this._scene.getEngine().getRenderHeight());
            effect.setFloat('radialIntensity', 1);
            effect.setFloat2('direction', 17, 17);
            effect.setFloat2('centerPosition', 0.5, 0.5);
        };
    };
    // highlights enhancing
    LensRenderingPipeline.prototype._createHighlightsPostProcess = function (ratio) {
        var _this = this;
        this._highlightsPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_3__["PostProcess"]("LensHighlights", "lensHighlights", ["gain", "threshold", "screen_width", "screen_height"], // uniforms
        [], // samplers
        ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, this._dofPentagon ? "#define PENTAGON\n" : "");
        this._highlightsPostProcess.onApply = function (effect) {
            effect.setFloat('gain', _this._highlightsGain);
            effect.setFloat('threshold', _this._highlightsThreshold);
            effect.setTextureFromPostProcess("textureSampler", _this._chromaticAberrationPostProcess);
            effect.setFloat('screen_width', _this._scene.getEngine().getRenderWidth());
            effect.setFloat('screen_height', _this._scene.getEngine().getRenderHeight());
        };
    };
    // colors shifting and distortion
    LensRenderingPipeline.prototype._createDepthOfFieldPostProcess = function (ratio) {
        var _this = this;
        this._depthOfFieldPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_3__["PostProcess"]("LensDepthOfField", "depthOfField", [
            "grain_amount", "blur_noise", "screen_width", "screen_height", "distortion", "dof_enabled",
            "screen_distance", "aperture", "darken", "edge_blur", "highlights", "near", "far"
        ], ["depthSampler", "grainSampler", "highlightsSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false);
        this._depthOfFieldPostProcess.onApply = function (effect) {
            effect.setTexture("depthSampler", _this._depthTexture);
            effect.setTexture("grainSampler", _this._grainTexture);
            effect.setTextureFromPostProcess("textureSampler", _this._highlightsPostProcess);
            effect.setTextureFromPostProcess("highlightsSampler", _this._depthOfFieldPostProcess);
            effect.setFloat('grain_amount', _this._grainAmount);
            effect.setBool('blur_noise', _this._blurNoise);
            effect.setFloat('screen_width', _this._scene.getEngine().getRenderWidth());
            effect.setFloat('screen_height', _this._scene.getEngine().getRenderHeight());
            effect.setFloat('distortion', _this._distortion);
            effect.setBool('dof_enabled', (_this._dofDistance !== -1));
            effect.setFloat('screen_distance', 1.0 / (0.1 - 1.0 / _this._dofDistance));
            effect.setFloat('aperture', _this._dofAperture);
            effect.setFloat('darken', _this._dofDarken);
            effect.setFloat('edge_blur', _this._edgeBlur);
            effect.setBool('highlights', (_this._highlightsGain !== -1));
            if (_this._scene.activeCamera) {
                effect.setFloat('near', _this._scene.activeCamera.minZ);
                effect.setFloat('far', _this._scene.activeCamera.maxZ);
            }
        };
    };
    // creates a black and white random noise texture, 512x512
    LensRenderingPipeline.prototype._createGrainTexture = function () {
        var size = 512;
        this._grainTexture = new _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_2__["DynamicTexture"]("LensNoiseTexture", size, this._scene, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].BILINEAR_SAMPLINGMODE);
        this._grainTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].WRAP_ADDRESSMODE;
        this._grainTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].WRAP_ADDRESSMODE;
        var context = this._grainTexture.getContext();
        var rand = function (min, max) {
            return Math.random() * (max - min) + min;
        };
        var value;
        for (var x = 0; x < size; x++) {
            for (var y = 0; y < size; y++) {
                value = Math.floor(rand(0.42, 0.58) * 255);
                context.fillStyle = 'rgb(' + value + ', ' + value + ', ' + value + ')';
                context.fillRect(x, y, 1, 1);
            }
        }
        this._grainTexture.update(false);
    };
    return LensRenderingPipeline;
}(_PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_4__["PostProcessRenderPipeline"]));



/***/ }),

/***/ "./PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts":
/*!**************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline.ts ***!
  \**************************************************************************/
/*! exports provided: SSAO2RenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SSAO2RenderingPipeline", function() { return SSAO2RenderingPipeline; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../Materials/Textures/dynamicTexture */ "./Materials/Textures/dynamicTexture.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipeline */ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../PostProcesses/passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts");
/* harmony import */ var _Shaders_ssao2_fragment__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../../Shaders/ssao2.fragment */ "./Shaders/ssao2.fragment.ts");
/* harmony import */ var _Shaders_ssaoCombine_fragment__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../../Shaders/ssaoCombine.fragment */ "./Shaders/ssaoCombine.fragment.ts");















/**
 * Render pipeline to produce ssao effect
 */
var SSAO2RenderingPipeline = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SSAO2RenderingPipeline, _super);
    /**
     * @constructor
     * @param name The rendering pipeline name
     * @param scene The scene linked to this pipeline
     * @param ratio The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, blurRatio: 1.0 }
     * @param cameras The array of cameras that the rendering pipeline will be attached to
     */
    function SSAO2RenderingPipeline(name, scene, ratio, cameras) {
        var _this = _super.call(this, scene.getEngine(), name) || this;
        // Members
        /**
         * @ignore
        * The PassPostProcess id in the pipeline that contains the original scene color
        */
        _this.SSAOOriginalSceneColorEffect = "SSAOOriginalSceneColorEffect";
        /**
         * @ignore
        * The SSAO PostProcess id in the pipeline
        */
        _this.SSAORenderEffect = "SSAORenderEffect";
        /**
         * @ignore
        * The horizontal blur PostProcess id in the pipeline
        */
        _this.SSAOBlurHRenderEffect = "SSAOBlurHRenderEffect";
        /**
         * @ignore
        * The vertical blur PostProcess id in the pipeline
        */
        _this.SSAOBlurVRenderEffect = "SSAOBlurVRenderEffect";
        /**
         * @ignore
        * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect)
        */
        _this.SSAOCombineRenderEffect = "SSAOCombineRenderEffect";
        /**
        * The output strength of the SSAO post-process. Default value is 1.0.
        */
        _this.totalStrength = 1.0;
        /**
        * Maximum depth value to still render AO. A smooth falloff makes the dimming more natural, so there will be no abrupt shading change.
        */
        _this.maxZ = 100.0;
        /**
        * In order to save performances, SSAO radius is clamped on close geometry. This ratio changes by how much
        */
        _this.minZAspect = 0.2;
        _this._samples = 8;
        _this._textureSamples = 1;
        _this._expensiveBlur = true;
        /**
        * The radius around the analyzed pixel used by the SSAO post-process. Default value is 2.0
        */
        _this.radius = 2.0;
        /**
        * The base color of the SSAO post-process
        * The final result is "base + ssao" between [0, 1]
        */
        _this.base = 0;
        _this._firstUpdate = true;
        _this._bits = new Uint32Array(1);
        _this._scene = scene;
        _this._ratio = ratio;
        if (!_this.isSupported) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Error("SSAO 2 needs WebGL 2 support.");
            return _this;
        }
        var ssaoRatio = _this._ratio.ssaoRatio || ratio;
        var blurRatio = _this._ratio.blurRatio || ratio;
        // Set up assets
        var geometryBufferRenderer = scene.enableGeometryBufferRenderer();
        _this._createRandomTexture();
        _this._depthTexture = geometryBufferRenderer.getGBuffer().textures[0];
        _this._normalTexture = geometryBufferRenderer.getGBuffer().textures[1];
        _this._originalColorPostProcess = new _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_9__["PassPostProcess"]("SSAOOriginalSceneColor", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
        _this._originalColorPostProcess.samples = _this.textureSamples;
        _this._createSSAOPostProcess(1.0);
        _this._createBlurPostProcess(ssaoRatio, blurRatio);
        _this._createSSAOCombinePostProcess(blurRatio);
        // Set up pipeline
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOOriginalSceneColorEffect, function () { return _this._originalColorPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAORenderEffect, function () { return _this._ssaoPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOBlurHRenderEffect, function () { return _this._blurHPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOBlurVRenderEffect, function () { return _this._blurVPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOCombineRenderEffect, function () { return _this._ssaoCombinePostProcess; }, true));
        // Finish
        scene.postProcessRenderPipelineManager.addPipeline(_this);
        if (cameras) {
            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
        }
        return _this;
    }
    Object.defineProperty(SSAO2RenderingPipeline.prototype, "samples", {
        get: function () {
            return this._samples;
        },
        /**
        * Number of samples used for the SSAO calculations. Default value is 8
        */
        set: function (n) {
            this._ssaoPostProcess.updateEffect("#define SAMPLES " + n + "\n#define SSAO");
            this._samples = n;
            this._sampleSphere = this._generateHemisphere();
            this._firstUpdate = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SSAO2RenderingPipeline.prototype, "textureSamples", {
        get: function () {
            return this._textureSamples;
        },
        /**
        * Number of samples to use for antialiasing
        */
        set: function (n) {
            this._textureSamples = n;
            this._originalColorPostProcess.samples = n;
            this._blurHPostProcess.samples = n;
            this._blurVPostProcess.samples = n;
            this._ssaoPostProcess.samples = n;
            this._ssaoCombinePostProcess.samples = n;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SSAO2RenderingPipeline.prototype, "expensiveBlur", {
        get: function () {
            return this._expensiveBlur;
        },
        /**
        * If bilateral blur should be used
        */
        set: function (b) {
            this._blurHPostProcess.updateEffect("#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (b ? "1" : "0") + "\n", null, ["textureSampler", "depthSampler"]);
            this._blurVPostProcess.updateEffect("#define BILATERAL_BLUR\n#define SAMPLES 16\n#define EXPENSIVE " + (b ? "1" : "0") + "\n", null, ["textureSampler", "depthSampler"]);
            this._expensiveBlur = b;
            this._firstUpdate = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SSAO2RenderingPipeline, "IsSupported", {
        /**
        *  Support test.
        */
        get: function () {
            var engine = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_11__["EngineStore"].LastCreatedEngine;
            if (!engine) {
                return false;
            }
            return engine.getCaps().drawBuffersExtension;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SSAO2RenderingPipeline.prototype, "scene", {
        /**
         * Gets active scene
         */
        get: function () {
            return this._scene;
        },
        enumerable: true,
        configurable: true
    });
    // Public Methods
    /**
     * Get the class name
     * @returns "SSAO2RenderingPipeline"
     */
    SSAO2RenderingPipeline.prototype.getClassName = function () {
        return "SSAO2RenderingPipeline";
    };
    /**
     * Removes the internal pipeline assets and detatches the pipeline from the scene cameras
     */
    SSAO2RenderingPipeline.prototype.dispose = function (disableGeometryBufferRenderer) {
        if (disableGeometryBufferRenderer === void 0) { disableGeometryBufferRenderer = false; }
        for (var i = 0; i < this._scene.cameras.length; i++) {
            var camera = this._scene.cameras[i];
            this._originalColorPostProcess.dispose(camera);
            this._ssaoPostProcess.dispose(camera);
            this._blurHPostProcess.dispose(camera);
            this._blurVPostProcess.dispose(camera);
            this._ssaoCombinePostProcess.dispose(camera);
        }
        this._randomTexture.dispose();
        if (disableGeometryBufferRenderer) {
            this._scene.disableGeometryBufferRenderer();
        }
        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
        _super.prototype.dispose.call(this);
    };
    // Private Methods
    SSAO2RenderingPipeline.prototype._createBlurPostProcess = function (ssaoRatio, blurRatio) {
        var _this = this;
        this._samplerOffsets = [];
        var expensive = this.expensiveBlur;
        for (var i = -8; i < 8; i++) {
            this._samplerOffsets.push(i * 2 + 0.5);
        }
        this._blurHPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("BlurH", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ssaoRatio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
        this._blurHPostProcess.onApply = function (effect) {
            if (!_this._scene.activeCamera) {
                return;
            }
            effect.setFloat("outSize", _this._ssaoCombinePostProcess.width > 0 ? _this._ssaoCombinePostProcess.width : _this._originalColorPostProcess.width);
            effect.setFloat("near", _this._scene.activeCamera.minZ);
            effect.setFloat("far", _this._scene.activeCamera.maxZ);
            effect.setFloat("radius", _this.radius);
            effect.setTexture("depthSampler", _this._depthTexture);
            if (_this._firstUpdate) {
                effect.setArray("samplerOffsets", _this._samplerOffsets);
            }
        };
        this._blurVPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("BlurV", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], blurRatio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_V\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n");
        this._blurVPostProcess.onApply = function (effect) {
            if (!_this._scene.activeCamera) {
                return;
            }
            effect.setFloat("outSize", _this._ssaoCombinePostProcess.height > 0 ? _this._ssaoCombinePostProcess.height : _this._originalColorPostProcess.height);
            effect.setFloat("near", _this._scene.activeCamera.minZ);
            effect.setFloat("far", _this._scene.activeCamera.maxZ);
            effect.setFloat("radius", _this.radius);
            effect.setTexture("depthSampler", _this._depthTexture);
            if (_this._firstUpdate) {
                effect.setArray("samplerOffsets", _this._samplerOffsets);
                _this._firstUpdate = false;
            }
        };
        this._blurHPostProcess.samples = this.textureSamples;
        this._blurVPostProcess.samples = this.textureSamples;
    };
    /** @hidden */
    SSAO2RenderingPipeline.prototype._rebuild = function () {
        this._firstUpdate = true;
        _super.prototype._rebuild.call(this);
    };
    //Van der Corput radical inverse
    SSAO2RenderingPipeline.prototype._radicalInverse_VdC = function (i) {
        this._bits[0] = i;
        this._bits[0] = ((this._bits[0] << 16) | (this._bits[0] >> 16)) >>> 0;
        this._bits[0] = ((this._bits[0] & 0x55555555) << 1) | ((this._bits[0] & 0xAAAAAAAA) >>> 1) >>> 0;
        this._bits[0] = ((this._bits[0] & 0x33333333) << 2) | ((this._bits[0] & 0xCCCCCCCC) >>> 2) >>> 0;
        this._bits[0] = ((this._bits[0] & 0x0F0F0F0F) << 4) | ((this._bits[0] & 0xF0F0F0F0) >>> 4) >>> 0;
        this._bits[0] = ((this._bits[0] & 0x00FF00FF) << 8) | ((this._bits[0] & 0xFF00FF00) >>> 8) >>> 0;
        return this._bits[0] * 2.3283064365386963e-10; // / 0x100000000 or / 4294967296
    };
    SSAO2RenderingPipeline.prototype._hammersley = function (i, n) {
        return [i / n, this._radicalInverse_VdC(i)];
    };
    SSAO2RenderingPipeline.prototype._hemisphereSample_uniform = function (u, v) {
        var phi = v * 2.0 * Math.PI;
        // rejecting samples that are close to tangent plane to avoid z-fighting artifacts
        var cosTheta = 1.0 - (u * 0.85 + 0.15);
        var sinTheta = Math.sqrt(1.0 - cosTheta * cosTheta);
        return new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](Math.cos(phi) * sinTheta, Math.sin(phi) * sinTheta, cosTheta);
    };
    SSAO2RenderingPipeline.prototype._generateHemisphere = function () {
        var numSamples = this.samples;
        var result = [];
        var vector;
        var i = 0;
        while (i < numSamples) {
            if (numSamples < 16) {
                vector = this._hemisphereSample_uniform(Math.random(), Math.random());
            }
            else {
                var rand = this._hammersley(i, numSamples);
                vector = this._hemisphereSample_uniform(rand[0], rand[1]);
            }
            result.push(vector.x, vector.y, vector.z);
            i++;
        }
        return result;
    };
    SSAO2RenderingPipeline.prototype._createSSAOPostProcess = function (ratio) {
        var _this = this;
        var numSamples = this.samples;
        this._sampleSphere = this._generateHemisphere();
        this._ssaoPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("ssao2", "ssao2", [
            "sampleSphere", "samplesFactor", "randTextureTiles", "totalStrength", "radius",
            "base", "range", "projection", "near", "far", "texelSize",
            "xViewport", "yViewport", "maxZ", "minZAspect"
        ], ["randomSampler", "normalSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define SAMPLES " + numSamples + "\n#define SSAO");
        this._ssaoPostProcess.onApply = function (effect) {
            if (_this._firstUpdate) {
                effect.setArray3("sampleSphere", _this._sampleSphere);
                effect.setFloat("randTextureTiles", 32.0);
            }
            if (!_this._scene.activeCamera) {
                return;
            }
            effect.setFloat("samplesFactor", 1 / _this.samples);
            effect.setFloat("totalStrength", _this.totalStrength);
            effect.setFloat2("texelSize", 1 / _this._ssaoPostProcess.width, 1 / _this._ssaoPostProcess.height);
            effect.setFloat("radius", _this.radius);
            effect.setFloat("maxZ", _this.maxZ);
            effect.setFloat("minZAspect", _this.minZAspect);
            effect.setFloat("base", _this.base);
            effect.setFloat("near", _this._scene.activeCamera.minZ);
            effect.setFloat("far", _this._scene.activeCamera.maxZ);
            effect.setFloat("xViewport", Math.tan(_this._scene.activeCamera.fov / 2) * _this._scene.getEngine().getAspectRatio(_this._scene.activeCamera, true));
            effect.setFloat("yViewport", Math.tan(_this._scene.activeCamera.fov / 2));
            effect.setMatrix("projection", _this._scene.getProjectionMatrix());
            effect.setTexture("textureSampler", _this._depthTexture);
            effect.setTexture("normalSampler", _this._normalTexture);
            effect.setTexture("randomSampler", _this._randomTexture);
        };
        this._ssaoPostProcess.samples = this.textureSamples;
    };
    SSAO2RenderingPipeline.prototype._createSSAOCombinePostProcess = function (ratio) {
        var _this = this;
        this._ssaoCombinePostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("ssaoCombine", "ssaoCombine", [], ["originalColor", "viewport"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false);
        this._ssaoCombinePostProcess.onApply = function (effect) {
            var viewport = _this._scene.activeCamera.viewport;
            effect.setVector4("viewport", _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector4[0].copyFromFloats(viewport.x, viewport.y, viewport.width, viewport.height));
            effect.setTextureFromPostProcess("originalColor", _this._originalColorPostProcess);
        };
        this._ssaoCombinePostProcess.samples = this.textureSamples;
    };
    SSAO2RenderingPipeline.prototype._createRandomTexture = function () {
        var size = 128;
        this._randomTexture = new _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_5__["DynamicTexture"]("SSAORandomTexture", size, this._scene, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].TRILINEAR_SAMPLINGMODE);
        this._randomTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].WRAP_ADDRESSMODE;
        this._randomTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_4__["Texture"].WRAP_ADDRESSMODE;
        var context = this._randomTexture.getContext();
        var rand = function (min, max) {
            return Math.random() * (max - min) + min;
        };
        var randVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        for (var x = 0; x < size; x++) {
            for (var y = 0; y < size; y++) {
                randVector.x = rand(0.0, 1.0);
                randVector.y = rand(0.0, 1.0);
                randVector.z = 0.0;
                randVector.normalize();
                randVector.scaleInPlace(255);
                randVector.x = Math.floor(randVector.x);
                randVector.y = Math.floor(randVector.y);
                context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')';
                context.fillRect(x, y, 1, 1);
            }
        }
        this._randomTexture.update(false);
    };
    /**
     * Serialize the rendering pipeline (Used when exporting)
     * @returns the serialized object
     */
    SSAO2RenderingPipeline.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["SerializationHelper"].Serialize(this);
        serializationObject.customType = "SSAO2RenderingPipeline";
        return serializationObject;
    };
    /**
     * Parse the serialized pipeline
     * @param source Source pipeline.
     * @param scene The scene to load the pipeline to.
     * @param rootUrl The URL of the serialized pipeline.
     * @returns An instantiated pipeline from the serialized object.
     */
    SSAO2RenderingPipeline.Parse = function (source, scene, rootUrl) {
        return _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["SerializationHelper"].Parse(function () { return new SSAO2RenderingPipeline(source._name, scene, source._ratio); }, source, scene, rootUrl);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], SSAO2RenderingPipeline.prototype, "totalStrength", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], SSAO2RenderingPipeline.prototype, "maxZ", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], SSAO2RenderingPipeline.prototype, "minZAspect", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])("samples")
    ], SSAO2RenderingPipeline.prototype, "_samples", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])("textureSamples")
    ], SSAO2RenderingPipeline.prototype, "_textureSamples", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], SSAO2RenderingPipeline.prototype, "_ratio", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])("expensiveBlur")
    ], SSAO2RenderingPipeline.prototype, "_expensiveBlur", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], SSAO2RenderingPipeline.prototype, "radius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], SSAO2RenderingPipeline.prototype, "base", void 0);
    return SSAO2RenderingPipeline;
}(_PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_7__["PostProcessRenderPipeline"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_10__["_TypeStore"].RegisteredTypes["BABYLON.SSAO2RenderingPipeline"] = SSAO2RenderingPipeline;


/***/ }),

/***/ "./PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.ts":
/*!*************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline.ts ***!
  \*************************************************************************/
/*! exports provided: SSAORenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SSAORenderingPipeline", function() { return SSAORenderingPipeline; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Materials/Textures/dynamicTexture */ "./Materials/Textures/dynamicTexture.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipeline */ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../PostProcesses/passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony import */ var _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../PostProcesses/blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts");
/* harmony import */ var _Shaders_ssao_fragment__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../Shaders/ssao.fragment */ "./Shaders/ssao.fragment.ts");
/* harmony import */ var _Shaders_ssaoCombine_fragment__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../../Shaders/ssaoCombine.fragment */ "./Shaders/ssaoCombine.fragment.ts");














/**
 * Render pipeline to produce ssao effect
 */
var SSAORenderingPipeline = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SSAORenderingPipeline, _super);
    /**
     * @constructor
     * @param name - The rendering pipeline name
     * @param scene - The scene linked to this pipeline
     * @param ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, combineRatio: 1.0 }
     * @param cameras - The array of cameras that the rendering pipeline will be attached to
     */
    function SSAORenderingPipeline(name, scene, ratio, cameras) {
        var _this = _super.call(this, scene.getEngine(), name) || this;
        // Members
        /**
         * @ignore
        * The PassPostProcess id in the pipeline that contains the original scene color
        */
        _this.SSAOOriginalSceneColorEffect = "SSAOOriginalSceneColorEffect";
        /**
         * @ignore
        * The SSAO PostProcess id in the pipeline
        */
        _this.SSAORenderEffect = "SSAORenderEffect";
        /**
         * @ignore
        * The horizontal blur PostProcess id in the pipeline
        */
        _this.SSAOBlurHRenderEffect = "SSAOBlurHRenderEffect";
        /**
         * @ignore
        * The vertical blur PostProcess id in the pipeline
        */
        _this.SSAOBlurVRenderEffect = "SSAOBlurVRenderEffect";
        /**
         * @ignore
        * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect)
        */
        _this.SSAOCombineRenderEffect = "SSAOCombineRenderEffect";
        /**
        * The output strength of the SSAO post-process. Default value is 1.0.
        */
        _this.totalStrength = 1.0;
        /**
        * The radius around the analyzed pixel used by the SSAO post-process. Default value is 0.0006
        */
        _this.radius = 0.0001;
        /**
        * Related to fallOff, used to interpolate SSAO samples (first interpolate function input) based on the occlusion difference of each pixel
        * Must not be equal to fallOff and superior to fallOff.
        * Default value is 0.0075
        */
        _this.area = 0.0075;
        /**
        * Related to area, used to interpolate SSAO samples (second interpolate function input) based on the occlusion difference of each pixel
        * Must not be equal to area and inferior to area.
        * Default value is 0.000001
        */
        _this.fallOff = 0.000001;
        /**
        * The base color of the SSAO post-process
        * The final result is "base + ssao" between [0, 1]
        */
        _this.base = 0.5;
        _this._firstUpdate = true;
        _this._scene = scene;
        // Set up assets
        _this._createRandomTexture();
        _this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on"
        var ssaoRatio = ratio.ssaoRatio || ratio;
        var combineRatio = ratio.combineRatio || ratio;
        _this._originalColorPostProcess = new _PostProcesses_passPostProcess__WEBPACK_IMPORTED_MODULE_7__["PassPostProcess"]("SSAOOriginalSceneColor", combineRatio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
        _this._createSSAOPostProcess(ssaoRatio);
        _this._createBlurPostProcess(ssaoRatio);
        _this._createSSAOCombinePostProcess(combineRatio);
        // Set up pipeline
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_6__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOOriginalSceneColorEffect, function () { return _this._originalColorPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_6__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAORenderEffect, function () { return _this._ssaoPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_6__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOBlurHRenderEffect, function () { return _this._blurHPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_6__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOBlurVRenderEffect, function () { return _this._blurVPostProcess; }, true));
        _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_6__["PostProcessRenderEffect"](scene.getEngine(), _this.SSAOCombineRenderEffect, function () { return _this._ssaoCombinePostProcess; }, true));
        // Finish
        scene.postProcessRenderPipelineManager.addPipeline(_this);
        if (cameras) {
            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
        }
        return _this;
    }
    Object.defineProperty(SSAORenderingPipeline.prototype, "scene", {
        /**
         * Gets active scene
         */
        get: function () {
            return this._scene;
        },
        enumerable: true,
        configurable: true
    });
    // Public Methods
    /**
     * Get the class name
     * @returns "SSAORenderingPipeline"
     */
    SSAORenderingPipeline.prototype.getClassName = function () {
        return "SSAORenderingPipeline";
    };
    /**
     * Removes the internal pipeline assets and detatches the pipeline from the scene cameras
     */
    SSAORenderingPipeline.prototype.dispose = function (disableDepthRender) {
        if (disableDepthRender === void 0) { disableDepthRender = false; }
        for (var i = 0; i < this._scene.cameras.length; i++) {
            var camera = this._scene.cameras[i];
            this._originalColorPostProcess.dispose(camera);
            this._ssaoPostProcess.dispose(camera);
            this._blurHPostProcess.dispose(camera);
            this._blurVPostProcess.dispose(camera);
            this._ssaoCombinePostProcess.dispose(camera);
        }
        this._randomTexture.dispose();
        if (disableDepthRender) {
            this._scene.disableDepthRenderer();
        }
        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras);
        _super.prototype.dispose.call(this);
    };
    // Private Methods
    SSAORenderingPipeline.prototype._createBlurPostProcess = function (ratio) {
        var _this = this;
        var size = 16;
        this._blurHPostProcess = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_8__["BlurPostProcess"]("BlurH", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1, 0), size, ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, _Engines_constants__WEBPACK_IMPORTED_MODULE_9__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this._blurVPostProcess = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_8__["BlurPostProcess"]("BlurV", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0, 1), size, ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, _Engines_constants__WEBPACK_IMPORTED_MODULE_9__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this._blurHPostProcess.onActivateObservable.add(function () {
            var dw = _this._blurHPostProcess.width / _this._scene.getEngine().getRenderWidth();
            _this._blurHPostProcess.kernel = size * dw;
        });
        this._blurVPostProcess.onActivateObservable.add(function () {
            var dw = _this._blurVPostProcess.height / _this._scene.getEngine().getRenderHeight();
            _this._blurVPostProcess.kernel = size * dw;
        });
    };
    /** @hidden */
    SSAORenderingPipeline.prototype._rebuild = function () {
        this._firstUpdate = true;
        _super.prototype._rebuild.call(this);
    };
    SSAORenderingPipeline.prototype._createSSAOPostProcess = function (ratio) {
        var _this = this;
        var numSamples = 16;
        var sampleSphere = [
            0.5381, 0.1856, -0.4319,
            0.1379, 0.2486, 0.4430,
            0.3371, 0.5679, -0.0057,
            -0.6999, -0.0451, -0.0019,
            0.0689, -0.1598, -0.8547,
            0.0560, 0.0069, -0.1843,
            -0.0146, 0.1402, 0.0762,
            0.0100, -0.1924, -0.0344,
            -0.3577, -0.5301, -0.4358,
            -0.3169, 0.1063, 0.0158,
            0.0103, -0.5869, 0.0046,
            -0.0897, -0.4940, 0.3287,
            0.7119, -0.0154, -0.0918,
            -0.0533, 0.0596, -0.5411,
            0.0352, -0.0631, 0.5460,
            -0.4776, 0.2847, -0.0271
        ];
        var samplesFactor = 1.0 / numSamples;
        this._ssaoPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_4__["PostProcess"]("ssao", "ssao", [
            "sampleSphere", "samplesFactor", "randTextureTiles", "totalStrength", "radius",
            "area", "fallOff", "base", "range", "viewport"
        ], ["randomSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define SAMPLES " + numSamples + "\n#define SSAO");
        this._ssaoPostProcess.onApply = function (effect) {
            if (_this._firstUpdate) {
                effect.setArray3("sampleSphere", sampleSphere);
                effect.setFloat("samplesFactor", samplesFactor);
                effect.setFloat("randTextureTiles", 4.0);
            }
            effect.setFloat("totalStrength", _this.totalStrength);
            effect.setFloat("radius", _this.radius);
            effect.setFloat("area", _this.area);
            effect.setFloat("fallOff", _this.fallOff);
            effect.setFloat("base", _this.base);
            effect.setTexture("textureSampler", _this._depthTexture);
            effect.setTexture("randomSampler", _this._randomTexture);
        };
    };
    SSAORenderingPipeline.prototype._createSSAOCombinePostProcess = function (ratio) {
        var _this = this;
        this._ssaoCombinePostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_4__["PostProcess"]("ssaoCombine", "ssaoCombine", [], ["originalColor", "viewport"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false);
        this._ssaoCombinePostProcess.onApply = function (effect) {
            effect.setVector4("viewport", _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector4[0].copyFromFloats(0, 0, 1.0, 1.0));
            effect.setTextureFromPostProcess("originalColor", _this._originalColorPostProcess);
        };
    };
    SSAORenderingPipeline.prototype._createRandomTexture = function () {
        var size = 512;
        this._randomTexture = new _Materials_Textures_dynamicTexture__WEBPACK_IMPORTED_MODULE_3__["DynamicTexture"]("SSAORandomTexture", size, this._scene, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].TRILINEAR_SAMPLINGMODE);
        this._randomTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].WRAP_ADDRESSMODE;
        this._randomTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].WRAP_ADDRESSMODE;
        var context = this._randomTexture.getContext();
        var rand = function (min, max) {
            return Math.random() * (max - min) + min;
        };
        var randVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
        for (var x = 0; x < size; x++) {
            for (var y = 0; y < size; y++) {
                randVector.x = Math.floor(rand(-1.0, 1.0) * 255);
                randVector.y = Math.floor(rand(-1.0, 1.0) * 255);
                randVector.z = Math.floor(rand(-1.0, 1.0) * 255);
                context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')';
                context.fillRect(x, y, 1, 1);
            }
        }
        this._randomTexture.update(false);
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_10__["serialize"])()
    ], SSAORenderingPipeline.prototype, "totalStrength", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_10__["serialize"])()
    ], SSAORenderingPipeline.prototype, "radius", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_10__["serialize"])()
    ], SSAORenderingPipeline.prototype, "area", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_10__["serialize"])()
    ], SSAORenderingPipeline.prototype, "fallOff", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_10__["serialize"])()
    ], SSAORenderingPipeline.prototype, "base", void 0);
    return SSAORenderingPipeline;
}(_PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_5__["PostProcessRenderPipeline"]));



/***/ }),

/***/ "./PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.ts":
/*!*****************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/Pipelines/standardRenderingPipeline.ts ***!
  \*****************************************************************************/
/*! exports provided: StandardRenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StandardRenderingPipeline", function() { return StandardRenderingPipeline; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../Maths/math.scalar */ "./Maths/math.scalar.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../PostProcesses/postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipeline */ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../PostProcesses/blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _PostProcesses_fxaaPostProcess__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../PostProcesses/fxaaPostProcess */ "./PostProcesses/fxaaPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_typeStore__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../../../Misc/typeStore */ "./Misc/typeStore.ts");
/* harmony import */ var _motionBlurPostProcess__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../../motionBlurPostProcess */ "./PostProcesses/motionBlurPostProcess.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../../PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts");
/* harmony import */ var _Shaders_standard_fragment__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../../../Shaders/standard.fragment */ "./Shaders/standard.fragment.ts");
















/**
 * Standard rendering pipeline
 * Default pipeline should be used going forward but the standard pipeline will be kept for backwards compatibility.
 * @see https://doc.babylonjs.com/how_to/using_standard_rendering_pipeline
 */
var StandardRenderingPipeline = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StandardRenderingPipeline, _super);
    /**
     * Default pipeline should be used going forward but the standard pipeline will be kept for backwards compatibility.
     * @constructor
     * @param name The rendering pipeline name
     * @param scene The scene linked to this pipeline
     * @param ratio The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)
     * @param originalPostProcess the custom original color post-process. Must be "reusable". Can be null.
     * @param cameras The array of cameras that the rendering pipeline will be attached to
     */
    function StandardRenderingPipeline(name, scene, ratio, originalPostProcess, cameras) {
        if (originalPostProcess === void 0) { originalPostProcess = null; }
        var _this = _super.call(this, scene.getEngine(), name) || this;
        /**
         * Post-process used to down scale an image x4
         */
        _this.downSampleX4PostProcess = null;
        /**
         * Post-process used to calculate the illuminated surfaces controlled by a threshold
         */
        _this.brightPassPostProcess = null;
        /**
         * Post-process array storing all the horizontal blur post-processes used by the pipeline
         */
        _this.blurHPostProcesses = [];
        /**
         * Post-process array storing all the vertical blur post-processes used by the pipeline
         */
        _this.blurVPostProcesses = [];
        /**
         * Post-process used to add colors of 2 textures (typically brightness + real scene color)
         */
        _this.textureAdderPostProcess = null;
        /**
         * Post-process used to create volumetric lighting effect
         */
        _this.volumetricLightPostProcess = null;
        /**
         * Post-process used to smooth the previous volumetric light post-process on the X axis
         */
        _this.volumetricLightSmoothXPostProcess = null;
        /**
         * Post-process used to smooth the previous volumetric light post-process on the Y axis
         */
        _this.volumetricLightSmoothYPostProcess = null;
        /**
         * Post-process used to merge the volumetric light effect and the real scene color
         */
        _this.volumetricLightMergePostProces = null;
        /**
         * Post-process used to store the final volumetric light post-process (attach/detach for debug purpose)
         */
        _this.volumetricLightFinalPostProcess = null;
        /**
         * Base post-process used to calculate the average luminance of the final image for HDR
         */
        _this.luminancePostProcess = null;
        /**
         * Post-processes used to create down sample post-processes in order to get
         * the average luminance of the final image for HDR
         * Array of length "StandardRenderingPipeline.LuminanceSteps"
         */
        _this.luminanceDownSamplePostProcesses = [];
        /**
         * Post-process used to create a HDR effect (light adaptation)
         */
        _this.hdrPostProcess = null;
        /**
         * Post-process used to store the final texture adder post-process (attach/detach for debug purpose)
         */
        _this.textureAdderFinalPostProcess = null;
        /**
         * Post-process used to store the final lens flare post-process (attach/detach for debug purpose)
         */
        _this.lensFlareFinalPostProcess = null;
        /**
         * Post-process used to merge the final HDR post-process and the real scene color
         */
        _this.hdrFinalPostProcess = null;
        /**
         * Post-process used to create a lens flare effect
         */
        _this.lensFlarePostProcess = null;
        /**
         * Post-process that merges the result of the lens flare post-process and the real scene color
         */
        _this.lensFlareComposePostProcess = null;
        /**
         * Post-process used to create a motion blur effect
         */
        _this.motionBlurPostProcess = null;
        /**
         * Post-process used to create a depth of field effect
         */
        _this.depthOfFieldPostProcess = null;
        /**
         * The Fast Approximate Anti-Aliasing post process which attemps to remove aliasing from an image.
         */
        _this.fxaaPostProcess = null;
        // Values
        /**
         * Represents the brightness threshold in order to configure the illuminated surfaces
         */
        _this.brightThreshold = 1.0;
        /**
         * Configures the blur intensity used for surexposed surfaces are highlighted surfaces (light halo)
         */
        _this.blurWidth = 512.0;
        /**
         * Sets if the blur for highlighted surfaces must be only horizontal
         */
        _this.horizontalBlur = false;
        /**
         * Texture used typically to simulate "dirty" on camera lens
         */
        _this.lensTexture = null;
        /**
         * Represents the offset coefficient based on Rayleigh principle. Typically in interval [-0.2, 0.2]
         */
        _this.volumetricLightCoefficient = 0.2;
        /**
         * The overall power of volumetric lights, typically in interval [0, 10] maximum
         */
        _this.volumetricLightPower = 4.0;
        /**
         * Used the set the blur intensity to smooth the volumetric lights
         */
        _this.volumetricLightBlurScale = 64.0;
        /**
         * Light (spot or directional) used to generate the volumetric lights rays
         * The source light must have a shadow generate so the pipeline can get its
         * depth map
         */
        _this.sourceLight = null;
        /**
         * For eye adaptation, represents the minimum luminance the eye can see
         */
        _this.hdrMinimumLuminance = 1.0;
        /**
         * For eye adaptation, represents the decrease luminance speed
         */
        _this.hdrDecreaseRate = 0.5;
        /**
         * For eye adaptation, represents the increase luminance speed
         */
        _this.hdrIncreaseRate = 0.5;
        /**
         * Lens color texture used by the lens flare effect. Mandatory if lens flare effect enabled
         */
        _this.lensColorTexture = null;
        /**
         * The overall strengh for the lens flare effect
         */
        _this.lensFlareStrength = 20.0;
        /**
         * Dispersion coefficient for lens flare ghosts
         */
        _this.lensFlareGhostDispersal = 1.4;
        /**
         * Main lens flare halo width
         */
        _this.lensFlareHaloWidth = 0.7;
        /**
         * Based on the lens distortion effect, defines how much the lens flare result
         * is distorted
         */
        _this.lensFlareDistortionStrength = 16.0;
        /**
         * Configures the blur intensity used for for lens flare (halo)
         */
        _this.lensFlareBlurWidth = 512.0;
        /**
         * Lens star texture must be used to simulate rays on the flares and is available
         * in the documentation
         */
        _this.lensStarTexture = null;
        /**
         * As the "lensTexture" (can be the same texture or different), it is used to apply the lens
         * flare effect by taking account of the dirt texture
         */
        _this.lensFlareDirtTexture = null;
        /**
         * Represents the focal length for the depth of field effect
         */
        _this.depthOfFieldDistance = 10.0;
        /**
         * Represents the blur intensity for the blurred part of the depth of field effect
         */
        _this.depthOfFieldBlurWidth = 64.0;
        /**
         * List of animations for the pipeline (IAnimatable implementation)
         */
        _this.animations = [];
        _this._currentDepthOfFieldSource = null;
        _this._fixedExposure = 1.0;
        _this._currentExposure = 1.0;
        _this._hdrAutoExposure = false;
        _this._hdrCurrentLuminance = 1.0;
        _this._motionStrength = 1.0;
        _this._isObjectBasedMotionBlur = false;
        _this._camerasToBeAttached = [];
        // Getters and setters
        _this._bloomEnabled = false;
        _this._depthOfFieldEnabled = false;
        _this._vlsEnabled = false;
        _this._lensFlareEnabled = false;
        _this._hdrEnabled = false;
        _this._motionBlurEnabled = false;
        _this._fxaaEnabled = false;
        _this._motionBlurSamples = 64.0;
        _this._volumetricLightStepsCount = 50.0;
        _this._samples = 1;
        _this._cameras = cameras || scene.cameras;
        _this._cameras = _this._cameras.slice();
        _this._camerasToBeAttached = _this._cameras.slice();
        // Initialize
        _this._scene = scene;
        _this._basePostProcess = originalPostProcess;
        _this._ratio = ratio;
        // Misc
        _this._floatTextureType = scene.getEngine().getCaps().textureFloatRender ? _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_FLOAT : _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_HALF_FLOAT;
        // Finish
        scene.postProcessRenderPipelineManager.addPipeline(_this);
        _this._buildPipeline();
        return _this;
    }
    Object.defineProperty(StandardRenderingPipeline.prototype, "exposure", {
        /**
         * Gets the overall exposure used by the pipeline
         */
        get: function () {
            return this._fixedExposure;
        },
        /**
         * Sets the overall exposure used by the pipeline
         */
        set: function (value) {
            this._fixedExposure = value;
            this._currentExposure = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "hdrAutoExposure", {
        /**
         * Gets wether or not the exposure of the overall pipeline should be automatically adjusted by the HDR post-process
         */
        get: function () {
            return this._hdrAutoExposure;
        },
        /**
         * Sets wether or not the exposure of the overall pipeline should be automatically adjusted by the HDR post-process
         */
        set: function (value) {
            this._hdrAutoExposure = value;
            if (this.hdrPostProcess) {
                var defines = ["#define HDR"];
                if (value) {
                    defines.push("#define AUTO_EXPOSURE");
                }
                this.hdrPostProcess.updateEffect(defines.join("\n"));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "motionStrength", {
        /**
         * Gets how much the image is blurred by the movement while using the motion blur post-process
         */
        get: function () {
            return this._motionStrength;
        },
        /**
         * Sets how much the image is blurred by the movement while using the motion blur post-process
         */
        set: function (strength) {
            this._motionStrength = strength;
            if (this._isObjectBasedMotionBlur && this.motionBlurPostProcess) {
                this.motionBlurPostProcess.motionStrength = strength;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "objectBasedMotionBlur", {
        /**
         * Gets wether or not the motion blur post-process is object based or screen based.
         */
        get: function () {
            return this._isObjectBasedMotionBlur;
        },
        /**
         * Sets wether or not the motion blur post-process should be object based or screen based
         */
        set: function (value) {
            var shouldRebuild = this._isObjectBasedMotionBlur !== value;
            this._isObjectBasedMotionBlur = value;
            if (shouldRebuild) {
                this._buildPipeline();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "BloomEnabled", {
        /**
         * @ignore
         * Specifies if the bloom pipeline is enabled
         */
        get: function () {
            return this._bloomEnabled;
        },
        set: function (enabled) {
            if (this._bloomEnabled === enabled) {
                return;
            }
            this._bloomEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "DepthOfFieldEnabled", {
        /**
         * @ignore
         * Specifies if the depth of field pipeline is enabed
         */
        get: function () {
            return this._depthOfFieldEnabled;
        },
        set: function (enabled) {
            if (this._depthOfFieldEnabled === enabled) {
                return;
            }
            this._depthOfFieldEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "LensFlareEnabled", {
        /**
         * @ignore
         * Specifies if the lens flare pipeline is enabed
         */
        get: function () {
            return this._lensFlareEnabled;
        },
        set: function (enabled) {
            if (this._lensFlareEnabled === enabled) {
                return;
            }
            this._lensFlareEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "HDREnabled", {
        /**
         * @ignore
         * Specifies if the HDR pipeline is enabled
         */
        get: function () {
            return this._hdrEnabled;
        },
        set: function (enabled) {
            if (this._hdrEnabled === enabled) {
                return;
            }
            this._hdrEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "VLSEnabled", {
        /**
         * @ignore
         * Specifies if the volumetric lights scattering effect is enabled
         */
        get: function () {
            return this._vlsEnabled;
        },
        set: function (enabled) {
            if (this._vlsEnabled === enabled) {
                return;
            }
            if (enabled) {
                var geometry = this._scene.enableGeometryBufferRenderer();
                if (!geometry) {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("Geometry renderer is not supported, cannot create volumetric lights in Standard Rendering Pipeline");
                    return;
                }
            }
            this._vlsEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "MotionBlurEnabled", {
        /**
         * @ignore
         * Specifies if the motion blur effect is enabled
         */
        get: function () {
            return this._motionBlurEnabled;
        },
        set: function (enabled) {
            if (this._motionBlurEnabled === enabled) {
                return;
            }
            this._motionBlurEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "fxaaEnabled", {
        /**
         * Specifies if anti-aliasing is enabled
         */
        get: function () {
            return this._fxaaEnabled;
        },
        set: function (enabled) {
            if (this._fxaaEnabled === enabled) {
                return;
            }
            this._fxaaEnabled = enabled;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "volumetricLightStepsCount", {
        /**
         * Specifies the number of steps used to calculate the volumetric lights
         * Typically in interval [50, 200]
         */
        get: function () {
            return this._volumetricLightStepsCount;
        },
        set: function (count) {
            if (this.volumetricLightPostProcess) {
                this.volumetricLightPostProcess.updateEffect("#define VLS\n#define NB_STEPS " + count.toFixed(1));
            }
            this._volumetricLightStepsCount = count;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "motionBlurSamples", {
        /**
         * Specifies the number of samples used for the motion blur effect
         * Typically in interval [16, 64]
         */
        get: function () {
            return this._motionBlurSamples;
        },
        set: function (samples) {
            if (this.motionBlurPostProcess) {
                if (this._isObjectBasedMotionBlur) {
                    this.motionBlurPostProcess.motionBlurSamples = samples;
                }
                else {
                    this.motionBlurPostProcess.updateEffect("#define MOTION_BLUR\n#define MAX_MOTION_SAMPLES " + samples.toFixed(1));
                }
            }
            this._motionBlurSamples = samples;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(StandardRenderingPipeline.prototype, "samples", {
        /**
         * Specifies MSAA sample count, setting this to 4 will provide 4x anti aliasing. (default: 1)
         */
        get: function () {
            return this._samples;
        },
        set: function (sampleCount) {
            if (this._samples === sampleCount) {
                return;
            }
            this._samples = sampleCount;
            this._buildPipeline();
        },
        enumerable: true,
        configurable: true
    });
    StandardRenderingPipeline.prototype._buildPipeline = function () {
        var _this = this;
        var ratio = this._ratio;
        var scene = this._scene;
        this._disposePostProcesses();
        if (this._cameras !== null) {
            this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
            // get back cameras to be used to reattach pipeline
            this._cameras = this._camerasToBeAttached.slice();
        }
        this._reset();
        // Create pass post-process
        if (!this._basePostProcess) {
            this.originalPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRPass", "standard", [], [], ratio, null, _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", this._floatTextureType);
            this.originalPostProcess.onApply = function () {
                _this._currentDepthOfFieldSource = _this.originalPostProcess;
            };
        }
        else {
            this.originalPostProcess = this._basePostProcess;
        }
        if (this._bloomEnabled || this._vlsEnabled || this._lensFlareEnabled || this._depthOfFieldEnabled || this._motionBlurEnabled) {
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRPassPostProcess", function () { return _this.originalPostProcess; }, true));
        }
        this._currentDepthOfFieldSource = this.originalPostProcess;
        if (this._bloomEnabled) {
            // Create down sample X4 post-process
            this._createDownSampleX4PostProcess(scene, ratio / 2);
            // Create bright pass post-process
            this._createBrightPassPostProcess(scene, ratio / 2);
            // Create gaussian blur post-processes (down sampling blurs)
            this._createBlurPostProcesses(scene, ratio / 4, 1);
            // Create texture adder post-process
            this._createTextureAdderPostProcess(scene, ratio);
            // Create depth-of-field source post-process
            this.textureAdderFinalPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRDepthOfFieldSource", "standard", [], [], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRBaseDepthOfFieldSource", function () { return _this.textureAdderFinalPostProcess; }, true));
        }
        if (this._vlsEnabled) {
            // Create volumetric light
            this._createVolumetricLightPostProcess(scene, ratio);
            // Create volumetric light final post-process
            this.volumetricLightFinalPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRVLSFinal", "standard", [], [], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRVLSFinal", function () { return _this.volumetricLightFinalPostProcess; }, true));
        }
        if (this._lensFlareEnabled) {
            // Create lens flare post-process
            this._createLensFlarePostProcess(scene, ratio);
            // Create depth-of-field source post-process post lens-flare and disable it now
            this.lensFlareFinalPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRPostLensFlareDepthOfFieldSource", "standard", [], [], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRPostLensFlareDepthOfFieldSource", function () { return _this.lensFlareFinalPostProcess; }, true));
        }
        if (this._hdrEnabled) {
            // Create luminance
            this._createLuminancePostProcesses(scene, this._floatTextureType);
            // Create HDR
            this._createHdrPostProcess(scene, ratio);
            // Create depth-of-field source post-process post hdr and disable it now
            this.hdrFinalPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRPostHDReDepthOfFieldSource", "standard", [], [], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRPostHDReDepthOfFieldSource", function () { return _this.hdrFinalPostProcess; }, true));
        }
        if (this._depthOfFieldEnabled) {
            // Create gaussian blur used by depth-of-field
            this._createBlurPostProcesses(scene, ratio / 2, 3, "depthOfFieldBlurWidth");
            // Create depth-of-field post-process
            this._createDepthOfFieldPostProcess(scene, ratio);
        }
        if (this._motionBlurEnabled) {
            // Create motion blur post-process
            this._createMotionBlurPostProcess(scene, ratio);
        }
        if (this._fxaaEnabled) {
            // Create fxaa post-process
            this.fxaaPostProcess = new _PostProcesses_fxaaPostProcess__WEBPACK_IMPORTED_MODULE_10__["FxaaPostProcess"]("fxaa", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRFxaa", function () { return _this.fxaaPostProcess; }, true));
        }
        if (this._cameras !== null) {
            this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
        }
        if (!this._enableMSAAOnFirstPostProcess(this._samples) && this._samples > 1) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0");
        }
    };
    // Down Sample X4 Post-Processs
    StandardRenderingPipeline.prototype._createDownSampleX4PostProcess = function (scene, ratio) {
        var _this = this;
        var downSampleX4Offsets = new Array(32);
        this.downSampleX4PostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRDownSampleX4", "standard", ["dsOffsets"], [], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define DOWN_SAMPLE_X4", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this.downSampleX4PostProcess.onApply = function (effect) {
            var id = 0;
            var width = _this.downSampleX4PostProcess.width;
            var height = _this.downSampleX4PostProcess.height;
            for (var i = -2; i < 2; i++) {
                for (var j = -2; j < 2; j++) {
                    downSampleX4Offsets[id] = (i + 0.5) * (1.0 / width);
                    downSampleX4Offsets[id + 1] = (j + 0.5) * (1.0 / height);
                    id += 2;
                }
            }
            effect.setArray2("dsOffsets", downSampleX4Offsets);
        };
        // Add to pipeline
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRDownSampleX4", function () { return _this.downSampleX4PostProcess; }, true));
    };
    // Brightpass Post-Process
    StandardRenderingPipeline.prototype._createBrightPassPostProcess = function (scene, ratio) {
        var _this = this;
        var brightOffsets = new Array(8);
        this.brightPassPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRBrightPass", "standard", ["dsOffsets", "brightThreshold"], [], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define BRIGHT_PASS", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this.brightPassPostProcess.onApply = function (effect) {
            var sU = (1.0 / _this.brightPassPostProcess.width);
            var sV = (1.0 / _this.brightPassPostProcess.height);
            brightOffsets[0] = -0.5 * sU;
            brightOffsets[1] = 0.5 * sV;
            brightOffsets[2] = 0.5 * sU;
            brightOffsets[3] = 0.5 * sV;
            brightOffsets[4] = -0.5 * sU;
            brightOffsets[5] = -0.5 * sV;
            brightOffsets[6] = 0.5 * sU;
            brightOffsets[7] = -0.5 * sV;
            effect.setArray2("dsOffsets", brightOffsets);
            effect.setFloat("brightThreshold", _this.brightThreshold);
        };
        // Add to pipeline
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRBrightPass", function () { return _this.brightPassPostProcess; }, true));
    };
    // Create blur H&V post-processes
    StandardRenderingPipeline.prototype._createBlurPostProcesses = function (scene, ratio, indice, blurWidthKey) {
        var _this = this;
        if (blurWidthKey === void 0) { blurWidthKey = "blurWidth"; }
        var engine = scene.getEngine();
        var blurX = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_9__["BlurPostProcess"]("HDRBlurH" + "_" + indice, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](1, 0), this[blurWidthKey], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        var blurY = new _PostProcesses_blurPostProcess__WEBPACK_IMPORTED_MODULE_9__["BlurPostProcess"]("HDRBlurV" + "_" + indice, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](0, 1), this[blurWidthKey], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        blurX.onActivateObservable.add(function () {
            var dw = blurX.width / engine.getRenderWidth();
            blurX.kernel = _this[blurWidthKey] * dw;
        });
        blurY.onActivateObservable.add(function () {
            var dw = blurY.height / engine.getRenderHeight();
            blurY.kernel = _this.horizontalBlur ? 64 * dw : _this[blurWidthKey] * dw;
        });
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRBlurH" + indice, function () { return blurX; }, true));
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRBlurV" + indice, function () { return blurY; }, true));
        this.blurHPostProcesses.push(blurX);
        this.blurVPostProcesses.push(blurY);
    };
    // Create texture adder post-process
    StandardRenderingPipeline.prototype._createTextureAdderPostProcess = function (scene, ratio) {
        var _this = this;
        this.textureAdderPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRTextureAdder", "standard", ["exposure"], ["otherSampler", "lensSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define TEXTURE_ADDER", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this.textureAdderPostProcess.onApply = function (effect) {
            effect.setTextureFromPostProcess("otherSampler", _this._vlsEnabled ? _this._currentDepthOfFieldSource : _this.originalPostProcess);
            effect.setTexture("lensSampler", _this.lensTexture);
            effect.setFloat("exposure", _this._currentExposure);
            _this._currentDepthOfFieldSource = _this.textureAdderFinalPostProcess;
        };
        // Add to pipeline
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRTextureAdder", function () { return _this.textureAdderPostProcess; }, true));
    };
    StandardRenderingPipeline.prototype._createVolumetricLightPostProcess = function (scene, ratio) {
        var _this = this;
        var geometryRenderer = scene.enableGeometryBufferRenderer();
        geometryRenderer.enablePosition = true;
        var geometry = geometryRenderer.getGBuffer();
        // Base post-process
        this.volumetricLightPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRVLS", "standard", ["shadowViewProjection", "cameraPosition", "sunDirection", "sunColor", "scatteringCoefficient", "scatteringPower", "depthValues"], ["shadowMapSampler", "positionSampler"], ratio / 8, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define VLS\n#define NB_STEPS " + this._volumetricLightStepsCount.toFixed(1));
        var depthValues = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
        this.volumetricLightPostProcess.onApply = function (effect) {
            if (_this.sourceLight && _this.sourceLight.getShadowGenerator() && _this._scene.activeCamera) {
                var generator = _this.sourceLight.getShadowGenerator();
                effect.setTexture("shadowMapSampler", generator.getShadowMap());
                effect.setTexture("positionSampler", geometry.textures[2]);
                effect.setColor3("sunColor", _this.sourceLight.diffuse);
                effect.setVector3("sunDirection", _this.sourceLight.getShadowDirection());
                effect.setVector3("cameraPosition", _this._scene.activeCamera.globalPosition);
                effect.setMatrix("shadowViewProjection", generator.getTransformMatrix());
                effect.setFloat("scatteringCoefficient", _this.volumetricLightCoefficient);
                effect.setFloat("scatteringPower", _this.volumetricLightPower);
                depthValues.x = _this.sourceLight.getDepthMinZ(_this._scene.activeCamera);
                depthValues.y = _this.sourceLight.getDepthMaxZ(_this._scene.activeCamera);
                effect.setVector2("depthValues", depthValues);
            }
        };
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRVLS", function () { return _this.volumetricLightPostProcess; }, true));
        // Smooth
        this._createBlurPostProcesses(scene, ratio / 4, 0, "volumetricLightBlurScale");
        // Merge
        this.volumetricLightMergePostProces = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRVLSMerge", "standard", [], ["originalSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define VLSMERGE");
        this.volumetricLightMergePostProces.onApply = function (effect) {
            effect.setTextureFromPostProcess("originalSampler", _this._bloomEnabled ? _this.textureAdderFinalPostProcess : _this.originalPostProcess);
            _this._currentDepthOfFieldSource = _this.volumetricLightFinalPostProcess;
        };
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRVLSMerge", function () { return _this.volumetricLightMergePostProces; }, true));
    };
    // Create luminance
    StandardRenderingPipeline.prototype._createLuminancePostProcesses = function (scene, textureType) {
        var _this = this;
        // Create luminance
        var size = Math.pow(3, StandardRenderingPipeline.LuminanceSteps);
        this.luminancePostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRLuminance", "standard", ["lumOffsets"], [], { width: size, height: size }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LUMINANCE", textureType);
        var offsets = [];
        this.luminancePostProcess.onApply = function (effect) {
            var sU = (1.0 / _this.luminancePostProcess.width);
            var sV = (1.0 / _this.luminancePostProcess.height);
            offsets[0] = -0.5 * sU;
            offsets[1] = 0.5 * sV;
            offsets[2] = 0.5 * sU;
            offsets[3] = 0.5 * sV;
            offsets[4] = -0.5 * sU;
            offsets[5] = -0.5 * sV;
            offsets[6] = 0.5 * sU;
            offsets[7] = -0.5 * sV;
            effect.setArray2("lumOffsets", offsets);
        };
        // Add to pipeline
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRLuminance", function () { return _this.luminancePostProcess; }, true));
        // Create down sample luminance
        for (var i = StandardRenderingPipeline.LuminanceSteps - 1; i >= 0; i--) {
            var size = Math.pow(3, i);
            var defines = "#define LUMINANCE_DOWN_SAMPLE\n";
            if (i === 0) {
                defines += "#define FINAL_DOWN_SAMPLER";
            }
            var postProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRLuminanceDownSample" + i, "standard", ["dsOffsets", "halfDestPixelSize"], [], { width: size, height: size }, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, defines, textureType);
            this.luminanceDownSamplePostProcesses.push(postProcess);
        }
        // Create callbacks and add effects
        var lastLuminance = this.luminancePostProcess;
        this.luminanceDownSamplePostProcesses.forEach(function (pp, index) {
            var downSampleOffsets = new Array(18);
            pp.onApply = function (effect) {
                if (!lastLuminance) {
                    return;
                }
                var id = 0;
                for (var x = -1; x < 2; x++) {
                    for (var y = -1; y < 2; y++) {
                        downSampleOffsets[id] = x / lastLuminance.width;
                        downSampleOffsets[id + 1] = y / lastLuminance.height;
                        id += 2;
                    }
                }
                effect.setArray2("dsOffsets", downSampleOffsets);
                effect.setFloat("halfDestPixelSize", 0.5 / lastLuminance.width);
                if (index === _this.luminanceDownSamplePostProcesses.length - 1) {
                    lastLuminance = _this.luminancePostProcess;
                }
                else {
                    lastLuminance = pp;
                }
            };
            if (index === _this.luminanceDownSamplePostProcesses.length - 1) {
                pp.onAfterRender = function () {
                    var pixel = scene.getEngine().readPixels(0, 0, 1, 1);
                    var bit_shift = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector4"](1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
                    _this._hdrCurrentLuminance = (pixel[0] * bit_shift.x + pixel[1] * bit_shift.y + pixel[2] * bit_shift.z + pixel[3] * bit_shift.w) / 100.0;
                };
            }
            _this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRLuminanceDownSample" + index, function () { return pp; }, true));
        });
    };
    // Create HDR post-process
    StandardRenderingPipeline.prototype._createHdrPostProcess = function (scene, ratio) {
        var _this = this;
        var defines = ["#define HDR"];
        if (this._hdrAutoExposure) {
            defines.push("#define AUTO_EXPOSURE");
        }
        this.hdrPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDR", "standard", ["averageLuminance"], ["textureAdderSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, defines.join("\n"), _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        var outputLiminance = 1;
        var time = 0;
        var lastTime = 0;
        this.hdrPostProcess.onApply = function (effect) {
            effect.setTextureFromPostProcess("textureAdderSampler", _this._currentDepthOfFieldSource);
            time += scene.getEngine().getDeltaTime();
            if (outputLiminance < 0) {
                outputLiminance = _this._hdrCurrentLuminance;
            }
            else {
                var dt = (lastTime - time) / 1000.0;
                if (_this._hdrCurrentLuminance < outputLiminance + _this.hdrDecreaseRate * dt) {
                    outputLiminance += _this.hdrDecreaseRate * dt;
                }
                else if (_this._hdrCurrentLuminance > outputLiminance - _this.hdrIncreaseRate * dt) {
                    outputLiminance -= _this.hdrIncreaseRate * dt;
                }
                else {
                    outputLiminance = _this._hdrCurrentLuminance;
                }
            }
            if (_this.hdrAutoExposure) {
                _this._currentExposure = _this._fixedExposure / outputLiminance;
            }
            else {
                outputLiminance = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_4__["Scalar"].Clamp(outputLiminance, _this.hdrMinimumLuminance, 1e20);
                effect.setFloat("averageLuminance", outputLiminance);
            }
            lastTime = time;
            _this._currentDepthOfFieldSource = _this.hdrFinalPostProcess;
        };
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDR", function () { return _this.hdrPostProcess; }, true));
    };
    // Create lens flare post-process
    StandardRenderingPipeline.prototype._createLensFlarePostProcess = function (scene, ratio) {
        var _this = this;
        this.lensFlarePostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRLensFlare", "standard", ["strength", "ghostDispersal", "haloWidth", "resolution", "distortionStrength"], ["lensColorSampler"], ratio / 2, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRLensFlare", function () { return _this.lensFlarePostProcess; }, true));
        this._createBlurPostProcesses(scene, ratio / 4, 2, "lensFlareBlurWidth");
        this.lensFlareComposePostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRLensFlareCompose", "standard", ["lensStarMatrix"], ["otherSampler", "lensDirtSampler", "lensStarSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE_COMPOSE", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRLensFlareCompose", function () { return _this.lensFlareComposePostProcess; }, true));
        var resolution = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"](0, 0);
        // Lens flare
        this.lensFlarePostProcess.onApply = function (effect) {
            effect.setTextureFromPostProcess("textureSampler", _this._bloomEnabled ? _this.blurHPostProcesses[0] : _this.originalPostProcess);
            effect.setTexture("lensColorSampler", _this.lensColorTexture);
            effect.setFloat("strength", _this.lensFlareStrength);
            effect.setFloat("ghostDispersal", _this.lensFlareGhostDispersal);
            effect.setFloat("haloWidth", _this.lensFlareHaloWidth);
            // Shift
            resolution.x = _this.lensFlarePostProcess.width;
            resolution.y = _this.lensFlarePostProcess.height;
            effect.setVector2("resolution", resolution);
            effect.setFloat("distortionStrength", _this.lensFlareDistortionStrength);
        };
        // Compose
        var scaleBias1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromValues(2.0, 0.0, -1.0, 0.0, 0.0, 2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
        var scaleBias2 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromValues(0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
        this.lensFlareComposePostProcess.onApply = function (effect) {
            if (!_this._scene.activeCamera) {
                return;
            }
            effect.setTextureFromPostProcess("otherSampler", _this._currentDepthOfFieldSource);
            effect.setTexture("lensDirtSampler", _this.lensFlareDirtTexture);
            effect.setTexture("lensStarSampler", _this.lensStarTexture);
            // Lens start rotation matrix
            var camerax = _this._scene.activeCamera.getViewMatrix().getRow(0);
            var cameraz = _this._scene.activeCamera.getViewMatrix().getRow(2);
            var camRot = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(camerax.toVector3(), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](1.0, 0.0, 0.0)) + _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Dot(cameraz.toVector3(), new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"](0.0, 0.0, 1.0));
            camRot *= 4.0;
            var starRotation = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].FromValues(Math.cos(camRot) * 0.5, -Math.sin(camRot), 0.0, 0.0, Math.sin(camRot), Math.cos(camRot) * 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
            var lensStarMatrix = scaleBias2.multiply(starRotation).multiply(scaleBias1);
            effect.setMatrix("lensStarMatrix", lensStarMatrix);
            _this._currentDepthOfFieldSource = _this.lensFlareFinalPostProcess;
        };
    };
    // Create depth-of-field post-process
    StandardRenderingPipeline.prototype._createDepthOfFieldPostProcess = function (scene, ratio) {
        var _this = this;
        this.depthOfFieldPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRDepthOfField", "standard", ["distance"], ["otherSampler", "depthSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define DEPTH_OF_FIELD", _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this.depthOfFieldPostProcess.onApply = function (effect) {
            effect.setTextureFromPostProcess("otherSampler", _this._currentDepthOfFieldSource);
            effect.setTexture("depthSampler", _this._getDepthTexture());
            effect.setFloat("distance", _this.depthOfFieldDistance);
        };
        // Add to pipeline
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRDepthOfField", function () { return _this.depthOfFieldPostProcess; }, true));
    };
    // Create motion blur post-process
    StandardRenderingPipeline.prototype._createMotionBlurPostProcess = function (scene, ratio) {
        var _this = this;
        if (this._isObjectBasedMotionBlur) {
            var mb = new _motionBlurPostProcess__WEBPACK_IMPORTED_MODULE_13__["MotionBlurPostProcess"]("HDRMotionBlur", scene, ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            mb.motionStrength = this.motionStrength;
            mb.motionBlurSamples = this.motionBlurSamples;
            this.motionBlurPostProcess = mb;
        }
        else {
            this.motionBlurPostProcess = new _PostProcesses_postProcess__WEBPACK_IMPORTED_MODULE_6__["PostProcess"]("HDRMotionBlur", "standard", ["inverseViewProjection", "prevViewProjection", "screenSize", "motionScale", "motionStrength"], ["depthSampler"], ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_5__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define MOTION_BLUR\n#define MAX_MOTION_SAMPLES " + this.motionBlurSamples.toFixed(1), _Engines_constants__WEBPACK_IMPORTED_MODULE_11__["Constants"].TEXTURETYPE_UNSIGNED_INT);
            var motionScale = 0;
            var prevViewProjection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
            var invViewProjection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
            var viewProjection = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
            var screenSize = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
            this.motionBlurPostProcess.onApply = function (effect) {
                viewProjection = scene.getProjectionMatrix().multiply(scene.getViewMatrix());
                viewProjection.invertToRef(invViewProjection);
                effect.setMatrix("inverseViewProjection", invViewProjection);
                effect.setMatrix("prevViewProjection", prevViewProjection);
                prevViewProjection = viewProjection;
                screenSize.x = _this.motionBlurPostProcess.width;
                screenSize.y = _this.motionBlurPostProcess.height;
                effect.setVector2("screenSize", screenSize);
                motionScale = scene.getEngine().getFps() / 60.0;
                effect.setFloat("motionScale", motionScale);
                effect.setFloat("motionStrength", _this.motionStrength);
                effect.setTexture("depthSampler", _this._getDepthTexture());
            };
        }
        this.addEffect(new _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_8__["PostProcessRenderEffect"](scene.getEngine(), "HDRMotionBlur", function () { return _this.motionBlurPostProcess; }, true));
    };
    StandardRenderingPipeline.prototype._getDepthTexture = function () {
        if (this._scene.getEngine().getCaps().drawBuffersExtension) {
            var renderer = this._scene.enableGeometryBufferRenderer();
            return renderer.getGBuffer().textures[0];
        }
        return this._scene.enableDepthRenderer().getDepthMap();
    };
    StandardRenderingPipeline.prototype._disposePostProcesses = function () {
        for (var i = 0; i < this._cameras.length; i++) {
            var camera = this._cameras[i];
            if (this.originalPostProcess) {
                this.originalPostProcess.dispose(camera);
            }
            if (this.downSampleX4PostProcess) {
                this.downSampleX4PostProcess.dispose(camera);
            }
            if (this.brightPassPostProcess) {
                this.brightPassPostProcess.dispose(camera);
            }
            if (this.textureAdderPostProcess) {
                this.textureAdderPostProcess.dispose(camera);
            }
            if (this.textureAdderFinalPostProcess) {
                this.textureAdderFinalPostProcess.dispose(camera);
            }
            if (this.volumetricLightPostProcess) {
                this.volumetricLightPostProcess.dispose(camera);
            }
            if (this.volumetricLightSmoothXPostProcess) {
                this.volumetricLightSmoothXPostProcess.dispose(camera);
            }
            if (this.volumetricLightSmoothYPostProcess) {
                this.volumetricLightSmoothYPostProcess.dispose(camera);
            }
            if (this.volumetricLightMergePostProces) {
                this.volumetricLightMergePostProces.dispose(camera);
            }
            if (this.volumetricLightFinalPostProcess) {
                this.volumetricLightFinalPostProcess.dispose(camera);
            }
            if (this.lensFlarePostProcess) {
                this.lensFlarePostProcess.dispose(camera);
            }
            if (this.lensFlareComposePostProcess) {
                this.lensFlareComposePostProcess.dispose(camera);
            }
            for (var j = 0; j < this.luminanceDownSamplePostProcesses.length; j++) {
                this.luminanceDownSamplePostProcesses[j].dispose(camera);
            }
            if (this.luminancePostProcess) {
                this.luminancePostProcess.dispose(camera);
            }
            if (this.hdrPostProcess) {
                this.hdrPostProcess.dispose(camera);
            }
            if (this.hdrFinalPostProcess) {
                this.hdrFinalPostProcess.dispose(camera);
            }
            if (this.depthOfFieldPostProcess) {
                this.depthOfFieldPostProcess.dispose(camera);
            }
            if (this.motionBlurPostProcess) {
                this.motionBlurPostProcess.dispose(camera);
            }
            if (this.fxaaPostProcess) {
                this.fxaaPostProcess.dispose(camera);
            }
            for (var j = 0; j < this.blurHPostProcesses.length; j++) {
                this.blurHPostProcesses[j].dispose(camera);
            }
            for (var j = 0; j < this.blurVPostProcesses.length; j++) {
                this.blurVPostProcesses[j].dispose(camera);
            }
        }
        this.originalPostProcess = null;
        this.downSampleX4PostProcess = null;
        this.brightPassPostProcess = null;
        this.textureAdderPostProcess = null;
        this.textureAdderFinalPostProcess = null;
        this.volumetricLightPostProcess = null;
        this.volumetricLightSmoothXPostProcess = null;
        this.volumetricLightSmoothYPostProcess = null;
        this.volumetricLightMergePostProces = null;
        this.volumetricLightFinalPostProcess = null;
        this.lensFlarePostProcess = null;
        this.lensFlareComposePostProcess = null;
        this.luminancePostProcess = null;
        this.hdrPostProcess = null;
        this.hdrFinalPostProcess = null;
        this.depthOfFieldPostProcess = null;
        this.motionBlurPostProcess = null;
        this.fxaaPostProcess = null;
        this.luminanceDownSamplePostProcesses = [];
        this.blurHPostProcesses = [];
        this.blurVPostProcesses = [];
    };
    /**
     * Dispose of the pipeline and stop all post processes
     */
    StandardRenderingPipeline.prototype.dispose = function () {
        this._disposePostProcesses();
        this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
        _super.prototype.dispose.call(this);
    };
    /**
     * Serialize the rendering pipeline (Used when exporting)
     * @returns the serialized object
     */
    StandardRenderingPipeline.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this);
        if (this.sourceLight) {
            serializationObject.sourceLightId = this.sourceLight.id;
        }
        serializationObject.customType = "StandardRenderingPipeline";
        return serializationObject;
    };
    /**
     * Parse the serialized pipeline
     * @param source Source pipeline.
     * @param scene The scene to load the pipeline to.
     * @param rootUrl The URL of the serialized pipeline.
     * @returns An instantiated pipeline from the serialized object.
     */
    StandardRenderingPipeline.Parse = function (source, scene, rootUrl) {
        var p = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return new StandardRenderingPipeline(source._name, scene, source._ratio); }, source, scene, rootUrl);
        if (source.sourceLightId) {
            p.sourceLight = scene.getLightByID(source.sourceLightId);
        }
        return p;
    };
    /**
     * Luminance steps
     */
    StandardRenderingPipeline.LuminanceSteps = 6;
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "brightThreshold", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "blurWidth", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "horizontalBlur", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "exposure", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("lensTexture")
    ], StandardRenderingPipeline.prototype, "lensTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "volumetricLightCoefficient", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "volumetricLightPower", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "volumetricLightBlurScale", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "hdrMinimumLuminance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "hdrDecreaseRate", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "hdrIncreaseRate", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "hdrAutoExposure", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("lensColorTexture")
    ], StandardRenderingPipeline.prototype, "lensColorTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "lensFlareStrength", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "lensFlareGhostDispersal", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "lensFlareHaloWidth", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "lensFlareDistortionStrength", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "lensFlareBlurWidth", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("lensStarTexture")
    ], StandardRenderingPipeline.prototype, "lensStarTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsTexture"])("lensFlareDirtTexture")
    ], StandardRenderingPipeline.prototype, "lensFlareDirtTexture", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "depthOfFieldDistance", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "depthOfFieldBlurWidth", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "motionStrength", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "objectBasedMotionBlur", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "_ratio", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "BloomEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "DepthOfFieldEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "LensFlareEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "HDREnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "VLSEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "MotionBlurEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "fxaaEnabled", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "volumetricLightStepsCount", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "motionBlurSamples", null);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], StandardRenderingPipeline.prototype, "samples", null);
    return StandardRenderingPipeline;
}(_PostProcesses_RenderPipeline_postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_7__["PostProcessRenderPipeline"]));

_Misc_typeStore__WEBPACK_IMPORTED_MODULE_12__["_TypeStore"].RegisteredTypes["BABYLON.StandardRenderingPipeline"] = StandardRenderingPipeline;


/***/ }),

/***/ "./PostProcesses/RenderPipeline/index.ts":
/*!***********************************************!*\
  !*** ./PostProcesses/RenderPipeline/index.ts ***!
  \***********************************************/
/*! exports provided: PostProcessRenderEffect, PostProcessRenderPipeline, PostProcessRenderPipelineManager, PostProcessRenderPipelineManagerSceneComponent, DefaultRenderingPipeline, LensRenderingPipeline, SSAO2RenderingPipeline, SSAORenderingPipeline, StandardRenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _Pipelines_index__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Pipelines/index */ "./PostProcesses/RenderPipeline/Pipelines/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultRenderingPipeline", function() { return _Pipelines_index__WEBPACK_IMPORTED_MODULE_0__["DefaultRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensRenderingPipeline", function() { return _Pipelines_index__WEBPACK_IMPORTED_MODULE_0__["LensRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAO2RenderingPipeline", function() { return _Pipelines_index__WEBPACK_IMPORTED_MODULE_0__["SSAO2RenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAORenderingPipeline", function() { return _Pipelines_index__WEBPACK_IMPORTED_MODULE_0__["SSAORenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardRenderingPipeline", function() { return _Pipelines_index__WEBPACK_IMPORTED_MODULE_0__["StandardRenderingPipeline"]; });

/* harmony import */ var _postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderEffect", function() { return _postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_1__["PostProcessRenderEffect"]; });

/* harmony import */ var _postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcessRenderPipeline */ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipeline", function() { return _postProcessRenderPipeline__WEBPACK_IMPORTED_MODULE_2__["PostProcessRenderPipeline"]; });

/* harmony import */ var _postProcessRenderPipelineManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./postProcessRenderPipelineManager */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManager", function() { return _postProcessRenderPipelineManager__WEBPACK_IMPORTED_MODULE_3__["PostProcessRenderPipelineManager"]; });

/* harmony import */ var _postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./postProcessRenderPipelineManagerSceneComponent */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManagerSceneComponent", function() { return _postProcessRenderPipelineManagerSceneComponent__WEBPACK_IMPORTED_MODULE_4__["PostProcessRenderPipelineManagerSceneComponent"]; });








/***/ }),

/***/ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts":
/*!*****************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/postProcessRenderEffect.ts ***!
  \*****************************************************************/
/*! exports provided: PostProcessRenderEffect */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderEffect", function() { return PostProcessRenderEffect; });
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");

/**
 * This represents a set of one or more post processes in Babylon.
 * A post process can be used to apply a shader to a texture after it is rendered.
 * @example https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
 */
var PostProcessRenderEffect = /** @class */ (function () {
    /**
     * Instantiates a post process render effect.
     * A post process can be used to apply a shader to a texture after it is rendered.
     * @param engine The engine the effect is tied to
     * @param name The name of the effect
     * @param getPostProcesses A function that returns a set of post processes which the effect will run in order to be run.
     * @param singleInstance False if this post process can be run on multiple cameras. (default: true)
     */
    function PostProcessRenderEffect(engine, name, getPostProcesses, singleInstance) {
        this._name = name;
        this._singleInstance = singleInstance || true;
        this._getPostProcesses = getPostProcesses;
        this._cameras = {};
        this._indicesForCamera = {};
        this._postProcesses = {};
    }
    Object.defineProperty(PostProcessRenderEffect.prototype, "isSupported", {
        /**
         * Checks if all the post processes in the effect are supported.
         */
        get: function () {
            for (var index in this._postProcesses) {
                if (this._postProcesses.hasOwnProperty(index)) {
                    var pps = this._postProcesses[index];
                    for (var ppIndex = 0; ppIndex < pps.length; ppIndex++) {
                        if (!pps[ppIndex].isSupported) {
                            return false;
                        }
                    }
                }
            }
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Updates the current state of the effect
     * @hidden
     */
    PostProcessRenderEffect.prototype._update = function () {
    };
    /**
     * Attaches the effect on cameras
     * @param cameras The camera to attach to.
     * @hidden
     */
    PostProcessRenderEffect.prototype._attachCameras = function (cameras) {
        var _this = this;
        var cameraKey;
        var cams = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].MakeArray(cameras || this._cameras);
        if (!cams) {
            return;
        }
        for (var i = 0; i < cams.length; i++) {
            var camera = cams[i];
            var cameraName = camera.name;
            if (this._singleInstance) {
                cameraKey = 0;
            }
            else {
                cameraKey = cameraName;
            }
            if (!this._postProcesses[cameraKey]) {
                var postProcess = this._getPostProcesses();
                if (postProcess) {
                    this._postProcesses[cameraKey] = Array.isArray(postProcess) ? postProcess : [postProcess];
                }
            }
            if (!this._indicesForCamera[cameraName]) {
                this._indicesForCamera[cameraName] = [];
            }
            this._postProcesses[cameraKey].forEach(function (postProcess) {
                var index = camera.attachPostProcess(postProcess);
                _this._indicesForCamera[cameraName].push(index);
            });
            if (!this._cameras[cameraName]) {
                this._cameras[cameraName] = camera;
            }
        }
    };
    /**
     * Detatches the effect on cameras
     * @param cameras The camera to detatch from.
     * @hidden
     */
    PostProcessRenderEffect.prototype._detachCameras = function (cameras) {
        var cams = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].MakeArray(cameras || this._cameras);
        if (!cams) {
            return;
        }
        for (var i = 0; i < cams.length; i++) {
            var camera = cams[i];
            var cameraName = camera.name;
            var postProcesses = this._postProcesses[this._singleInstance ? 0 : cameraName];
            if (postProcesses) {
                postProcesses.forEach(function (postProcess) {
                    camera.detachPostProcess(postProcess);
                });
            }
            if (this._cameras[cameraName]) {
                this._cameras[cameraName] = null;
            }
        }
    };
    /**
     * Enables the effect on given cameras
     * @param cameras The camera to enable.
     * @hidden
     */
    PostProcessRenderEffect.prototype._enable = function (cameras) {
        var _this = this;
        var cams = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].MakeArray(cameras || this._cameras);
        if (!cams) {
            return;
        }
        for (var i = 0; i < cams.length; i++) {
            var camera = cams[i];
            var cameraName = camera.name;
            for (var j = 0; j < this._indicesForCamera[cameraName].length; j++) {
                if (camera._postProcesses[this._indicesForCamera[cameraName][j]] === undefined || camera._postProcesses[this._indicesForCamera[cameraName][j]] === null) {
                    this._postProcesses[this._singleInstance ? 0 : cameraName].forEach(function (postProcess) {
                        cams[i].attachPostProcess(postProcess, _this._indicesForCamera[cameraName][j]);
                    });
                }
            }
        }
    };
    /**
     * Disables the effect on the given cameras
     * @param cameras The camera to disable.
     * @hidden
     */
    PostProcessRenderEffect.prototype._disable = function (cameras) {
        var cams = _Misc_tools__WEBPACK_IMPORTED_MODULE_0__["Tools"].MakeArray(cameras || this._cameras);
        if (!cams) {
            return;
        }
        for (var i = 0; i < cams.length; i++) {
            var camera = cams[i];
            var cameraName = camera.name;
            this._postProcesses[this._singleInstance ? 0 : cameraName].forEach(function (postProcess) {
                camera.detachPostProcess(postProcess);
            });
        }
    };
    /**
     * Gets a list of the post processes contained in the effect.
     * @param camera The camera to get the post processes on.
     * @returns The list of the post processes in the effect.
     */
    PostProcessRenderEffect.prototype.getPostProcesses = function (camera) {
        if (this._singleInstance) {
            return this._postProcesses[0];
        }
        else {
            if (!camera) {
                return null;
            }
            return this._postProcesses[camera.name];
        }
    };
    return PostProcessRenderEffect;
}());



/***/ }),

/***/ "./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts":
/*!*******************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/postProcessRenderPipeline.ts ***!
  \*******************************************************************/
/*! exports provided: PostProcessRenderPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipeline", function() { return PostProcessRenderPipeline; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../Misc/decorators */ "./Misc/decorators.ts");



/**
 * PostProcessRenderPipeline
 * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
 */
var PostProcessRenderPipeline = /** @class */ (function () {
    /**
     * Initializes a PostProcessRenderPipeline
     * @param engine engine to add the pipeline to
     * @param name name of the pipeline
     */
    function PostProcessRenderPipeline(engine, name) {
        this.engine = engine;
        this._name = name;
        this._renderEffects = {};
        this._renderEffectsForIsolatedPass = new Array();
        this._cameras = [];
    }
    Object.defineProperty(PostProcessRenderPipeline.prototype, "name", {
        /**
         * Gets pipeline name
         */
        get: function () {
            return this._name;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the class name
     * @returns "PostProcessRenderPipeline"
     */
    PostProcessRenderPipeline.prototype.getClassName = function () {
        return "PostProcessRenderPipeline";
    };
    Object.defineProperty(PostProcessRenderPipeline.prototype, "isSupported", {
        /**
         * If all the render effects in the pipeline are supported
         */
        get: function () {
            for (var renderEffectName in this._renderEffects) {
                if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                    if (!this._renderEffects[renderEffectName].isSupported) {
                        return false;
                    }
                }
            }
            return true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Adds an effect to the pipeline
     * @param renderEffect the effect to add
     */
    PostProcessRenderPipeline.prototype.addEffect = function (renderEffect) {
        this._renderEffects[renderEffect._name] = renderEffect;
    };
    // private
    /** @hidden */
    PostProcessRenderPipeline.prototype._rebuild = function () {
    };
    /** @hidden */
    PostProcessRenderPipeline.prototype._enableEffect = function (renderEffectName, cameras) {
        var renderEffects = this._renderEffects[renderEffectName];
        if (!renderEffects) {
            return;
        }
        renderEffects._enable(_Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].MakeArray(cameras || this._cameras));
    };
    /** @hidden */
    PostProcessRenderPipeline.prototype._disableEffect = function (renderEffectName, cameras) {
        var renderEffects = this._renderEffects[renderEffectName];
        if (!renderEffects) {
            return;
        }
        renderEffects._disable(_Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].MakeArray(cameras || this._cameras));
    };
    /** @hidden */
    PostProcessRenderPipeline.prototype._attachCameras = function (cameras, unique) {
        var cams = _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].MakeArray(cameras || this._cameras);
        if (!cams) {
            return;
        }
        var indicesToDelete = [];
        var i;
        for (i = 0; i < cams.length; i++) {
            var camera = cams[i];
            var cameraName = camera.name;
            if (this._cameras.indexOf(camera) === -1) {
                this._cameras[cameraName] = camera;
            }
            else if (unique) {
                indicesToDelete.push(i);
            }
        }
        for (i = 0; i < indicesToDelete.length; i++) {
            cameras.splice(indicesToDelete[i], 1);
        }
        for (var renderEffectName in this._renderEffects) {
            if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                this._renderEffects[renderEffectName]._attachCameras(cams);
            }
        }
    };
    /** @hidden */
    PostProcessRenderPipeline.prototype._detachCameras = function (cameras) {
        var cams = _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].MakeArray(cameras || this._cameras);
        if (!cams) {
            return;
        }
        for (var renderEffectName in this._renderEffects) {
            if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                this._renderEffects[renderEffectName]._detachCameras(cams);
            }
        }
        for (var i = 0; i < cams.length; i++) {
            this._cameras.splice(this._cameras.indexOf(cams[i]), 1);
        }
    };
    /** @hidden */
    PostProcessRenderPipeline.prototype._update = function () {
        for (var renderEffectName in this._renderEffects) {
            if (this._renderEffects.hasOwnProperty(renderEffectName)) {
                this._renderEffects[renderEffectName]._update();
            }
        }
        for (var i = 0; i < this._cameras.length; i++) {
            var cameraName = this._cameras[i].name;
            if (this._renderEffectsForIsolatedPass[cameraName]) {
                this._renderEffectsForIsolatedPass[cameraName]._update();
            }
        }
    };
    /** @hidden */
    PostProcessRenderPipeline.prototype._reset = function () {
        this._renderEffects = {};
        this._renderEffectsForIsolatedPass = new Array();
    };
    PostProcessRenderPipeline.prototype._enableMSAAOnFirstPostProcess = function (sampleCount) {
        if (this.engine.webGLVersion === 1) {
            return false;
        }
        // Set samples of the very first post process to 4 to enable native anti-aliasing in browsers that support webGL 2.0 (See: https://github.com/BabylonJS/Babylon.js/issues/3754)
        var effectKeys = Object.keys(this._renderEffects);
        if (effectKeys.length > 0) {
            var postProcesses = this._renderEffects[effectKeys[0]].getPostProcesses();
            if (postProcesses) {
                postProcesses[0].samples = sampleCount;
            }
        }
        return true;
    };
    /**
     * Disposes of the pipeline
     */
    PostProcessRenderPipeline.prototype.dispose = function () {
        // Must be implemented by children
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], PostProcessRenderPipeline.prototype, "_name", void 0);
    return PostProcessRenderPipeline;
}());



/***/ }),

/***/ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManager.ts":
/*!**************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/postProcessRenderPipelineManager.ts ***!
  \**************************************************************************/
/*! exports provided: PostProcessRenderPipelineManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManager", function() { return PostProcessRenderPipelineManager; });
/**
 * PostProcessRenderPipelineManager class
 * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
 */
var PostProcessRenderPipelineManager = /** @class */ (function () {
    /**
     * Initializes a PostProcessRenderPipelineManager
     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocessrenderpipeline
     */
    function PostProcessRenderPipelineManager() {
        this._renderPipelines = {};
    }
    Object.defineProperty(PostProcessRenderPipelineManager.prototype, "supportedPipelines", {
        /**
         * Gets the list of supported render pipelines
         */
        get: function () {
            var result = [];
            for (var renderPipelineName in this._renderPipelines) {
                if (this._renderPipelines.hasOwnProperty(renderPipelineName)) {
                    var pipeline = this._renderPipelines[renderPipelineName];
                    if (pipeline.isSupported) {
                        result.push(pipeline);
                    }
                }
            }
            return result;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Adds a pipeline to the manager
     * @param renderPipeline The pipeline to add
     */
    PostProcessRenderPipelineManager.prototype.addPipeline = function (renderPipeline) {
        this._renderPipelines[renderPipeline._name] = renderPipeline;
    };
    /**
     * Attaches a camera to the pipeline
     * @param renderPipelineName The name of the pipeline to attach to
     * @param cameras the camera to attach
     * @param unique if the camera can be attached multiple times to the pipeline
     */
    PostProcessRenderPipelineManager.prototype.attachCamerasToRenderPipeline = function (renderPipelineName, cameras, unique) {
        if (unique === void 0) { unique = false; }
        var renderPipeline = this._renderPipelines[renderPipelineName];
        if (!renderPipeline) {
            return;
        }
        renderPipeline._attachCameras(cameras, unique);
    };
    /**
     * Detaches a camera from the pipeline
     * @param renderPipelineName The name of the pipeline to detach from
     * @param cameras the camera to detach
     */
    PostProcessRenderPipelineManager.prototype.detachCamerasFromRenderPipeline = function (renderPipelineName, cameras) {
        var renderPipeline = this._renderPipelines[renderPipelineName];
        if (!renderPipeline) {
            return;
        }
        renderPipeline._detachCameras(cameras);
    };
    /**
     * Enables an effect by name on a pipeline
     * @param renderPipelineName the name of the pipeline to enable the effect in
     * @param renderEffectName the name of the effect to enable
     * @param cameras the cameras that the effect should be enabled on
     */
    PostProcessRenderPipelineManager.prototype.enableEffectInPipeline = function (renderPipelineName, renderEffectName, cameras) {
        var renderPipeline = this._renderPipelines[renderPipelineName];
        if (!renderPipeline) {
            return;
        }
        renderPipeline._enableEffect(renderEffectName, cameras);
    };
    /**
     * Disables an effect by name on a pipeline
     * @param renderPipelineName the name of the pipeline to disable the effect in
     * @param renderEffectName the name of the effect to disable
     * @param cameras the cameras that the effect should be disabled on
     */
    PostProcessRenderPipelineManager.prototype.disableEffectInPipeline = function (renderPipelineName, renderEffectName, cameras) {
        var renderPipeline = this._renderPipelines[renderPipelineName];
        if (!renderPipeline) {
            return;
        }
        renderPipeline._disableEffect(renderEffectName, cameras);
    };
    /**
     * Updates the state of all contained render pipelines and disposes of any non supported pipelines
     */
    PostProcessRenderPipelineManager.prototype.update = function () {
        for (var renderPipelineName in this._renderPipelines) {
            if (this._renderPipelines.hasOwnProperty(renderPipelineName)) {
                var pipeline = this._renderPipelines[renderPipelineName];
                if (!pipeline.isSupported) {
                    pipeline.dispose();
                    delete this._renderPipelines[renderPipelineName];
                }
                else {
                    pipeline._update();
                }
            }
        }
    };
    /** @hidden */
    PostProcessRenderPipelineManager.prototype._rebuild = function () {
        for (var renderPipelineName in this._renderPipelines) {
            if (this._renderPipelines.hasOwnProperty(renderPipelineName)) {
                var pipeline = this._renderPipelines[renderPipelineName];
                pipeline._rebuild();
            }
        }
    };
    /**
     * Disposes of the manager and pipelines
     */
    PostProcessRenderPipelineManager.prototype.dispose = function () {
        for (var renderPipelineName in this._renderPipelines) {
            if (this._renderPipelines.hasOwnProperty(renderPipelineName)) {
                var pipeline = this._renderPipelines[renderPipelineName];
                pipeline.dispose();
            }
        }
    };
    return PostProcessRenderPipelineManager;
}());



/***/ }),

/***/ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts":
/*!****************************************************************************************!*\
  !*** ./PostProcesses/RenderPipeline/postProcessRenderPipelineManagerSceneComponent.ts ***!
  \****************************************************************************************/
/*! exports provided: PostProcessRenderPipelineManagerSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManagerSceneComponent", function() { return PostProcessRenderPipelineManagerSceneComponent; });
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _postProcessRenderPipelineManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcessRenderPipelineManager */ "./PostProcesses/RenderPipeline/postProcessRenderPipelineManager.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../scene */ "./scene.ts");



Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype, "postProcessRenderPipelineManager", {
    get: function () {
        if (!this._postProcessRenderPipelineManager) {
            // Register the G Buffer component to the scene.
            var component = this._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].NAME_POSTPROCESSRENDERPIPELINEMANAGER);
            if (!component) {
                component = new PostProcessRenderPipelineManagerSceneComponent(this);
                this._addComponent(component);
            }
            this._postProcessRenderPipelineManager = new _postProcessRenderPipelineManager__WEBPACK_IMPORTED_MODULE_1__["PostProcessRenderPipelineManager"]();
        }
        return this._postProcessRenderPipelineManager;
    },
    enumerable: true,
    configurable: true
});
/**
 * Defines the Render Pipeline scene component responsible to rendering pipelines
 */
var PostProcessRenderPipelineManagerSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function PostProcessRenderPipelineManagerSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].NAME_POSTPROCESSRENDERPIPELINEMANAGER;
        this.scene = scene;
    }
    /**
     * Registers the component in a given scene
     */
    PostProcessRenderPipelineManagerSceneComponent.prototype.register = function () {
        this.scene._gatherRenderTargetsStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_0__["SceneComponentConstants"].STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER, this, this._gatherRenderTargets);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    PostProcessRenderPipelineManagerSceneComponent.prototype.rebuild = function () {
        if (this.scene._postProcessRenderPipelineManager) {
            this.scene._postProcessRenderPipelineManager._rebuild();
        }
    };
    /**
     * Disposes the component and the associated ressources
     */
    PostProcessRenderPipelineManagerSceneComponent.prototype.dispose = function () {
        if (this.scene._postProcessRenderPipelineManager) {
            this.scene._postProcessRenderPipelineManager.dispose();
        }
    };
    PostProcessRenderPipelineManagerSceneComponent.prototype._gatherRenderTargets = function () {
        if (this.scene._postProcessRenderPipelineManager) {
            this.scene._postProcessRenderPipelineManager.update();
        }
    };
    return PostProcessRenderPipelineManagerSceneComponent;
}());



/***/ }),

/***/ "./PostProcesses/anaglyphPostProcess.ts":
/*!**********************************************!*\
  !*** ./PostProcesses/anaglyphPostProcess.ts ***!
  \**********************************************/
/*! exports provided: AnaglyphPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AnaglyphPostProcess", function() { return AnaglyphPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_anaglyph_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Shaders/anaglyph.fragment */ "./Shaders/anaglyph.fragment.ts");



/**
 * Postprocess used to generate anaglyphic rendering
 */
var AnaglyphPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AnaglyphPostProcess, _super);
    /**
     * Creates a new AnaglyphPostProcess
     * @param name defines postprocess name
     * @param options defines creation options or target ratio scale
     * @param rigCameras defines cameras using this postprocess
     * @param samplingMode defines required sampling mode (BABYLON.Texture.NEAREST_SAMPLINGMODE by default)
     * @param engine defines hosting engine
     * @param reusable defines if the postprocess will be reused multiple times per frame
     */
    function AnaglyphPostProcess(name, options, rigCameras, samplingMode, engine, reusable) {
        var _this = _super.call(this, name, "anaglyph", null, ["leftSampler"], options, rigCameras[1], samplingMode, engine, reusable) || this;
        _this._passedProcess = rigCameras[0]._rigPostProcess;
        _this.onApplyObservable.add(function (effect) {
            effect.setTextureFromPostProcess("leftSampler", _this._passedProcess);
        });
        return _this;
    }
    return AnaglyphPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/blackAndWhitePostProcess.ts":
/*!***************************************************!*\
  !*** ./PostProcesses/blackAndWhitePostProcess.ts ***!
  \***************************************************/
/*! exports provided: BlackAndWhitePostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BlackAndWhitePostProcess", function() { return BlackAndWhitePostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_blackAndWhite_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Shaders/blackAndWhite.fragment */ "./Shaders/blackAndWhite.fragment.ts");



/**
 * Post process used to render in black and white
 */
var BlackAndWhitePostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BlackAndWhitePostProcess, _super);
    /**
     * Creates a black and white post process
     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#black-and-white
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     */
    function BlackAndWhitePostProcess(name, options, camera, samplingMode, engine, reusable) {
        var _this = _super.call(this, name, "blackAndWhite", ["degree"], null, options, camera, samplingMode, engine, reusable) || this;
        /**
         * Linear about to convert he result to black and white (default: 1)
         */
        _this.degree = 1;
        _this.onApplyObservable.add(function (effect) {
            effect.setFloat("degree", _this.degree);
        });
        return _this;
    }
    return BlackAndWhitePostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/bloomEffect.ts":
/*!**************************************!*\
  !*** ./PostProcesses/bloomEffect.ts ***!
  \**************************************/
/*! exports provided: BloomEffect */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BloomEffect", function() { return BloomEffect; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _extractHighlightsPostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./extractHighlightsPostProcess */ "./PostProcesses/extractHighlightsPostProcess.ts");
/* harmony import */ var _blurPostProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _bloomMergePostProcess__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./bloomMergePostProcess */ "./PostProcesses/bloomMergePostProcess.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");







/**
 * The bloom effect spreads bright areas of an image to simulate artifacts seen in cameras
 */
var BloomEffect = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BloomEffect, _super);
    /**
     * Creates a new instance of @see BloomEffect
     * @param scene The scene the effect belongs to.
     * @param bloomScale The ratio of the blur texture to the input texture that should be used to compute the bloom.
     * @param bloomKernel The size of the kernel to be used when applying the blur.
     * @param bloomWeight The the strength of bloom.
     * @param pipelineTextureType The type of texture to be used when performing the post processing.
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function BloomEffect(scene, bloomScale, bloomWeight, bloomKernel, pipelineTextureType, blockCompilation) {
        if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, scene.getEngine(), "bloom", function () {
            return _this._effects;
        }, true) || this;
        _this.bloomScale = bloomScale;
        /**
         * @hidden Internal
         */
        _this._effects = [];
        _this._downscale = new _extractHighlightsPostProcess__WEBPACK_IMPORTED_MODULE_2__["ExtractHighlightsPostProcess"]("highlights", 1.0, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
        _this._blurX = new _blurPostProcess__WEBPACK_IMPORTED_MODULE_3__["BlurPostProcess"]("horizontal blur", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"](1.0, 0), 10.0, bloomScale, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
        _this._blurX.alwaysForcePOT = true;
        _this._blurX.autoClear = false;
        _this._blurY = new _blurPostProcess__WEBPACK_IMPORTED_MODULE_3__["BlurPostProcess"]("vertical blur", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector2"](0, 1.0), 10.0, bloomScale, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, undefined, blockCompilation);
        _this._blurY.alwaysForcePOT = true;
        _this._blurY.autoClear = false;
        _this.kernel = bloomKernel;
        _this._effects = [_this._downscale, _this._blurX, _this._blurY];
        _this._merge = new _bloomMergePostProcess__WEBPACK_IMPORTED_MODULE_4__["BloomMergePostProcess"]("bloomMerge", _this._downscale, _this._blurY, bloomWeight, bloomScale, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
        _this._merge.autoClear = false;
        _this._effects.push(_this._merge);
        return _this;
    }
    Object.defineProperty(BloomEffect.prototype, "threshold", {
        /**
         * The luminance threshold to find bright areas of the image to bloom.
         */
        get: function () {
            return this._downscale.threshold;
        },
        set: function (value) {
            this._downscale.threshold = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BloomEffect.prototype, "weight", {
        /**
         * The strength of the bloom.
         */
        get: function () {
            return this._merge.weight;
        },
        set: function (value) {
            this._merge.weight = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BloomEffect.prototype, "kernel", {
        /**
         * Specifies the size of the bloom blur kernel, relative to the final output size
         */
        get: function () {
            return this._blurX.kernel / this.bloomScale;
        },
        set: function (value) {
            this._blurX.kernel = value * this.bloomScale;
            this._blurY.kernel = value * this.bloomScale;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes each of the internal effects for a given camera.
     * @param camera The camera to dispose the effect on.
     */
    BloomEffect.prototype.disposeEffects = function (camera) {
        for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
            this._effects[effectIndex].dispose(camera);
        }
    };
    /**
     * @hidden Internal
     */
    BloomEffect.prototype._updateEffects = function () {
        for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
            this._effects[effectIndex].updateEffect();
        }
    };
    /**
     * Internal
     * @returns if all the contained post processes are ready.
     * @hidden
     */
    BloomEffect.prototype._isReady = function () {
        for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
            if (!this._effects[effectIndex].isReady()) {
                return false;
            }
        }
        return true;
    };
    return BloomEffect;
}(_PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_1__["PostProcessRenderEffect"]));



/***/ }),

/***/ "./PostProcesses/bloomMergePostProcess.ts":
/*!************************************************!*\
  !*** ./PostProcesses/bloomMergePostProcess.ts ***!
  \************************************************/
/*! exports provided: BloomMergePostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BloomMergePostProcess", function() { return BloomMergePostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_bloomMerge_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/bloomMerge.fragment */ "./Shaders/bloomMerge.fragment.ts");




/**
 * The BloomMergePostProcess merges blurred images with the original based on the values of the circle of confusion.
 */
var BloomMergePostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BloomMergePostProcess, _super);
    /**
     * Creates a new instance of @see BloomMergePostProcess
     * @param name The name of the effect.
     * @param originalFromInput Post process which's input will be used for the merge.
     * @param blurred Blurred highlights post process which's output will be used.
     * @param weight Weight of the bloom to be added to the original input.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function BloomMergePostProcess(name, originalFromInput, blurred,
    /** Weight of the bloom to be added to the original input. */
    weight, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "bloomMerge", ["bloomWeight"], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2", "bloomBlur"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true) || this;
        _this.weight = weight;
        _this.onApplyObservable.add(function (effect) {
            effect.setTextureFromPostProcess("textureSampler", originalFromInput);
            effect.setTextureFromPostProcessOutput("bloomBlur", blurred);
            effect.setFloat("bloomWeight", _this.weight);
        });
        if (!blockCompilation) {
            _this.updateEffect();
        }
        return _this;
    }
    return BloomMergePostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/blurPostProcess.ts":
/*!******************************************!*\
  !*** ./PostProcesses/blurPostProcess.ts ***!
  \******************************************/
/*! exports provided: BlurPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BlurPostProcess", function() { return BlurPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_kernelBlur_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/kernelBlur.fragment */ "./Shaders/kernelBlur.fragment.ts");
/* harmony import */ var _Shaders_kernelBlur_vertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Shaders/kernelBlur.vertex */ "./Shaders/kernelBlur.vertex.ts");






/**
 * The Blur Post Process which blurs an image based on a kernel and direction.
 * Can be used twice in x and y directions to perform a guassian blur in two passes.
 */
var BlurPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BlurPostProcess, _super);
    /**
     * Creates a new instance BlurPostProcess
     * @param name The name of the effect.
     * @param direction The direction in which to blur the image.
     * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
     * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function BlurPostProcess(name,
    /** The direction in which to blur the image. */
    direction, kernel, options, camera, samplingMode, engine, reusable, textureType, defines, blockCompilation) {
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (defines === void 0) { defines = ""; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["circleOfConfusionSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", { varyingCount: 0, depCount: 0 }, true) || this;
        _this.direction = direction;
        _this.blockCompilation = blockCompilation;
        _this._packedFloat = false;
        _this._staticDefines = "";
        _this._staticDefines = defines;
        _this.onApplyObservable.add(function (effect) {
            if (_this._outputTexture) {
                effect.setFloat2('delta', (1 / _this._outputTexture.width) * _this.direction.x, (1 / _this._outputTexture.height) * _this.direction.y);
            }
            else {
                effect.setFloat2('delta', (1 / _this.width) * _this.direction.x, (1 / _this.height) * _this.direction.y);
            }
        });
        _this.kernel = kernel;
        return _this;
    }
    Object.defineProperty(BlurPostProcess.prototype, "kernel", {
        /**
         * Gets the length in pixels of the blur sample region
         */
        get: function () {
            return this._idealKernel;
        },
        /**
         * Sets the length in pixels of the blur sample region
         */
        set: function (v) {
            if (this._idealKernel === v) {
                return;
            }
            v = Math.max(v, 1);
            this._idealKernel = v;
            this._kernel = this._nearestBestKernel(v);
            if (!this.blockCompilation) {
                this._updateParameters();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(BlurPostProcess.prototype, "packedFloat", {
        /**
         * Gets wether or not the blur is unpacking/repacking floats
         */
        get: function () {
            return this._packedFloat;
        },
        /**
         * Sets wether or not the blur needs to unpack/repack floats
         */
        set: function (v) {
            if (this._packedFloat === v) {
                return;
            }
            this._packedFloat = v;
            if (!this.blockCompilation) {
                this._updateParameters();
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Updates the effect with the current post process compile time values and recompiles the shader.
     * @param defines Define statements that should be added at the beginning of the shader. (default: null)
     * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
     * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
     * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
     * @param onCompiled Called when the shader has been compiled.
     * @param onError Called if there is an error when compiling a shader.
     */
    BlurPostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
        if (defines === void 0) { defines = null; }
        if (uniforms === void 0) { uniforms = null; }
        if (samplers === void 0) { samplers = null; }
        this._updateParameters(onCompiled, onError);
    };
    BlurPostProcess.prototype._updateParameters = function (onCompiled, onError) {
        // Generate sampling offsets and weights
        var N = this._kernel;
        var centerIndex = (N - 1) / 2;
        // Generate Gaussian sampling weights over kernel
        var offsets = [];
        var weights = [];
        var totalWeight = 0;
        for (var i = 0; i < N; i++) {
            var u = i / (N - 1);
            var w = this._gaussianWeight(u * 2.0 - 1);
            offsets[i] = (i - centerIndex);
            weights[i] = w;
            totalWeight += w;
        }
        // Normalize weights
        for (var i = 0; i < weights.length; i++) {
            weights[i] /= totalWeight;
        }
        // Optimize: combine samples to take advantage of hardware linear sampling
        // Walk from left to center, combining pairs (symmetrically)
        var linearSamplingWeights = [];
        var linearSamplingOffsets = [];
        var linearSamplingMap = [];
        for (var i = 0; i <= centerIndex; i += 2) {
            var j = Math.min(i + 1, Math.floor(centerIndex));
            var singleCenterSample = i === j;
            if (singleCenterSample) {
                linearSamplingMap.push({ o: offsets[i], w: weights[i] });
            }
            else {
                var sharedCell = j === centerIndex;
                var weightLinear = (weights[i] + weights[j] * (sharedCell ? .5 : 1.));
                var offsetLinear = offsets[i] + 1 / (1 + weights[i] / weights[j]);
                if (offsetLinear === 0) {
                    linearSamplingMap.push({ o: offsets[i], w: weights[i] });
                    linearSamplingMap.push({ o: offsets[i + 1], w: weights[i + 1] });
                }
                else {
                    linearSamplingMap.push({ o: offsetLinear, w: weightLinear });
                    linearSamplingMap.push({ o: -offsetLinear, w: weightLinear });
                }
            }
        }
        for (var i = 0; i < linearSamplingMap.length; i++) {
            linearSamplingOffsets[i] = linearSamplingMap[i].o;
            linearSamplingWeights[i] = linearSamplingMap[i].w;
        }
        // Replace with optimized
        offsets = linearSamplingOffsets;
        weights = linearSamplingWeights;
        // Generate shaders
        var maxVaryingRows = this.getEngine().getCaps().maxVaryingVectors;
        var freeVaryingVec2 = Math.max(maxVaryingRows, 0.) - 1; // Because of sampleCenter
        var varyingCount = Math.min(offsets.length, freeVaryingVec2);
        var defines = "";
        defines += this._staticDefines;
        // The DOF fragment should ignore the center pixel when looping as it is handled manualy in the fragment shader.
        if (this._staticDefines.indexOf("DOF") != -1) {
            defines += "#define CENTER_WEIGHT " + this._glslFloat(weights[varyingCount - 1]) + "\r\n";
            varyingCount--;
        }
        for (var i = 0; i < varyingCount; i++) {
            defines += "#define KERNEL_OFFSET" + i + " " + this._glslFloat(offsets[i]) + "\r\n";
            defines += "#define KERNEL_WEIGHT" + i + " " + this._glslFloat(weights[i]) + "\r\n";
        }
        var depCount = 0;
        for (var i = freeVaryingVec2; i < offsets.length; i++) {
            defines += "#define KERNEL_DEP_OFFSET" + depCount + " " + this._glslFloat(offsets[i]) + "\r\n";
            defines += "#define KERNEL_DEP_WEIGHT" + depCount + " " + this._glslFloat(weights[i]) + "\r\n";
            depCount++;
        }
        if (this.packedFloat) {
            defines += "#define PACKEDFLOAT 1";
        }
        this.blockCompilation = false;
        _super.prototype.updateEffect.call(this, defines, null, null, {
            varyingCount: varyingCount,
            depCount: depCount
        }, onCompiled, onError);
    };
    /**
     * Best kernels are odd numbers that when divided by 2, their integer part is even, so 5, 9 or 13.
     * Other odd kernels optimize correctly but require proportionally more samples, even kernels are
     * possible but will produce minor visual artifacts. Since each new kernel requires a new shader we
     * want to minimize kernel changes, having gaps between physical kernels is helpful in that regard.
     * The gaps between physical kernels are compensated for in the weighting of the samples
     * @param idealKernel Ideal blur kernel.
     * @return Nearest best kernel.
     */
    BlurPostProcess.prototype._nearestBestKernel = function (idealKernel) {
        var v = Math.round(idealKernel);
        for (var _i = 0, _a = [v, v - 1, v + 1, v - 2, v + 2]; _i < _a.length; _i++) {
            var k = _a[_i];
            if (((k % 2) !== 0) && ((Math.floor(k / 2) % 2) === 0) && k > 0) {
                return Math.max(k, 3);
            }
        }
        return Math.max(v, 3);
    };
    /**
     * Calculates the value of a Gaussian distribution with sigma 3 at a given point.
     * @param x The point on the Gaussian distribution to sample.
     * @return the value of the Gaussian function at x.
     */
    BlurPostProcess.prototype._gaussianWeight = function (x) {
        //reference: Engines/ImageProcessingBlur.cpp #dcc760
        // We are evaluating the Gaussian (normal) distribution over a kernel parameter space of [-1,1],
        // so we truncate at three standard deviations by setting stddev (sigma) to 1/3.
        // The choice of 3-sigma truncation is common but arbitrary, and means that the signal is
        // truncated at around 1.3% of peak strength.
        //the distribution is scaled to account for the difference between the actual kernel size and the requested kernel size
        var sigma = (1 / 3);
        var denominator = Math.sqrt(2.0 * Math.PI) * sigma;
        var exponent = -((x * x) / (2.0 * sigma * sigma));
        var weight = (1.0 / denominator) * Math.exp(exponent);
        return weight;
    };
    /**
      * Generates a string that can be used as a floating point number in GLSL.
      * @param x Value to print.
      * @param decimalFigures Number of decimal places to print the number to (excluding trailing 0s).
      * @return GLSL float string.
      */
    BlurPostProcess.prototype._glslFloat = function (x, decimalFigures) {
        if (decimalFigures === void 0) { decimalFigures = 8; }
        return x.toFixed(decimalFigures).replace(/0+$/, '');
    };
    return BlurPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/chromaticAberrationPostProcess.ts":
/*!*********************************************************!*\
  !*** ./PostProcesses/chromaticAberrationPostProcess.ts ***!
  \*********************************************************/
/*! exports provided: ChromaticAberrationPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ChromaticAberrationPostProcess", function() { return ChromaticAberrationPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_chromaticAberration_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/chromaticAberration.fragment */ "./Shaders/chromaticAberration.fragment.ts");





/**
 * The ChromaticAberrationPostProcess separates the rgb channels in an image to produce chromatic distortion around the edges of the screen
 */
var ChromaticAberrationPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ChromaticAberrationPostProcess, _super);
    /**
     * Creates a new instance ChromaticAberrationPostProcess
     * @param name The name of the effect.
     * @param screenWidth The width of the screen to apply the effect on.
     * @param screenHeight The height of the screen to apply the effect on.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function ChromaticAberrationPostProcess(name, screenWidth, screenHeight, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "chromaticAberration", ["chromatic_aberration", "screen_width", "screen_height", "direction", "radialIntensity", "centerPosition"], [], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation) || this;
        /**
         * The amount of seperation of rgb channels (default: 30)
         */
        _this.aberrationAmount = 30;
        /**
         * The amount the effect will increase for pixels closer to the edge of the screen. (default: 0)
         */
        _this.radialIntensity = 0;
        /**
         * The normilized direction in which the rgb channels should be seperated. If set to 0,0 radial direction will be used. (default: Vector2(0.707,0.707))
         */
        _this.direction = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0.707, 0.707);
        /**
         * The center position where the radialIntensity should be around. [0.5,0.5 is center of screen, 1,1 is top right corder] (default: Vector2(0.5 ,0.5))
         */
        _this.centerPosition = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0.5, 0.5);
        _this.onApplyObservable.add(function (effect) {
            effect.setFloat('chromatic_aberration', _this.aberrationAmount);
            effect.setFloat('screen_width', screenWidth);
            effect.setFloat('screen_height', screenHeight);
            effect.setFloat('radialIntensity', _this.radialIntensity);
            effect.setFloat2('direction', _this.direction.x, _this.direction.y);
            effect.setFloat2('centerPosition', _this.centerPosition.x, _this.centerPosition.y);
        });
        return _this;
    }
    return ChromaticAberrationPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/circleOfConfusionPostProcess.ts":
/*!*******************************************************!*\
  !*** ./PostProcesses/circleOfConfusionPostProcess.ts ***!
  \*******************************************************/
/*! exports provided: CircleOfConfusionPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CircleOfConfusionPostProcess", function() { return CircleOfConfusionPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_circleOfConfusion_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/circleOfConfusion.fragment */ "./Shaders/circleOfConfusion.fragment.ts");





/**
 * The CircleOfConfusionPostProcess computes the circle of confusion value for each pixel given required lens parameters. See https://en.wikipedia.org/wiki/Circle_of_confusion
 */
var CircleOfConfusionPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CircleOfConfusionPostProcess, _super);
    /**
     * Creates a new instance CircleOfConfusionPostProcess
     * @param name The name of the effect.
     * @param depthTexture The depth texture of the scene to compute the circle of confusion. This must be set in order for this to function but may be set after initialization if needed.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function CircleOfConfusionPostProcess(name, depthTexture, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "circleOfConfusion", ["cameraMinMaxZ", "focusDistance", "cocPrecalculation"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation) || this;
        /**
         * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
         */
        _this.lensSize = 50;
        /**
         * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
         */
        _this.fStop = 1.4;
        /**
         * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
         */
        _this.focusDistance = 2000;
        /**
         * Focal length of the effect's camera in scene units/1000 (eg. millimeter). (default: 50)
         */
        _this.focalLength = 50;
        _this._depthTexture = null;
        _this._depthTexture = depthTexture;
        _this.onApplyObservable.add(function (effect) {
            if (!_this._depthTexture) {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("No depth texture set on CircleOfConfusionPostProcess");
                return;
            }
            effect.setTexture("depthSampler", _this._depthTexture);
            // Circle of confusion calculation, See https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch23.html
            var aperture = _this.lensSize / _this.fStop;
            var cocPrecalculation = ((aperture * _this.focalLength) / ((_this.focusDistance - _this.focalLength))); // * ((this.focusDistance - pixelDistance)/pixelDistance) [This part is done in shader]
            effect.setFloat('focusDistance', _this.focusDistance);
            effect.setFloat('cocPrecalculation', cocPrecalculation);
            effect.setFloat2('cameraMinMaxZ', _this._depthTexture.activeCamera.minZ, _this._depthTexture.activeCamera.maxZ);
        });
        return _this;
    }
    Object.defineProperty(CircleOfConfusionPostProcess.prototype, "depthTexture", {
        /**
         * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
         */
        set: function (value) {
            this._depthTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    return CircleOfConfusionPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/colorCorrectionPostProcess.ts":
/*!*****************************************************!*\
  !*** ./PostProcesses/colorCorrectionPostProcess.ts ***!
  \*****************************************************/
/*! exports provided: ColorCorrectionPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorCorrectionPostProcess", function() { return ColorCorrectionPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Shaders_colorCorrection_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/colorCorrection.fragment */ "./Shaders/colorCorrection.fragment.ts");




/**
 *
 * This post-process allows the modification of rendered colors by using
 * a 'look-up table' (LUT). This effect is also called Color Grading.
 *
 * The object needs to be provided an url to a texture containing the color
 * look-up table: the texture must be 256 pixels wide and 16 pixels high.
 * Use an image editing software to tweak the LUT to match your needs.
 *
 * For an example of a color LUT, see here:
 * @see http://udn.epicgames.com/Three/rsrc/Three/ColorGrading/RGBTable16x1.png
 * For explanations on color grading, see here:
 * @see http://udn.epicgames.com/Three/ColorGrading.html
 *
 */
var ColorCorrectionPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ColorCorrectionPostProcess, _super);
    function ColorCorrectionPostProcess(name, colorTableUrl, options, camera, samplingMode, engine, reusable) {
        var _this = _super.call(this, name, 'colorCorrection', null, ['colorTable'], options, camera, samplingMode, engine, reusable) || this;
        _this._colorTableTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"](colorTableUrl, camera.getScene(), true, false, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].TRILINEAR_SAMPLINGMODE);
        _this._colorTableTexture.anisotropicFilteringLevel = 1;
        _this._colorTableTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].CLAMP_ADDRESSMODE;
        _this._colorTableTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].CLAMP_ADDRESSMODE;
        _this.onApply = function (effect) {
            effect.setTexture("colorTable", _this._colorTableTexture);
        };
        return _this;
    }
    return ColorCorrectionPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/convolutionPostProcess.ts":
/*!*************************************************!*\
  !*** ./PostProcesses/convolutionPostProcess.ts ***!
  \*************************************************/
/*! exports provided: ConvolutionPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConvolutionPostProcess", function() { return ConvolutionPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_convolution_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/convolution.fragment */ "./Shaders/convolution.fragment.ts");




/**
 * The ConvolutionPostProcess applies a 3x3 kernel to every pixel of the
 * input texture to perform effects such as edge detection or sharpening
 * See http://en.wikipedia.org/wiki/Kernel_(image_processing)
 */
var ConvolutionPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ConvolutionPostProcess, _super);
    /**
     * Creates a new instance ConvolutionPostProcess
     * @param name The name of the effect.
     * @param kernel Array of 9 values corresponding to the 3x3 kernel to be applied
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     */
    function ConvolutionPostProcess(name,
    /** Array of 9 values corresponding to the 3x3 kernel to be applied */
    kernel, options, camera, samplingMode, engine, reusable, textureType) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        var _this = _super.call(this, name, "convolution", ["kernel", "screenSize"], null, options, camera, samplingMode, engine, reusable, null, textureType) || this;
        _this.kernel = kernel;
        _this.onApply = function (effect) {
            effect.setFloat2("screenSize", _this.width, _this.height);
            effect.setArray("kernel", _this.kernel);
        };
        return _this;
    }
    // Statics
    /**
     * Edge detection 0 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
     */
    ConvolutionPostProcess.EdgeDetect0Kernel = [1, 0, -1, 0, 0, 0, -1, 0, 1];
    /**
     * Edge detection 1 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
     */
    ConvolutionPostProcess.EdgeDetect1Kernel = [0, 1, 0, 1, -4, 1, 0, 1, 0];
    /**
     * Edge detection 2 see https://en.wikipedia.org/wiki/Kernel_(image_processing)
     */
    ConvolutionPostProcess.EdgeDetect2Kernel = [-1, -1, -1, -1, 8, -1, -1, -1, -1];
    /**
     * Kernel to sharpen an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)
     */
    ConvolutionPostProcess.SharpenKernel = [0, -1, 0, -1, 5, -1, 0, -1, 0];
    /**
     * Kernel to emboss an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)
     */
    ConvolutionPostProcess.EmbossKernel = [-2, -1, 0, -1, 1, 1, 0, 1, 2];
    /**
     * Kernel to blur an image see https://en.wikipedia.org/wiki/Kernel_(image_processing)
     */
    ConvolutionPostProcess.GaussianKernel = [0, 1, 0, 1, 1, 1, 0, 1, 0];
    return ConvolutionPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/depthOfFieldBlurPostProcess.ts":
/*!******************************************************!*\
  !*** ./PostProcesses/depthOfFieldBlurPostProcess.ts ***!
  \******************************************************/
/*! exports provided: DepthOfFieldBlurPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldBlurPostProcess", function() { return DepthOfFieldBlurPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _blurPostProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");




/**
 * The DepthOfFieldBlurPostProcess applied a blur in a give direction.
 * This blur differs from the standard BlurPostProcess as it attempts to avoid blurring pixels
 * based on samples that have a large difference in distance than the center pixel.
 * See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
 */
var DepthOfFieldBlurPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DepthOfFieldBlurPostProcess, _super);
    /**
     * Creates a new instance CircleOfConfusionPostProcess
     * @param name The name of the effect.
     * @param scene The scene the effect belongs to.
     * @param direction The direction the blur should be applied.
     * @param kernel The size of the kernel used to blur.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param circleOfConfusion The circle of confusion + depth map to be used to avoid blurring accross edges
     * @param imageToBlur The image to apply the blur to (default: Current rendered frame)
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function DepthOfFieldBlurPostProcess(name, scene, direction, kernel, options, camera, circleOfConfusion, imageToBlur, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (imageToBlur === void 0) { imageToBlur = null; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].BILINEAR_SAMPLINGMODE; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, direction, kernel, options, camera, samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE, engine, reusable, textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT, "#define DOF 1\r\n", blockCompilation) || this;
        _this.direction = direction;
        _this.onApplyObservable.add(function (effect) {
            if (imageToBlur != null) {
                effect.setTextureFromPostProcess("textureSampler", imageToBlur);
            }
            effect.setTextureFromPostProcessOutput("circleOfConfusionSampler", circleOfConfusion);
            if (scene.activeCamera) {
                effect.setFloat2('cameraMinMaxZ', scene.activeCamera.minZ, scene.activeCamera.maxZ);
            }
        });
        return _this;
    }
    return DepthOfFieldBlurPostProcess;
}(_blurPostProcess__WEBPACK_IMPORTED_MODULE_2__["BlurPostProcess"]));



/***/ }),

/***/ "./PostProcesses/depthOfFieldEffect.ts":
/*!*********************************************!*\
  !*** ./PostProcesses/depthOfFieldEffect.ts ***!
  \*********************************************/
/*! exports provided: DepthOfFieldEffectBlurLevel, DepthOfFieldEffect */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffectBlurLevel", function() { return DepthOfFieldEffectBlurLevel; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffect", function() { return DepthOfFieldEffect; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../PostProcesses/RenderPipeline/postProcessRenderEffect */ "./PostProcesses/RenderPipeline/postProcessRenderEffect.ts");
/* harmony import */ var _circleOfConfusionPostProcess__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./circleOfConfusionPostProcess */ "./PostProcesses/circleOfConfusionPostProcess.ts");
/* harmony import */ var _depthOfFieldBlurPostProcess__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./depthOfFieldBlurPostProcess */ "./PostProcesses/depthOfFieldBlurPostProcess.ts");
/* harmony import */ var _depthOfFieldMergePostProcess__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./depthOfFieldMergePostProcess */ "./PostProcesses/depthOfFieldMergePostProcess.ts");







/**
 * Specifies the level of max blur that should be applied when using the depth of field effect
 */
var DepthOfFieldEffectBlurLevel;
(function (DepthOfFieldEffectBlurLevel) {
    /**
     * Subtle blur
     */
    DepthOfFieldEffectBlurLevel[DepthOfFieldEffectBlurLevel["Low"] = 0] = "Low";
    /**
     * Medium blur
     */
    DepthOfFieldEffectBlurLevel[DepthOfFieldEffectBlurLevel["Medium"] = 1] = "Medium";
    /**
     * Large blur
     */
    DepthOfFieldEffectBlurLevel[DepthOfFieldEffectBlurLevel["High"] = 2] = "High";
})(DepthOfFieldEffectBlurLevel || (DepthOfFieldEffectBlurLevel = {}));
/**
 * The depth of field effect applies a blur to objects that are closer or further from where the camera is focusing.
 */
var DepthOfFieldEffect = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DepthOfFieldEffect, _super);
    /**
     * Creates a new instance DepthOfFieldEffect
     * @param scene The scene the effect belongs to.
     * @param depthTexture The depth texture of the scene to compute the circle of confusion.This must be set in order for this to function but may be set after initialization if needed.
     * @param pipelineTextureType The type of texture to be used when performing the post processing.
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function DepthOfFieldEffect(scene, depthTexture, blurLevel, pipelineTextureType, blockCompilation) {
        if (blurLevel === void 0) { blurLevel = DepthOfFieldEffectBlurLevel.Low; }
        if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, scene.getEngine(), "depth of field", function () {
            return _this._effects;
        }, true) || this;
        /**
         * @hidden Internal post processes in depth of field effect
         */
        _this._effects = [];
        // Circle of confusion value for each pixel is used to determine how much to blur that pixel
        _this._circleOfConfusion = new _circleOfConfusionPostProcess__WEBPACK_IMPORTED_MODULE_4__["CircleOfConfusionPostProcess"]("circleOfConfusion", depthTexture, 1, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
        // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur)
        // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts
        // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
        _this._depthOfFieldBlurY = [];
        _this._depthOfFieldBlurX = [];
        var blurCount = 1;
        var kernelSize = 15;
        switch (blurLevel) {
            case DepthOfFieldEffectBlurLevel.High: {
                blurCount = 3;
                kernelSize = 51;
                break;
            }
            case DepthOfFieldEffectBlurLevel.Medium: {
                blurCount = 2;
                kernelSize = 31;
                break;
            }
            default: {
                kernelSize = 15;
                blurCount = 1;
                break;
            }
        }
        var adjustedKernelSize = kernelSize / Math.pow(2, blurCount - 1);
        var ratio = 1.0;
        for (var i = 0; i < blurCount; i++) {
            var blurY = new _depthOfFieldBlurPostProcess__WEBPACK_IMPORTED_MODULE_5__["DepthOfFieldBlurPostProcess"]("verticle blur", scene, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](0, 1.0), adjustedKernelSize, ratio, null, _this._circleOfConfusion, i == 0 ? _this._circleOfConfusion : null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
            blurY.autoClear = false;
            ratio = 0.75 / Math.pow(2, i);
            var blurX = new _depthOfFieldBlurPostProcess__WEBPACK_IMPORTED_MODULE_5__["DepthOfFieldBlurPostProcess"]("horizontal blur", scene, new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1.0, 0), adjustedKernelSize, ratio, null, _this._circleOfConfusion, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
            blurX.autoClear = false;
            _this._depthOfFieldBlurY.push(blurY);
            _this._depthOfFieldBlurX.push(blurX);
        }
        // Set all post processes on the effect.
        _this._effects = [_this._circleOfConfusion];
        for (var i = 0; i < _this._depthOfFieldBlurX.length; i++) {
            _this._effects.push(_this._depthOfFieldBlurY[i]);
            _this._effects.push(_this._depthOfFieldBlurX[i]);
        }
        // Merge blurred images with original image based on circleOfConfusion
        _this._dofMerge = new _depthOfFieldMergePostProcess__WEBPACK_IMPORTED_MODULE_6__["DepthOfFieldMergePostProcess"]("dofMerge", _this._circleOfConfusion, _this._circleOfConfusion, _this._depthOfFieldBlurX, ratio, null, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
        _this._dofMerge.autoClear = false;
        _this._effects.push(_this._dofMerge);
        return _this;
    }
    Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
        get: function () {
            return this._circleOfConfusion.focalLength;
        },
        /**
         * The focal the length of the camera used in the effect in scene units/1000 (eg. millimeter)
         */
        set: function (value) {
            this._circleOfConfusion.focalLength = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DepthOfFieldEffect.prototype, "fStop", {
        get: function () {
            return this._circleOfConfusion.fStop;
        },
        /**
         * F-Stop of the effect's camera. The diameter of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
         */
        set: function (value) {
            this._circleOfConfusion.fStop = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DepthOfFieldEffect.prototype, "focusDistance", {
        get: function () {
            return this._circleOfConfusion.focusDistance;
        },
        /**
         * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
         */
        set: function (value) {
            this._circleOfConfusion.focusDistance = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(DepthOfFieldEffect.prototype, "lensSize", {
        get: function () {
            return this._circleOfConfusion.lensSize;
        },
        /**
         * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
         */
        set: function (value) {
            this._circleOfConfusion.lensSize = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
    * Get the current class name of the current effet
    * @returns "DepthOfFieldEffect"
    */
    DepthOfFieldEffect.prototype.getClassName = function () {
        return "DepthOfFieldEffect";
    };
    Object.defineProperty(DepthOfFieldEffect.prototype, "depthTexture", {
        /**
         * Depth texture to be used to compute the circle of confusion. This must be set here or in the constructor in order for the post process to function.
         */
        set: function (value) {
            this._circleOfConfusion.depthTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes each of the internal effects for a given camera.
     * @param camera The camera to dispose the effect on.
     */
    DepthOfFieldEffect.prototype.disposeEffects = function (camera) {
        for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
            this._effects[effectIndex].dispose(camera);
        }
    };
    /**
     * @hidden Internal
     */
    DepthOfFieldEffect.prototype._updateEffects = function () {
        for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
            this._effects[effectIndex].updateEffect();
        }
    };
    /**
     * Internal
     * @returns if all the contained post processes are ready.
     * @hidden
     */
    DepthOfFieldEffect.prototype._isReady = function () {
        for (var effectIndex = 0; effectIndex < this._effects.length; effectIndex++) {
            if (!this._effects[effectIndex].isReady()) {
                return false;
            }
        }
        return true;
    };
    return DepthOfFieldEffect;
}(_PostProcesses_RenderPipeline_postProcessRenderEffect__WEBPACK_IMPORTED_MODULE_3__["PostProcessRenderEffect"]));



/***/ }),

/***/ "./PostProcesses/depthOfFieldMergePostProcess.ts":
/*!*******************************************************!*\
  !*** ./PostProcesses/depthOfFieldMergePostProcess.ts ***!
  \*******************************************************/
/*! exports provided: DepthOfFieldMergePostProcessOptions, DepthOfFieldMergePostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcessOptions", function() { return DepthOfFieldMergePostProcessOptions; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcess", function() { return DepthOfFieldMergePostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_depthOfFieldMerge_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/depthOfFieldMerge.fragment */ "./Shaders/depthOfFieldMerge.fragment.ts");




/**
 * Options to be set when merging outputs from the default pipeline.
 */
var DepthOfFieldMergePostProcessOptions = /** @class */ (function () {
    function DepthOfFieldMergePostProcessOptions() {
    }
    return DepthOfFieldMergePostProcessOptions;
}());

/**
 * The DepthOfFieldMergePostProcess merges blurred images with the original based on the values of the circle of confusion.
 */
var DepthOfFieldMergePostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DepthOfFieldMergePostProcess, _super);
    /**
     * Creates a new instance of DepthOfFieldMergePostProcess
     * @param name The name of the effect.
     * @param originalFromInput Post process which's input will be used for the merge.
     * @param circleOfConfusion Circle of confusion post process which's output will be used to blur each pixel.
     * @param blurSteps Blur post processes from low to high which will be mixed with the original image.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function DepthOfFieldMergePostProcess(name, originalFromInput, circleOfConfusion, blurSteps, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "depthOfFieldMerge", [], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true) || this;
        _this.blurSteps = blurSteps;
        _this.onApplyObservable.add(function (effect) {
            effect.setTextureFromPostProcess("textureSampler", originalFromInput);
            effect.setTextureFromPostProcessOutput("circleOfConfusionSampler", circleOfConfusion);
            blurSteps.forEach(function (step, index) {
                effect.setTextureFromPostProcessOutput("blurStep" + (blurSteps.length - index - 1), step);
            });
        });
        if (!blockCompilation) {
            _this.updateEffect();
        }
        return _this;
    }
    /**
     * Updates the effect with the current post process compile time values and recompiles the shader.
     * @param defines Define statements that should be added at the beginning of the shader. (default: null)
     * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
     * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
     * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
     * @param onCompiled Called when the shader has been compiled.
     * @param onError Called if there is an error when compiling a shader.
     */
    DepthOfFieldMergePostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
        if (defines === void 0) { defines = null; }
        if (uniforms === void 0) { uniforms = null; }
        if (samplers === void 0) { samplers = null; }
        if (!defines) {
            defines = "";
            defines += "#define BLUR_LEVEL " + (this.blurSteps.length - 1) + "\n";
        }
        _super.prototype.updateEffect.call(this, defines, uniforms, samplers, indexParameters, onCompiled, onError);
    };
    return DepthOfFieldMergePostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/displayPassPostProcess.ts":
/*!*************************************************!*\
  !*** ./PostProcesses/displayPassPostProcess.ts ***!
  \*************************************************/
/*! exports provided: DisplayPassPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DisplayPassPostProcess", function() { return DisplayPassPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_displayPass_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Shaders/displayPass.fragment */ "./Shaders/displayPass.fragment.ts");



/**
 * DisplayPassPostProcess which produces an output the same as it's input
 */
var DisplayPassPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DisplayPassPostProcess, _super);
    /**
     * Creates the DisplayPassPostProcess
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     */
    function DisplayPassPostProcess(name, options, camera, samplingMode, engine, reusable) {
        return _super.call(this, name, "displayPass", ["passSampler"], ["passSampler"], options, camera, samplingMode, engine, reusable) || this;
    }
    return DisplayPassPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/extractHighlightsPostProcess.ts":
/*!*******************************************************!*\
  !*** ./PostProcesses/extractHighlightsPostProcess.ts ***!
  \*******************************************************/
/*! exports provided: ExtractHighlightsPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExtractHighlightsPostProcess", function() { return ExtractHighlightsPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Maths_math_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.constants */ "./Maths/math.constants.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_extractHighlights_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/extractHighlights.fragment */ "./Shaders/extractHighlights.fragment.ts");





/**
 * The extract highlights post process sets all pixels to black except pixels above the specified luminance threshold. Used as the first step for a bloom effect.
 */
var ExtractHighlightsPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExtractHighlightsPostProcess, _super);
    function ExtractHighlightsPostProcess(name, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "extractHighlights", ["threshold", "exposure"], null, options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation) || this;
        /**
         * The luminance threshold, pixels below this value will be set to black.
         */
        _this.threshold = 0.9;
        /** @hidden */
        _this._exposure = 1;
        /**
         * Post process which has the input texture to be used when performing highlight extraction
         * @hidden
         */
        _this._inputPostProcess = null;
        _this.onApplyObservable.add(function (effect) {
            if (_this._inputPostProcess) {
                effect.setTextureFromPostProcess("textureSampler", _this._inputPostProcess);
            }
            effect.setFloat('threshold', Math.pow(_this.threshold, _Maths_math_constants__WEBPACK_IMPORTED_MODULE_2__["ToGammaSpace"]));
            effect.setFloat('exposure', _this._exposure);
        });
        return _this;
    }
    return ExtractHighlightsPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/filterPostProcess.ts":
/*!********************************************!*\
  !*** ./PostProcesses/filterPostProcess.ts ***!
  \********************************************/
/*! exports provided: FilterPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FilterPostProcess", function() { return FilterPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_filter_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Shaders/filter.fragment */ "./Shaders/filter.fragment.ts");



/**
 * Applies a kernel filter to the image
 */
var FilterPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FilterPostProcess, _super);
    /**
     *
     * @param name The name of the effect.
     * @param kernelMatrix The matrix to be applied to the image
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     */
    function FilterPostProcess(name,
    /** The matrix to be applied to the image */
    kernelMatrix, options, camera, samplingMode, engine, reusable) {
        var _this = _super.call(this, name, "filter", ["kernelMatrix"], null, options, camera, samplingMode, engine, reusable) || this;
        _this.kernelMatrix = kernelMatrix;
        _this.onApply = function (effect) {
            effect.setMatrix("kernelMatrix", _this.kernelMatrix);
        };
        return _this;
    }
    return FilterPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/fxaaPostProcess.ts":
/*!******************************************!*\
  !*** ./PostProcesses/fxaaPostProcess.ts ***!
  \******************************************/
/*! exports provided: FxaaPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FxaaPostProcess", function() { return FxaaPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_fxaa_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/fxaa.fragment */ "./Shaders/fxaa.fragment.ts");
/* harmony import */ var _Shaders_fxaa_vertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Shaders/fxaa.vertex */ "./Shaders/fxaa.vertex.ts");






/**
 * Fxaa post process
 * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#fxaa
 */
var FxaaPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FxaaPostProcess, _super);
    function FxaaPostProcess(name, options, camera, samplingMode, engine, reusable, textureType) {
        if (camera === void 0) { camera = null; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        var _this = _super.call(this, name, "fxaa", ["texelSize"], null, options, camera, samplingMode || _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].BILINEAR_SAMPLINGMODE, engine, reusable, null, textureType, "fxaa", undefined, true) || this;
        var defines = _this._getDefines();
        _this.updateEffect(defines);
        _this.onApplyObservable.add(function (effect) {
            var texelSize = _this.texelSize;
            effect.setFloat2("texelSize", texelSize.x, texelSize.y);
        });
        return _this;
    }
    FxaaPostProcess.prototype._getDefines = function () {
        var engine = this.getEngine();
        if (!engine) {
            return null;
        }
        var glInfo = engine.getGlInfo();
        if (glInfo && glInfo.renderer && glInfo.renderer.toLowerCase().indexOf("mali") > -1) {
            return "#define MALI 1\n";
        }
        return null;
    };
    return FxaaPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/grainPostProcess.ts":
/*!*******************************************!*\
  !*** ./PostProcesses/grainPostProcess.ts ***!
  \*******************************************/
/*! exports provided: GrainPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GrainPostProcess", function() { return GrainPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_grain_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/grain.fragment */ "./Shaders/grain.fragment.ts");




/**
 * The GrainPostProcess adds noise to the image at mid luminance levels
 */
var GrainPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](GrainPostProcess, _super);
    /**
     * Creates a new instance of @see GrainPostProcess
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function GrainPostProcess(name, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "grain", ["intensity", "animatedSeed"], [], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation) || this;
        /**
         * The intensity of the grain added (default: 30)
         */
        _this.intensity = 30;
        /**
         * If the grain should be randomized on every frame
         */
        _this.animated = false;
        _this.onApplyObservable.add(function (effect) {
            effect.setFloat('intensity', _this.intensity);
            effect.setFloat('animatedSeed', _this.animated ? Math.random() + 1 : 1);
        });
        return _this;
    }
    return GrainPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/highlightsPostProcess.ts":
/*!************************************************!*\
  !*** ./PostProcesses/highlightsPostProcess.ts ***!
  \************************************************/
/*! exports provided: HighlightsPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HighlightsPostProcess", function() { return HighlightsPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_highlights_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/highlights.fragment */ "./Shaders/highlights.fragment.ts");




/**
 * Extracts highlights from the image
 * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses
 */
var HighlightsPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](HighlightsPostProcess, _super);
    /**
     * Extracts highlights from the image
     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of texture for the post process (default: Engine.TEXTURETYPE_UNSIGNED_INT)
     */
    function HighlightsPostProcess(name, options, camera, samplingMode, engine, reusable, textureType) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        return _super.call(this, name, "highlights", null, null, options, camera, samplingMode, engine, reusable, null, textureType) || this;
    }
    return HighlightsPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/imageProcessingPostProcess.ts":
/*!*****************************************************!*\
  !*** ./PostProcesses/imageProcessingPostProcess.ts ***!
  \*****************************************************/
/*! exports provided: ImageProcessingPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingPostProcess", function() { return ImageProcessingPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_imageProcessing_fragment__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Shaders/imageProcessing.fragment */ "./Shaders/imageProcessing.fragment.ts");
/* harmony import */ var _Shaders_postprocess_vertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Shaders/postprocess.vertex */ "./Shaders/postprocess.vertex.ts");








/**
 * ImageProcessingPostProcess
 * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#imageprocessing
 */
var ImageProcessingPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ImageProcessingPostProcess, _super);
    function ImageProcessingPostProcess(name, options, camera, samplingMode, engine, reusable, textureType, imageProcessingConfiguration) {
        if (camera === void 0) { camera = null; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        var _this = _super.call(this, name, "imageProcessing", [], [], options, camera, samplingMode, engine, reusable, null, textureType, "postprocess", null, true) || this;
        _this._fromLinearSpace = true;
        /**
         * Defines cache preventing GC.
         */
        _this._defines = {
            IMAGEPROCESSING: false,
            VIGNETTE: false,
            VIGNETTEBLENDMODEMULTIPLY: false,
            VIGNETTEBLENDMODEOPAQUE: false,
            TONEMAPPING: false,
            TONEMAPPING_ACES: false,
            CONTRAST: false,
            COLORCURVES: false,
            COLORGRADING: false,
            COLORGRADING3D: false,
            FROMLINEARSPACE: false,
            SAMPLER3DGREENDEPTH: false,
            SAMPLER3DBGRMAP: false,
            IMAGEPROCESSINGPOSTPROCESS: false,
            EXPOSURE: false,
        };
        // Setup the configuration as forced by the constructor. This would then not force the
        // scene materials output in linear space and let untouched the default forward pass.
        if (imageProcessingConfiguration) {
            imageProcessingConfiguration.applyByPostProcess = true;
            _this._attachImageProcessingConfiguration(imageProcessingConfiguration, true);
            // This will cause the shader to be compiled
            _this.fromLinearSpace = false;
        }
        // Setup the default processing configuration to the scene.
        else {
            _this._attachImageProcessingConfiguration(null, true);
            _this.imageProcessingConfiguration.applyByPostProcess = true;
        }
        _this.onApply = function (effect) {
            _this.imageProcessingConfiguration.bind(effect, _this.aspectRatio);
        };
        return _this;
    }
    Object.defineProperty(ImageProcessingPostProcess.prototype, "imageProcessingConfiguration", {
        /**
         * Gets the image processing configuration used either in this material.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        /**
         * Sets the Default image processing configuration used either in the this material.
         *
         * If sets to null, the scene one is in use.
         */
        set: function (value) {
            // We are almost sure it is applied by post process as
            // We are in the post process :-)
            value.applyByPostProcess = true;
            this._attachImageProcessingConfiguration(value);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attaches a new image processing configuration to the PBR Material.
     * @param configuration
     */
    ImageProcessingPostProcess.prototype._attachImageProcessingConfiguration = function (configuration, doNotBuild) {
        var _this = this;
        if (doNotBuild === void 0) { doNotBuild = false; }
        if (configuration === this._imageProcessingConfiguration) {
            return;
        }
        // Detaches observer.
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        // Pick the scene configuration if needed.
        if (!configuration) {
            var scene = null;
            var engine = this.getEngine();
            var camera = this.getCamera();
            if (camera) {
                scene = camera.getScene();
            }
            else if (engine && engine.scenes) {
                var scenes = engine.scenes;
                scene = scenes[scenes.length - 1];
            }
            else {
                scene = _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene;
            }
            this._imageProcessingConfiguration = scene.imageProcessingConfiguration;
        }
        else {
            this._imageProcessingConfiguration = configuration;
        }
        // Attaches observer.
        if (this._imageProcessingConfiguration) {
            this._imageProcessingObserver = this._imageProcessingConfiguration.onUpdateParameters.add(function () {
                _this._updateParameters();
            });
        }
        // Ensure the effect will be rebuilt.
        if (!doNotBuild) {
            this._updateParameters();
        }
    };
    Object.defineProperty(ImageProcessingPostProcess.prototype, "colorCurves", {
        /**
         * Gets Color curves setup used in the effect if colorCurvesEnabled is set to true .
         */
        get: function () {
            return this.imageProcessingConfiguration.colorCurves;
        },
        /**
         * Sets Color curves setup used in the effect if colorCurvesEnabled is set to true .
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorCurves = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "colorCurvesEnabled", {
        /**
         * Gets wether the color curves effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorCurvesEnabled;
        },
        /**
         * Sets wether the color curves effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorCurvesEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "colorGradingTexture", {
        /**
         * Gets Color grading LUT texture used in the effect if colorGradingEnabled is set to true.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorGradingTexture;
        },
        /**
         * Sets Color grading LUT texture used in the effect if colorGradingEnabled is set to true.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorGradingTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "colorGradingEnabled", {
        /**
         * Gets wether the color grading effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.colorGradingEnabled;
        },
        /**
         * Gets wether the color grading effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.colorGradingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "exposure", {
        /**
         * Gets exposure used in the effect.
         */
        get: function () {
            return this.imageProcessingConfiguration.exposure;
        },
        /**
         * Sets exposure used in the effect.
         */
        set: function (value) {
            this.imageProcessingConfiguration.exposure = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "toneMappingEnabled", {
        /**
         * Gets wether tonemapping is enabled or not.
         */
        get: function () {
            return this._imageProcessingConfiguration.toneMappingEnabled;
        },
        /**
         * Sets wether tonemapping is enabled or not
         */
        set: function (value) {
            this._imageProcessingConfiguration.toneMappingEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "toneMappingType", {
        /**
         * Gets the type of tone mapping effect.
         */
        get: function () {
            return this._imageProcessingConfiguration.toneMappingType;
        },
        /**
         * Sets the type of tone mapping effect.
         */
        set: function (value) {
            this._imageProcessingConfiguration.toneMappingType = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "contrast", {
        /**
         * Gets contrast used in the effect.
         */
        get: function () {
            return this.imageProcessingConfiguration.contrast;
        },
        /**
         * Sets contrast used in the effect.
         */
        set: function (value) {
            this.imageProcessingConfiguration.contrast = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteStretch", {
        /**
         * Gets Vignette stretch size.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteStretch;
        },
        /**
         * Sets Vignette stretch size.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteStretch = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteCentreX", {
        /**
         * Gets Vignette centre X Offset.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteCentreX;
        },
        /**
         * Sets Vignette centre X Offset.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteCentreX = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteCentreY", {
        /**
         * Gets Vignette centre Y Offset.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteCentreY;
        },
        /**
         * Sets Vignette centre Y Offset.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteCentreY = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteWeight", {
        /**
         * Gets Vignette weight or intensity of the vignette effect.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteWeight;
        },
        /**
         * Sets Vignette weight or intensity of the vignette effect.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteWeight = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteColor", {
        /**
         * Gets Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)
         * if vignetteEnabled is set to true.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteColor;
        },
        /**
         * Sets Color of the vignette applied on the screen through the chosen blend mode (vignetteBlendMode)
         * if vignetteEnabled is set to true.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteColor = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteCameraFov", {
        /**
         * Gets Camera field of view used by the Vignette effect.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteCameraFov;
        },
        /**
         * Sets Camera field of view used by the Vignette effect.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteCameraFov = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteBlendMode", {
        /**
         * Gets the vignette blend mode allowing different kind of effect.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteBlendMode;
        },
        /**
         * Sets the vignette blend mode allowing different kind of effect.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteBlendMode = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "vignetteEnabled", {
        /**
         * Gets wether the vignette effect is enabled.
         */
        get: function () {
            return this.imageProcessingConfiguration.vignetteEnabled;
        },
        /**
         * Sets wether the vignette effect is enabled.
         */
        set: function (value) {
            this.imageProcessingConfiguration.vignetteEnabled = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ImageProcessingPostProcess.prototype, "fromLinearSpace", {
        /**
         * Gets wether the input of the processing is in Gamma or Linear Space.
         */
        get: function () {
            return this._fromLinearSpace;
        },
        /**
         * Sets wether the input of the processing is in Gamma or Linear Space.
         */
        set: function (value) {
            if (this._fromLinearSpace === value) {
                return;
            }
            this._fromLinearSpace = value;
            this._updateParameters();
        },
        enumerable: true,
        configurable: true
    });
    /**
     *  "ImageProcessingPostProcess"
     * @returns "ImageProcessingPostProcess"
     */
    ImageProcessingPostProcess.prototype.getClassName = function () {
        return "ImageProcessingPostProcess";
    };
    ImageProcessingPostProcess.prototype._updateParameters = function () {
        this._defines.FROMLINEARSPACE = this._fromLinearSpace;
        this.imageProcessingConfiguration.prepareDefines(this._defines, true);
        var defines = "";
        for (var define in this._defines) {
            if (this._defines[define]) {
                defines += "#define " + define + ";\r\n";
            }
        }
        var samplers = ["textureSampler"];
        var uniforms = ["scale"];
        if (_Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_2__["ImageProcessingConfiguration"]) {
            _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_2__["ImageProcessingConfiguration"].PrepareSamplers(samplers, this._defines);
            _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_2__["ImageProcessingConfiguration"].PrepareUniforms(uniforms, this._defines);
        }
        this.updateEffect(defines, uniforms, samplers);
    };
    ImageProcessingPostProcess.prototype.dispose = function (camera) {
        _super.prototype.dispose.call(this, camera);
        if (this._imageProcessingConfiguration && this._imageProcessingObserver) {
            this._imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingObserver);
        }
        if (this._imageProcessingConfiguration) {
            this.imageProcessingConfiguration.applyByPostProcess = false;
        }
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], ImageProcessingPostProcess.prototype, "_fromLinearSpace", void 0);
    return ImageProcessingPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_3__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/index.ts":
/*!********************************!*\
  !*** ./PostProcesses/index.ts ***!
  \********************************/
/*! exports provided: AnaglyphPostProcess, BlackAndWhitePostProcess, BloomEffect, BloomMergePostProcess, BlurPostProcess, ChromaticAberrationPostProcess, CircleOfConfusionPostProcess, ColorCorrectionPostProcess, ConvolutionPostProcess, DepthOfFieldBlurPostProcess, DepthOfFieldEffectBlurLevel, DepthOfFieldEffect, DepthOfFieldMergePostProcessOptions, DepthOfFieldMergePostProcess, DisplayPassPostProcess, ExtractHighlightsPostProcess, FilterPostProcess, FxaaPostProcess, GrainPostProcess, HighlightsPostProcess, ImageProcessingPostProcess, MotionBlurPostProcess, PassPostProcess, PassCubePostProcess, PostProcess, PostProcessManager, RefractionPostProcess, SharpenPostProcess, StereoscopicInterlacePostProcess, TonemappingOperator, TonemapPostProcess, VolumetricLightScatteringPostProcess, VRDistortionCorrectionPostProcess, VRMultiviewToSingleviewPostProcess, PostProcessRenderEffect, PostProcessRenderPipeline, PostProcessRenderPipelineManager, PostProcessRenderPipelineManagerSceneComponent, DefaultRenderingPipeline, LensRenderingPipeline, SSAO2RenderingPipeline, SSAORenderingPipeline, StandardRenderingPipeline */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _anaglyphPostProcess__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./anaglyphPostProcess */ "./PostProcesses/anaglyphPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphPostProcess", function() { return _anaglyphPostProcess__WEBPACK_IMPORTED_MODULE_0__["AnaglyphPostProcess"]; });

/* harmony import */ var _blackAndWhitePostProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./blackAndWhitePostProcess */ "./PostProcesses/blackAndWhitePostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BlackAndWhitePostProcess", function() { return _blackAndWhitePostProcess__WEBPACK_IMPORTED_MODULE_1__["BlackAndWhitePostProcess"]; });

/* harmony import */ var _bloomEffect__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./bloomEffect */ "./PostProcesses/bloomEffect.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BloomEffect", function() { return _bloomEffect__WEBPACK_IMPORTED_MODULE_2__["BloomEffect"]; });

/* harmony import */ var _bloomMergePostProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./bloomMergePostProcess */ "./PostProcesses/bloomMergePostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BloomMergePostProcess", function() { return _bloomMergePostProcess__WEBPACK_IMPORTED_MODULE_3__["BloomMergePostProcess"]; });

/* harmony import */ var _blurPostProcess__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./blurPostProcess */ "./PostProcesses/blurPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BlurPostProcess", function() { return _blurPostProcess__WEBPACK_IMPORTED_MODULE_4__["BlurPostProcess"]; });

/* harmony import */ var _chromaticAberrationPostProcess__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./chromaticAberrationPostProcess */ "./PostProcesses/chromaticAberrationPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ChromaticAberrationPostProcess", function() { return _chromaticAberrationPostProcess__WEBPACK_IMPORTED_MODULE_5__["ChromaticAberrationPostProcess"]; });

/* harmony import */ var _circleOfConfusionPostProcess__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./circleOfConfusionPostProcess */ "./PostProcesses/circleOfConfusionPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CircleOfConfusionPostProcess", function() { return _circleOfConfusionPostProcess__WEBPACK_IMPORTED_MODULE_6__["CircleOfConfusionPostProcess"]; });

/* harmony import */ var _colorCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./colorCorrectionPostProcess */ "./PostProcesses/colorCorrectionPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorCorrectionPostProcess", function() { return _colorCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_7__["ColorCorrectionPostProcess"]; });

/* harmony import */ var _convolutionPostProcess__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./convolutionPostProcess */ "./PostProcesses/convolutionPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConvolutionPostProcess", function() { return _convolutionPostProcess__WEBPACK_IMPORTED_MODULE_8__["ConvolutionPostProcess"]; });

/* harmony import */ var _depthOfFieldBlurPostProcess__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./depthOfFieldBlurPostProcess */ "./PostProcesses/depthOfFieldBlurPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldBlurPostProcess", function() { return _depthOfFieldBlurPostProcess__WEBPACK_IMPORTED_MODULE_9__["DepthOfFieldBlurPostProcess"]; });

/* harmony import */ var _depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./depthOfFieldEffect */ "./PostProcesses/depthOfFieldEffect.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffectBlurLevel", function() { return _depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_10__["DepthOfFieldEffectBlurLevel"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffect", function() { return _depthOfFieldEffect__WEBPACK_IMPORTED_MODULE_10__["DepthOfFieldEffect"]; });

/* harmony import */ var _depthOfFieldMergePostProcess__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./depthOfFieldMergePostProcess */ "./PostProcesses/depthOfFieldMergePostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcessOptions", function() { return _depthOfFieldMergePostProcess__WEBPACK_IMPORTED_MODULE_11__["DepthOfFieldMergePostProcessOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcess", function() { return _depthOfFieldMergePostProcess__WEBPACK_IMPORTED_MODULE_11__["DepthOfFieldMergePostProcess"]; });

/* harmony import */ var _displayPassPostProcess__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./displayPassPostProcess */ "./PostProcesses/displayPassPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DisplayPassPostProcess", function() { return _displayPassPostProcess__WEBPACK_IMPORTED_MODULE_12__["DisplayPassPostProcess"]; });

/* harmony import */ var _extractHighlightsPostProcess__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./extractHighlightsPostProcess */ "./PostProcesses/extractHighlightsPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtractHighlightsPostProcess", function() { return _extractHighlightsPostProcess__WEBPACK_IMPORTED_MODULE_13__["ExtractHighlightsPostProcess"]; });

/* harmony import */ var _filterPostProcess__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./filterPostProcess */ "./PostProcesses/filterPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilterPostProcess", function() { return _filterPostProcess__WEBPACK_IMPORTED_MODULE_14__["FilterPostProcess"]; });

/* harmony import */ var _fxaaPostProcess__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./fxaaPostProcess */ "./PostProcesses/fxaaPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FxaaPostProcess", function() { return _fxaaPostProcess__WEBPACK_IMPORTED_MODULE_15__["FxaaPostProcess"]; });

/* harmony import */ var _grainPostProcess__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./grainPostProcess */ "./PostProcesses/grainPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GrainPostProcess", function() { return _grainPostProcess__WEBPACK_IMPORTED_MODULE_16__["GrainPostProcess"]; });

/* harmony import */ var _highlightsPostProcess__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./highlightsPostProcess */ "./PostProcesses/highlightsPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HighlightsPostProcess", function() { return _highlightsPostProcess__WEBPACK_IMPORTED_MODULE_17__["HighlightsPostProcess"]; });

/* harmony import */ var _imageProcessingPostProcess__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./imageProcessingPostProcess */ "./PostProcesses/imageProcessingPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingPostProcess", function() { return _imageProcessingPostProcess__WEBPACK_IMPORTED_MODULE_18__["ImageProcessingPostProcess"]; });

/* harmony import */ var _motionBlurPostProcess__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./motionBlurPostProcess */ "./PostProcesses/motionBlurPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotionBlurPostProcess", function() { return _motionBlurPostProcess__WEBPACK_IMPORTED_MODULE_19__["MotionBlurPostProcess"]; });

/* harmony import */ var _passPostProcess__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./passPostProcess */ "./PostProcesses/passPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PassPostProcess", function() { return _passPostProcess__WEBPACK_IMPORTED_MODULE_20__["PassPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PassCubePostProcess", function() { return _passPostProcess__WEBPACK_IMPORTED_MODULE_20__["PassCubePostProcess"]; });

/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcess", function() { return _postProcess__WEBPACK_IMPORTED_MODULE_21__["PostProcess"]; });

/* harmony import */ var _postProcessManager__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./postProcessManager */ "./PostProcesses/postProcessManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessManager", function() { return _postProcessManager__WEBPACK_IMPORTED_MODULE_22__["PostProcessManager"]; });

/* harmony import */ var _refractionPostProcess__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./refractionPostProcess */ "./PostProcesses/refractionPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionPostProcess", function() { return _refractionPostProcess__WEBPACK_IMPORTED_MODULE_23__["RefractionPostProcess"]; });

/* harmony import */ var _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./RenderPipeline/index */ "./PostProcesses/RenderPipeline/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderEffect", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["PostProcessRenderEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipeline", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["PostProcessRenderPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManager", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["PostProcessRenderPipelineManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManagerSceneComponent", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["PostProcessRenderPipelineManagerSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultRenderingPipeline", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["DefaultRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensRenderingPipeline", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["LensRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAO2RenderingPipeline", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["SSAO2RenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAORenderingPipeline", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["SSAORenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardRenderingPipeline", function() { return _RenderPipeline_index__WEBPACK_IMPORTED_MODULE_24__["StandardRenderingPipeline"]; });

/* harmony import */ var _sharpenPostProcess__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./sharpenPostProcess */ "./PostProcesses/sharpenPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SharpenPostProcess", function() { return _sharpenPostProcess__WEBPACK_IMPORTED_MODULE_25__["SharpenPostProcess"]; });

/* harmony import */ var _stereoscopicInterlacePostProcess__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./stereoscopicInterlacePostProcess */ "./PostProcesses/stereoscopicInterlacePostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicInterlacePostProcess", function() { return _stereoscopicInterlacePostProcess__WEBPACK_IMPORTED_MODULE_26__["StereoscopicInterlacePostProcess"]; });

/* harmony import */ var _tonemapPostProcess__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./tonemapPostProcess */ "./PostProcesses/tonemapPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TonemappingOperator", function() { return _tonemapPostProcess__WEBPACK_IMPORTED_MODULE_27__["TonemappingOperator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TonemapPostProcess", function() { return _tonemapPostProcess__WEBPACK_IMPORTED_MODULE_27__["TonemapPostProcess"]; });

/* harmony import */ var _volumetricLightScatteringPostProcess__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./volumetricLightScatteringPostProcess */ "./PostProcesses/volumetricLightScatteringPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VolumetricLightScatteringPostProcess", function() { return _volumetricLightScatteringPostProcess__WEBPACK_IMPORTED_MODULE_28__["VolumetricLightScatteringPostProcess"]; });

/* harmony import */ var _vrDistortionCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./vrDistortionCorrectionPostProcess */ "./PostProcesses/vrDistortionCorrectionPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDistortionCorrectionPostProcess", function() { return _vrDistortionCorrectionPostProcess__WEBPACK_IMPORTED_MODULE_29__["VRDistortionCorrectionPostProcess"]; });

/* harmony import */ var _vrMultiviewToSingleviewPostProcess__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./vrMultiviewToSingleviewPostProcess */ "./PostProcesses/vrMultiviewToSingleviewPostProcess.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRMultiviewToSingleviewPostProcess", function() { return _vrMultiviewToSingleviewPostProcess__WEBPACK_IMPORTED_MODULE_30__["VRMultiviewToSingleviewPostProcess"]; });


































/***/ }),

/***/ "./PostProcesses/motionBlurPostProcess.ts":
/*!************************************************!*\
  !*** ./PostProcesses/motionBlurPostProcess.ts ***!
  \************************************************/
/*! exports provided: MotionBlurPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MotionBlurPostProcess", function() { return MotionBlurPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Rendering_geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Rendering/geometryBufferRenderer */ "./Rendering/geometryBufferRenderer.ts");
/* harmony import */ var _Animations_animatable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Animations/animatable */ "./Animations/animatable.ts");
/* harmony import */ var _Rendering_geometryBufferRendererSceneComponent__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Rendering/geometryBufferRendererSceneComponent */ "./Rendering/geometryBufferRendererSceneComponent.ts");
/* harmony import */ var _Shaders_motionBlur_fragment__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Shaders/motionBlur.fragment */ "./Shaders/motionBlur.fragment.ts");









/**
 * The Motion Blur Post Process which blurs an image based on the objects velocity in scene.
 * Velocity can be affected by each object's rotation, position and scale depending on the transformation speed.
 * As an example, all you have to do is to create the post-process:
 *  var mb = new BABYLON.MotionBlurPostProcess(
 *      'mb', // The name of the effect.
 *      scene, // The scene containing the objects to blur according to their velocity.
 *      1.0, // The required width/height ratio to downsize to before computing the render pass.
 *      camera // The camera to apply the render pass to.
 * );
 * Then, all objects moving, rotating and/or scaling will be blurred depending on the transformation speed.
 */
var MotionBlurPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MotionBlurPostProcess, _super);
    /**
     * Creates a new instance MotionBlurPostProcess
     * @param name The name of the effect.
     * @param scene The scene containing the objects to blur according to their velocity.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function MotionBlurPostProcess(name, scene, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_4__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "motionBlur", ["motionStrength", "motionScale", "screenSize"], ["velocitySampler"], options, camera, samplingMode, engine, reusable, "#define GEOMETRY_SUPPORTED\n#define SAMPLES 64.0", textureType, undefined, null, blockCompilation) || this;
        /**
         * Defines how much the image is blurred by the movement. Default value is equal to 1
         */
        _this.motionStrength = 1;
        _this._motionBlurSamples = 32;
        _this._geometryBufferRenderer = scene.enableGeometryBufferRenderer();
        if (!_this._geometryBufferRenderer) {
            // Geometry buffer renderer is not supported. So, work as a passthrough.
            _Misc_logger__WEBPACK_IMPORTED_MODULE_1__["Logger"].Warn("Multiple Render Target support needed to compute object based motion blur");
            _this.updateEffect();
        }
        else {
            // Geometry buffer renderer is supported.
            _this._geometryBufferRenderer.enableVelocity = true;
            _this.onApply = function (effect) {
                effect.setVector2("screenSize", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](_this.width, _this.height));
                effect.setFloat("motionScale", scene.getAnimationRatio());
                effect.setFloat("motionStrength", _this.motionStrength);
                if (_this._geometryBufferRenderer) {
                    var velocityIndex = _this._geometryBufferRenderer.getTextureIndex(_Rendering_geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_5__["GeometryBufferRenderer"].VELOCITY_TEXTURE_TYPE);
                    effect.setTexture("velocitySampler", _this._geometryBufferRenderer.getGBuffer().textures[velocityIndex]);
                }
            };
        }
        return _this;
    }
    Object.defineProperty(MotionBlurPostProcess.prototype, "motionBlurSamples", {
        /**
         * Gets the number of iterations are used for motion blur quality. Default value is equal to 32
         */
        get: function () {
            return this._motionBlurSamples;
        },
        /**
         * Sets the number of iterations to be used for motion blur quality
         */
        set: function (samples) {
            this._motionBlurSamples = samples;
            if (this._geometryBufferRenderer) {
                this.updateEffect("#define GEOMETRY_SUPPORTED\n#define SAMPLES " + samples.toFixed(1));
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Excludes the given skinned mesh from computing bones velocities.
     * Computing bones velocities can have a cost and that cost. The cost can be saved by calling this function and by passing the skinned mesh reference to ignore.
     * @param skinnedMesh The mesh containing the skeleton to ignore when computing the velocity map.
     */
    MotionBlurPostProcess.prototype.excludeSkinnedMesh = function (skinnedMesh) {
        if (this._geometryBufferRenderer && skinnedMesh.skeleton) {
            this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity.push(skinnedMesh);
        }
    };
    /**
     * Removes the given skinned mesh from the excluded meshes to integrate bones velocities while rendering the velocity map.
     * @param skinnedMesh The mesh containing the skeleton that has been ignored previously.
     * @see excludeSkinnedMesh to exclude a skinned mesh from bones velocity computation.
     */
    MotionBlurPostProcess.prototype.removeExcludedSkinnedMesh = function (skinnedMesh) {
        if (this._geometryBufferRenderer && skinnedMesh.skeleton) {
            var index = this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity.indexOf(skinnedMesh);
            if (index !== -1) {
                this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity.splice(index, 1);
            }
        }
    };
    /**
     * Disposes the post process.
     * @param camera The camera to dispose the post process on.
     */
    MotionBlurPostProcess.prototype.dispose = function (camera) {
        if (this._geometryBufferRenderer) {
            // Clear previous transformation matrices dictionary used to compute objects velocities
            this._geometryBufferRenderer._previousTransformationMatrices = {};
            this._geometryBufferRenderer._previousBonesTransformationMatrices = {};
            this._geometryBufferRenderer.excludedSkinnedMeshesFromVelocity = [];
        }
        _super.prototype.dispose.call(this, camera);
    };
    return MotionBlurPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_3__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/passPostProcess.ts":
/*!******************************************!*\
  !*** ./PostProcesses/passPostProcess.ts ***!
  \******************************************/
/*! exports provided: PassPostProcess, PassCubePostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PassPostProcess", function() { return PassPostProcess; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PassCubePostProcess", function() { return PassCubePostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");
/* harmony import */ var _Shaders_pass_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/pass.fragment */ "./Shaders/pass.fragment.ts");
/* harmony import */ var _Shaders_passCube_fragment__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Shaders/passCube.fragment */ "./Shaders/passCube.fragment.ts");






/**
 * PassPostProcess which produces an output the same as it's input
 */
var PassPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PassPostProcess, _super);
    /**
     * Creates the PassPostProcess
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType The type of texture to be used when performing the post processing.
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function PassPostProcess(name, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (camera === void 0) { camera = null; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        return _super.call(this, name, "pass", null, null, options, camera, samplingMode, engine, reusable, undefined, textureType, undefined, null, blockCompilation) || this;
    }
    return PassPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));

/**
 * PassCubePostProcess which produces an output the same as it's input (which must be a cube texture)
 */
var PassCubePostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PassCubePostProcess, _super);
    /**
     * Creates the PassCubePostProcess
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType The type of texture to be used when performing the post processing.
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function PassCubePostProcess(name, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (camera === void 0) { camera = null; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_1__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "passCube", null, null, options, camera, samplingMode, engine, reusable, "#define POSITIVEX", textureType, undefined, null, blockCompilation) || this;
        _this._face = 0;
        return _this;
    }
    Object.defineProperty(PassCubePostProcess.prototype, "face", {
        /**
         * Gets or sets the cube face to display.
         *  * 0 is +X
         *  * 1 is -X
         *  * 2 is +Y
         *  * 3 is -Y
         *  * 4 is +Z
         *  * 5 is -Z
         */
        get: function () {
            return this._face;
        },
        set: function (value) {
            if (value < 0 || value > 5) {
                return;
            }
            this._face = value;
            switch (this._face) {
                case 0:
                    this.updateEffect("#define POSITIVEX");
                    break;
                case 1:
                    this.updateEffect("#define NEGATIVEX");
                    break;
                case 2:
                    this.updateEffect("#define POSITIVEY");
                    break;
                case 3:
                    this.updateEffect("#define NEGATIVEY");
                    break;
                case 4:
                    this.updateEffect("#define POSITIVEZ");
                    break;
                case 5:
                    this.updateEffect("#define NEGATIVEZ");
                    break;
            }
        },
        enumerable: true,
        configurable: true
    });
    return PassCubePostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));

_Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"]._RescalePostProcessFactory = function (engine) {
    return new PassPostProcess("rescale", 1, null, _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTURE_BILINEAR_SAMPLINGMODE, engine, false, _Engines_engine__WEBPACK_IMPORTED_MODULE_3__["Engine"].TEXTURETYPE_UNSIGNED_INT);
};


/***/ }),

/***/ "./PostProcesses/postProcess.ts":
/*!**************************************!*\
  !*** ./PostProcesses/postProcess.ts ***!
  \**************************************/
/*! exports provided: PostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcess", function() { return PostProcess; });
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_postprocess_vertex__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/postprocess.vertex */ "./Shaders/postprocess.vertex.ts");
/* harmony import */ var _Engines_engine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/engine */ "./Engines/engine.ts");






/**
 * PostProcess can be used to apply a shader to a texture after it has been rendered
 * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
 */
var PostProcess = /** @class */ (function () {
    /**
     * Creates a new instance PostProcess
     * @param name The name of the PostProcess.
     * @param fragmentUrl The url of the fragment shader to be used.
     * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.
     * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.
     * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param defines String of defines that will be set when running the fragment shader. (default: null)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
     * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
     * @param blockCompilation If the shader should not be compiled imediatly. (default: false)
     */
    function PostProcess(
    /** Name of the PostProcess. */
    name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE; }
        if (defines === void 0) { defines = null; }
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (vertexUrl === void 0) { vertexUrl = "postprocess"; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        this.name = name;
        /**
        * Width of the texture to apply the post process on
        */
        this.width = -1;
        /**
        * Height of the texture to apply the post process on
        */
        this.height = -1;
        /**
        * Internal, reference to the location where this postprocess was output to. (Typically the texture on the next postprocess in the chain)
        * @hidden
        */
        this._outputTexture = null;
        /**
        * If the buffer needs to be cleared before applying the post process. (default: true)
        * Should be set to false if shader will overwrite all previous pixels.
        */
        this.autoClear = true;
        /**
        * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
        */
        this.alphaMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ALPHA_DISABLE;
        /**
        * Animations to be used for the post processing
        */
        this.animations = new Array();
        /**
         * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
         * Can only be used on a single postprocess or on the last one of a chain. (default: false)
         */
        this.enablePixelPerfectMode = false;
        /**
         * Force the postprocess to be applied without taking in account viewport
         */
        this.forceFullscreenViewport = true;
        /**
         * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
         *
         * | Value | Type                                | Description |
         * | ----- | ----------------------------------- | ----------- |
         * | 1     | SCALEMODE_FLOOR                     | [engine.scalemode_floor](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_floor) |
         * | 2     | SCALEMODE_NEAREST                   | [engine.scalemode_nearest](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_nearest) |
         * | 3     | SCALEMODE_CEILING                   | [engine.scalemode_ceiling](http://doc.babylonjs.com/api/classes/babylon.engine#scalemode_ceiling) |
         *
         */
        this.scaleMode = _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].SCALEMODE_FLOOR;
        /**
        * Force textures to be a power of two (default: false)
        */
        this.alwaysForcePOT = false;
        this._samples = 1;
        /**
        * Modify the scale of the post process to be the same as the viewport (default: false)
        */
        this.adaptScaleToCurrentViewport = false;
        this._reusable = false;
        /**
        * Smart array of input and output textures for the post process.
        * @hidden
        */
        this._textures = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](2);
        /**
        * The index in _textures that corresponds to the output texture.
        * @hidden
        */
        this._currentRenderTextureInd = 0;
        this._scaleRatio = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"](1, 1);
        this._texelSize = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__["Vector2"].Zero();
        // Events
        /**
        * An event triggered when the postprocess is activated.
        */
        this.onActivateObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered when the postprocess changes its size.
        */
        this.onSizeChangedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered when the postprocess applies its effect.
        */
        this.onApplyObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered before rendering the postprocess
        */
        this.onBeforeRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        /**
        * An event triggered after rendering the postprocess
        */
        this.onAfterRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        if (camera != null) {
            this._camera = camera;
            this._scene = camera.getScene();
            camera.attachPostProcess(this);
            this._engine = this._scene.getEngine();
            this._scene.postProcesses.push(this);
            this.uniqueId = this._scene.getUniqueId();
        }
        else if (engine) {
            this._engine = engine;
            this._engine.postProcesses.push(this);
        }
        this._options = options;
        this.renderTargetSamplingMode = samplingMode ? samplingMode : _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_NEAREST_SAMPLINGMODE;
        this._reusable = reusable || false;
        this._textureType = textureType;
        this._samplers = samplers || [];
        this._samplers.push("textureSampler");
        this._fragmentUrl = fragmentUrl;
        this._vertexUrl = vertexUrl;
        this._parameters = parameters || [];
        this._parameters.push("scale");
        this._indexParameters = indexParameters;
        if (!blockCompilation) {
            this.updateEffect(defines);
        }
    }
    Object.defineProperty(PostProcess.prototype, "samples", {
        /**
        * Number of sample textures (default: 1)
        */
        get: function () {
            return this._samples;
        },
        set: function (n) {
            var _this = this;
            this._samples = Math.min(n, this._engine.getCaps().maxMSAASamples);
            this._textures.forEach(function (texture) {
                if (texture.samples !== _this._samples) {
                    _this._engine.updateRenderTargetTextureSampleCount(texture, _this._samples);
                }
            });
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the fragment url or shader name used in the post process.
     * @returns the fragment url or name in the shader store.
     */
    PostProcess.prototype.getEffectName = function () {
        return this._fragmentUrl;
    };
    Object.defineProperty(PostProcess.prototype, "onActivate", {
        /**
        * A function that is added to the onActivateObservable
        */
        set: function (callback) {
            if (this._onActivateObserver) {
                this.onActivateObservable.remove(this._onActivateObserver);
            }
            if (callback) {
                this._onActivateObserver = this.onActivateObservable.add(callback);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PostProcess.prototype, "onSizeChanged", {
        /**
        * A function that is added to the onSizeChangedObservable
        */
        set: function (callback) {
            if (this._onSizeChangedObserver) {
                this.onSizeChangedObservable.remove(this._onSizeChangedObserver);
            }
            this._onSizeChangedObserver = this.onSizeChangedObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PostProcess.prototype, "onApply", {
        /**
        * A function that is added to the onApplyObservable
        */
        set: function (callback) {
            if (this._onApplyObserver) {
                this.onApplyObservable.remove(this._onApplyObserver);
            }
            this._onApplyObserver = this.onApplyObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PostProcess.prototype, "onBeforeRender", {
        /**
        * A function that is added to the onBeforeRenderObservable
        */
        set: function (callback) {
            if (this._onBeforeRenderObserver) {
                this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
            }
            this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PostProcess.prototype, "onAfterRender", {
        /**
        * A function that is added to the onAfterRenderObservable
        */
        set: function (callback) {
            if (this._onAfterRenderObserver) {
                this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
            }
            this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PostProcess.prototype, "inputTexture", {
        /**
        * The input texture for this post process and the output texture of the previous post process. When added to a pipeline the previous post process will
        * render it's output into this texture and this texture will be used as textureSampler in the fragment shader of this post process.
        */
        get: function () {
            return this._textures.data[this._currentRenderTextureInd];
        },
        set: function (value) {
            this._forcedOutputTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
    * Gets the camera which post process is applied to.
    * @returns The camera the post process is applied to.
    */
    PostProcess.prototype.getCamera = function () {
        return this._camera;
    };
    Object.defineProperty(PostProcess.prototype, "texelSize", {
        /**
        * Gets the texel size of the postprocess.
        * See https://en.wikipedia.org/wiki/Texel_(graphics)
        */
        get: function () {
            if (this._shareOutputWithPostProcess) {
                return this._shareOutputWithPostProcess.texelSize;
            }
            if (this._forcedOutputTexture) {
                this._texelSize.copyFromFloats(1.0 / this._forcedOutputTexture.width, 1.0 / this._forcedOutputTexture.height);
            }
            return this._texelSize;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets a string idenfifying the name of the class
     * @returns "PostProcess" string
     */
    PostProcess.prototype.getClassName = function () {
        return "PostProcess";
    };
    /**
     * Gets the engine which this post process belongs to.
     * @returns The engine the post process was enabled with.
     */
    PostProcess.prototype.getEngine = function () {
        return this._engine;
    };
    /**
     * The effect that is created when initializing the post process.
     * @returns The created effect corresponding the the postprocess.
     */
    PostProcess.prototype.getEffect = function () {
        return this._effect;
    };
    /**
     * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.
     * @param postProcess The post process to share the output with.
     * @returns This post process.
     */
    PostProcess.prototype.shareOutputWith = function (postProcess) {
        this._disposeTextures();
        this._shareOutputWithPostProcess = postProcess;
        return this;
    };
    /**
     * Reverses the effect of calling shareOutputWith and returns the post process back to its original state.
     * This should be called if the post process that shares output with this post process is disabled/disposed.
     */
    PostProcess.prototype.useOwnOutput = function () {
        if (this._textures.length == 0) {
            this._textures = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](2);
        }
        this._shareOutputWithPostProcess = null;
    };
    /**
     * Updates the effect with the current post process compile time values and recompiles the shader.
     * @param defines Define statements that should be added at the beginning of the shader. (default: null)
     * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
     * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
     * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
     * @param onCompiled Called when the shader has been compiled.
     * @param onError Called if there is an error when compiling a shader.
     */
    PostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
        if (defines === void 0) { defines = null; }
        if (uniforms === void 0) { uniforms = null; }
        if (samplers === void 0) { samplers = null; }
        this._effect = this._engine.createEffect({ vertex: this._vertexUrl, fragment: this._fragmentUrl }, ["position"], uniforms || this._parameters, samplers || this._samplers, defines !== null ? defines : "", undefined, onCompiled, onError, indexParameters || this._indexParameters);
    };
    /**
     * The post process is reusable if it can be used multiple times within one frame.
     * @returns If the post process is reusable
     */
    PostProcess.prototype.isReusable = function () {
        return this._reusable;
    };
    /** invalidate frameBuffer to hint the postprocess to create a depth buffer */
    PostProcess.prototype.markTextureDirty = function () {
        this.width = -1;
    };
    /**
     * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
     * When this post process is used in a pipeline, this is call will bind the input texture of this post process to the output of the previous.
     * @param camera The camera that will be used in the post process. This camera will be used when calling onActivateObservable.
     * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)
     * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)
     * @returns The target texture that was bound to be written to.
     */
    PostProcess.prototype.activate = function (camera, sourceTexture, forceDepthStencil) {
        var _this = this;
        if (sourceTexture === void 0) { sourceTexture = null; }
        camera = camera || this._camera;
        var scene = camera.getScene();
        var engine = scene.getEngine();
        var maxSize = engine.getCaps().maxTextureSize;
        var requiredWidth = ((sourceTexture ? sourceTexture.width : this._engine.getRenderWidth(true)) * this._options) | 0;
        var requiredHeight = ((sourceTexture ? sourceTexture.height : this._engine.getRenderHeight(true)) * this._options) | 0;
        // If rendering to a webvr camera's left or right eye only half the width should be used to avoid resize when rendered to screen
        var webVRCamera = camera.parent;
        if (webVRCamera && (webVRCamera.leftCamera == camera || webVRCamera.rightCamera == camera)) {
            requiredWidth /= 2;
        }
        var desiredWidth = (this._options.width || requiredWidth);
        var desiredHeight = this._options.height || requiredHeight;
        if (!this._shareOutputWithPostProcess && !this._forcedOutputTexture) {
            if (this.adaptScaleToCurrentViewport) {
                var currentViewport = engine.currentViewport;
                if (currentViewport) {
                    desiredWidth *= currentViewport.width;
                    desiredHeight *= currentViewport.height;
                }
            }
            if (this.renderTargetSamplingMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].TEXTURE_TRILINEAR_SAMPLINGMODE || this.alwaysForcePOT) {
                if (!this._options.width) {
                    desiredWidth = engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].GetExponentOfTwo(desiredWidth, maxSize, this.scaleMode) : desiredWidth;
                }
                if (!this._options.height) {
                    desiredHeight = engine.needPOTTextures ? _Engines_engine__WEBPACK_IMPORTED_MODULE_5__["Engine"].GetExponentOfTwo(desiredHeight, maxSize, this.scaleMode) : desiredHeight;
                }
            }
            if (this.width !== desiredWidth || this.height !== desiredHeight) {
                if (this._textures.length > 0) {
                    for (var i = 0; i < this._textures.length; i++) {
                        this._engine._releaseTexture(this._textures.data[i]);
                    }
                    this._textures.reset();
                }
                this.width = desiredWidth;
                this.height = desiredHeight;
                var textureSize = { width: this.width, height: this.height };
                var textureOptions = {
                    generateMipMaps: false,
                    generateDepthBuffer: forceDepthStencil || camera._postProcesses.indexOf(this) === 0,
                    generateStencilBuffer: (forceDepthStencil || camera._postProcesses.indexOf(this) === 0) && this._engine.isStencilEnable,
                    samplingMode: this.renderTargetSamplingMode,
                    type: this._textureType
                };
                this._textures.push(this._engine.createRenderTargetTexture(textureSize, textureOptions));
                if (this._reusable) {
                    this._textures.push(this._engine.createRenderTargetTexture(textureSize, textureOptions));
                }
                this._texelSize.copyFromFloats(1.0 / this.width, 1.0 / this.height);
                this.onSizeChangedObservable.notifyObservers(this);
            }
            this._textures.forEach(function (texture) {
                if (texture.samples !== _this.samples) {
                    _this._engine.updateRenderTargetTextureSampleCount(texture, _this.samples);
                }
            });
        }
        var target;
        if (this._shareOutputWithPostProcess) {
            target = this._shareOutputWithPostProcess.inputTexture;
        }
        else if (this._forcedOutputTexture) {
            target = this._forcedOutputTexture;
            this.width = this._forcedOutputTexture.width;
            this.height = this._forcedOutputTexture.height;
        }
        else {
            target = this.inputTexture;
        }
        // Bind the input of this post process to be used as the output of the previous post process.
        if (this.enablePixelPerfectMode) {
            this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);
            this._engine.bindFramebuffer(target, 0, requiredWidth, requiredHeight, this.forceFullscreenViewport);
        }
        else {
            this._scaleRatio.copyFromFloats(1, 1);
            this._engine.bindFramebuffer(target, 0, undefined, undefined, this.forceFullscreenViewport);
        }
        this.onActivateObservable.notifyObservers(camera);
        // Clear
        if (this.autoClear && this.alphaMode === _Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ALPHA_DISABLE) {
            this._engine.clear(this.clearColor ? this.clearColor : scene.clearColor, scene._allowPostProcessClearColor, true, true);
        }
        if (this._reusable) {
            this._currentRenderTextureInd = (this._currentRenderTextureInd + 1) % 2;
        }
        return target;
    };
    Object.defineProperty(PostProcess.prototype, "isSupported", {
        /**
         * If the post process is supported.
         */
        get: function () {
            return this._effect.isSupported;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PostProcess.prototype, "aspectRatio", {
        /**
         * The aspect ratio of the output texture.
         */
        get: function () {
            if (this._shareOutputWithPostProcess) {
                return this._shareOutputWithPostProcess.aspectRatio;
            }
            if (this._forcedOutputTexture) {
                return this._forcedOutputTexture.width / this._forcedOutputTexture.height;
            }
            return this.width / this.height;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Get a value indicating if the post-process is ready to be used
     * @returns true if the post-process is ready (shader is compiled)
     */
    PostProcess.prototype.isReady = function () {
        return this._effect && this._effect.isReady();
    };
    /**
     * Binds all textures and uniforms to the shader, this will be run on every pass.
     * @returns the effect corresponding to this post process. Null if not compiled or not ready.
     */
    PostProcess.prototype.apply = function () {
        // Check
        if (!this._effect || !this._effect.isReady()) {
            return null;
        }
        // States
        this._engine.enableEffect(this._effect);
        this._engine.setState(false);
        this._engine.setDepthBuffer(false);
        this._engine.setDepthWrite(false);
        // Alpha
        this._engine.setAlphaMode(this.alphaMode);
        if (this.alphaConstants) {
            this.getEngine().setAlphaConstants(this.alphaConstants.r, this.alphaConstants.g, this.alphaConstants.b, this.alphaConstants.a);
        }
        // Bind the output texture of the preivous post process as the input to this post process.
        var source;
        if (this._shareOutputWithPostProcess) {
            source = this._shareOutputWithPostProcess.inputTexture;
        }
        else if (this._forcedOutputTexture) {
            source = this._forcedOutputTexture;
        }
        else {
            source = this.inputTexture;
        }
        this._effect._bindTexture("textureSampler", source);
        // Parameters
        this._effect.setVector2("scale", this._scaleRatio);
        this.onApplyObservable.notifyObservers(this._effect);
        return this._effect;
    };
    PostProcess.prototype._disposeTextures = function () {
        if (this._shareOutputWithPostProcess || this._forcedOutputTexture) {
            return;
        }
        if (this._textures.length > 0) {
            for (var i = 0; i < this._textures.length; i++) {
                this._engine._releaseTexture(this._textures.data[i]);
            }
        }
        this._textures.dispose();
    };
    /**
     * Disposes the post process.
     * @param camera The camera to dispose the post process on.
     */
    PostProcess.prototype.dispose = function (camera) {
        camera = camera || this._camera;
        this._disposeTextures();
        if (this._scene) {
            var index_1 = this._scene.postProcesses.indexOf(this);
            if (index_1 !== -1) {
                this._scene.postProcesses.splice(index_1, 1);
            }
        }
        else {
            var index_2 = this._engine.postProcesses.indexOf(this);
            if (index_2 !== -1) {
                this._engine.postProcesses.splice(index_2, 1);
            }
        }
        if (!camera) {
            return;
        }
        camera.detachPostProcess(this);
        var index = camera._postProcesses.indexOf(this);
        if (index === 0 && camera._postProcesses.length > 0) {
            var firstPostProcess = this._camera._getFirstPostProcess();
            if (firstPostProcess) {
                firstPostProcess.markTextureDirty();
            }
        }
        this.onActivateObservable.clear();
        this.onAfterRenderObservable.clear();
        this.onApplyObservable.clear();
        this.onBeforeRenderObservable.clear();
        this.onSizeChangedObservable.clear();
    };
    return PostProcess;
}());



/***/ }),

/***/ "./PostProcesses/postProcessManager.ts":
/*!*********************************************!*\
  !*** ./PostProcesses/postProcessManager.ts ***!
  \*********************************************/
/*! exports provided: PostProcessManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PostProcessManager", function() { return PostProcessManager; });
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");



/**
 * PostProcessManager is used to manage one or more post processes or post process pipelines
 * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
 */
var PostProcessManager = /** @class */ (function () {
    /**
     * Creates a new instance PostProcess
     * @param scene The scene that the post process is associated with.
     */
    function PostProcessManager(scene) {
        this._vertexBuffers = {};
        this._scene = scene;
    }
    PostProcessManager.prototype._prepareBuffers = function () {
        if (this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind]) {
            return;
        }
        // VBO
        var vertices = [];
        vertices.push(1, 1);
        vertices.push(-1, 1);
        vertices.push(-1, -1);
        vertices.push(1, -1);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"](this._scene.getEngine(), vertices, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, false, false, 2);
        this._buildIndexBuffer();
    };
    PostProcessManager.prototype._buildIndexBuffer = function () {
        // Indices
        var indices = [];
        indices.push(0);
        indices.push(1);
        indices.push(2);
        indices.push(0);
        indices.push(2);
        indices.push(3);
        this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
    };
    /**
     * Rebuilds the vertex buffers of the manager.
     * @hidden
     */
    PostProcessManager.prototype._rebuild = function () {
        var vb = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        if (!vb) {
            return;
        }
        vb._rebuild();
        this._buildIndexBuffer();
    };
    // Methods
    /**
     * Prepares a frame to be run through a post process.
     * @param sourceTexture The input texture to the post procesess. (default: null)
     * @param postProcesses An array of post processes to be run. (default: null)
     * @returns True if the post processes were able to be run.
     * @hidden
     */
    PostProcessManager.prototype._prepareFrame = function (sourceTexture, postProcesses) {
        if (sourceTexture === void 0) { sourceTexture = null; }
        if (postProcesses === void 0) { postProcesses = null; }
        var camera = this._scene.activeCamera;
        if (!camera) {
            return false;
        }
        postProcesses = postProcesses || camera._postProcesses.filter(function (pp) { return pp != null; });
        if (!postProcesses || postProcesses.length === 0 || !this._scene.postProcessesEnabled) {
            return false;
        }
        postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);
        return true;
    };
    /**
     * Manually render a set of post processes to a texture.
     * @param postProcesses An array of post processes to be run.
     * @param targetTexture The target texture to render to.
     * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight
     * @param faceIndex defines the face to render to if a cubemap is defined as the target
     * @param lodLevel defines which lod of the texture to render to
     */
    PostProcessManager.prototype.directRender = function (postProcesses, targetTexture, forceFullscreenViewport, faceIndex, lodLevel) {
        if (targetTexture === void 0) { targetTexture = null; }
        if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
        if (faceIndex === void 0) { faceIndex = 0; }
        if (lodLevel === void 0) { lodLevel = 0; }
        var engine = this._scene.getEngine();
        for (var index = 0; index < postProcesses.length; index++) {
            if (index < postProcesses.length - 1) {
                postProcesses[index + 1].activate(this._scene.activeCamera, targetTexture);
            }
            else {
                if (targetTexture) {
                    engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport, undefined, lodLevel);
                }
                else {
                    engine.restoreDefaultFramebuffer();
                }
            }
            var pp = postProcesses[index];
            var effect = pp.apply();
            if (effect) {
                pp.onBeforeRenderObservable.notifyObservers(effect);
                // VBOs
                this._prepareBuffers();
                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
                // Draw order
                engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_0__["Material"].TriangleFillMode, 0, 6);
                pp.onAfterRenderObservable.notifyObservers(effect);
            }
        }
        // Restore depth buffer
        engine.setDepthBuffer(true);
        engine.setDepthWrite(true);
    };
    /**
     * Finalize the result of the output of the postprocesses.
     * @param doNotPresent If true the result will not be displayed to the screen.
     * @param targetTexture The target texture to render to.
     * @param faceIndex The index of the face to bind the target texture to.
     * @param postProcesses The array of post processes to render.
     * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)
     * @hidden
     */
    PostProcessManager.prototype._finalizeFrame = function (doNotPresent, targetTexture, faceIndex, postProcesses, forceFullscreenViewport) {
        if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
        var camera = this._scene.activeCamera;
        if (!camera) {
            return;
        }
        postProcesses = postProcesses || camera._postProcesses.filter(function (pp) { return pp != null; });
        if (postProcesses.length === 0 || !this._scene.postProcessesEnabled) {
            return;
        }
        var engine = this._scene.getEngine();
        for (var index = 0, len = postProcesses.length; index < len; index++) {
            var pp = postProcesses[index];
            if (index < len - 1) {
                pp._outputTexture = postProcesses[index + 1].activate(camera, targetTexture);
            }
            else {
                if (targetTexture) {
                    engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport);
                    pp._outputTexture = targetTexture;
                }
                else {
                    engine.restoreDefaultFramebuffer();
                    pp._outputTexture = null;
                }
            }
            if (doNotPresent) {
                break;
            }
            var effect = pp.apply();
            if (effect) {
                pp.onBeforeRenderObservable.notifyObservers(effect);
                // VBOs
                this._prepareBuffers();
                engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
                // Draw order
                engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_0__["Material"].TriangleFillMode, 0, 6);
                pp.onAfterRenderObservable.notifyObservers(effect);
            }
        }
        // Restore states
        engine.setDepthBuffer(true);
        engine.setDepthWrite(true);
        engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].ALPHA_DISABLE);
    };
    /**
     * Disposes of the post process manager.
     */
    PostProcessManager.prototype.dispose = function () {
        var buffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        if (buffer) {
            buffer.dispose();
            this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = null;
        }
        if (this._indexBuffer) {
            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
            this._indexBuffer = null;
        }
    };
    return PostProcessManager;
}());



/***/ }),

/***/ "./PostProcesses/refractionPostProcess.ts":
/*!************************************************!*\
  !*** ./PostProcesses/refractionPostProcess.ts ***!
  \************************************************/
/*! exports provided: RefractionPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RefractionPostProcess", function() { return RefractionPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_refraction_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/refraction.fragment */ "./Shaders/refraction.fragment.ts");




/**
 * Post process which applies a refractin texture
 * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#refraction
 */
var RefractionPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RefractionPostProcess, _super);
    /**
     * Initializes the RefractionPostProcess
     * @see https://doc.babylonjs.com/how_to/how_to_use_postprocesses#refraction
     * @param name The name of the effect.
     * @param refractionTextureUrl Url of the refraction texture to use
     * @param color the base color of the refraction (used to taint the rendering)
     * @param depth simulated refraction depth
     * @param colorLevel the coefficient of the base color (0 to remove base color tainting)
     * @param camera The camera to apply the render pass to.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     */
    function RefractionPostProcess(name, refractionTextureUrl,
    /** the base color of the refraction (used to taint the rendering) */
    color,
    /** simulated refraction depth */
    depth,
    /** the coefficient of the base color (0 to remove base color tainting) */
    colorLevel, options, camera, samplingMode, engine, reusable) {
        var _this = _super.call(this, name, "refraction", ["baseColor", "depth", "colorLevel"], ["refractionSampler"], options, camera, samplingMode, engine, reusable) || this;
        _this.color = color;
        _this.depth = depth;
        _this.colorLevel = colorLevel;
        _this._ownRefractionTexture = true;
        _this.onActivateObservable.add(function (cam) {
            _this._refTexture = _this._refTexture || new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"](refractionTextureUrl, cam.getScene());
        });
        _this.onApplyObservable.add(function (effect) {
            effect.setColor3("baseColor", _this.color);
            effect.setFloat("depth", _this.depth);
            effect.setFloat("colorLevel", _this.colorLevel);
            effect.setTexture("refractionSampler", _this._refTexture);
        });
        return _this;
    }
    Object.defineProperty(RefractionPostProcess.prototype, "refractionTexture", {
        /**
         * Gets or sets the refraction texture
         * Please note that you are responsible for disposing the texture if you set it manually
         */
        get: function () {
            return this._refTexture;
        },
        set: function (value) {
            if (this._refTexture && this._ownRefractionTexture) {
                this._refTexture.dispose();
            }
            this._refTexture = value;
            this._ownRefractionTexture = false;
        },
        enumerable: true,
        configurable: true
    });
    // Methods
    /**
     * Disposes of the post process
     * @param camera Camera to dispose post process on
     */
    RefractionPostProcess.prototype.dispose = function (camera) {
        if (this._refTexture && this._ownRefractionTexture) {
            this._refTexture.dispose();
            this._refTexture = null;
        }
        _super.prototype.dispose.call(this, camera);
    };
    return RefractionPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/sharpenPostProcess.ts":
/*!*********************************************!*\
  !*** ./PostProcesses/sharpenPostProcess.ts ***!
  \*********************************************/
/*! exports provided: SharpenPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SharpenPostProcess", function() { return SharpenPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_sharpen_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/sharpen.fragment */ "./Shaders/sharpen.fragment.ts");




/**
 * The SharpenPostProcess applies a sharpen kernel to every pixel
 * See http://en.wikipedia.org/wiki/Kernel_(image_processing)
 */
var SharpenPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SharpenPostProcess, _super);
    /**
     * Creates a new instance ConvolutionPostProcess
     * @param name The name of the effect.
     * @param options The required width/height ratio to downsize to before computing the render pass.
     * @param camera The camera to apply the render pass to.
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     * @param textureType Type of textures used when performing the post process. (default: 0)
     * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
     */
    function SharpenPostProcess(name, options, camera, samplingMode, engine, reusable, textureType, blockCompilation) {
        if (textureType === void 0) { textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        if (blockCompilation === void 0) { blockCompilation = false; }
        var _this = _super.call(this, name, "sharpen", ["sharpnessAmounts", "screenSize"], null, options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, blockCompilation) || this;
        /**
         * How much of the original color should be applied. Setting this to 0 will display edge detection. (default: 1)
         */
        _this.colorAmount = 1.0;
        /**
         * How much sharpness should be applied (default: 0.3)
         */
        _this.edgeAmount = 0.3;
        _this.onApply = function (effect) {
            effect.setFloat2("screenSize", _this.width, _this.height);
            effect.setFloat2("sharpnessAmounts", _this.edgeAmount, _this.colorAmount);
        };
        return _this;
    }
    return SharpenPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/stereoscopicInterlacePostProcess.ts":
/*!***********************************************************!*\
  !*** ./PostProcesses/stereoscopicInterlacePostProcess.ts ***!
  \***********************************************************/
/*! exports provided: StereoscopicInterlacePostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StereoscopicInterlacePostProcess", function() { return StereoscopicInterlacePostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_stereoscopicInterlace_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/stereoscopicInterlace.fragment */ "./Shaders/stereoscopicInterlace.fragment.ts");




/**
 * StereoscopicInterlacePostProcess used to render stereo views from a rigged camera
 */
var StereoscopicInterlacePostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](StereoscopicInterlacePostProcess, _super);
    /**
     * Initializes a StereoscopicInterlacePostProcess
     * @param name The name of the effect.
     * @param rigCameras The rig cameras to be appled to the post process
     * @param isStereoscopicHoriz If the rendered results are horizontal or verticle
     * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
     * @param engine The engine which the post process will be applied. (default: current engine)
     * @param reusable If the post process can be reused on the same frame. (default: false)
     */
    function StereoscopicInterlacePostProcess(name, rigCameras, isStereoscopicHoriz, samplingMode, engine, reusable) {
        var _this = _super.call(this, name, "stereoscopicInterlace", ['stepSize'], ['camASampler'], 1, rigCameras[1], samplingMode, engine, reusable, isStereoscopicHoriz ? "#define IS_STEREOSCOPIC_HORIZ 1" : undefined) || this;
        _this._passedProcess = rigCameras[0]._rigPostProcess;
        _this._stepSize = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1 / _this.width, 1 / _this.height);
        _this.onSizeChangedObservable.add(function () {
            _this._stepSize = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](1 / _this.width, 1 / _this.height);
        });
        _this.onApplyObservable.add(function (effect) {
            effect.setTextureFromPostProcess("camASampler", _this._passedProcess);
            effect.setFloat2("stepSize", _this._stepSize.x, _this._stepSize.y);
        });
        return _this;
    }
    return StereoscopicInterlacePostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/tonemapPostProcess.ts":
/*!*********************************************!*\
  !*** ./PostProcesses/tonemapPostProcess.ts ***!
  \*********************************************/
/*! exports provided: TonemappingOperator, TonemapPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TonemappingOperator", function() { return TonemappingOperator; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TonemapPostProcess", function() { return TonemapPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_tonemap_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/tonemap.fragment */ "./Shaders/tonemap.fragment.ts");




/** Defines operator used for tonemapping */
var TonemappingOperator;
(function (TonemappingOperator) {
    /** Hable */
    TonemappingOperator[TonemappingOperator["Hable"] = 0] = "Hable";
    /** Reinhard */
    TonemappingOperator[TonemappingOperator["Reinhard"] = 1] = "Reinhard";
    /** HejiDawson */
    TonemappingOperator[TonemappingOperator["HejiDawson"] = 2] = "HejiDawson";
    /** Photographic */
    TonemappingOperator[TonemappingOperator["Photographic"] = 3] = "Photographic";
})(TonemappingOperator || (TonemappingOperator = {}));
/**
 * Defines a post process to apply tone mapping
 */
var TonemapPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TonemapPostProcess, _super);
    /**
     * Creates a new TonemapPostProcess
     * @param name defines the name of the postprocess
     * @param _operator defines the operator to use
     * @param exposureAdjustment defines the required exposure adjustement
     * @param camera defines the camera to use (can be null)
     * @param samplingMode defines the required sampling mode (BABYLON.Texture.BILINEAR_SAMPLINGMODE by default)
     * @param engine defines the hosting engine (can be ignore if camera is set)
     * @param textureFormat defines the texture format to use (BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT by default)
     */
    function TonemapPostProcess(name, _operator,
    /** Defines the required exposure adjustement */
    exposureAdjustment, camera, samplingMode, engine, textureFormat) {
        if (samplingMode === void 0) { samplingMode = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURE_BILINEAR_SAMPLINGMODE; }
        if (textureFormat === void 0) { textureFormat = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_INT; }
        var _this = _super.call(this, name, "tonemap", ["_ExposureAdjustment"], null, 1.0, camera, samplingMode, engine, true, null, textureFormat) || this;
        _this._operator = _operator;
        _this.exposureAdjustment = exposureAdjustment;
        var defines = "#define ";
        if (_this._operator === TonemappingOperator.Hable) {
            defines += "HABLE_TONEMAPPING";
        }
        else if (_this._operator === TonemappingOperator.Reinhard) {
            defines += "REINHARD_TONEMAPPING";
        }
        else if (_this._operator === TonemappingOperator.HejiDawson) {
            defines += "OPTIMIZED_HEJIDAWSON_TONEMAPPING";
        }
        else if (_this._operator === TonemappingOperator.Photographic) {
            defines += "PHOTOGRAPHIC_TONEMAPPING";
        }
        //sadly a second call to create the effect.
        _this.updateEffect(defines);
        _this.onApply = function (effect) {
            effect.setFloat("_ExposureAdjustment", _this.exposureAdjustment);
        };
        return _this;
    }
    return TonemapPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_1__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/volumetricLightScatteringPostProcess.ts":
/*!***************************************************************!*\
  !*** ./PostProcesses/volumetricLightScatteringPostProcess.ts ***!
  \***************************************************************/
/*! exports provided: VolumetricLightScatteringPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VolumetricLightScatteringPostProcess", function() { return VolumetricLightScatteringPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Meshes/mesh */ "./Meshes/mesh.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Materials/standardMaterial */ "./Materials/standardMaterial.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Meshes_Builders_planeBuilder__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../Meshes/Builders/planeBuilder */ "./Meshes/Builders/planeBuilder.ts");
/* harmony import */ var _Shaders_depth_vertex__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../Shaders/depth.vertex */ "./Shaders/depth.vertex.ts");
/* harmony import */ var _Shaders_volumetricLightScattering_fragment__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../Shaders/volumetricLightScattering.fragment */ "./Shaders/volumetricLightScattering.fragment.ts");
/* harmony import */ var _Shaders_volumetricLightScatteringPass_vertex__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../Shaders/volumetricLightScatteringPass.vertex */ "./Shaders/volumetricLightScatteringPass.vertex.ts");
/* harmony import */ var _Shaders_volumetricLightScatteringPass_fragment__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../Shaders/volumetricLightScatteringPass.fragment */ "./Shaders/volumetricLightScatteringPass.fragment.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../Maths/math.viewport */ "./Maths/math.viewport.ts");





















/**
 *  Inspired by http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html
 */
var VolumetricLightScatteringPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VolumetricLightScatteringPostProcess, _super);
    /**
     * @constructor
     * @param name The post-process name
     * @param ratio The size of the post-process and/or internal pass (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5)
     * @param camera The camera that the post-process will be attached to
     * @param mesh The mesh used to create the light scattering
     * @param samples The post-process quality, default 100
     * @param samplingModeThe post-process filtering mode
     * @param engine The babylon engine
     * @param reusable If the post-process is reusable
     * @param scene The constructor needs a scene reference to initialize internal components. If "camera" is null a "scene" must be provided
     */
    function VolumetricLightScatteringPostProcess(name, ratio, camera, mesh, samples, samplingMode, engine, reusable, scene) {
        if (samples === void 0) { samples = 100; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__["Texture"].BILINEAR_SAMPLINGMODE; }
        var _this = _super.call(this, name, "volumetricLightScattering", ["decay", "exposure", "weight", "meshPositionOnScreen", "density"], ["lightScatteringSampler"], ratio.postProcessRatio || ratio, camera, samplingMode, engine, reusable, "#define NUM_SAMPLES " + samples) || this;
        _this._screenCoordinates = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector2"].Zero();
        /**
        * Custom position of the mesh. Used if "useCustomMeshPosition" is set to "true"
        */
        _this.customMeshPosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        /**
        * Set if the post-process should use a custom position for the light source (true) or the internal mesh position (false)
        */
        _this.useCustomMeshPosition = false;
        /**
        * If the post-process should inverse the light scattering direction
        */
        _this.invert = true;
        /**
        * Array containing the excluded meshes not rendered in the internal pass
        */
        _this.excludedMeshes = new Array();
        /**
        * Controls the overall intensity of the post-process
        */
        _this.exposure = 0.3;
        /**
        * Dissipates each sample's contribution in range [0, 1]
        */
        _this.decay = 0.96815;
        /**
        * Controls the overall intensity of each sample
        */
        _this.weight = 0.58767;
        /**
        * Controls the density of each sample
        */
        _this.density = 0.926;
        scene = ((camera === null) ? scene : camera.getScene()); // parameter "scene" can be null.
        engine = scene.getEngine();
        _this._viewPort = new _Maths_math_viewport__WEBPACK_IMPORTED_MODULE_20__["Viewport"](0, 0, 1, 1).toGlobal(engine.getRenderWidth(), engine.getRenderHeight());
        // Configure mesh
        _this.mesh = ((mesh !== null) ? mesh : VolumetricLightScatteringPostProcess.CreateDefaultMesh("VolumetricLightScatteringMesh", scene));
        // Configure
        _this._createPass(scene, ratio.passRatio || ratio);
        _this.onActivate = function (camera) {
            if (!_this.isSupported) {
                _this.dispose(camera);
            }
            _this.onActivate = null;
        };
        _this.onApplyObservable.add(function (effect) {
            _this._updateMeshScreenCoordinates(scene);
            effect.setTexture("lightScatteringSampler", _this._volumetricLightScatteringRTT);
            effect.setFloat("exposure", _this.exposure);
            effect.setFloat("decay", _this.decay);
            effect.setFloat("weight", _this.weight);
            effect.setFloat("density", _this.density);
            effect.setVector2("meshPositionOnScreen", _this._screenCoordinates);
        });
        return _this;
    }
    Object.defineProperty(VolumetricLightScatteringPostProcess.prototype, "useDiffuseColor", {
        /**
         * @hidden
         * VolumetricLightScatteringPostProcess.useDiffuseColor is no longer used, use the mesh material directly instead
         */
        get: function () {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("VolumetricLightScatteringPostProcess.useDiffuseColor is no longer used, use the mesh material directly instead");
            return false;
        },
        set: function (useDiffuseColor) {
            _Misc_logger__WEBPACK_IMPORTED_MODULE_2__["Logger"].Warn("VolumetricLightScatteringPostProcess.useDiffuseColor is no longer used, use the mesh material directly instead");
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the string "VolumetricLightScatteringPostProcess"
     * @returns "VolumetricLightScatteringPostProcess"
     */
    VolumetricLightScatteringPostProcess.prototype.getClassName = function () {
        return "VolumetricLightScatteringPostProcess";
    };
    VolumetricLightScatteringPostProcess.prototype._isReady = function (subMesh, useInstances) {
        var mesh = subMesh.getMesh();
        // Render this.mesh as default
        if (mesh === this.mesh && mesh.material) {
            return mesh.material.isReady(mesh);
        }
        var defines = [];
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].PositionKind];
        var material = subMesh.getMaterial();
        // Alpha test
        if (material) {
            if (material.needAlphaTesting()) {
                defines.push("#define ALPHATEST");
            }
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].UVKind)) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].UVKind);
                defines.push("#define UV1");
            }
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].UV2Kind)) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].UV2Kind);
                defines.push("#define UV2");
            }
        }
        // Bones
        if (mesh.useBones && mesh.computeBonesUsingShaders) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_4__["VertexBuffer"].MatricesWeightsKind);
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            defines.push("#define BonesPerMesh " + (mesh.skeleton ? (mesh.skeleton.bones.length + 1) : 0));
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Instances
        if (useInstances) {
            defines.push("#define INSTANCES");
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_8__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        // Get correct effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            this._volumetricLightScatteringPass = mesh.getScene().getEngine().createEffect("volumetricLightScatteringPass", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix"], ["diffuseSampler"], join, undefined, undefined, undefined, { maxSimultaneousMorphTargets: mesh.numBoneInfluencers });
        }
        return this._volumetricLightScatteringPass.isReady();
    };
    /**
     * Sets the new light position for light scattering effect
     * @param position The new custom light position
     */
    VolumetricLightScatteringPostProcess.prototype.setCustomMeshPosition = function (position) {
        this.customMeshPosition = position;
    };
    /**
     * Returns the light position for light scattering effect
     * @return Vector3 The custom light position
     */
    VolumetricLightScatteringPostProcess.prototype.getCustomMeshPosition = function () {
        return this.customMeshPosition;
    };
    /**
     * Disposes the internal assets and detaches the post-process from the camera
     */
    VolumetricLightScatteringPostProcess.prototype.dispose = function (camera) {
        var rttIndex = camera.getScene().customRenderTargets.indexOf(this._volumetricLightScatteringRTT);
        if (rttIndex !== -1) {
            camera.getScene().customRenderTargets.splice(rttIndex, 1);
        }
        this._volumetricLightScatteringRTT.dispose();
        _super.prototype.dispose.call(this, camera);
    };
    /**
     * Returns the render target texture used by the post-process
     * @return the render target texture used by the post-process
     */
    VolumetricLightScatteringPostProcess.prototype.getPass = function () {
        return this._volumetricLightScatteringRTT;
    };
    // Private methods
    VolumetricLightScatteringPostProcess.prototype._meshExcluded = function (mesh) {
        if (this.excludedMeshes.length > 0 && this.excludedMeshes.indexOf(mesh) !== -1) {
            return true;
        }
        return false;
    };
    VolumetricLightScatteringPostProcess.prototype._createPass = function (scene, ratio) {
        var _this = this;
        var engine = scene.getEngine();
        this._volumetricLightScatteringRTT = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_11__["RenderTargetTexture"]("volumetricLightScatteringMap", { width: engine.getRenderWidth() * ratio, height: engine.getRenderHeight() * ratio }, scene, false, true, _Engines_constants__WEBPACK_IMPORTED_MODULE_13__["Constants"].TEXTURETYPE_UNSIGNED_INT);
        this._volumetricLightScatteringRTT.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__["Texture"].CLAMP_ADDRESSMODE;
        this._volumetricLightScatteringRTT.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_10__["Texture"].CLAMP_ADDRESSMODE;
        this._volumetricLightScatteringRTT.renderList = null;
        this._volumetricLightScatteringRTT.renderParticles = false;
        this._volumetricLightScatteringRTT.ignoreCameraViewport = true;
        var camera = this.getCamera();
        if (camera) {
            camera.customRenderTargets.push(this._volumetricLightScatteringRTT);
        }
        else {
            scene.customRenderTargets.push(this._volumetricLightScatteringRTT);
        }
        // Custom render function for submeshes
        var renderSubMesh = function (subMesh) {
            var mesh = subMesh.getRenderingMesh();
            if (_this._meshExcluded(mesh)) {
                return;
            }
            mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
            var material = subMesh.getMaterial();
            if (!material) {
                return;
            }
            var scene = mesh.getScene();
            var engine = scene.getEngine();
            // Culling
            engine.setState(material.backFaceCulling);
            // Managing instances
            var batch = mesh._getInstancesRenderList(subMesh._id);
            if (batch.mustReturn) {
                return;
            }
            var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null);
            if (_this._isReady(subMesh, hardwareInstancedRendering)) {
                var effect = _this._volumetricLightScatteringPass;
                if (mesh === _this.mesh) {
                    if (subMesh.effect) {
                        effect = subMesh.effect;
                    }
                    else {
                        effect = material.getEffect();
                    }
                }
                engine.enableEffect(effect);
                mesh._bind(subMesh, effect, _Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFillMode);
                if (mesh === _this.mesh) {
                    material.bind(mesh.getWorldMatrix(), mesh);
                }
                else {
                    _this._volumetricLightScatteringPass.setMatrix("viewProjection", scene.getTransformMatrix());
                    // Alpha test
                    if (material && material.needAlphaTesting()) {
                        var alphaTexture = material.getAlphaTestTexture();
                        _this._volumetricLightScatteringPass.setTexture("diffuseSampler", alphaTexture);
                        if (alphaTexture) {
                            _this._volumetricLightScatteringPass.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
                        }
                    }
                    // Bones
                    if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                    }
                }
                // Draw
                mesh._processRendering(subMesh, _this._volumetricLightScatteringPass, _Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return effect.setMatrix("world", world); });
            }
        };
        // Render target texture callbacks
        var savedSceneClearColor;
        var sceneClearColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_19__["Color4"](0.0, 0.0, 0.0, 1.0);
        this._volumetricLightScatteringRTT.onBeforeRenderObservable.add(function () {
            savedSceneClearColor = scene.clearColor;
            scene.clearColor = sceneClearColor;
        });
        this._volumetricLightScatteringRTT.onAfterRenderObservable.add(function () {
            scene.clearColor = savedSceneClearColor;
        });
        this._volumetricLightScatteringRTT.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes) {
            var engine = scene.getEngine();
            var index;
            if (depthOnlySubMeshes.length) {
                engine.setColorWrite(false);
                for (index = 0; index < depthOnlySubMeshes.length; index++) {
                    renderSubMesh(depthOnlySubMeshes.data[index]);
                }
                engine.setColorWrite(true);
            }
            for (index = 0; index < opaqueSubMeshes.length; index++) {
                renderSubMesh(opaqueSubMeshes.data[index]);
            }
            for (index = 0; index < alphaTestSubMeshes.length; index++) {
                renderSubMesh(alphaTestSubMeshes.data[index]);
            }
            if (transparentSubMeshes.length) {
                // Sort sub meshes
                for (index = 0; index < transparentSubMeshes.length; index++) {
                    var submesh = transparentSubMeshes.data[index];
                    var boundingInfo = submesh.getBoundingInfo();
                    if (boundingInfo && scene.activeCamera) {
                        submesh._alphaIndex = submesh.getMesh().alphaIndex;
                        submesh._distanceToCamera = boundingInfo.boundingSphere.centerWorld.subtract(scene.activeCamera.position).length();
                    }
                }
                var sortedArray = transparentSubMeshes.data.slice(0, transparentSubMeshes.length);
                sortedArray.sort(function (a, b) {
                    // Alpha index first
                    if (a._alphaIndex > b._alphaIndex) {
                        return 1;
                    }
                    if (a._alphaIndex < b._alphaIndex) {
                        return -1;
                    }
                    // Then distance to camera
                    if (a._distanceToCamera < b._distanceToCamera) {
                        return 1;
                    }
                    if (a._distanceToCamera > b._distanceToCamera) {
                        return -1;
                    }
                    return 0;
                });
                // Render sub meshes
                engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_13__["Constants"].ALPHA_COMBINE);
                for (index = 0; index < sortedArray.length; index++) {
                    renderSubMesh(sortedArray[index]);
                }
                engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_13__["Constants"].ALPHA_DISABLE);
            }
        };
    };
    VolumetricLightScatteringPostProcess.prototype._updateMeshScreenCoordinates = function (scene) {
        var transform = scene.getTransformMatrix();
        var meshPosition;
        if (this.useCustomMeshPosition) {
            meshPosition = this.customMeshPosition;
        }
        else if (this.attachedNode) {
            meshPosition = this.attachedNode.position;
        }
        else {
            meshPosition = this.mesh.parent ? this.mesh.getAbsolutePosition() : this.mesh.position;
        }
        var pos = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Project(meshPosition, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity(), transform, this._viewPort);
        this._screenCoordinates.x = pos.x / this._viewPort.width;
        this._screenCoordinates.y = pos.y / this._viewPort.height;
        if (this.invert) {
            this._screenCoordinates.y = 1.0 - this._screenCoordinates.y;
        }
    };
    // Static methods
    /**
    * Creates a default mesh for the Volumeric Light Scattering post-process
    * @param name The mesh name
    * @param scene The scene where to create the mesh
    * @return the default mesh
    */
    VolumetricLightScatteringPostProcess.CreateDefaultMesh = function (name, scene) {
        var mesh = _Meshes_mesh__WEBPACK_IMPORTED_MODULE_6__["Mesh"].CreatePlane(name, 1, scene);
        mesh.billboardMode = _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_5__["AbstractMesh"].BILLBOARDMODE_ALL;
        var material = new _Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_9__["StandardMaterial"](name + "Material", scene);
        material.emissiveColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_19__["Color3"](1, 1, 1);
        mesh.material = material;
        return mesh;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], VolumetricLightScatteringPostProcess.prototype, "customMeshPosition", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "useCustomMeshPosition", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "invert", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsMeshReference"])()
    ], VolumetricLightScatteringPostProcess.prototype, "mesh", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "excludedMeshes", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "exposure", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "decay", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "weight", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
    ], VolumetricLightScatteringPostProcess.prototype, "density", void 0);
    return VolumetricLightScatteringPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_12__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/vrDistortionCorrectionPostProcess.ts":
/*!************************************************************!*\
  !*** ./PostProcesses/vrDistortionCorrectionPostProcess.ts ***!
  \************************************************************/
/*! exports provided: VRDistortionCorrectionPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRDistortionCorrectionPostProcess", function() { return VRDistortionCorrectionPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_vrDistortionCorrection_fragment__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Shaders/vrDistortionCorrection.fragment */ "./Shaders/vrDistortionCorrection.fragment.ts");





/**
 * VRDistortionCorrectionPostProcess used for mobile VR
 */
var VRDistortionCorrectionPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRDistortionCorrectionPostProcess, _super);
    /**
     * Initializes the VRDistortionCorrectionPostProcess
     * @param name The name of the effect.
     * @param camera The camera to apply the render pass to.
     * @param isRightEye If this is for the right eye distortion
     * @param vrMetrics All the required metrics for the VR camera
     */
    function VRDistortionCorrectionPostProcess(name, camera, isRightEye, vrMetrics) {
        var _this = _super.call(this, name, "vrDistortionCorrection", [
            'LensCenter',
            'Scale',
            'ScaleIn',
            'HmdWarpParam'
        ], null, vrMetrics.postProcessScaleFactor, camera, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].BILINEAR_SAMPLINGMODE) || this;
        _this._isRightEye = isRightEye;
        _this._distortionFactors = vrMetrics.distortionK;
        _this._postProcessScaleFactor = vrMetrics.postProcessScaleFactor;
        _this._lensCenterOffset = vrMetrics.lensCenterOffset;
        _this.adaptScaleToCurrentViewport = true;
        _this.onSizeChangedObservable.add(function () {
            _this._scaleIn = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](2, 2 / _this.aspectRatio);
            _this._scaleFactor = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](.5 * (1 / _this._postProcessScaleFactor), .5 * (1 / _this._postProcessScaleFactor) * _this.aspectRatio);
            _this._lensCenter = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector2"](_this._isRightEye ? 0.5 - _this._lensCenterOffset * 0.5 : 0.5 + _this._lensCenterOffset * 0.5, 0.5);
        });
        _this.onApplyObservable.add(function (effect) {
            effect.setFloat2("LensCenter", _this._lensCenter.x, _this._lensCenter.y);
            effect.setFloat2("Scale", _this._scaleFactor.x, _this._scaleFactor.y);
            effect.setFloat2("ScaleIn", _this._scaleIn.x, _this._scaleIn.y);
            effect.setFloat4("HmdWarpParam", _this._distortionFactors[0], _this._distortionFactors[1], _this._distortionFactors[2], _this._distortionFactors[3]);
        });
        return _this;
    }
    return VRDistortionCorrectionPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_3__["PostProcess"]));



/***/ }),

/***/ "./PostProcesses/vrMultiviewToSingleviewPostProcess.ts":
/*!*************************************************************!*\
  !*** ./PostProcesses/vrMultiviewToSingleviewPostProcess.ts ***!
  \*************************************************************/
/*! exports provided: VRMultiviewToSingleviewPostProcess */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VRMultiviewToSingleviewPostProcess", function() { return VRMultiviewToSingleviewPostProcess; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _postProcess__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./postProcess */ "./PostProcesses/postProcess.ts");
/* harmony import */ var _Shaders_vrMultiviewToSingleview_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Shaders/vrMultiviewToSingleview.fragment */ "./Shaders/vrMultiviewToSingleview.fragment.ts");
/* harmony import */ var _Engines_Extensions_engine_multiview__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Engines/Extensions/engine.multiview */ "./Engines/Extensions/engine.multiview.ts");





/**
 * VRMultiviewToSingleview used to convert multiview texture arrays to standard textures for scenarios such as webVR
 * This will not be used for webXR as it supports displaying texture arrays directly
 */
var VRMultiviewToSingleviewPostProcess = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](VRMultiviewToSingleviewPostProcess, _super);
    /**
     * Initializes a VRMultiviewToSingleview
     * @param name name of the post process
     * @param camera camera to be applied to
     * @param scaleFactor scaling factor to the size of the output texture
     */
    function VRMultiviewToSingleviewPostProcess(name, camera, scaleFactor) {
        var _this = _super.call(this, name, "vrMultiviewToSingleview", ["imageIndex"], ["multiviewSampler"], scaleFactor, camera, _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_1__["Texture"].BILINEAR_SAMPLINGMODE) || this;
        _this.onSizeChangedObservable.add(function () {
        });
        _this.onApplyObservable.add(function (effect) {
            if (camera._scene.activeCamera && camera._scene.activeCamera.isLeftCamera) {
                effect.setInt("imageIndex", 0);
            }
            else {
                effect.setInt("imageIndex", 1);
            }
            effect.setTexture("multiviewSampler", camera._multiviewTexture);
        });
        return _this;
    }
    return VRMultiviewToSingleviewPostProcess;
}(_postProcess__WEBPACK_IMPORTED_MODULE_2__["PostProcess"]));



/***/ }),

/***/ "./Probes/index.ts":
/*!*************************!*\
  !*** ./Probes/index.ts ***!
  \*************************/
/*! exports provided: ReflectionProbe */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _reflectionProbe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./reflectionProbe */ "./Probes/reflectionProbe.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionProbe", function() { return _reflectionProbe__WEBPACK_IMPORTED_MODULE_0__["ReflectionProbe"]; });




/***/ }),

/***/ "./Probes/reflectionProbe.ts":
/*!***********************************!*\
  !*** ./Probes/reflectionProbe.ts ***!
  \***********************************/
/*! exports provided: ReflectionProbe */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReflectionProbe", function() { return ReflectionProbe; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../abstractScene */ "./abstractScene.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");






_abstractScene__WEBPACK_IMPORTED_MODULE_4__["AbstractScene"].prototype.removeReflectionProbe = function (toRemove) {
    if (!this.reflectionProbes) {
        return -1;
    }
    var index = this.reflectionProbes.indexOf(toRemove);
    if (index !== -1) {
        this.reflectionProbes.splice(index, 1);
    }
    return index;
};
_abstractScene__WEBPACK_IMPORTED_MODULE_4__["AbstractScene"].prototype.addReflectionProbe = function (newReflectionProbe) {
    if (!this.reflectionProbes) {
        this.reflectionProbes = [];
    }
    this.reflectionProbes.push(newReflectionProbe);
};
/**
 * Class used to generate realtime reflection / refraction cube textures
 * @see http://doc.babylonjs.com/how_to/how_to_use_reflection_probes
 */
var ReflectionProbe = /** @class */ (function () {
    /**
     * Creates a new reflection probe
     * @param name defines the name of the probe
     * @param size defines the texture resolution (for each face)
     * @param scene defines the hosting scene
     * @param generateMipMaps defines if mip maps should be generated automatically (true by default)
     * @param useFloat defines if HDR data (flaot data) should be used to store colors (false by default)
     */
    function ReflectionProbe(
    /** defines the name of the probe */
    name, size, scene, generateMipMaps, useFloat) {
        var _this = this;
        if (generateMipMaps === void 0) { generateMipMaps = true; }
        if (useFloat === void 0) { useFloat = false; }
        this.name = name;
        this._viewMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Identity();
        this._target = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this._add = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this._invertYAxis = false;
        /** Gets or sets probe position (center of the cube map) */
        this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        this._scene = scene;
        // Create the scene field if not exist.
        if (!this._scene.reflectionProbes) {
            this._scene.reflectionProbes = new Array();
        }
        this._scene.reflectionProbes.push(this);
        this._renderTargetTexture = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_2__["RenderTargetTexture"](name, size, scene, generateMipMaps, true, useFloat ? _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_FLOAT : _Engines_constants__WEBPACK_IMPORTED_MODULE_5__["Constants"].TEXTURETYPE_UNSIGNED_INT, true);
        this._renderTargetTexture.onBeforeRenderObservable.add(function (faceIndex) {
            switch (faceIndex) {
                case 0:
                    _this._add.copyFromFloats(1, 0, 0);
                    break;
                case 1:
                    _this._add.copyFromFloats(-1, 0, 0);
                    break;
                case 2:
                    _this._add.copyFromFloats(0, _this._invertYAxis ? 1 : -1, 0);
                    break;
                case 3:
                    _this._add.copyFromFloats(0, _this._invertYAxis ? -1 : 1, 0);
                    break;
                case 4:
                    _this._add.copyFromFloats(0, 0, 1);
                    break;
                case 5:
                    _this._add.copyFromFloats(0, 0, -1);
                    break;
            }
            if (_this._attachedMesh) {
                _this.position.copyFrom(_this._attachedMesh.getAbsolutePosition());
            }
            _this.position.addToRef(_this._add, _this._target);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].LookAtLHToRef(_this.position, _this._target, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Up(), _this._viewMatrix);
            if (scene.activeCamera) {
                _this._projectionMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].PerspectiveFovLH(Math.PI / 2, 1, scene.activeCamera.minZ, scene.activeCamera.maxZ);
                scene.setTransformMatrix(_this._viewMatrix, _this._projectionMatrix);
            }
            scene._forcedViewPosition = _this.position;
        });
        this._renderTargetTexture.onAfterUnbindObservable.add(function () {
            scene._forcedViewPosition = null;
            scene.updateTransformMatrix(true);
        });
    }
    Object.defineProperty(ReflectionProbe.prototype, "samples", {
        /** Gets or sets the number of samples to use for multi-sampling (0 by default). Required WebGL2 */
        get: function () {
            return this._renderTargetTexture.samples;
        },
        set: function (value) {
            this._renderTargetTexture.samples = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionProbe.prototype, "refreshRate", {
        /** Gets or sets the refresh rate to use (on every frame by default) */
        get: function () {
            return this._renderTargetTexture.refreshRate;
        },
        set: function (value) {
            this._renderTargetTexture.refreshRate = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the hosting scene
     * @returns a Scene
     */
    ReflectionProbe.prototype.getScene = function () {
        return this._scene;
    };
    Object.defineProperty(ReflectionProbe.prototype, "cubeTexture", {
        /** Gets the internal CubeTexture used to render to */
        get: function () {
            return this._renderTargetTexture;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ReflectionProbe.prototype, "renderList", {
        /** Gets the list of meshes to render */
        get: function () {
            return this._renderTargetTexture.renderList;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Attach the probe to a specific mesh (Rendering will be done from attached mesh's position)
     * @param mesh defines the mesh to attach to
     */
    ReflectionProbe.prototype.attachToMesh = function (mesh) {
        this._attachedMesh = mesh;
    };
    /**
     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
     */
    ReflectionProbe.prototype.setRenderingAutoClearDepthStencil = function (renderingGroupId, autoClearDepthStencil) {
        this._renderTargetTexture.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil);
    };
    /**
     * Clean all associated resources
     */
    ReflectionProbe.prototype.dispose = function () {
        var index = this._scene.reflectionProbes.indexOf(this);
        if (index !== -1) {
            // Remove from the scene if found
            this._scene.reflectionProbes.splice(index, 1);
        }
        if (this._renderTargetTexture) {
            this._renderTargetTexture.dispose();
            this._renderTargetTexture = null;
        }
    };
    /**
     * Converts the reflection probe information to a readable string for debug purpose.
     * @param fullDetails Supports for multiple levels of logging within scene loading
     * @returns the human readable reflection probe info
     */
    ReflectionProbe.prototype.toString = function (fullDetails) {
        var ret = "Name: " + this.name;
        if (fullDetails) {
            ret += ", position: " + this.position.toString();
            if (this._attachedMesh) {
                ret += ", attached mesh: " + this._attachedMesh.name;
            }
        }
        return ret;
    };
    /**
     * Get the class name of the relfection probe.
     * @returns "ReflectionProbe"
     */
    ReflectionProbe.prototype.getClassName = function () {
        return "ReflectionProbe";
    };
    /**
     * Serialize the reflection probe to a JSON representation we can easily use in the resepective Parse function.
     * @returns The JSON representation of the texture
     */
    ReflectionProbe.prototype.serialize = function () {
        var serializationObject = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Serialize(this, this._renderTargetTexture.serialize());
        serializationObject.isReflectionProbe = true;
        return serializationObject;
    };
    /**
     * Parse the JSON representation of a reflection probe in order to recreate the reflection probe in the given scene.
     * @param parsedReflectionProbe Define the JSON representation of the reflection probe
     * @param scene Define the scene the parsed reflection probe should be instantiated in
     * @param rootUrl Define the root url of the parsing sequence in the case of relative dependencies
     * @returns The parsed reflection probe if successful
     */
    ReflectionProbe.Parse = function (parsedReflectionProbe, scene, rootUrl) {
        var reflectionProbe = null;
        if (scene.reflectionProbes) {
            for (var index = 0; index < scene.reflectionProbes.length; index++) {
                var rp = scene.reflectionProbes[index];
                if (rp.name === parsedReflectionProbe.name) {
                    reflectionProbe = rp;
                    break;
                }
            }
        }
        reflectionProbe = _Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["SerializationHelper"].Parse(function () { return reflectionProbe || new ReflectionProbe(parsedReflectionProbe.name, parsedReflectionProbe.renderTargetSize, scene, parsedReflectionProbe._generateMipMaps); }, parsedReflectionProbe, scene, rootUrl);
        reflectionProbe.cubeTexture._waitingRenderList = parsedReflectionProbe.renderList;
        if (parsedReflectionProbe._attachedMesh) {
            reflectionProbe.attachToMesh(scene.getMeshByID(parsedReflectionProbe._attachedMesh));
        }
        return reflectionProbe;
    };
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsMeshReference"])()
    ], ReflectionProbe.prototype, "_attachedMesh", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsVector3"])()
    ], ReflectionProbe.prototype, "position", void 0);
    return ReflectionProbe;
}());



/***/ }),

/***/ "./Rendering/boundingBoxRenderer.ts":
/*!******************************************!*\
  !*** ./Rendering/boundingBoxRenderer.ts ***!
  \******************************************/
/*! exports provided: BoundingBoxRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxRenderer", function() { return BoundingBoxRenderer; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/mesh.vertexData */ "./Meshes/mesh.vertexData.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_shaderMaterial__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Materials/shaderMaterial */ "./Materials/shaderMaterial.ts");
/* harmony import */ var _Meshes_Builders_boxBuilder__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Meshes/Builders/boxBuilder */ "./Meshes/Builders/boxBuilder.ts");
/* harmony import */ var _Shaders_color_fragment__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Shaders/color.fragment */ "./Shaders/color.fragment.ts");
/* harmony import */ var _Shaders_color_vertex__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Shaders/color.vertex */ "./Shaders/color.vertex.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");













Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype, "forceShowBoundingBoxes", {
    get: function () {
        return this._forceShowBoundingBoxes || false;
    },
    set: function (value) {
        this._forceShowBoundingBoxes = value;
        // Lazyly creates a BB renderer if needed.
        if (value) {
            this.getBoundingBoxRenderer();
        }
    },
    enumerable: true,
    configurable: true
});
_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype.getBoundingBoxRenderer = function () {
    if (!this._boundingBoxRenderer) {
        this._boundingBoxRenderer = new BoundingBoxRenderer(this);
    }
    return this._boundingBoxRenderer;
};
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype, "showBoundingBox", {
    get: function () {
        return this._showBoundingBox || false;
    },
    set: function (value) {
        this._showBoundingBox = value;
        // Lazyly creates a BB renderer if needed.
        if (value) {
            this.getScene().getBoundingBoxRenderer();
        }
    },
    enumerable: true,
    configurable: true
});
/**
 * Component responsible of rendering the bounding box of the meshes in a scene.
 * This is usually used through the mesh.showBoundingBox or the scene.forceShowBoundingBoxes properties
 */
var BoundingBoxRenderer = /** @class */ (function () {
    /**
     * Instantiates a new bounding box renderer in a scene.
     * @param scene the scene the  renderer renders in
     */
    function BoundingBoxRenderer(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_6__["SceneComponentConstants"].NAME_BOUNDINGBOXRENDERER;
        /**
         * Color of the bounding box lines placed in front of an object
         */
        this.frontColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_12__["Color3"](1, 1, 1);
        /**
         * Color of the bounding box lines placed behind an object
         */
        this.backColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_12__["Color3"](0.1, 0.1, 0.1);
        /**
         * Defines if the renderer should show the back lines or not
         */
        this.showBackLines = true;
        /**
         * @hidden
         */
        this.renderList = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_5__["SmartArray"](32);
        this._vertexBuffers = {};
        this._fillIndexBuffer = null;
        this._fillIndexData = null;
        this.scene = scene;
        scene._addComponent(this);
    }
    /**
     * Registers the component in a given scene
     */
    BoundingBoxRenderer.prototype.register = function () {
        this.scene._beforeEvaluateActiveMeshStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_6__["SceneComponentConstants"].STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER, this, this.reset);
        this.scene._activeMeshStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_6__["SceneComponentConstants"].STEP_ACTIVEMESH_BOUNDINGBOXRENDERER, this, this._activeMesh);
        this.scene._evaluateSubMeshStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_6__["SceneComponentConstants"].STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER, this, this._evaluateSubMesh);
        this.scene._afterRenderingGroupDrawStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_6__["SceneComponentConstants"].STEP_AFTERRENDERINGGROUPDRAW_BOUNDINGBOXRENDERER, this, this.render);
    };
    BoundingBoxRenderer.prototype._evaluateSubMesh = function (mesh, subMesh) {
        if (mesh.showSubMeshesBoundingBox) {
            var boundingInfo = subMesh.getBoundingInfo();
            if (boundingInfo !== null && boundingInfo !== undefined) {
                boundingInfo.boundingBox._tag = mesh.renderingGroupId;
                this.renderList.push(boundingInfo.boundingBox);
            }
        }
    };
    BoundingBoxRenderer.prototype._activeMesh = function (sourceMesh, mesh) {
        if (sourceMesh.showBoundingBox || this.scene.forceShowBoundingBoxes) {
            var boundingInfo = sourceMesh.getBoundingInfo();
            boundingInfo.boundingBox._tag = mesh.renderingGroupId;
            this.renderList.push(boundingInfo.boundingBox);
        }
    };
    BoundingBoxRenderer.prototype._prepareRessources = function () {
        if (this._colorShader) {
            return;
        }
        this._colorShader = new _Materials_shaderMaterial__WEBPACK_IMPORTED_MODULE_8__["ShaderMaterial"]("colorShader", this.scene, "color", {
            attributes: [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind],
            uniforms: ["world", "viewProjection", "color"]
        });
        var engine = this.scene.getEngine();
        var boxdata = _Meshes_mesh_vertexData__WEBPACK_IMPORTED_MODULE_3__["VertexData"].CreateBox({ size: 1.0 });
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"](engine, boxdata.positions, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, false);
        this._createIndexBuffer();
        this._fillIndexData = boxdata.indices;
    };
    BoundingBoxRenderer.prototype._createIndexBuffer = function () {
        var engine = this.scene.getEngine();
        this._indexBuffer = engine.createIndexBuffer([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 7, 1, 6, 2, 5, 3, 4]);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    BoundingBoxRenderer.prototype.rebuild = function () {
        var vb = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        if (vb) {
            vb._rebuild();
        }
        this._createIndexBuffer();
    };
    /**
     * @hidden
     */
    BoundingBoxRenderer.prototype.reset = function () {
        this.renderList.reset();
    };
    /**
     * Render the bounding boxes of a specific rendering group
     * @param renderingGroupId defines the rendering group to render
     */
    BoundingBoxRenderer.prototype.render = function (renderingGroupId) {
        if (this.renderList.length === 0) {
            return;
        }
        this._prepareRessources();
        if (!this._colorShader.isReady()) {
            return;
        }
        var engine = this.scene.getEngine();
        engine.setDepthWrite(false);
        this._colorShader._preBind();
        for (var boundingBoxIndex = 0; boundingBoxIndex < this.renderList.length; boundingBoxIndex++) {
            var boundingBox = this.renderList.data[boundingBoxIndex];
            if (boundingBox._tag !== renderingGroupId) {
                continue;
            }
            var min = boundingBox.minimum;
            var max = boundingBox.maximum;
            var diff = max.subtract(min);
            var median = min.add(diff.scale(0.5));
            var worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Scaling(diff.x, diff.y, diff.z)
                .multiply(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Translation(median.x, median.y, median.z))
                .multiply(boundingBox.getWorldMatrix());
            // VBOs
            engine.bindBuffers(this._vertexBuffers, this._indexBuffer, this._colorShader.getEffect());
            if (this.showBackLines) {
                // Back
                engine.setDepthFunctionToGreaterOrEqual();
                this.scene.resetCachedMaterial();
                this._colorShader.setColor4("color", this.backColor.toColor4());
                this._colorShader.bind(worldMatrix);
                // Draw order
                engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].LineListDrawMode, 0, 24);
            }
            // Front
            engine.setDepthFunctionToLess();
            this.scene.resetCachedMaterial();
            this._colorShader.setColor4("color", this.frontColor.toColor4());
            this._colorShader.bind(worldMatrix);
            // Draw order
            engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].LineListDrawMode, 0, 24);
        }
        this._colorShader.unbind();
        engine.setDepthFunctionToLessOrEqual();
        engine.setDepthWrite(true);
    };
    /**
     * In case of occlusion queries, we can render the occlusion bounding box through this method
     * @param mesh Define the mesh to render the occlusion bounding box for
     */
    BoundingBoxRenderer.prototype.renderOcclusionBoundingBox = function (mesh) {
        this._prepareRessources();
        if (!this._colorShader.isReady() || !mesh._boundingInfo) {
            return;
        }
        var engine = this.scene.getEngine();
        if (!this._fillIndexBuffer) {
            this._fillIndexBuffer = engine.createIndexBuffer(this._fillIndexData);
        }
        engine.setDepthWrite(false);
        engine.setColorWrite(false);
        this._colorShader._preBind();
        var boundingBox = mesh._boundingInfo.boundingBox;
        var min = boundingBox.minimum;
        var max = boundingBox.maximum;
        var diff = max.subtract(min);
        var median = min.add(diff.scale(0.5));
        var worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Scaling(diff.x, diff.y, diff.z)
            .multiply(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Matrix"].Translation(median.x, median.y, median.z))
            .multiply(boundingBox.getWorldMatrix());
        engine.bindBuffers(this._vertexBuffers, this._fillIndexBuffer, this._colorShader.getEffect());
        engine.setDepthFunctionToLess();
        this.scene.resetCachedMaterial();
        this._colorShader.bind(worldMatrix);
        engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFillMode, 0, 36);
        this._colorShader.unbind();
        engine.setDepthFunctionToLessOrEqual();
        engine.setDepthWrite(true);
        engine.setColorWrite(true);
    };
    /**
     * Dispose and release the resources attached to this renderer.
     */
    BoundingBoxRenderer.prototype.dispose = function () {
        if (!this._colorShader) {
            return;
        }
        this.renderList.dispose();
        this._colorShader.dispose();
        var buffer = this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        if (buffer) {
            buffer.dispose();
            this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = null;
        }
        this.scene.getEngine()._releaseBuffer(this._indexBuffer);
        if (this._fillIndexBuffer) {
            this.scene.getEngine()._releaseBuffer(this._fillIndexBuffer);
            this._fillIndexBuffer = null;
        }
    };
    return BoundingBoxRenderer;
}());



/***/ }),

/***/ "./Rendering/depthRenderer.ts":
/*!************************************!*\
  !*** ./Rendering/depthRenderer.ts ***!
  \************************************/
/*! exports provided: DepthRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthRenderer", function() { return DepthRenderer; });
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Materials/Textures/renderTargetTexture */ "./Materials/Textures/renderTargetTexture.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_depth_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Shaders/depth.fragment */ "./Shaders/depth.fragment.ts");
/* harmony import */ var _Shaders_depth_vertex__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Shaders/depth.vertex */ "./Shaders/depth.vertex.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");










/**
 * This represents a depth renderer in Babylon.
 * A depth renderer will render to it's depth map every frame which can be displayed or used in post processing
 */
var DepthRenderer = /** @class */ (function () {
    /**
     * Instantiates a depth renderer
     * @param scene The scene the renderer belongs to
     * @param type The texture type of the depth map (default: Engine.TEXTURETYPE_FLOAT)
     * @param camera The camera to be used to render the depth map (default: scene's active camera)
     * @param storeNonLinearDepth Defines whether the depth is stored linearly like in Babylon Shadows or directly like glFragCoord.z
     */
    function DepthRenderer(scene, type, camera, storeNonLinearDepth) {
        var _this = this;
        if (type === void 0) { type = _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_FLOAT; }
        if (camera === void 0) { camera = null; }
        if (storeNonLinearDepth === void 0) { storeNonLinearDepth = false; }
        /**
         * Specifiess that the depth renderer will only be used within
         * the camera it is created for.
         * This can help forcing its rendering during the camera processing.
         */
        this.useOnlyInActiveCamera = false;
        this._scene = scene;
        this._storeNonLinearDepth = storeNonLinearDepth;
        this.isPacked = type === _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTURETYPE_UNSIGNED_BYTE;
        if (this.isPacked) {
            this._clearColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__["Color4"](1.0, 1.0, 1.0, 1.0);
        }
        else {
            this._clearColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_0__["Color4"](1.0, 0.0, 0.0, 1.0);
        }
        DepthRenderer._SceneComponentInitialization(this._scene);
        this._camera = camera;
        var engine = scene.getEngine();
        // Render target
        var format = (this.isPacked || engine.webGLVersion === 1) ? _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_RGBA : _Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].TEXTUREFORMAT_R;
        this._depthMap = new _Materials_Textures_renderTargetTexture__WEBPACK_IMPORTED_MODULE_3__["RenderTargetTexture"]("depthMap", { width: engine.getRenderWidth(), height: engine.getRenderHeight() }, this._scene, false, true, type, false, undefined, undefined, undefined, undefined, format);
        this._depthMap.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].CLAMP_ADDRESSMODE;
        this._depthMap.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].CLAMP_ADDRESSMODE;
        this._depthMap.refreshRate = 1;
        this._depthMap.renderParticles = false;
        this._depthMap.renderList = null;
        // Camera to get depth map from to support multiple concurrent cameras
        this._depthMap.activeCamera = this._camera;
        this._depthMap.ignoreCameraViewport = true;
        this._depthMap.useCameraPostProcesses = false;
        // set default depth value to 1.0 (far away)
        this._depthMap.onClearObservable.add(function (engine) {
            engine.clear(_this._clearColor, true, true, true);
        });
        // Custom render function
        var renderSubMesh = function (subMesh) {
            var mesh = subMesh.getRenderingMesh();
            var scene = _this._scene;
            var engine = scene.getEngine();
            var material = subMesh.getMaterial();
            mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
            if (!material) {
                return;
            }
            // Culling and reverse (right handed system)
            engine.setState(material.backFaceCulling, 0, false, scene.useRightHandedSystem);
            // Managing instances
            var batch = mesh._getInstancesRenderList(subMesh._id);
            if (batch.mustReturn) {
                return;
            }
            var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null);
            var camera = _this._camera || scene.activeCamera;
            if (_this.isReady(subMesh, hardwareInstancedRendering) && camera) {
                engine.enableEffect(_this._effect);
                mesh._bind(subMesh, _this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_4__["Material"].TriangleFillMode);
                _this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                _this._effect.setFloat2("depthValues", camera.minZ, camera.minZ + camera.maxZ);
                // Alpha test
                if (material && material.needAlphaTesting()) {
                    var alphaTexture = material.getAlphaTestTexture();
                    if (alphaTexture) {
                        _this._effect.setTexture("diffuseSampler", alphaTexture);
                        _this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
                    }
                }
                // Bones
                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                    _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                }
                // Morph targets
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].BindMorphTargetParameters(mesh, _this._effect);
                // Draw
                mesh._processRendering(subMesh, _this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_4__["Material"].TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._effect.setMatrix("world", world); });
            }
        };
        this._depthMap.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes) {
            var index;
            if (depthOnlySubMeshes.length) {
                engine.setColorWrite(false);
                for (index = 0; index < depthOnlySubMeshes.length; index++) {
                    renderSubMesh(depthOnlySubMeshes.data[index]);
                }
                engine.setColorWrite(true);
            }
            for (index = 0; index < opaqueSubMeshes.length; index++) {
                renderSubMesh(opaqueSubMeshes.data[index]);
            }
            for (index = 0; index < alphaTestSubMeshes.length; index++) {
                renderSubMesh(alphaTestSubMeshes.data[index]);
            }
        };
    }
    /**
     * Creates the depth rendering effect and checks if the effect is ready.
     * @param subMesh The submesh to be used to render the depth map of
     * @param useInstances If multiple world instances should be used
     * @returns if the depth renderer is ready to render the depth map
     */
    DepthRenderer.prototype.isReady = function (subMesh, useInstances) {
        var material = subMesh.getMaterial();
        if (material.disableDepthWrite) {
            return false;
        }
        var defines = [];
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        var mesh = subMesh.getMesh();
        // Alpha test
        if (material && material.needAlphaTesting() && material.getAlphaTestTexture()) {
            defines.push("#define ALPHATEST");
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind)) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind);
                defines.push("#define UV1");
            }
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind)) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind);
                defines.push("#define UV2");
            }
        }
        // Bones
        if (mesh.useBones && mesh.computeBonesUsingShaders) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind);
            if (mesh.numBoneInfluencers > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind);
            }
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            defines.push("#define BonesPerMesh " + (mesh.skeleton ? mesh.skeleton.bones.length + 1 : 0));
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Morph targets
        var morphTargetManager = mesh.morphTargetManager;
        var numMorphInfluencers = 0;
        if (morphTargetManager) {
            if (morphTargetManager.numInfluencers > 0) {
                numMorphInfluencers = morphTargetManager.numInfluencers;
                defines.push("#define MORPHTARGETS");
                defines.push("#define NUM_MORPH_INFLUENCERS " + numMorphInfluencers);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, numMorphInfluencers);
            }
        }
        // Instances
        if (useInstances) {
            defines.push("#define INSTANCES");
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_5__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        // None linear depth
        if (this._storeNonLinearDepth) {
            defines.push("#define NONLINEARDEPTH");
        }
        // Float Mode
        if (this.isPacked) {
            defines.push("#define PACKED");
        }
        // Get correct effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            this._effect = this._scene.getEngine().createEffect("depth", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "depthValues", "morphTargetInfluences"], ["diffuseSampler"], join, undefined, undefined, undefined, { maxSimultaneousMorphTargets: numMorphInfluencers });
        }
        return this._effect.isReady();
    };
    /**
     * Gets the texture which the depth map will be written to.
     * @returns The depth map texture
     */
    DepthRenderer.prototype.getDepthMap = function () {
        return this._depthMap;
    };
    /**
     * Disposes of the depth renderer.
     */
    DepthRenderer.prototype.dispose = function () {
        this._depthMap.dispose();
    };
    /** @hidden */
    DepthRenderer._SceneComponentInitialization = function (_) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__["_DevTools"].WarnImport("DepthRendererSceneComponent");
    };
    return DepthRenderer;
}());



/***/ }),

/***/ "./Rendering/depthRendererSceneComponent.ts":
/*!**************************************************!*\
  !*** ./Rendering/depthRendererSceneComponent.ts ***!
  \**************************************************/
/*! exports provided: DepthRendererSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DepthRendererSceneComponent", function() { return DepthRendererSceneComponent; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _depthRenderer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./depthRenderer */ "./Rendering/depthRenderer.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");




_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype.enableDepthRenderer = function (camera, storeNonLinearDepth) {
    if (storeNonLinearDepth === void 0) { storeNonLinearDepth = false; }
    camera = camera || this.activeCamera;
    if (!camera) {
        throw "No camera available to enable depth renderer";
    }
    if (!this._depthRenderer) {
        this._depthRenderer = {};
    }
    if (!this._depthRenderer[camera.id]) {
        var textureType = 0;
        if (this.getEngine().getCaps().textureHalfFloatRender) {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_HALF_FLOAT;
        }
        else if (this.getEngine().getCaps().textureFloatRender) {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT;
        }
        else {
            textureType = _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_UNSIGNED_BYTE;
        }
        this._depthRenderer[camera.id] = new _depthRenderer__WEBPACK_IMPORTED_MODULE_1__["DepthRenderer"](this, textureType, camera, storeNonLinearDepth);
    }
    return this._depthRenderer[camera.id];
};
_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype.disableDepthRenderer = function (camera) {
    camera = camera || this.activeCamera;
    if (!camera || !this._depthRenderer || !this._depthRenderer[camera.id]) {
        return;
    }
    this._depthRenderer[camera.id].dispose();
    delete this._depthRenderer[camera.id];
};
/**
 * Defines the Depth Renderer scene component responsible to manage a depth buffer useful
 * in several rendering techniques.
 */
var DepthRendererSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function DepthRendererSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].NAME_DEPTHRENDERER;
        this.scene = scene;
    }
    /**
     * Registers the component in a given scene
     */
    DepthRendererSceneComponent.prototype.register = function () {
        this.scene._gatherRenderTargetsStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].STEP_GATHERRENDERTARGETS_DEPTHRENDERER, this, this._gatherRenderTargets);
        this.scene._gatherActiveCameraRenderTargetsStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER, this, this._gatherActiveCameraRenderTargets);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    DepthRendererSceneComponent.prototype.rebuild = function () {
        // Nothing to do for this component
    };
    /**
     * Disposes the component and the associated ressources
     */
    DepthRendererSceneComponent.prototype.dispose = function () {
        for (var key in this.scene._depthRenderer) {
            this.scene._depthRenderer[key].dispose();
        }
    };
    DepthRendererSceneComponent.prototype._gatherRenderTargets = function (renderTargets) {
        if (this.scene._depthRenderer) {
            for (var key in this.scene._depthRenderer) {
                var depthRenderer = this.scene._depthRenderer[key];
                if (!depthRenderer.useOnlyInActiveCamera) {
                    renderTargets.push(depthRenderer.getDepthMap());
                }
            }
        }
    };
    DepthRendererSceneComponent.prototype._gatherActiveCameraRenderTargets = function (renderTargets) {
        if (this.scene._depthRenderer) {
            for (var key in this.scene._depthRenderer) {
                var depthRenderer = this.scene._depthRenderer[key];
                if (depthRenderer.useOnlyInActiveCamera && this.scene.activeCamera.id === key) {
                    renderTargets.push(depthRenderer.getDepthMap());
                }
            }
        }
    };
    return DepthRendererSceneComponent;
}());

_depthRenderer__WEBPACK_IMPORTED_MODULE_1__["DepthRenderer"]._SceneComponentInitialization = function (scene) {
    // Register the G Buffer component to the scene.
    var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_3__["SceneComponentConstants"].NAME_DEPTHRENDERER);
    if (!component) {
        component = new DepthRendererSceneComponent(scene);
        scene._addComponent(component);
    }
};


/***/ }),

/***/ "./Rendering/edgesRenderer.ts":
/*!************************************!*\
  !*** ./Rendering/edgesRenderer.ts ***!
  \************************************/
/*! exports provided: EdgesRenderer, LineEdgesRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EdgesRenderer", function() { return EdgesRenderer; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LineEdgesRenderer", function() { return LineEdgesRenderer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Meshes/linesMesh */ "./Meshes/linesMesh.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_shaderMaterial__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/shaderMaterial */ "./Materials/shaderMaterial.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Shaders_line_fragment__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Shaders/line.fragment */ "./Shaders/line.fragment.ts");
/* harmony import */ var _Shaders_line_vertex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Shaders/line.vertex */ "./Shaders/line.vertex.ts");











_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype.disableEdgesRendering = function () {
    if (this._edgesRenderer) {
        this._edgesRenderer.dispose();
        this._edgesRenderer = null;
    }
    return this;
};
_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype.enableEdgesRendering = function (epsilon, checkVerticesInsteadOfIndices) {
    if (epsilon === void 0) { epsilon = 0.95; }
    if (checkVerticesInsteadOfIndices === void 0) { checkVerticesInsteadOfIndices = false; }
    this.disableEdgesRendering();
    this._edgesRenderer = new EdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
    return this;
};
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_2__["AbstractMesh"].prototype, "edgesRenderer", {
    get: function () {
        return this._edgesRenderer;
    },
    enumerable: true,
    configurable: true
});
_Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__["LinesMesh"].prototype.enableEdgesRendering = function (epsilon, checkVerticesInsteadOfIndices) {
    if (epsilon === void 0) { epsilon = 0.95; }
    if (checkVerticesInsteadOfIndices === void 0) { checkVerticesInsteadOfIndices = false; }
    this.disableEdgesRendering();
    this._edgesRenderer = new LineEdgesRenderer(this, epsilon, checkVerticesInsteadOfIndices);
    return this;
};
_Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__["InstancedLinesMesh"].prototype.enableEdgesRendering = function (epsilon, checkVerticesInsteadOfIndices) {
    if (epsilon === void 0) { epsilon = 0.95; }
    if (checkVerticesInsteadOfIndices === void 0) { checkVerticesInsteadOfIndices = false; }
    _Meshes_linesMesh__WEBPACK_IMPORTED_MODULE_3__["LinesMesh"].prototype.enableEdgesRendering.apply(this, arguments);
    return this;
};
/**
 * FaceAdjacencies Helper class to generate edges
 */
var FaceAdjacencies = /** @class */ (function () {
    function FaceAdjacencies() {
        this.edges = new Array();
        this.edgesConnectedCount = 0;
    }
    return FaceAdjacencies;
}());
/**
 * This class is used to generate edges of the mesh that could then easily be rendered in a scene.
 */
var EdgesRenderer = /** @class */ (function () {
    /**
     * Creates an instance of the EdgesRenderer. It is primarily use to display edges of a mesh.
     * Beware when you use this class with complex objects as the adjacencies computation can be really long
     * @param  source Mesh used to create edges
     * @param  epsilon sum of angles in adjacency to check for edge
     * @param  checkVerticesInsteadOfIndices bases the edges detection on vertices vs indices
     * @param  generateEdgesLines - should generate Lines or only prepare resources.
     */
    function EdgesRenderer(source, epsilon, checkVerticesInsteadOfIndices, generateEdgesLines) {
        var _this = this;
        if (epsilon === void 0) { epsilon = 0.95; }
        if (checkVerticesInsteadOfIndices === void 0) { checkVerticesInsteadOfIndices = false; }
        if (generateEdgesLines === void 0) { generateEdgesLines = true; }
        /**
         * Define the size of the edges with an orthographic camera
         */
        this.edgesWidthScalerForOrthographic = 1000.0;
        /**
         * Define the size of the edges with a perspective camera
         */
        this.edgesWidthScalerForPerspective = 50.0;
        this._linesPositions = new Array();
        this._linesNormals = new Array();
        this._linesIndices = new Array();
        this._buffers = {};
        this._checkVerticesInsteadOfIndices = false;
        /** Gets or sets a boolean indicating if the edgesRenderer is active */
        this.isEnabled = true;
        this._source = source;
        this._checkVerticesInsteadOfIndices = checkVerticesInsteadOfIndices;
        this._epsilon = epsilon;
        this._prepareRessources();
        if (generateEdgesLines) {
            this._generateEdgesLines();
        }
        this._meshRebuildObserver = this._source.onRebuildObservable.add(function () {
            _this._rebuild();
        });
        this._meshDisposeObserver = this._source.onDisposeObservable.add(function () {
            _this.dispose();
        });
    }
    EdgesRenderer.prototype._prepareRessources = function () {
        if (this._lineShader) {
            return;
        }
        this._lineShader = new _Materials_shaderMaterial__WEBPACK_IMPORTED_MODULE_6__["ShaderMaterial"]("lineShader", this._source.getScene(), "line", {
            attributes: ["position", "normal"],
            uniforms: ["worldViewProjection", "color", "width", "aspectRatio"]
        });
        this._lineShader.disableDepthWrite = true;
        this._lineShader.backFaceCulling = false;
    };
    /** @hidden */
    EdgesRenderer.prototype._rebuild = function () {
        var buffer = this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        if (buffer) {
            buffer._rebuild();
        }
        buffer = this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind];
        if (buffer) {
            buffer._rebuild();
        }
        var scene = this._source.getScene();
        var engine = scene.getEngine();
        this._ib = engine.createIndexBuffer(this._linesIndices);
    };
    /**
     * Releases the required resources for the edges renderer
     */
    EdgesRenderer.prototype.dispose = function () {
        this._source.onRebuildObservable.remove(this._meshRebuildObserver);
        this._source.onDisposeObservable.remove(this._meshDisposeObserver);
        var buffer = this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind];
        if (buffer) {
            buffer.dispose();
            this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = null;
        }
        buffer = this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind];
        if (buffer) {
            buffer.dispose();
            this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind] = null;
        }
        if (this._ib) {
            this._source.getScene().getEngine()._releaseBuffer(this._ib);
        }
        this._lineShader.dispose();
    };
    EdgesRenderer.prototype._processEdgeForAdjacencies = function (pa, pb, p0, p1, p2) {
        if (pa === p0 && pb === p1 || pa === p1 && pb === p0) {
            return 0;
        }
        if (pa === p1 && pb === p2 || pa === p2 && pb === p1) {
            return 1;
        }
        if (pa === p2 && pb === p0 || pa === p0 && pb === p2) {
            return 2;
        }
        return -1;
    };
    EdgesRenderer.prototype._processEdgeForAdjacenciesWithVertices = function (pa, pb, p0, p1, p2) {
        if (pa.equalsWithEpsilon(p0) && pb.equalsWithEpsilon(p1) || pa.equalsWithEpsilon(p1) && pb.equalsWithEpsilon(p0)) {
            return 0;
        }
        if (pa.equalsWithEpsilon(p1) && pb.equalsWithEpsilon(p2) || pa.equalsWithEpsilon(p2) && pb.equalsWithEpsilon(p1)) {
            return 1;
        }
        if (pa.equalsWithEpsilon(p2) && pb.equalsWithEpsilon(p0) || pa.equalsWithEpsilon(p0) && pb.equalsWithEpsilon(p2)) {
            return 2;
        }
        return -1;
    };
    /**
     * Checks if the pair of p0 and p1 is en edge
     * @param faceIndex
     * @param edge
     * @param faceNormals
     * @param  p0
     * @param  p1
     * @private
     */
    EdgesRenderer.prototype._checkEdge = function (faceIndex, edge, faceNormals, p0, p1) {
        var needToCreateLine;
        if (edge === undefined) {
            needToCreateLine = true;
        }
        else {
            var dotProduct = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Dot(faceNormals[faceIndex], faceNormals[edge]);
            needToCreateLine = dotProduct < this._epsilon;
        }
        if (needToCreateLine) {
            this.createLine(p0, p1, this._linesPositions.length / 3);
        }
    };
    /**
     * push line into the position, normal and index buffer
     * @protected
     */
    EdgesRenderer.prototype.createLine = function (p0, p1, offset) {
        // Positions
        this._linesPositions.push(p0.x, p0.y, p0.z, p0.x, p0.y, p0.z, p1.x, p1.y, p1.z, p1.x, p1.y, p1.z);
        // Normals
        this._linesNormals.push(p1.x, p1.y, p1.z, -1, p1.x, p1.y, p1.z, 1, p0.x, p0.y, p0.z, -1, p0.x, p0.y, p0.z, 1);
        // Indices
        this._linesIndices.push(offset, offset + 1, offset + 2, offset, offset + 2, offset + 3);
    };
    /**
     * Generates lines edges from adjacencjes
     * @private
     */
    EdgesRenderer.prototype._generateEdgesLines = function () {
        var positions = this._source.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
        var indices = this._source.getIndices();
        if (!indices || !positions) {
            return;
        }
        // First let's find adjacencies
        var adjacencies = new Array();
        var faceNormals = new Array();
        var index;
        var faceAdjacencies;
        // Prepare faces
        for (index = 0; index < indices.length; index += 3) {
            faceAdjacencies = new FaceAdjacencies();
            var p0Index = indices[index];
            var p1Index = indices[index + 1];
            var p2Index = indices[index + 2];
            faceAdjacencies.p0 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](positions[p0Index * 3], positions[p0Index * 3 + 1], positions[p0Index * 3 + 2]);
            faceAdjacencies.p1 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](positions[p1Index * 3], positions[p1Index * 3 + 1], positions[p1Index * 3 + 2]);
            faceAdjacencies.p2 = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"](positions[p2Index * 3], positions[p2Index * 3 + 1], positions[p2Index * 3 + 2]);
            var faceNormal = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].Cross(faceAdjacencies.p1.subtract(faceAdjacencies.p0), faceAdjacencies.p2.subtract(faceAdjacencies.p1));
            faceNormal.normalize();
            faceNormals.push(faceNormal);
            adjacencies.push(faceAdjacencies);
        }
        // Scan
        for (index = 0; index < adjacencies.length; index++) {
            faceAdjacencies = adjacencies[index];
            for (var otherIndex = index + 1; otherIndex < adjacencies.length; otherIndex++) {
                var otherFaceAdjacencies = adjacencies[otherIndex];
                if (faceAdjacencies.edgesConnectedCount === 3) { // Full
                    break;
                }
                if (otherFaceAdjacencies.edgesConnectedCount === 3) { // Full
                    continue;
                }
                var otherP0 = indices[otherIndex * 3];
                var otherP1 = indices[otherIndex * 3 + 1];
                var otherP2 = indices[otherIndex * 3 + 2];
                for (var edgeIndex = 0; edgeIndex < 3; edgeIndex++) {
                    var otherEdgeIndex = 0;
                    if (faceAdjacencies.edges[edgeIndex] !== undefined) {
                        continue;
                    }
                    switch (edgeIndex) {
                        case 0:
                            if (this._checkVerticesInsteadOfIndices) {
                                otherEdgeIndex = this._processEdgeForAdjacenciesWithVertices(faceAdjacencies.p0, faceAdjacencies.p1, otherFaceAdjacencies.p0, otherFaceAdjacencies.p1, otherFaceAdjacencies.p2);
                            }
                            else {
                                otherEdgeIndex = this._processEdgeForAdjacencies(indices[index * 3], indices[index * 3 + 1], otherP0, otherP1, otherP2);
                            }
                            break;
                        case 1:
                            if (this._checkVerticesInsteadOfIndices) {
                                otherEdgeIndex = this._processEdgeForAdjacenciesWithVertices(faceAdjacencies.p1, faceAdjacencies.p2, otherFaceAdjacencies.p0, otherFaceAdjacencies.p1, otherFaceAdjacencies.p2);
                            }
                            else {
                                otherEdgeIndex = this._processEdgeForAdjacencies(indices[index * 3 + 1], indices[index * 3 + 2], otherP0, otherP1, otherP2);
                            }
                            break;
                        case 2:
                            if (this._checkVerticesInsteadOfIndices) {
                                otherEdgeIndex = this._processEdgeForAdjacenciesWithVertices(faceAdjacencies.p2, faceAdjacencies.p0, otherFaceAdjacencies.p0, otherFaceAdjacencies.p1, otherFaceAdjacencies.p2);
                            }
                            else {
                                otherEdgeIndex = this._processEdgeForAdjacencies(indices[index * 3 + 2], indices[index * 3], otherP0, otherP1, otherP2);
                            }
                            break;
                    }
                    if (otherEdgeIndex === -1) {
                        continue;
                    }
                    faceAdjacencies.edges[edgeIndex] = otherIndex;
                    otherFaceAdjacencies.edges[otherEdgeIndex] = index;
                    faceAdjacencies.edgesConnectedCount++;
                    otherFaceAdjacencies.edgesConnectedCount++;
                    if (faceAdjacencies.edgesConnectedCount === 3) {
                        break;
                    }
                }
            }
        }
        // Create lines
        for (index = 0; index < adjacencies.length; index++) {
            // We need a line when a face has no adjacency on a specific edge or if all the adjacencies has an angle greater than epsilon
            var current = adjacencies[index];
            this._checkEdge(index, current.edges[0], faceNormals, current.p0, current.p1);
            this._checkEdge(index, current.edges[1], faceNormals, current.p1, current.p2);
            this._checkEdge(index, current.edges[2], faceNormals, current.p2, current.p0);
        }
        // Merge into a single mesh
        var engine = this._source.getScene().getEngine();
        this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"](engine, this._linesPositions, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, false);
        this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"](engine, this._linesNormals, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, false, false, 4);
        this._ib = engine.createIndexBuffer(this._linesIndices);
        this._indicesCount = this._linesIndices.length;
    };
    /**
     * Checks wether or not the edges renderer is ready to render.
     * @return true if ready, otherwise false.
     */
    EdgesRenderer.prototype.isReady = function () {
        return this._lineShader.isReady();
    };
    /**
     * Renders the edges of the attached mesh,
     */
    EdgesRenderer.prototype.render = function () {
        var scene = this._source.getScene();
        if (!this.isReady() || !scene.activeCamera) {
            return;
        }
        var engine = scene.getEngine();
        this._lineShader._preBind();
        if (this._source.edgesColor.a !== 1) {
            engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].ALPHA_COMBINE);
        }
        else {
            engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_8__["Constants"].ALPHA_DISABLE);
        }
        // VBOs
        engine.bindBuffers(this._buffers, this._ib, this._lineShader.getEffect());
        scene.resetCachedMaterial();
        this._lineShader.setColor4("color", this._source.edgesColor);
        if (scene.activeCamera.mode === _Cameras_camera__WEBPACK_IMPORTED_MODULE_7__["Camera"].ORTHOGRAPHIC_CAMERA) {
            this._lineShader.setFloat("width", this._source.edgesWidth / this.edgesWidthScalerForOrthographic);
        }
        else {
            this._lineShader.setFloat("width", this._source.edgesWidth / this.edgesWidthScalerForPerspective);
        }
        this._lineShader.setFloat("aspectRatio", engine.getAspectRatio(scene.activeCamera));
        this._lineShader.bind(this._source.getWorldMatrix());
        // Draw order
        engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, 0, this._indicesCount);
        this._lineShader.unbind();
    };
    return EdgesRenderer;
}());

/**
 * LineEdgesRenderer for LineMeshes to remove unnecessary triangulation
 */
var LineEdgesRenderer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](LineEdgesRenderer, _super);
    /**
     * This constructor turns off auto generating edges line in Edges Renderer to make it here.
     * @param  source LineMesh used to generate edges
     * @param  epsilon not important (specified angle for edge detection)
     * @param  checkVerticesInsteadOfIndices not important for LineMesh
     */
    function LineEdgesRenderer(source, epsilon, checkVerticesInsteadOfIndices) {
        if (epsilon === void 0) { epsilon = 0.95; }
        if (checkVerticesInsteadOfIndices === void 0) { checkVerticesInsteadOfIndices = false; }
        var _this = _super.call(this, source, epsilon, checkVerticesInsteadOfIndices, false) || this;
        _this._generateEdgesLines();
        return _this;
    }
    /**
     * Generate edges for each line in LinesMesh. Every Line should be rendered as edge.
     */
    LineEdgesRenderer.prototype._generateEdgesLines = function () {
        var positions = this._source.getVerticesData(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
        var indices = this._source.getIndices();
        if (!indices || !positions) {
            return;
        }
        var p0 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Vector3[0];
        var p1 = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["TmpVectors"].Vector3[1];
        var len = indices.length - 1;
        for (var i = 0, offset = 0; i < len; i += 2, offset += 4) {
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].FromArrayToRef(positions, 3 * indices[i], p0);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_4__["Vector3"].FromArrayToRef(positions, 3 * indices[i + 1], p1);
            this.createLine(p0, p1, offset);
        }
        // Merge into a single mesh
        var engine = this._source.getScene().getEngine();
        this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"](engine, this._linesPositions, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, false);
        this._buffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind] = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"](engine, this._linesNormals, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, false, false, 4);
        this._ib = engine.createIndexBuffer(this._linesIndices);
        this._indicesCount = this._linesIndices.length;
    };
    return LineEdgesRenderer;
}(EdgesRenderer));



/***/ }),

/***/ "./Rendering/geometryBufferRenderer.ts":
/*!*********************************************!*\
  !*** ./Rendering/geometryBufferRenderer.ts ***!
  \*********************************************/
/*! exports provided: GeometryBufferRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRenderer", function() { return GeometryBufferRenderer; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_Textures_multiRenderTarget__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Materials/Textures/multiRenderTarget */ "./Materials/Textures/multiRenderTarget.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Shaders_geometry_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Shaders/geometry.fragment */ "./Shaders/geometry.fragment.ts");
/* harmony import */ var _Shaders_geometry_vertex__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Shaders/geometry.vertex */ "./Shaders/geometry.vertex.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");











/**
 * This renderer is helpfull to fill one of the render target with a geometry buffer.
 */
var GeometryBufferRenderer = /** @class */ (function () {
    /**
     * Creates a new G Buffer for the scene
     * @param scene The scene the buffer belongs to
     * @param ratio How big is the buffer related to the main canvas.
     */
    function GeometryBufferRenderer(scene, ratio) {
        if (ratio === void 0) { ratio = 1; }
        /**
         * Dictionary used to store the previous transformation matrices of each rendered mesh
         * in order to compute objects velocities when enableVelocity is set to "true"
         * @hidden
         */
        this._previousTransformationMatrices = {};
        /**
         * Dictionary used to store the previous bones transformation matrices of each rendered mesh
         * in order to compute objects velocities when enableVelocity is set to "true"
         * @hidden
         */
        this._previousBonesTransformationMatrices = {};
        /**
         * Array used to store the ignored skinned meshes while computing velocity map (typically used by the motion blur post-process).
         * Avoids computing bones velocities and computes only mesh's velocity itself (position, rotation, scaling).
         */
        this.excludedSkinnedMeshesFromVelocity = [];
        this._enablePosition = false;
        this._enableVelocity = false;
        this._positionIndex = -1;
        this._velocityIndex = -1;
        this._scene = scene;
        this._ratio = ratio;
        GeometryBufferRenderer._SceneComponentInitialization(this._scene);
        // Render target
        this._createRenderTargets();
    }
    Object.defineProperty(GeometryBufferRenderer.prototype, "renderList", {
        /**
         * Set the render list (meshes to be rendered) used in the G buffer.
         */
        set: function (meshes) {
            this._multiRenderTarget.renderList = meshes;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GeometryBufferRenderer.prototype, "isSupported", {
        /**
         * Gets wether or not G buffer are supported by the running hardware.
         * This requires draw buffer supports
         */
        get: function () {
            return this._multiRenderTarget.isSupported;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Returns the index of the given texture type in the G-Buffer textures array
     * @param textureType The texture type constant. For example GeometryBufferRenderer.POSITION_TEXTURE_INDEX
     * @returns the index of the given texture type in the G-Buffer textures array
     */
    GeometryBufferRenderer.prototype.getTextureIndex = function (textureType) {
        switch (textureType) {
            case GeometryBufferRenderer.POSITION_TEXTURE_TYPE: return this._positionIndex;
            case GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE: return this._velocityIndex;
            default: return -1;
        }
    };
    Object.defineProperty(GeometryBufferRenderer.prototype, "enablePosition", {
        /**
         * Gets a boolean indicating if objects positions are enabled for the G buffer.
         */
        get: function () {
            return this._enablePosition;
        },
        /**
         * Sets whether or not objects positions are enabled for the G buffer.
         */
        set: function (enable) {
            this._enablePosition = enable;
            this.dispose();
            this._createRenderTargets();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GeometryBufferRenderer.prototype, "enableVelocity", {
        /**
         * Gets a boolean indicating if objects velocities are enabled for the G buffer.
         */
        get: function () {
            return this._enableVelocity;
        },
        /**
         * Sets wether or not objects velocities are enabled for the G buffer.
         */
        set: function (enable) {
            this._enableVelocity = enable;
            if (!enable) {
                this._previousTransformationMatrices = {};
            }
            this.dispose();
            this._createRenderTargets();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GeometryBufferRenderer.prototype, "scene", {
        /**
         * Gets the scene associated with the buffer.
         */
        get: function () {
            return this._scene;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(GeometryBufferRenderer.prototype, "ratio", {
        /**
         * Gets the ratio used by the buffer during its creation.
         * How big is the buffer related to the main canvas.
         */
        get: function () {
            return this._ratio;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Checks wether everything is ready to render a submesh to the G buffer.
     * @param subMesh the submesh to check readiness for
     * @param useInstances is the mesh drawn using instance or not
     * @returns true if ready otherwise false
     */
    GeometryBufferRenderer.prototype.isReady = function (subMesh, useInstances) {
        var material = subMesh.getMaterial();
        if (material && material.disableDepthWrite) {
            return false;
        }
        var defines = [];
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind];
        var mesh = subMesh.getMesh();
        // Alpha test
        if (material && material.needAlphaTesting()) {
            defines.push("#define ALPHATEST");
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind)) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UVKind);
                defines.push("#define UV1");
            }
            if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind)) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].UV2Kind);
                defines.push("#define UV2");
            }
        }
        // Buffers
        if (this._enablePosition) {
            defines.push("#define POSITION");
            defines.push("#define POSITION_INDEX " + this._positionIndex);
        }
        if (this._enableVelocity) {
            defines.push("#define VELOCITY");
            defines.push("#define VELOCITY_INDEX " + this._velocityIndex);
            if (this.excludedSkinnedMeshesFromVelocity.indexOf(mesh) === -1) {
                defines.push("#define BONES_VELOCITY_ENABLED");
            }
        }
        // Bones
        if (mesh.useBones && mesh.computeBonesUsingShaders) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsKind);
            if (mesh.numBoneInfluencers > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].MatricesWeightsExtraKind);
            }
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            defines.push("#define BonesPerMesh " + (mesh.skeleton ? mesh.skeleton.bones.length + 1 : 0));
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Morph targets
        var morphTargetManager = mesh.morphTargetManager;
        var numMorphInfluencers = 0;
        if (morphTargetManager) {
            if (morphTargetManager.numInfluencers > 0) {
                numMorphInfluencers = morphTargetManager.numInfluencers;
                defines.push("#define MORPHTARGETS");
                defines.push("#define NUM_MORPH_INFLUENCERS " + numMorphInfluencers);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, numMorphInfluencers);
            }
        }
        // Instances
        if (useInstances) {
            defines.push("#define INSTANCES");
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        // Setup textures count
        defines.push("#define RENDER_TARGET_COUNT " + this._multiRenderTarget.textures.length);
        // Get correct effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            this._effect = this._scene.getEngine().createEffect("geometry", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "view", "previousWorld", "previousViewProjection", "mPreviousBones", "morphTargetInfluences"], ["diffuseSampler"], join, undefined, undefined, undefined, { buffersCount: this._enablePosition ? 3 : 2, maxSimultaneousMorphTargets: numMorphInfluencers });
        }
        return this._effect.isReady();
    };
    /**
     * Gets the current underlying G Buffer.
     * @returns the buffer
     */
    GeometryBufferRenderer.prototype.getGBuffer = function () {
        return this._multiRenderTarget;
    };
    Object.defineProperty(GeometryBufferRenderer.prototype, "samples", {
        /**
         * Gets the number of samples used to render the buffer (anti aliasing).
         */
        get: function () {
            return this._multiRenderTarget.samples;
        },
        /**
         * Sets the number of samples used to render the buffer (anti aliasing).
         */
        set: function (value) {
            this._multiRenderTarget.samples = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Disposes the renderer and frees up associated resources.
     */
    GeometryBufferRenderer.prototype.dispose = function () {
        this.getGBuffer().dispose();
    };
    GeometryBufferRenderer.prototype._createRenderTargets = function () {
        var _this = this;
        var engine = this._scene.getEngine();
        var count = 2;
        if (this._enablePosition) {
            this._positionIndex = count;
            count++;
        }
        if (this._enableVelocity) {
            this._velocityIndex = count;
            count++;
        }
        this._multiRenderTarget = new _Materials_Textures_multiRenderTarget__WEBPACK_IMPORTED_MODULE_4__["MultiRenderTarget"]("gBuffer", { width: engine.getRenderWidth() * this._ratio, height: engine.getRenderHeight() * this._ratio }, count, this._scene, { generateMipMaps: false, generateDepthTexture: true, defaultType: _Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].TEXTURETYPE_FLOAT });
        if (!this.isSupported) {
            return;
        }
        this._multiRenderTarget.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].CLAMP_ADDRESSMODE;
        this._multiRenderTarget.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_3__["Texture"].CLAMP_ADDRESSMODE;
        this._multiRenderTarget.refreshRate = 1;
        this._multiRenderTarget.renderParticles = false;
        this._multiRenderTarget.renderList = null;
        // set default depth value to 1.0 (far away)
        this._multiRenderTarget.onClearObservable.add(function (engine) {
            engine.clear(new _Maths_math_color__WEBPACK_IMPORTED_MODULE_10__["Color4"](0.0, 0.0, 0.0, 1.0), true, true, true);
        });
        // Custom render function
        var renderSubMesh = function (subMesh) {
            var mesh = subMesh.getRenderingMesh();
            var scene = _this._scene;
            var engine = scene.getEngine();
            var material = subMesh.getMaterial();
            if (!material) {
                return;
            }
            mesh._internalAbstractMeshDataInfo._isActiveIntermediate = false;
            // Velocity
            if (_this._enableVelocity && !_this._previousTransformationMatrices[mesh.uniqueId]) {
                _this._previousTransformationMatrices[mesh.uniqueId] = {
                    world: _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].Identity(),
                    viewProjection: scene.getTransformMatrix()
                };
                if (mesh.skeleton) {
                    var bonesTransformations = mesh.skeleton.getTransformMatrices(mesh);
                    _this._previousBonesTransformationMatrices[mesh.uniqueId] = _this._copyBonesTransformationMatrices(bonesTransformations, new Float32Array(bonesTransformations.length));
                }
            }
            // Culling
            engine.setState(material.backFaceCulling, 0, false, scene.useRightHandedSystem);
            // Managing instances
            var batch = mesh._getInstancesRenderList(subMesh._id);
            if (batch.mustReturn) {
                return;
            }
            var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null);
            if (_this.isReady(subMesh, hardwareInstancedRendering)) {
                engine.enableEffect(_this._effect);
                mesh._bind(subMesh, _this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode);
                _this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
                _this._effect.setMatrix("view", scene.getViewMatrix());
                // Alpha test
                if (material && material.needAlphaTesting()) {
                    var alphaTexture = material.getAlphaTestTexture();
                    if (alphaTexture) {
                        _this._effect.setTexture("diffuseSampler", alphaTexture);
                        _this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
                    }
                }
                // Bones
                if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
                    _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                    if (_this._enableVelocity) {
                        _this._effect.setMatrices("mPreviousBones", _this._previousBonesTransformationMatrices[mesh.uniqueId]);
                    }
                }
                // Morph targets
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].BindMorphTargetParameters(mesh, _this._effect);
                // Velocity
                if (_this._enableVelocity) {
                    _this._effect.setMatrix("previousWorld", _this._previousTransformationMatrices[mesh.uniqueId].world);
                    _this._effect.setMatrix("previousViewProjection", _this._previousTransformationMatrices[mesh.uniqueId].viewProjection);
                }
                // Draw
                mesh._processRendering(subMesh, _this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._effect.setMatrix("world", world); });
            }
            // Velocity
            if (_this._enableVelocity) {
                _this._previousTransformationMatrices[mesh.uniqueId].world = mesh.getWorldMatrix().clone();
                _this._previousTransformationMatrices[mesh.uniqueId].viewProjection = _this._scene.getTransformMatrix().clone();
                if (mesh.skeleton) {
                    _this._copyBonesTransformationMatrices(mesh.skeleton.getTransformMatrices(mesh), _this._previousBonesTransformationMatrices[mesh.uniqueId]);
                }
            }
        };
        this._multiRenderTarget.customRenderFunction = function (opaqueSubMeshes, alphaTestSubMeshes, transparentSubMeshes, depthOnlySubMeshes) {
            var index;
            if (depthOnlySubMeshes.length) {
                engine.setColorWrite(false);
                for (index = 0; index < depthOnlySubMeshes.length; index++) {
                    renderSubMesh(depthOnlySubMeshes.data[index]);
                }
                engine.setColorWrite(true);
            }
            for (index = 0; index < opaqueSubMeshes.length; index++) {
                renderSubMesh(opaqueSubMeshes.data[index]);
            }
            for (index = 0; index < alphaTestSubMeshes.length; index++) {
                renderSubMesh(alphaTestSubMeshes.data[index]);
            }
        };
    };
    // Copies the bones transformation matrices into the target array and returns the target's reference
    GeometryBufferRenderer.prototype._copyBonesTransformationMatrices = function (source, target) {
        for (var i = 0; i < source.length; i++) {
            target[i] = source[i];
        }
        return target;
    };
    /**
     * Constant used to retrieve the position texture index in the G-Buffer textures array
     * using getIndex(GeometryBufferRenderer.POSITION_TEXTURE_INDEX)
     */
    GeometryBufferRenderer.POSITION_TEXTURE_TYPE = 1;
    /**
     * Constant used to retrieve the velocity texture index in the G-Buffer textures array
     * using getIndex(GeometryBufferRenderer.VELOCITY_TEXTURE_INDEX)
     */
    GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE = 2;
    /** @hidden */
    GeometryBufferRenderer._SceneComponentInitialization = function (_) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_9__["_DevTools"].WarnImport("GeometryBufferRendererSceneComponent");
    };
    return GeometryBufferRenderer;
}());



/***/ }),

/***/ "./Rendering/geometryBufferRendererSceneComponent.ts":
/*!***********************************************************!*\
  !*** ./Rendering/geometryBufferRendererSceneComponent.ts ***!
  \***********************************************************/
/*! exports provided: GeometryBufferRendererSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRendererSceneComponent", function() { return GeometryBufferRendererSceneComponent; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./geometryBufferRenderer */ "./Rendering/geometryBufferRenderer.ts");



Object.defineProperty(_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype, "geometryBufferRenderer", {
    get: function () {
        this._geometryBufferRenderer;
    },
    set: function (value) {
        if (value && value.isSupported) {
            this._geometryBufferRenderer = value;
        }
    },
    enumerable: true,
    configurable: true
});
_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype.enableGeometryBufferRenderer = function (ratio) {
    if (ratio === void 0) { ratio = 1; }
    if (this._geometryBufferRenderer) {
        return this._geometryBufferRenderer;
    }
    this._geometryBufferRenderer = new _geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_2__["GeometryBufferRenderer"](this, ratio);
    if (!this._geometryBufferRenderer.isSupported) {
        this._geometryBufferRenderer = null;
    }
    return this._geometryBufferRenderer;
};
_scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].prototype.disableGeometryBufferRenderer = function () {
    if (!this._geometryBufferRenderer) {
        return;
    }
    this._geometryBufferRenderer.dispose();
    this._geometryBufferRenderer = null;
};
/**
 * Defines the Geometry Buffer scene component responsible to manage a G-Buffer useful
 * in several rendering techniques.
 */
var GeometryBufferRendererSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function GeometryBufferRendererSceneComponent(scene) {
        /**
         * The component name helpful to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_GEOMETRYBUFFERRENDERER;
        this.scene = scene;
    }
    /**
     * Registers the component in a given scene
     */
    GeometryBufferRendererSceneComponent.prototype.register = function () {
        this.scene._gatherRenderTargetsStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER, this, this._gatherRenderTargets);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    GeometryBufferRendererSceneComponent.prototype.rebuild = function () {
        // Nothing to do for this component
    };
    /**
     * Disposes the component and the associated ressources
     */
    GeometryBufferRendererSceneComponent.prototype.dispose = function () {
        // Nothing to do for this component
    };
    GeometryBufferRendererSceneComponent.prototype._gatherRenderTargets = function (renderTargets) {
        if (this.scene._geometryBufferRenderer) {
            renderTargets.push(this.scene._geometryBufferRenderer.getGBuffer());
        }
    };
    return GeometryBufferRendererSceneComponent;
}());

_geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_2__["GeometryBufferRenderer"]._SceneComponentInitialization = function (scene) {
    // Register the G Buffer component to the scene.
    var component = scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_1__["SceneComponentConstants"].NAME_GEOMETRYBUFFERRENDERER);
    if (!component) {
        component = new GeometryBufferRendererSceneComponent(scene);
        scene._addComponent(component);
    }
};


/***/ }),

/***/ "./Rendering/index.ts":
/*!****************************!*\
  !*** ./Rendering/index.ts ***!
  \****************************/
/*! exports provided: BoundingBoxRenderer, DepthRenderer, DepthRendererSceneComponent, EdgesRenderer, LineEdgesRenderer, GeometryBufferRenderer, GeometryBufferRendererSceneComponent, OutlineRenderer, RenderingGroup, RenderingGroupInfo, RenderingManager, UtilityLayerRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _boundingBoxRenderer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./boundingBoxRenderer */ "./Rendering/boundingBoxRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxRenderer", function() { return _boundingBoxRenderer__WEBPACK_IMPORTED_MODULE_0__["BoundingBoxRenderer"]; });

/* harmony import */ var _depthRenderer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./depthRenderer */ "./Rendering/depthRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthRenderer", function() { return _depthRenderer__WEBPACK_IMPORTED_MODULE_1__["DepthRenderer"]; });

/* harmony import */ var _depthRendererSceneComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./depthRendererSceneComponent */ "./Rendering/depthRendererSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthRendererSceneComponent", function() { return _depthRendererSceneComponent__WEBPACK_IMPORTED_MODULE_2__["DepthRendererSceneComponent"]; });

/* harmony import */ var _edgesRenderer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./edgesRenderer */ "./Rendering/edgesRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EdgesRenderer", function() { return _edgesRenderer__WEBPACK_IMPORTED_MODULE_3__["EdgesRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LineEdgesRenderer", function() { return _edgesRenderer__WEBPACK_IMPORTED_MODULE_3__["LineEdgesRenderer"]; });

/* harmony import */ var _geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./geometryBufferRenderer */ "./Rendering/geometryBufferRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRenderer", function() { return _geometryBufferRenderer__WEBPACK_IMPORTED_MODULE_4__["GeometryBufferRenderer"]; });

/* harmony import */ var _geometryBufferRendererSceneComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./geometryBufferRendererSceneComponent */ "./Rendering/geometryBufferRendererSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRendererSceneComponent", function() { return _geometryBufferRendererSceneComponent__WEBPACK_IMPORTED_MODULE_5__["GeometryBufferRendererSceneComponent"]; });

/* harmony import */ var _outlineRenderer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./outlineRenderer */ "./Rendering/outlineRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OutlineRenderer", function() { return _outlineRenderer__WEBPACK_IMPORTED_MODULE_6__["OutlineRenderer"]; });

/* harmony import */ var _renderingGroup__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./renderingGroup */ "./Rendering/renderingGroup.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingGroup", function() { return _renderingGroup__WEBPACK_IMPORTED_MODULE_7__["RenderingGroup"]; });

/* harmony import */ var _renderingManager__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./renderingManager */ "./Rendering/renderingManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingGroupInfo", function() { return _renderingManager__WEBPACK_IMPORTED_MODULE_8__["RenderingGroupInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingManager", function() { return _renderingManager__WEBPACK_IMPORTED_MODULE_8__["RenderingManager"]; });

/* harmony import */ var _utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utilityLayerRenderer */ "./Rendering/utilityLayerRenderer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UtilityLayerRenderer", function() { return _utilityLayerRenderer__WEBPACK_IMPORTED_MODULE_9__["UtilityLayerRenderer"]; });













/***/ }),

/***/ "./Rendering/outlineRenderer.ts":
/*!**************************************!*\
  !*** ./Rendering/outlineRenderer.ts ***!
  \**************************************/
/*! exports provided: OutlineRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OutlineRenderer", function() { return OutlineRenderer; });
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/materialHelper */ "./Materials/materialHelper.ts");
/* harmony import */ var _Shaders_outline_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Shaders/outline.fragment */ "./Shaders/outline.fragment.ts");
/* harmony import */ var _Shaders_outline_vertex__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../Shaders/outline.vertex */ "./Shaders/outline.vertex.ts");









/**
 * Gets the outline renderer associated with the scene
 * @returns a OutlineRenderer
 */
_scene__WEBPACK_IMPORTED_MODULE_2__["Scene"].prototype.getOutlineRenderer = function () {
    if (!this._outlineRenderer) {
        this._outlineRenderer = new OutlineRenderer(this);
    }
    return this._outlineRenderer;
};
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "renderOutline", {
    get: function () {
        return this._renderOutline;
    },
    set: function (value) {
        if (value) {
            // Lazy Load the component.
            this.getScene().getOutlineRenderer();
        }
        this._renderOutline = value;
    },
    enumerable: true,
    configurable: true
});
Object.defineProperty(_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["AbstractMesh"].prototype, "renderOverlay", {
    get: function () {
        return this._renderOverlay;
    },
    set: function (value) {
        if (value) {
            // Lazy Load the component.
            this.getScene().getOutlineRenderer();
        }
        this._renderOverlay = value;
    },
    enumerable: true,
    configurable: true
});
/**
 * This class is responsible to draw bothe outline/overlay of meshes.
 * It should not be used directly but through the available method on mesh.
 */
var OutlineRenderer = /** @class */ (function () {
    /**
     * Instantiates a new outline renderer. (There could be only one per scene).
     * @param scene Defines the scene it belongs to
     */
    function OutlineRenderer(scene) {
        /**
         * The name of the component. Each component must have a unique name.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_OUTLINERENDERER;
        /**
         * Defines a zOffset to prevent zFighting between the overlay and the mesh.
         */
        this.zOffset = 1;
        this.scene = scene;
        this._engine = scene.getEngine();
        this.scene._addComponent(this);
    }
    /**
     * Register the component to one instance of a scene.
     */
    OutlineRenderer.prototype.register = function () {
        this.scene._beforeRenderingMeshStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].STEP_BEFORERENDERINGMESH_OUTLINE, this, this._beforeRenderingMesh);
        this.scene._afterRenderingMeshStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].STEP_AFTERRENDERINGMESH_OUTLINE, this, this._afterRenderingMesh);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    OutlineRenderer.prototype.rebuild = function () {
        // Nothing to do here.
    };
    /**
     * Disposes the component and the associated ressources.
     */
    OutlineRenderer.prototype.dispose = function () {
        // Nothing to do here.
    };
    /**
     * Renders the outline in the canvas.
     * @param subMesh Defines the sumesh to render
     * @param batch Defines the batch of meshes in case of instances
     * @param useOverlay Defines if the rendering is for the overlay or the outline
     */
    OutlineRenderer.prototype.render = function (subMesh, batch, useOverlay) {
        var _this = this;
        if (useOverlay === void 0) { useOverlay = false; }
        var scene = this.scene;
        var engine = scene.getEngine();
        var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
        if (!this.isReady(subMesh, hardwareInstancedRendering)) {
            return;
        }
        var mesh = subMesh.getRenderingMesh();
        var material = subMesh.getMaterial();
        if (!material || !scene.activeCamera) {
            return;
        }
        engine.enableEffect(this._effect);
        // Logarithmic depth
        if (material.useLogarithmicDepth) {
            this._effect.setFloat("logarithmicDepthConstant", 2.0 / (Math.log(scene.activeCamera.maxZ + 1.0) / Math.LN2));
        }
        this._effect.setFloat("offset", useOverlay ? 0 : mesh.outlineWidth);
        this._effect.setColor4("color", useOverlay ? mesh.overlayColor : mesh.outlineColor, useOverlay ? mesh.overlayAlpha : material.alpha);
        this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
        // Bones
        if (mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
            this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
        }
        // Morph targets
        _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].BindMorphTargetParameters(mesh, this._effect);
        mesh._bind(subMesh, this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode);
        // Alpha test
        if (material && material.needAlphaTesting()) {
            var alphaTexture = material.getAlphaTestTexture();
            if (alphaTexture) {
                this._effect.setTexture("diffuseSampler", alphaTexture);
                this._effect.setMatrix("diffuseMatrix", alphaTexture.getTextureMatrix());
            }
        }
        engine.setZOffset(-this.zOffset);
        mesh._processRendering(subMesh, this._effect, _Materials_material__WEBPACK_IMPORTED_MODULE_5__["Material"].TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { _this._effect.setMatrix("world", world); });
        engine.setZOffset(0);
    };
    /**
     * Returns whether or not the outline renderer is ready for a given submesh.
     * All the dependencies e.g. submeshes, texture, effect... mus be ready
     * @param subMesh Defines the submesh to check readyness for
     * @param useInstances Defines wheter wee are trying to render instances or not
     * @returns true if ready otherwise false
     */
    OutlineRenderer.prototype.isReady = function (subMesh, useInstances) {
        var defines = [];
        var attribs = [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].PositionKind, _Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].NormalKind];
        var mesh = subMesh.getMesh();
        var material = subMesh.getMaterial();
        if (material) {
            // Alpha test
            if (material.needAlphaTesting()) {
                defines.push("#define ALPHATEST");
                if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UVKind)) {
                    attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UVKind);
                    defines.push("#define UV1");
                }
                if (mesh.isVerticesDataPresent(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UV2Kind)) {
                    attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UV2Kind);
                    defines.push("#define UV2");
                }
            }
            //Logarithmic depth
            if (material.useLogarithmicDepth) {
                defines.push("#define LOGARITHMICDEPTH");
            }
        }
        // Bones
        if (mesh.useBones && mesh.computeBonesUsingShaders) {
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind);
            attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsKind);
            if (mesh.numBoneInfluencers > 4) {
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind);
                attribs.push(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsExtraKind);
            }
            defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);
            defines.push("#define BonesPerMesh " + (mesh.skeleton ? mesh.skeleton.bones.length + 1 : 0));
        }
        else {
            defines.push("#define NUM_BONE_INFLUENCERS 0");
        }
        // Morph targets
        var morphTargetManager = mesh.morphTargetManager;
        var numMorphInfluencers = 0;
        if (morphTargetManager) {
            if (morphTargetManager.numInfluencers > 0) {
                numMorphInfluencers = morphTargetManager.numInfluencers;
                defines.push("#define MORPHTARGETS");
                defines.push("#define NUM_MORPH_INFLUENCERS " + numMorphInfluencers);
                _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, numMorphInfluencers);
            }
        }
        // Instances
        if (useInstances) {
            defines.push("#define INSTANCES");
            _Materials_materialHelper__WEBPACK_IMPORTED_MODULE_6__["MaterialHelper"].PushAttributesForInstances(attribs);
        }
        // Get correct effect
        var join = defines.join("\n");
        if (this._cachedDefines !== join) {
            this._cachedDefines = join;
            this._effect = this.scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant", "morphTargetInfluences"], ["diffuseSampler"], join, undefined, undefined, undefined, { maxSimultaneousMorphTargets: numMorphInfluencers });
        }
        return this._effect.isReady();
    };
    OutlineRenderer.prototype._beforeRenderingMesh = function (mesh, subMesh, batch) {
        // Outline - step 1
        this._savedDepthWrite = this._engine.getDepthWrite();
        if (mesh.renderOutline) {
            var material = subMesh.getMaterial();
            if (material && material.needAlphaBlending()) {
                this._engine.cacheStencilState();
                // Draw only to stencil buffer for the original mesh
                // The resulting stencil buffer will be used so the outline is not visible inside the mesh when the mesh is transparent
                this._engine.setDepthWrite(false);
                this._engine.setColorWrite(false);
                this._engine.setStencilBuffer(true);
                this._engine.setStencilOperationPass(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].REPLACE);
                this._engine.setStencilFunction(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ALWAYS);
                this._engine.setStencilMask(OutlineRenderer._StencilReference);
                this._engine.setStencilFunctionReference(OutlineRenderer._StencilReference);
                this.render(subMesh, batch, /* This sets offset to 0 */ true);
                this._engine.setColorWrite(true);
                this._engine.setStencilFunction(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].NOTEQUAL);
            }
            // Draw the outline using the above stencil if needed to avoid drawing within the mesh
            this._engine.setDepthWrite(false);
            this.render(subMesh, batch);
            this._engine.setDepthWrite(this._savedDepthWrite);
            if (material && material.needAlphaBlending()) {
                this._engine.restoreStencilState();
            }
        }
    };
    OutlineRenderer.prototype._afterRenderingMesh = function (mesh, subMesh, batch) {
        // Overlay
        if (mesh.renderOverlay) {
            var currentMode = this._engine.getAlphaMode();
            this._engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_3__["Constants"].ALPHA_COMBINE);
            this.render(subMesh, batch, true);
            this._engine.setAlphaMode(currentMode);
        }
        // Outline - step 2
        if (mesh.renderOutline && this._savedDepthWrite) {
            this._engine.setDepthWrite(true);
            this._engine.setColorWrite(false);
            this.render(subMesh, batch);
            this._engine.setColorWrite(true);
        }
    };
    /**
     * Stencil value used to avoid outline being seen within the mesh when the mesh is transparent
     */
    OutlineRenderer._StencilReference = 0x04;
    return OutlineRenderer;
}());



/***/ }),

/***/ "./Rendering/renderingGroup.ts":
/*!*************************************!*\
  !*** ./Rendering/renderingGroup.ts ***!
  \*************************************/
/*! exports provided: RenderingGroup */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderingGroup", function() { return RenderingGroup; });
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");



/**
 * This represents the object necessary to create a rendering group.
 * This is exclusively used and created by the rendering manager.
 * To modify the behavior, you use the available helpers in your scene or meshes.
 * @hidden
 */
var RenderingGroup = /** @class */ (function () {
    /**
     * Creates a new rendering group.
     * @param index The rendering group index
     * @param opaqueSortCompareFn The opaque sort comparison function. If null no order is applied
     * @param alphaTestSortCompareFn The alpha test sort comparison function. If null no order is applied
     * @param transparentSortCompareFn The transparent sort comparison function. If null back to front + alpha index sort is applied
     */
    function RenderingGroup(index, scene, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn) {
        if (opaqueSortCompareFn === void 0) { opaqueSortCompareFn = null; }
        if (alphaTestSortCompareFn === void 0) { alphaTestSortCompareFn = null; }
        if (transparentSortCompareFn === void 0) { transparentSortCompareFn = null; }
        this.index = index;
        this._opaqueSubMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](256);
        this._transparentSubMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](256);
        this._alphaTestSubMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](256);
        this._depthOnlySubMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](256);
        this._particleSystems = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](256);
        this._spriteManagers = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](256);
        /** @hidden */
        this._edgesRenderers = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_0__["SmartArray"](16);
        this._scene = scene;
        this.opaqueSortCompareFn = opaqueSortCompareFn;
        this.alphaTestSortCompareFn = alphaTestSortCompareFn;
        this.transparentSortCompareFn = transparentSortCompareFn;
    }
    Object.defineProperty(RenderingGroup.prototype, "opaqueSortCompareFn", {
        /**
         * Set the opaque sort comparison function.
         * If null the sub meshes will be render in the order they were created
         */
        set: function (value) {
            this._opaqueSortCompareFn = value;
            if (value) {
                this._renderOpaque = this.renderOpaqueSorted;
            }
            else {
                this._renderOpaque = RenderingGroup.renderUnsorted;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RenderingGroup.prototype, "alphaTestSortCompareFn", {
        /**
         * Set the alpha test sort comparison function.
         * If null the sub meshes will be render in the order they were created
         */
        set: function (value) {
            this._alphaTestSortCompareFn = value;
            if (value) {
                this._renderAlphaTest = this.renderAlphaTestSorted;
            }
            else {
                this._renderAlphaTest = RenderingGroup.renderUnsorted;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(RenderingGroup.prototype, "transparentSortCompareFn", {
        /**
         * Set the transparent sort comparison function.
         * If null the sub meshes will be render in the order they were created
         */
        set: function (value) {
            if (value) {
                this._transparentSortCompareFn = value;
            }
            else {
                this._transparentSortCompareFn = RenderingGroup.defaultTransparentSortCompare;
            }
            this._renderTransparent = this.renderTransparentSorted;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Render all the sub meshes contained in the group.
     * @param customRenderFunction Used to override the default render behaviour of the group.
     * @returns true if rendered some submeshes.
     */
    RenderingGroup.prototype.render = function (customRenderFunction, renderSprites, renderParticles, activeMeshes) {
        if (customRenderFunction) {
            customRenderFunction(this._opaqueSubMeshes, this._alphaTestSubMeshes, this._transparentSubMeshes, this._depthOnlySubMeshes);
            return;
        }
        var engine = this._scene.getEngine();
        // Depth only
        if (this._depthOnlySubMeshes.length !== 0) {
            engine.setColorWrite(false);
            this._renderAlphaTest(this._depthOnlySubMeshes);
            engine.setColorWrite(true);
        }
        // Opaque
        if (this._opaqueSubMeshes.length !== 0) {
            this._renderOpaque(this._opaqueSubMeshes);
        }
        // Alpha test
        if (this._alphaTestSubMeshes.length !== 0) {
            this._renderAlphaTest(this._alphaTestSubMeshes);
        }
        var stencilState = engine.getStencilBuffer();
        engine.setStencilBuffer(false);
        // Sprites
        if (renderSprites) {
            this._renderSprites();
        }
        // Particles
        if (renderParticles) {
            this._renderParticles(activeMeshes);
        }
        if (this.onBeforeTransparentRendering) {
            this.onBeforeTransparentRendering();
        }
        // Transparent
        if (this._transparentSubMeshes.length !== 0) {
            this._renderTransparent(this._transparentSubMeshes);
            engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].ALPHA_DISABLE);
        }
        // Set back stencil to false in case it changes before the edge renderer.
        engine.setStencilBuffer(false);
        // Edges
        if (this._edgesRenderers.length) {
            for (var edgesRendererIndex = 0; edgesRendererIndex < this._edgesRenderers.length; edgesRendererIndex++) {
                this._edgesRenderers.data[edgesRendererIndex].render();
            }
            engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].ALPHA_DISABLE);
        }
        // Restore Stencil state.
        engine.setStencilBuffer(stencilState);
    };
    /**
     * Renders the opaque submeshes in the order from the opaqueSortCompareFn.
     * @param subMeshes The submeshes to render
     */
    RenderingGroup.prototype.renderOpaqueSorted = function (subMeshes) {
        return RenderingGroup.renderSorted(subMeshes, this._opaqueSortCompareFn, this._scene.activeCamera, false);
    };
    /**
     * Renders the opaque submeshes in the order from the alphatestSortCompareFn.
     * @param subMeshes The submeshes to render
     */
    RenderingGroup.prototype.renderAlphaTestSorted = function (subMeshes) {
        return RenderingGroup.renderSorted(subMeshes, this._alphaTestSortCompareFn, this._scene.activeCamera, false);
    };
    /**
     * Renders the opaque submeshes in the order from the transparentSortCompareFn.
     * @param subMeshes The submeshes to render
     */
    RenderingGroup.prototype.renderTransparentSorted = function (subMeshes) {
        return RenderingGroup.renderSorted(subMeshes, this._transparentSortCompareFn, this._scene.activeCamera, true);
    };
    /**
     * Renders the submeshes in a specified order.
     * @param subMeshes The submeshes to sort before render
     * @param sortCompareFn The comparison function use to sort
     * @param cameraPosition The camera position use to preprocess the submeshes to help sorting
     * @param transparent Specifies to activate blending if true
     */
    RenderingGroup.renderSorted = function (subMeshes, sortCompareFn, camera, transparent) {
        var subIndex = 0;
        var subMesh;
        var cameraPosition = camera ? camera.globalPosition : RenderingGroup._zeroVector;
        for (; subIndex < subMeshes.length; subIndex++) {
            subMesh = subMeshes.data[subIndex];
            subMesh._alphaIndex = subMesh.getMesh().alphaIndex;
            subMesh._distanceToCamera = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Distance(subMesh.getBoundingInfo().boundingSphere.centerWorld, cameraPosition);
        }
        var sortedArray = subMeshes.data.slice(0, subMeshes.length);
        if (sortCompareFn) {
            sortedArray.sort(sortCompareFn);
        }
        for (subIndex = 0; subIndex < sortedArray.length; subIndex++) {
            subMesh = sortedArray[subIndex];
            if (transparent) {
                var material = subMesh.getMaterial();
                if (material && material.needDepthPrePass) {
                    var engine = material.getScene().getEngine();
                    engine.setColorWrite(false);
                    engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_2__["Constants"].ALPHA_DISABLE);
                    subMesh.render(false);
                    engine.setColorWrite(true);
                }
            }
            subMesh.render(transparent);
        }
    };
    /**
     * Renders the submeshes in the order they were dispatched (no sort applied).
     * @param subMeshes The submeshes to render
     */
    RenderingGroup.renderUnsorted = function (subMeshes) {
        for (var subIndex = 0; subIndex < subMeshes.length; subIndex++) {
            var submesh = subMeshes.data[subIndex];
            submesh.render(false);
        }
    };
    /**
     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)
     * are rendered back to front if in the same alpha index.
     *
     * @param a The first submesh
     * @param b The second submesh
     * @returns The result of the comparison
     */
    RenderingGroup.defaultTransparentSortCompare = function (a, b) {
        // Alpha index first
        if (a._alphaIndex > b._alphaIndex) {
            return 1;
        }
        if (a._alphaIndex < b._alphaIndex) {
            return -1;
        }
        // Then distance to camera
        return RenderingGroup.backToFrontSortCompare(a, b);
    };
    /**
     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)
     * are rendered back to front.
     *
     * @param a The first submesh
     * @param b The second submesh
     * @returns The result of the comparison
     */
    RenderingGroup.backToFrontSortCompare = function (a, b) {
        // Then distance to camera
        if (a._distanceToCamera < b._distanceToCamera) {
            return 1;
        }
        if (a._distanceToCamera > b._distanceToCamera) {
            return -1;
        }
        return 0;
    };
    /**
     * Build in function which can be applied to ensure meshes of a special queue (opaque, alpha test, transparent)
     * are rendered front to back (prevent overdraw).
     *
     * @param a The first submesh
     * @param b The second submesh
     * @returns The result of the comparison
     */
    RenderingGroup.frontToBackSortCompare = function (a, b) {
        // Then distance to camera
        if (a._distanceToCamera < b._distanceToCamera) {
            return -1;
        }
        if (a._distanceToCamera > b._distanceToCamera) {
            return 1;
        }
        return 0;
    };
    /**
     * Resets the different lists of submeshes to prepare a new frame.
     */
    RenderingGroup.prototype.prepare = function () {
        this._opaqueSubMeshes.reset();
        this._transparentSubMeshes.reset();
        this._alphaTestSubMeshes.reset();
        this._depthOnlySubMeshes.reset();
        this._particleSystems.reset();
        this._spriteManagers.reset();
        this._edgesRenderers.reset();
    };
    RenderingGroup.prototype.dispose = function () {
        this._opaqueSubMeshes.dispose();
        this._transparentSubMeshes.dispose();
        this._alphaTestSubMeshes.dispose();
        this._depthOnlySubMeshes.dispose();
        this._particleSystems.dispose();
        this._spriteManagers.dispose();
        this._edgesRenderers.dispose();
    };
    /**
     * Inserts the submesh in its correct queue depending on its material.
     * @param subMesh The submesh to dispatch
     * @param [mesh] Optional reference to the submeshes's mesh. Provide if you have an exiting reference to improve performance.
     * @param [material] Optional reference to the submeshes's material. Provide if you have an exiting reference to improve performance.
     */
    RenderingGroup.prototype.dispatch = function (subMesh, mesh, material) {
        // Get mesh and materials if not provided
        if (mesh === undefined) {
            mesh = subMesh.getMesh();
        }
        if (material === undefined) {
            material = subMesh.getMaterial();
        }
        if (material === null || material === undefined) {
            return;
        }
        if (material.needAlphaBlendingForMesh(mesh)) { // Transparent
            this._transparentSubMeshes.push(subMesh);
        }
        else if (material.needAlphaTesting()) { // Alpha test
            if (material.needDepthPrePass) {
                this._depthOnlySubMeshes.push(subMesh);
            }
            this._alphaTestSubMeshes.push(subMesh);
        }
        else {
            if (material.needDepthPrePass) {
                this._depthOnlySubMeshes.push(subMesh);
            }
            this._opaqueSubMeshes.push(subMesh); // Opaque
        }
        mesh._renderingGroup = this;
        if (mesh._edgesRenderer && mesh._edgesRenderer.isEnabled) {
            this._edgesRenderers.push(mesh._edgesRenderer);
        }
    };
    RenderingGroup.prototype.dispatchSprites = function (spriteManager) {
        this._spriteManagers.push(spriteManager);
    };
    RenderingGroup.prototype.dispatchParticles = function (particleSystem) {
        this._particleSystems.push(particleSystem);
    };
    RenderingGroup.prototype._renderParticles = function (activeMeshes) {
        if (this._particleSystems.length === 0) {
            return;
        }
        // Particles
        var activeCamera = this._scene.activeCamera;
        this._scene.onBeforeParticlesRenderingObservable.notifyObservers(this._scene);
        for (var particleIndex = 0; particleIndex < this._particleSystems.length; particleIndex++) {
            var particleSystem = this._particleSystems.data[particleIndex];
            if ((activeCamera && activeCamera.layerMask & particleSystem.layerMask) === 0) {
                continue;
            }
            var emitter = particleSystem.emitter;
            if (!emitter.position || !activeMeshes || activeMeshes.indexOf(emitter) !== -1) {
                this._scene._activeParticles.addCount(particleSystem.render(), false);
            }
        }
        this._scene.onAfterParticlesRenderingObservable.notifyObservers(this._scene);
    };
    RenderingGroup.prototype._renderSprites = function () {
        if (!this._scene.spritesEnabled || this._spriteManagers.length === 0) {
            return;
        }
        // Sprites
        var activeCamera = this._scene.activeCamera;
        this._scene.onBeforeSpritesRenderingObservable.notifyObservers(this._scene);
        for (var id = 0; id < this._spriteManagers.length; id++) {
            var spriteManager = this._spriteManagers.data[id];
            if (((activeCamera && activeCamera.layerMask & spriteManager.layerMask) !== 0)) {
                spriteManager.render();
            }
        }
        this._scene.onAfterSpritesRenderingObservable.notifyObservers(this._scene);
    };
    RenderingGroup._zeroVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero();
    return RenderingGroup;
}());



/***/ }),

/***/ "./Rendering/renderingManager.ts":
/*!***************************************!*\
  !*** ./Rendering/renderingManager.ts ***!
  \***************************************/
/*! exports provided: RenderingGroupInfo, RenderingManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderingGroupInfo", function() { return RenderingGroupInfo; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RenderingManager", function() { return RenderingManager; });
/* harmony import */ var _renderingGroup__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./renderingGroup */ "./Rendering/renderingGroup.ts");

/**
 * This class is used by the onRenderingGroupObservable
 */
var RenderingGroupInfo = /** @class */ (function () {
    function RenderingGroupInfo() {
    }
    return RenderingGroupInfo;
}());

/**
 * This is the manager responsible of all the rendering for meshes sprites and particles.
 * It is enable to manage the different groups as well as the different necessary sort functions.
 * This should not be used directly aside of the few static configurations
 */
var RenderingManager = /** @class */ (function () {
    /**
     * Instantiates a new rendering group for a particular scene
     * @param scene Defines the scene the groups belongs to
     */
    function RenderingManager(scene) {
        /**
         * @hidden
         */
        this._useSceneAutoClearSetup = false;
        this._renderingGroups = new Array();
        this._autoClearDepthStencil = {};
        this._customOpaqueSortCompareFn = {};
        this._customAlphaTestSortCompareFn = {};
        this._customTransparentSortCompareFn = {};
        this._renderingGroupInfo = new RenderingGroupInfo();
        this._scene = scene;
        for (var i = RenderingManager.MIN_RENDERINGGROUPS; i < RenderingManager.MAX_RENDERINGGROUPS; i++) {
            this._autoClearDepthStencil[i] = { autoClear: true, depth: true, stencil: true };
        }
    }
    RenderingManager.prototype._clearDepthStencilBuffer = function (depth, stencil) {
        if (depth === void 0) { depth = true; }
        if (stencil === void 0) { stencil = true; }
        if (this._depthStencilBufferAlreadyCleaned) {
            return;
        }
        this._scene.getEngine().clear(null, false, depth, stencil);
        this._depthStencilBufferAlreadyCleaned = true;
    };
    /**
     * Renders the entire managed groups. This is used by the scene or the different rennder targets.
     * @hidden
     */
    RenderingManager.prototype.render = function (customRenderFunction, activeMeshes, renderParticles, renderSprites) {
        // Update the observable context (not null as it only goes away on dispose)
        var info = this._renderingGroupInfo;
        info.scene = this._scene;
        info.camera = this._scene.activeCamera;
        // Dispatch sprites
        if (this._scene.spriteManagers && renderSprites) {
            for (var index = 0; index < this._scene.spriteManagers.length; index++) {
                var manager = this._scene.spriteManagers[index];
                this.dispatchSprites(manager);
            }
        }
        // Render
        for (var index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {
            this._depthStencilBufferAlreadyCleaned = index === RenderingManager.MIN_RENDERINGGROUPS;
            var renderingGroup = this._renderingGroups[index];
            if (!renderingGroup) {
                continue;
            }
            var renderingGroupMask = Math.pow(2, index);
            info.renderingGroupId = index;
            // Before Observable
            this._scene.onBeforeRenderingGroupObservable.notifyObservers(info, renderingGroupMask);
            // Clear depth/stencil if needed
            if (RenderingManager.AUTOCLEAR) {
                var autoClear = this._useSceneAutoClearSetup ?
                    this._scene.getAutoClearDepthStencilSetup(index) :
                    this._autoClearDepthStencil[index];
                if (autoClear && autoClear.autoClear) {
                    this._clearDepthStencilBuffer(autoClear.depth, autoClear.stencil);
                }
            }
            // Render
            for (var _i = 0, _a = this._scene._beforeRenderingGroupDrawStage; _i < _a.length; _i++) {
                var step = _a[_i];
                step.action(index);
            }
            renderingGroup.render(customRenderFunction, renderSprites, renderParticles, activeMeshes);
            for (var _b = 0, _c = this._scene._afterRenderingGroupDrawStage; _b < _c.length; _b++) {
                var step = _c[_b];
                step.action(index);
            }
            // After Observable
            this._scene.onAfterRenderingGroupObservable.notifyObservers(info, renderingGroupMask);
        }
    };
    /**
     * Resets the different information of the group to prepare a new frame
     * @hidden
     */
    RenderingManager.prototype.reset = function () {
        for (var index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {
            var renderingGroup = this._renderingGroups[index];
            if (renderingGroup) {
                renderingGroup.prepare();
            }
        }
    };
    /**
     * Dispose and release the group and its associated resources.
     * @hidden
     */
    RenderingManager.prototype.dispose = function () {
        this.freeRenderingGroups();
        this._renderingGroups.length = 0;
        this._renderingGroupInfo = null;
    };
    /**
     * Clear the info related to rendering groups preventing retention points during dispose.
     */
    RenderingManager.prototype.freeRenderingGroups = function () {
        for (var index = RenderingManager.MIN_RENDERINGGROUPS; index < RenderingManager.MAX_RENDERINGGROUPS; index++) {
            var renderingGroup = this._renderingGroups[index];
            if (renderingGroup) {
                renderingGroup.dispose();
            }
        }
    };
    RenderingManager.prototype._prepareRenderingGroup = function (renderingGroupId) {
        if (this._renderingGroups[renderingGroupId] === undefined) {
            this._renderingGroups[renderingGroupId] = new _renderingGroup__WEBPACK_IMPORTED_MODULE_0__["RenderingGroup"](renderingGroupId, this._scene, this._customOpaqueSortCompareFn[renderingGroupId], this._customAlphaTestSortCompareFn[renderingGroupId], this._customTransparentSortCompareFn[renderingGroupId]);
        }
    };
    /**
     * Add a sprite manager to the rendering manager in order to render it this frame.
     * @param spriteManager Define the sprite manager to render
     */
    RenderingManager.prototype.dispatchSprites = function (spriteManager) {
        var renderingGroupId = spriteManager.renderingGroupId || 0;
        this._prepareRenderingGroup(renderingGroupId);
        this._renderingGroups[renderingGroupId].dispatchSprites(spriteManager);
    };
    /**
     * Add a particle system to the rendering manager in order to render it this frame.
     * @param particleSystem Define the particle system to render
     */
    RenderingManager.prototype.dispatchParticles = function (particleSystem) {
        var renderingGroupId = particleSystem.renderingGroupId || 0;
        this._prepareRenderingGroup(renderingGroupId);
        this._renderingGroups[renderingGroupId].dispatchParticles(particleSystem);
    };
    /**
     * Add a submesh to the manager in order to render it this frame
     * @param subMesh The submesh to dispatch
     * @param mesh Optional reference to the submeshes's mesh. Provide if you have an exiting reference to improve performance.
     * @param material Optional reference to the submeshes's material. Provide if you have an exiting reference to improve performance.
     */
    RenderingManager.prototype.dispatch = function (subMesh, mesh, material) {
        if (mesh === undefined) {
            mesh = subMesh.getMesh();
        }
        var renderingGroupId = mesh.renderingGroupId || 0;
        this._prepareRenderingGroup(renderingGroupId);
        this._renderingGroups[renderingGroupId].dispatch(subMesh, mesh, material);
    };
    /**
     * Overrides the default sort function applied in the renderging group to prepare the meshes.
     * This allowed control for front to back rendering or reversly depending of the special needs.
     *
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.
     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.
     * @param transparentSortCompareFn The transparent queue comparison function use to sort.
     */
    RenderingManager.prototype.setRenderingOrder = function (renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn) {
        if (opaqueSortCompareFn === void 0) { opaqueSortCompareFn = null; }
        if (alphaTestSortCompareFn === void 0) { alphaTestSortCompareFn = null; }
        if (transparentSortCompareFn === void 0) { transparentSortCompareFn = null; }
        this._customOpaqueSortCompareFn[renderingGroupId] = opaqueSortCompareFn;
        this._customAlphaTestSortCompareFn[renderingGroupId] = alphaTestSortCompareFn;
        this._customTransparentSortCompareFn[renderingGroupId] = transparentSortCompareFn;
        if (this._renderingGroups[renderingGroupId]) {
            var group = this._renderingGroups[renderingGroupId];
            group.opaqueSortCompareFn = this._customOpaqueSortCompareFn[renderingGroupId];
            group.alphaTestSortCompareFn = this._customAlphaTestSortCompareFn[renderingGroupId];
            group.transparentSortCompareFn = this._customTransparentSortCompareFn[renderingGroupId];
        }
    };
    /**
     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.
     *
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
     * @param depth Automatically clears depth between groups if true and autoClear is true.
     * @param stencil Automatically clears stencil between groups if true and autoClear is true.
     */
    RenderingManager.prototype.setRenderingAutoClearDepthStencil = function (renderingGroupId, autoClearDepthStencil, depth, stencil) {
        if (depth === void 0) { depth = true; }
        if (stencil === void 0) { stencil = true; }
        this._autoClearDepthStencil[renderingGroupId] = {
            autoClear: autoClearDepthStencil,
            depth: depth,
            stencil: stencil
        };
    };
    /**
     * Gets the current auto clear configuration for one rendering group of the rendering
     * manager.
     * @param index the rendering group index to get the information for
     * @returns The auto clear setup for the requested rendering group
     */
    RenderingManager.prototype.getAutoClearDepthStencilSetup = function (index) {
        return this._autoClearDepthStencil[index];
    };
    /**
     * The max id used for rendering groups (not included)
     */
    RenderingManager.MAX_RENDERINGGROUPS = 4;
    /**
     * The min id used for rendering groups (included)
     */
    RenderingManager.MIN_RENDERINGGROUPS = 0;
    /**
     * Used to globally prevent autoclearing scenes.
     */
    RenderingManager.AUTOCLEAR = true;
    return RenderingManager;
}());



/***/ }),

/***/ "./Rendering/utilityLayerRenderer.ts":
/*!*******************************************!*\
  !*** ./Rendering/utilityLayerRenderer.ts ***!
  \*******************************************/
/*! exports provided: UtilityLayerRenderer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UtilityLayerRenderer", function() { return UtilityLayerRenderer; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Events/pointerEvents */ "./Events/pointerEvents.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Lights/hemisphericLight */ "./Lights/hemisphericLight.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");







/**
 * Renders a layer on top of an existing scene
 */
var UtilityLayerRenderer = /** @class */ (function () {
    /**
     * Instantiates a UtilityLayerRenderer
     * @param originalScene the original scene that will be rendered on top of
     * @param handleEvents boolean indicating if the utility layer should handle events
     */
    function UtilityLayerRenderer(
    /** the original scene that will be rendered on top of */
    originalScene, handleEvents) {
        var _this = this;
        if (handleEvents === void 0) { handleEvents = true; }
        this.originalScene = originalScene;
        this._pointerCaptures = {};
        this._lastPointerEvents = {};
        this._sharedGizmoLight = null;
        this._renderCamera = null;
        /**
         * If the picking should be done on the utility layer prior to the actual scene (Default: true)
         */
        this.pickUtilitySceneFirst = true;
        /**
         *  If the utility layer should automatically be rendered on top of existing scene
        */
        this.shouldRender = true;
        /**
         * If set to true, only pointer down onPointerObservable events will be blocked when picking is occluded by original scene
         */
        this.onlyCheckPointerDownEvents = true;
        /**
         * If set to false, only pointerUp, pointerDown and pointerMove will be sent to the utilityLayerScene (false by default)
         */
        this.processAllEvents = false;
        /**
         * Observable raised when the pointer move from the utility layer scene to the main scene
         */
        this.onPointerOutObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        // Create scene which will be rendered in the foreground and remove it from being referenced by engine to avoid interfering with existing app
        this.utilityLayerScene = new _scene__WEBPACK_IMPORTED_MODULE_0__["Scene"](originalScene.getEngine(), { virtual: true });
        this.utilityLayerScene.useRightHandedSystem = originalScene.useRightHandedSystem;
        this.utilityLayerScene._allowPostProcessClearColor = false;
        // Detach controls on utility scene, events will be fired by logic below to handle picking priority
        this.utilityLayerScene.detachControl();
        if (handleEvents) {
            this._originalPointerObserver = originalScene.onPrePointerObservable.add(function (prePointerInfo, eventState) {
                if (!_this.utilityLayerScene.activeCamera) {
                    return;
                }
                if (!_this.processAllEvents) {
                    if (prePointerInfo.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERMOVE
                        && prePointerInfo.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERUP
                        && prePointerInfo.type !== _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERDOWN) {
                        return;
                    }
                }
                _this.utilityLayerScene.pointerX = originalScene.pointerX;
                _this.utilityLayerScene.pointerY = originalScene.pointerY;
                var pointerEvent = (prePointerInfo.event);
                if (originalScene.isPointerCaptured(pointerEvent.pointerId)) {
                    _this._pointerCaptures[pointerEvent.pointerId] = false;
                    return;
                }
                var utilityScenePick = prePointerInfo.ray ? _this.utilityLayerScene.pickWithRay(prePointerInfo.ray) : _this.utilityLayerScene.pick(originalScene.pointerX, originalScene.pointerY);
                if (!prePointerInfo.ray && utilityScenePick) {
                    prePointerInfo.ray = utilityScenePick.ray;
                }
                // always fire the prepointer oversvable
                _this.utilityLayerScene.onPrePointerObservable.notifyObservers(prePointerInfo);
                // allow every non pointer down event to flow to the utility layer
                if (_this.onlyCheckPointerDownEvents && prePointerInfo.type != _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERDOWN) {
                    if (!prePointerInfo.skipOnPointerObservable) {
                        _this.utilityLayerScene.onPointerObservable.notifyObservers(new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerInfo"](prePointerInfo.type, prePointerInfo.event, utilityScenePick));
                    }
                    if (prePointerInfo.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERUP && _this._pointerCaptures[pointerEvent.pointerId]) {
                        _this._pointerCaptures[pointerEvent.pointerId] = false;
                    }
                    return;
                }
                if (_this.utilityLayerScene.autoClearDepthAndStencil || _this.pickUtilitySceneFirst) {
                    // If this layer is an overlay, check if this layer was hit and if so, skip pointer events for the main scene
                    if (utilityScenePick && utilityScenePick.hit) {
                        if (!prePointerInfo.skipOnPointerObservable) {
                            _this.utilityLayerScene.onPointerObservable.notifyObservers(new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerInfo"](prePointerInfo.type, prePointerInfo.event, utilityScenePick));
                        }
                        prePointerInfo.skipOnPointerObservable = true;
                    }
                }
                else {
                    var originalScenePick = prePointerInfo.ray ? originalScene.pickWithRay(prePointerInfo.ray) : originalScene.pick(originalScene.pointerX, originalScene.pointerY);
                    var pointerEvent_1 = (prePointerInfo.event);
                    // If the layer can be occluded by the original scene, only fire pointer events to the first layer that hit they ray
                    if (originalScenePick && utilityScenePick) {
                        // No pick in utility scene
                        if (utilityScenePick.distance === 0 && originalScenePick.pickedMesh) {
                            if (_this.mainSceneTrackerPredicate && _this.mainSceneTrackerPredicate(originalScenePick.pickedMesh)) {
                                // We touched an utility mesh present in the main scene
                                _this._notifyObservers(prePointerInfo, originalScenePick, pointerEvent_1);
                                prePointerInfo.skipOnPointerObservable = true;
                            }
                            else if (prePointerInfo.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERDOWN) {
                                _this._pointerCaptures[pointerEvent_1.pointerId] = true;
                            }
                            else if (_this._lastPointerEvents[pointerEvent_1.pointerId]) {
                                // We need to send a last pointerup to the utilityLayerScene to make sure animations can complete
                                _this.onPointerOutObservable.notifyObservers(pointerEvent_1.pointerId);
                                delete _this._lastPointerEvents[pointerEvent_1.pointerId];
                            }
                        }
                        else if (!_this._pointerCaptures[pointerEvent_1.pointerId] && (utilityScenePick.distance < originalScenePick.distance || originalScenePick.distance === 0)) {
                            // We pick something in utility scene or the pick in utility is closer than the one in main scene
                            _this._notifyObservers(prePointerInfo, utilityScenePick, pointerEvent_1);
                            // If a previous utility layer set this, do not unset this
                            if (!prePointerInfo.skipOnPointerObservable) {
                                prePointerInfo.skipOnPointerObservable = utilityScenePick.distance > 0;
                            }
                        }
                        else if (!_this._pointerCaptures[pointerEvent_1.pointerId] && (utilityScenePick.distance > originalScenePick.distance)) {
                            // We have a pick in both scenes but main is closer than utility
                            // We touched an utility mesh present in the main scene
                            if (_this.mainSceneTrackerPredicate && _this.mainSceneTrackerPredicate(originalScenePick.pickedMesh)) {
                                _this._notifyObservers(prePointerInfo, originalScenePick, pointerEvent_1);
                                prePointerInfo.skipOnPointerObservable = true;
                            }
                            else if (_this._lastPointerEvents[pointerEvent_1.pointerId]) {
                                // We need to send a last pointerup to the utilityLayerScene to make sure animations can complete
                                _this.onPointerOutObservable.notifyObservers(pointerEvent_1.pointerId);
                                delete _this._lastPointerEvents[pointerEvent_1.pointerId];
                            }
                        }
                        if (prePointerInfo.type === _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerEventTypes"].POINTERUP && _this._pointerCaptures[pointerEvent_1.pointerId]) {
                            _this._pointerCaptures[pointerEvent_1.pointerId] = false;
                        }
                    }
                }
            });
            // As a newly added utility layer will be rendered over the screen last, it's pointer events should be processed first
            if (this._originalPointerObserver) {
                originalScene.onPrePointerObservable.makeObserverTopPriority(this._originalPointerObserver);
            }
        }
        // Render directly on top of existing scene without clearing
        this.utilityLayerScene.autoClear = false;
        this._afterRenderObserver = this.originalScene.onAfterCameraRenderObservable.add(function (camera) {
            // Only render when the render camera finishes rendering
            if (_this.shouldRender && camera == _this.getRenderCamera()) {
                _this.render();
            }
        });
        this._sceneDisposeObserver = this.originalScene.onDisposeObservable.add(function () {
            _this.dispose();
        });
        this._updateCamera();
    }
    /**
     * Gets the camera that is used to render the utility layer (when not set, this will be the last active camera)
     * @returns the camera that is used when rendering the utility layer
     */
    UtilityLayerRenderer.prototype.getRenderCamera = function () {
        if (this._renderCamera) {
            return this._renderCamera;
        }
        else if (this.originalScene.activeCameras.length > 1) {
            return this.originalScene.activeCameras[this.originalScene.activeCameras.length - 1];
        }
        else {
            return this.originalScene.activeCamera;
        }
    };
    /**
     * Sets the camera that should be used when rendering the utility layer (If set to null the last active camera will be used)
     * @param cam the camera that should be used when rendering the utility layer
     */
    UtilityLayerRenderer.prototype.setRenderCamera = function (cam) {
        this._renderCamera = cam;
    };
    /**
     * @hidden
     * Light which used by gizmos to get light shading
     */
    UtilityLayerRenderer.prototype._getSharedGizmoLight = function () {
        if (!this._sharedGizmoLight) {
            this._sharedGizmoLight = new _Lights_hemisphericLight__WEBPACK_IMPORTED_MODULE_4__["HemisphericLight"]("shared gizmo light", new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_5__["Vector3"](0, 1, 0), this.utilityLayerScene);
            this._sharedGizmoLight.intensity = 2;
            this._sharedGizmoLight.groundColor = _Maths_math_color__WEBPACK_IMPORTED_MODULE_6__["Color3"].Gray();
        }
        return this._sharedGizmoLight;
    };
    Object.defineProperty(UtilityLayerRenderer, "DefaultUtilityLayer", {
        /**
         * A shared utility layer that can be used to overlay objects into a scene (Depth map of the previous scene is cleared before drawing on top of it)
         */
        get: function () {
            if (UtilityLayerRenderer._DefaultUtilityLayer == null) {
                UtilityLayerRenderer._DefaultUtilityLayer = new UtilityLayerRenderer(_Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__["EngineStore"].LastCreatedScene);
                UtilityLayerRenderer._DefaultUtilityLayer.originalScene.onDisposeObservable.addOnce(function () {
                    UtilityLayerRenderer._DefaultUtilityLayer = null;
                });
            }
            return UtilityLayerRenderer._DefaultUtilityLayer;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(UtilityLayerRenderer, "DefaultKeepDepthUtilityLayer", {
        /**
         * A shared utility layer that can be used to embed objects into a scene (Depth map of the previous scene is not cleared before drawing on top of it)
         */
        get: function () {
            if (UtilityLayerRenderer._DefaultKeepDepthUtilityLayer == null) {
                UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = new UtilityLayerRenderer(_Engines_engineStore__WEBPACK_IMPORTED_MODULE_3__["EngineStore"].LastCreatedScene);
                UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
                UtilityLayerRenderer._DefaultKeepDepthUtilityLayer.originalScene.onDisposeObservable.addOnce(function () {
                    UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = null;
                });
            }
            return UtilityLayerRenderer._DefaultKeepDepthUtilityLayer;
        },
        enumerable: true,
        configurable: true
    });
    UtilityLayerRenderer.prototype._notifyObservers = function (prePointerInfo, pickInfo, pointerEvent) {
        if (!prePointerInfo.skipOnPointerObservable) {
            this.utilityLayerScene.onPointerObservable.notifyObservers(new _Events_pointerEvents__WEBPACK_IMPORTED_MODULE_2__["PointerInfo"](prePointerInfo.type, prePointerInfo.event, pickInfo));
            this._lastPointerEvents[pointerEvent.pointerId] = true;
        }
    };
    /**
     * Renders the utility layers scene on top of the original scene
     */
    UtilityLayerRenderer.prototype.render = function () {
        this._updateCamera();
        if (this.utilityLayerScene.activeCamera) {
            // Set the camera's scene to utility layers scene
            var oldScene = this.utilityLayerScene.activeCamera.getScene();
            var camera = this.utilityLayerScene.activeCamera;
            camera._scene = this.utilityLayerScene;
            if (camera.leftCamera) {
                camera.leftCamera._scene = this.utilityLayerScene;
            }
            if (camera.rightCamera) {
                camera.rightCamera._scene = this.utilityLayerScene;
            }
            this.utilityLayerScene.render(false);
            // Reset camera's scene back to original
            camera._scene = oldScene;
            if (camera.leftCamera) {
                camera.leftCamera._scene = oldScene;
            }
            if (camera.rightCamera) {
                camera.rightCamera._scene = oldScene;
            }
        }
    };
    /**
     * Disposes of the renderer
     */
    UtilityLayerRenderer.prototype.dispose = function () {
        this.onPointerOutObservable.clear();
        if (this._afterRenderObserver) {
            this.originalScene.onAfterCameraRenderObservable.remove(this._afterRenderObserver);
        }
        if (this._sceneDisposeObserver) {
            this.originalScene.onDisposeObservable.remove(this._sceneDisposeObserver);
        }
        if (this._originalPointerObserver) {
            this.originalScene.onPrePointerObservable.remove(this._originalPointerObserver);
        }
        this.utilityLayerScene.dispose();
    };
    UtilityLayerRenderer.prototype._updateCamera = function () {
        this.utilityLayerScene.cameraToUseForPointers = this.getRenderCamera();
        this.utilityLayerScene.activeCamera = this.getRenderCamera();
    };
    UtilityLayerRenderer._DefaultUtilityLayer = null;
    UtilityLayerRenderer._DefaultKeepDepthUtilityLayer = null;
    return UtilityLayerRenderer;
}());



/***/ }),

/***/ "./Shaders/ShadersInclude/backgroundFragmentDeclaration.ts":
/*!*****************************************************************!*\
  !*** ./Shaders/ShadersInclude/backgroundFragmentDeclaration.ts ***!
  \*****************************************************************/
/*! exports provided: backgroundFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backgroundFragmentDeclaration", function() { return backgroundFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'backgroundFragmentDeclaration';
var shader = " uniform vec4 vPrimaryColor;\n#ifdef USEHIGHLIGHTANDSHADOWCOLORS\nuniform vec4 vPrimaryColorShadow;\n#endif\nuniform float shadowLevel;\nuniform float alpha;\n#ifdef DIFFUSE\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\nuniform mat4 reflectionMatrix;\nuniform vec3 vReflectionMicrosurfaceInfos;\n#endif\n#if defined(REFLECTIONFRESNEL) || defined(OPACITYFRESNEL)\nuniform vec3 vBackgroundCenter;\n#endif\n#ifdef REFLECTIONFRESNEL\nuniform vec4 vReflectionControl;\n#endif\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(REFRACTION)\nuniform mat4 view;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var backgroundFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/backgroundUboDeclaration.ts":
/*!************************************************************!*\
  !*** ./Shaders/ShadersInclude/backgroundUboDeclaration.ts ***!
  \************************************************************/
/*! exports provided: backgroundUboDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backgroundUboDeclaration", function() { return backgroundUboDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'backgroundUboDeclaration';
var shader = "layout(std140,column_major) uniform;\nuniform Material\n{\nuniform vec4 vPrimaryColor;\nuniform vec4 vPrimaryColorShadow;\nuniform vec2 vDiffuseInfos;\nuniform vec2 vReflectionInfos;\nuniform mat4 diffuseMatrix;\nuniform mat4 reflectionMatrix;\nuniform vec3 vReflectionMicrosurfaceInfos;\nuniform float fFovMultiplier;\nuniform float pointSize;\nuniform float shadowLevel;\nuniform float alpha;\n#if defined(REFLECTIONFRESNEL) || defined(OPACITYFRESNEL)\nuniform vec3 vBackgroundCenter;\n#endif\n#ifdef REFLECTIONFRESNEL\nuniform vec4 vReflectionControl;\n#endif\n};\nuniform Scene {\nmat4 viewProjection;\n#ifdef MULTIVIEW\nmat4 viewProjectionR;\n#endif\nmat4 view;\n};";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var backgroundUboDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/backgroundVertexDeclaration.ts":
/*!***************************************************************!*\
  !*** ./Shaders/ShadersInclude/backgroundVertexDeclaration.ts ***!
  \***************************************************************/
/*! exports provided: backgroundVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backgroundVertexDeclaration", function() { return backgroundVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'backgroundVertexDeclaration';
var shader = "uniform mat4 view;\nuniform mat4 viewProjection;\nuniform float shadowLevel;\n#ifdef DIFFUSE\nuniform mat4 diffuseMatrix;\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\nuniform mat4 reflectionMatrix;\nuniform vec3 vReflectionMicrosurfaceInfos;\nuniform float fFovMultiplier;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var backgroundVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/bonesDeclaration.ts":
/*!****************************************************!*\
  !*** ./Shaders/ShadersInclude/bonesDeclaration.ts ***!
  \****************************************************/
/*! exports provided: bonesDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bonesDeclaration", function() { return bonesDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'bonesDeclaration';
var shader = "#if NUM_BONE_INFLUENCERS>0\n#ifdef BONETEXTURE\nuniform sampler2D boneSampler;\nuniform float boneTextureWidth;\n#else\nuniform mat4 mBones[BonesPerMesh];\n#endif\nattribute vec4 matricesIndices;\nattribute vec4 matricesWeights;\n#if NUM_BONE_INFLUENCERS>4\nattribute vec4 matricesIndicesExtra;\nattribute vec4 matricesWeightsExtra;\n#endif\n#ifdef BONETEXTURE\nmat4 readMatrixFromRawSampler(sampler2D smp,float index)\n{\nfloat offset=index*4.0;\nfloat dx=1.0/boneTextureWidth;\nvec4 m0=texture2D(smp,vec2(dx*(offset+0.5),0.));\nvec4 m1=texture2D(smp,vec2(dx*(offset+1.5),0.));\nvec4 m2=texture2D(smp,vec2(dx*(offset+2.5),0.));\nvec4 m3=texture2D(smp,vec2(dx*(offset+3.5),0.));\nreturn mat4(m0,m1,m2,m3);\n}\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var bonesDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/bonesVertex.ts":
/*!***********************************************!*\
  !*** ./Shaders/ShadersInclude/bonesVertex.ts ***!
  \***********************************************/
/*! exports provided: bonesVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bonesVertex", function() { return bonesVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'bonesVertex';
var shader = "#if NUM_BONE_INFLUENCERS>0\nmat4 influence;\n#ifdef BONETEXTURE\ninfluence=readMatrixFromRawSampler(boneSampler,matricesIndices[0])*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndices[1])*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndices[2])*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndices[3])*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[0])*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[1])*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[2])*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\ninfluence+=readMatrixFromRawSampler(boneSampler,matricesIndicesExtra[3])*matricesWeightsExtra[3];\n#endif\n#else\ninfluence=mBones[int(matricesIndices[0])]*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\ninfluence+=mBones[int(matricesIndices[1])]*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\ninfluence+=mBones[int(matricesIndices[2])]*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\ninfluence+=mBones[int(matricesIndices[3])]*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\ninfluence+=mBones[int(matricesIndicesExtra[0])]*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\ninfluence+=mBones[int(matricesIndicesExtra[1])]*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\ninfluence+=mBones[int(matricesIndicesExtra[2])]*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\ninfluence+=mBones[int(matricesIndicesExtra[3])]*matricesWeightsExtra[3];\n#endif\n#endif\nfinalWorld=finalWorld*influence;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var bonesVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/bumpFragment.ts":
/*!************************************************!*\
  !*** ./Shaders/ShadersInclude/bumpFragment.ts ***!
  \************************************************/
/*! exports provided: bumpFragment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bumpFragment", function() { return bumpFragment; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'bumpFragment';
var shader = "vec2 uvOffset=vec2(0.0,0.0);\n#if defined(BUMP) || defined(PARALLAX)\n#ifdef NORMALXYSCALE\nfloat normalScale=1.0;\n#else\nfloat normalScale=vBumpInfos.y;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#else\nmat3 TBN=cotangent_frame(normalW*normalScale,vPositionW,vBumpUV);\n#endif\n#elif defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBN=vTBN;\n#else\nmat3 TBN=cotangent_frame(normalW,vPositionW,vMainUV1,vec2(1.,1.));\n#endif\n#endif\n#ifdef PARALLAX\nmat3 invTBN=transposeMat3(TBN);\n#ifdef PARALLAXOCCLUSION\nuvOffset=parallaxOcclusion(invTBN*-viewDirectionW,invTBN*normalW,vBumpUV,vBumpInfos.z);\n#else\nuvOffset=parallaxOffset(invTBN*viewDirectionW,vBumpInfos.z);\n#endif\n#endif\n#ifdef BUMP\n#ifdef OBJECTSPACE_NORMALMAP\nnormalW=normalize(texture2D(bumpSampler,vBumpUV).xyz*2.0-1.0);\nnormalW=normalize(mat3(normalMatrix)*normalW);\n#else\nnormalW=perturbNormal(TBN,vBumpUV+uvOffset);\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var bumpFragment = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/bumpFragmentFunctions.ts":
/*!*********************************************************!*\
  !*** ./Shaders/ShadersInclude/bumpFragmentFunctions.ts ***!
  \*********************************************************/
/*! exports provided: bumpFragmentFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bumpFragmentFunctions", function() { return bumpFragmentFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'bumpFragmentFunctions';
var shader = "#if defined(BUMP) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#if defined(TANGENT) && defined(NORMAL)\nvarying mat3 vTBN;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nuniform mat4 normalMatrix;\n#endif\nvec3 perturbNormal(mat3 cotangentFrame,vec3 textureSample,float scale)\n{\ntextureSample=textureSample*2.0-1.0;\n#ifdef NORMALXYSCALE\ntextureSample=normalize(textureSample*vec3(scale,scale,1.0));\n#endif\nreturn normalize(cotangentFrame*textureSample);\n}\n\nmat3 cotangent_frame(vec3 normal,vec3 p,vec2 uv,vec2 tangentSpaceParams)\n{\n\nuv=gl_FrontFacing ? uv : -uv;\n\nvec3 dp1=dFdx(p);\nvec3 dp2=dFdy(p);\nvec2 duv1=dFdx(uv);\nvec2 duv2=dFdy(uv);\n\nvec3 dp2perp=cross(dp2,normal);\nvec3 dp1perp=cross(normal,dp1);\nvec3 tangent=dp2perp*duv1.x+dp1perp*duv2.x;\nvec3 bitangent=dp2perp*duv1.y+dp1perp*duv2.y;\n\ntangent*=tangentSpaceParams.x;\nbitangent*=tangentSpaceParams.y;\n\nfloat invmax=inversesqrt(max(dot(tangent,tangent),dot(bitangent,bitangent)));\nreturn mat3(tangent*invmax,bitangent*invmax,normal);\n}\n#endif\n#ifdef BUMP\n#ifndef PBR\n#if BUMPDIRECTUV == 1\n#define vBumpUV vMainUV1\n#elif BUMPDIRECTUV == 2\n#define vBumpUV vMainUV2\n#else\nvarying vec2 vBumpUV;\n#endif\nuniform sampler2D bumpSampler;\n#endif\nvec3 perturbNormal(mat3 cotangentFrame,vec2 uv)\n{\nreturn perturbNormal(cotangentFrame,texture2D(bumpSampler,uv).xyz,vBumpInfos.y);\n}\nvec3 perturbNormal(mat3 cotangentFrame,vec3 color)\n{\nreturn perturbNormal(cotangentFrame,color,vBumpInfos.y);\n}\n\nmat3 cotangent_frame(vec3 normal,vec3 p,vec2 uv)\n{\nreturn cotangent_frame(normal,p,uv,vTangentSpaceParams);\n}\n#endif\n#if defined(BUMP) && defined(PARALLAX)\nconst float minSamples=4.;\nconst float maxSamples=15.;\nconst int iMaxSamples=15;\n\nvec2 parallaxOcclusion(vec3 vViewDirCoT,vec3 vNormalCoT,vec2 texCoord,float parallaxScale) {\nfloat parallaxLimit=length(vViewDirCoT.xy)/vViewDirCoT.z;\nparallaxLimit*=parallaxScale;\nvec2 vOffsetDir=normalize(vViewDirCoT.xy);\nvec2 vMaxOffset=vOffsetDir*parallaxLimit;\nfloat numSamples=maxSamples+(dot(vViewDirCoT,vNormalCoT)*(minSamples-maxSamples));\nfloat stepSize=1.0/numSamples;\n\nfloat currRayHeight=1.0;\nvec2 vCurrOffset=vec2(0,0);\nvec2 vLastOffset=vec2(0,0);\nfloat lastSampledHeight=1.0;\nfloat currSampledHeight=1.0;\nfor (int i=0; i<iMaxSamples; i++)\n{\ncurrSampledHeight=texture2D(bumpSampler,vBumpUV+vCurrOffset).w;\n\nif (currSampledHeight>currRayHeight)\n{\nfloat delta1=currSampledHeight-currRayHeight;\nfloat delta2=(currRayHeight+stepSize)-lastSampledHeight;\nfloat ratio=delta1/(delta1+delta2);\nvCurrOffset=(ratio)* vLastOffset+(1.0-ratio)*vCurrOffset;\n\nbreak;\n}\nelse\n{\ncurrRayHeight-=stepSize;\nvLastOffset=vCurrOffset;\nvCurrOffset+=stepSize*vMaxOffset;\nlastSampledHeight=currSampledHeight;\n}\n}\nreturn vCurrOffset;\n}\nvec2 parallaxOffset(vec3 viewDir,float heightScale)\n{\n\nfloat height=texture2D(bumpSampler,vBumpUV).w;\nvec2 texCoordOffset=heightScale*viewDir.xy*height;\nreturn -texCoordOffset;\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var bumpFragmentFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/bumpVertex.ts":
/*!**********************************************!*\
  !*** ./Shaders/ShadersInclude/bumpVertex.ts ***!
  \**********************************************/
/*! exports provided: bumpVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bumpVertex", function() { return bumpVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'bumpVertex';
var shader = "#if defined(BUMP) || defined(PARALLAX) || defined(CLEARCOAT_BUMP)\n#if defined(TANGENT) && defined(NORMAL)\nvec3 tbnNormal=normalize(normalUpdated);\nvec3 tbnTangent=normalize(tangentUpdated.xyz);\nvec3 tbnBitangent=cross(tbnNormal,tbnTangent)*tangentUpdated.w;\nvTBN=mat3(finalWorld)*mat3(tbnTangent,tbnBitangent,tbnNormal);\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var bumpVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/bumpVertexDeclaration.ts":
/*!*********************************************************!*\
  !*** ./Shaders/ShadersInclude/bumpVertexDeclaration.ts ***!
  \*********************************************************/
/*! exports provided: bumpVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bumpVertexDeclaration", function() { return bumpVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'bumpVertexDeclaration';
var shader = "#if defined(BUMP) || defined(PARALLAX) || defined(CLEARCOAT_BUMP)\n#if defined(TANGENT) && defined(NORMAL)\nvarying mat3 vTBN;\n#endif\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var bumpVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/clipPlaneFragment.ts":
/*!*****************************************************!*\
  !*** ./Shaders/ShadersInclude/clipPlaneFragment.ts ***!
  \*****************************************************/
/*! exports provided: clipPlaneFragment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipPlaneFragment", function() { return clipPlaneFragment; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'clipPlaneFragment';
var shader = "#ifdef CLIPPLANE\nif (fClipDistance>0.0)\n{\ndiscard;\n}\n#endif\n#ifdef CLIPPLANE2\nif (fClipDistance2>0.0)\n{\ndiscard;\n}\n#endif\n#ifdef CLIPPLANE3\nif (fClipDistance3>0.0)\n{\ndiscard;\n}\n#endif\n#ifdef CLIPPLANE4\nif (fClipDistance4>0.0)\n{\ndiscard;\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var clipPlaneFragment = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts":
/*!****************************************************************!*\
  !*** ./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts ***!
  \****************************************************************/
/*! exports provided: clipPlaneFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipPlaneFragmentDeclaration", function() { return clipPlaneFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'clipPlaneFragmentDeclaration';
var shader = "#ifdef CLIPPLANE\nvarying float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nvarying float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nvarying float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nvarying float fClipDistance4;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var clipPlaneFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration2.ts":
/*!*****************************************************************!*\
  !*** ./Shaders/ShadersInclude/clipPlaneFragmentDeclaration2.ts ***!
  \*****************************************************************/
/*! exports provided: clipPlaneFragmentDeclaration2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipPlaneFragmentDeclaration2", function() { return clipPlaneFragmentDeclaration2; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'clipPlaneFragmentDeclaration2';
var shader = "#ifdef CLIPPLANE\nin float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nin float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nin float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nin float fClipDistance4;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var clipPlaneFragmentDeclaration2 = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/clipPlaneVertex.ts":
/*!***************************************************!*\
  !*** ./Shaders/ShadersInclude/clipPlaneVertex.ts ***!
  \***************************************************/
/*! exports provided: clipPlaneVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipPlaneVertex", function() { return clipPlaneVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'clipPlaneVertex';
var shader = "#ifdef CLIPPLANE\nfClipDistance=dot(worldPos,vClipPlane);\n#endif\n#ifdef CLIPPLANE2\nfClipDistance2=dot(worldPos,vClipPlane2);\n#endif\n#ifdef CLIPPLANE3\nfClipDistance3=dot(worldPos,vClipPlane3);\n#endif\n#ifdef CLIPPLANE4\nfClipDistance4=dot(worldPos,vClipPlane4);\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var clipPlaneVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts":
/*!**************************************************************!*\
  !*** ./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts ***!
  \**************************************************************/
/*! exports provided: clipPlaneVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipPlaneVertexDeclaration", function() { return clipPlaneVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'clipPlaneVertexDeclaration';
var shader = "#ifdef CLIPPLANE\nuniform vec4 vClipPlane;\nvarying float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nuniform vec4 vClipPlane2;\nvarying float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nuniform vec4 vClipPlane3;\nvarying float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nuniform vec4 vClipPlane4;\nvarying float fClipDistance4;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var clipPlaneVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration2.ts":
/*!***************************************************************!*\
  !*** ./Shaders/ShadersInclude/clipPlaneVertexDeclaration2.ts ***!
  \***************************************************************/
/*! exports provided: clipPlaneVertexDeclaration2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipPlaneVertexDeclaration2", function() { return clipPlaneVertexDeclaration2; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'clipPlaneVertexDeclaration2';
var shader = "#ifdef CLIPPLANE\nuniform vec4 vClipPlane;\nout float fClipDistance;\n#endif\n#ifdef CLIPPLANE2\nuniform vec4 vClipPlane2;\nout float fClipDistance2;\n#endif\n#ifdef CLIPPLANE3\nuniform vec4 vClipPlane3;\nout float fClipDistance3;\n#endif\n#ifdef CLIPPLANE4\nuniform vec4 vClipPlane4;\nout float fClipDistance4;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var clipPlaneVertexDeclaration2 = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/defaultFragmentDeclaration.ts":
/*!**************************************************************!*\
  !*** ./Shaders/ShadersInclude/defaultFragmentDeclaration.ts ***!
  \**************************************************************/
/*! exports provided: defaultFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultFragmentDeclaration", function() { return defaultFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'defaultFragmentDeclaration';
var shader = "uniform vec4 vDiffuseColor;\n#ifdef SPECULARTERM\nuniform vec4 vSpecularColor;\n#endif\nuniform vec3 vEmissiveColor;\nuniform float visibility;\n\n#ifdef DIFFUSE\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform vec2 vAmbientInfos;\n#endif\n#ifdef OPACITY\nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform vec2 vTangentSpaceParams;\n#endif\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(REFRACTION)\nuniform mat4 view;\n#endif\n#ifdef REFRACTION\nuniform vec4 vRefractionInfos;\n#ifndef REFRACTIONMAP_3D\nuniform mat4 refractionMatrix;\n#endif\n#ifdef REFRACTIONFRESNEL\nuniform vec4 refractionLeftColor;\nuniform vec4 refractionRightColor;\n#endif\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;\n#endif\n#ifdef DIFFUSEFRESNEL\nuniform vec4 diffuseLeftColor;\nuniform vec4 diffuseRightColor;\n#endif\n#ifdef OPACITYFRESNEL\nuniform vec4 opacityParts;\n#endif\n#ifdef EMISSIVEFRESNEL\nuniform vec4 emissiveLeftColor;\nuniform vec4 emissiveRightColor;\n#endif\n\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\n#if defined(REFLECTIONMAP_PLANAR) || defined(REFLECTIONMAP_CUBIC) || defined(REFLECTIONMAP_PROJECTION) || defined(REFLECTIONMAP_EQUIRECTANGULAR) || defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_SKYBOX)\nuniform mat4 reflectionMatrix;\n#endif\n#ifndef REFLECTIONMAP_SKYBOX\n#if defined(USE_LOCAL_REFLECTIONMAP_CUBIC) && defined(REFLECTIONMAP_CUBIC)\nuniform vec3 vReflectionPosition;\nuniform vec3 vReflectionSize;\n#endif\n#endif\n#ifdef REFLECTIONFRESNEL\nuniform vec4 reflectionLeftColor;\nuniform vec4 reflectionRightColor;\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var defaultFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/defaultUboDeclaration.ts":
/*!*********************************************************!*\
  !*** ./Shaders/ShadersInclude/defaultUboDeclaration.ts ***!
  \*********************************************************/
/*! exports provided: defaultUboDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultUboDeclaration", function() { return defaultUboDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'defaultUboDeclaration';
var shader = "layout(std140,column_major) uniform;\nuniform Material\n{\nvec4 diffuseLeftColor;\nvec4 diffuseRightColor;\nvec4 opacityParts;\nvec4 reflectionLeftColor;\nvec4 reflectionRightColor;\nvec4 refractionLeftColor;\nvec4 refractionRightColor;\nvec4 emissiveLeftColor;\nvec4 emissiveRightColor;\nvec2 vDiffuseInfos;\nvec2 vAmbientInfos;\nvec2 vOpacityInfos;\nvec2 vReflectionInfos;\nvec3 vReflectionPosition;\nvec3 vReflectionSize;\nvec2 vEmissiveInfos;\nvec2 vLightmapInfos;\nvec2 vSpecularInfos;\nvec3 vBumpInfos;\nmat4 diffuseMatrix;\nmat4 ambientMatrix;\nmat4 opacityMatrix;\nmat4 reflectionMatrix;\nmat4 emissiveMatrix;\nmat4 lightmapMatrix;\nmat4 specularMatrix;\nmat4 bumpMatrix;\nvec2 vTangentSpaceParams;\nfloat pointSize;\nmat4 refractionMatrix;\nvec4 vRefractionInfos;\nvec4 vSpecularColor;\nvec3 vEmissiveColor;\nfloat visibility;\nvec4 vDiffuseColor;\n};\nuniform Scene {\nmat4 viewProjection;\n#ifdef MULTIVIEW\nmat4 viewProjectionR;\n#endif\nmat4 view;\n};\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var defaultUboDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/defaultVertexDeclaration.ts":
/*!************************************************************!*\
  !*** ./Shaders/ShadersInclude/defaultVertexDeclaration.ts ***!
  \************************************************************/
/*! exports provided: defaultVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultVertexDeclaration", function() { return defaultVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'defaultVertexDeclaration';
var shader = "\nuniform mat4 viewProjection;\nuniform mat4 view;\n#ifdef DIFFUSE\nuniform mat4 diffuseMatrix;\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform mat4 ambientMatrix;\nuniform vec2 vAmbientInfos;\n#endif\n#ifdef OPACITY\nuniform mat4 opacityMatrix;\nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\nuniform mat4 emissiveMatrix;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\nuniform mat4 lightmapMatrix;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;\nuniform mat4 specularMatrix;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform mat4 bumpMatrix;\n#endif\n#ifdef REFLECTION\nuniform mat4 reflectionMatrix;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var defaultVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/depthPrePass.ts":
/*!************************************************!*\
  !*** ./Shaders/ShadersInclude/depthPrePass.ts ***!
  \************************************************/
/*! exports provided: depthPrePass */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthPrePass", function() { return depthPrePass; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'depthPrePass';
var shader = "#ifdef DEPTHPREPASS\ngl_FragColor=vec4(0.,0.,0.,1.0);\nreturn;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var depthPrePass = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/fogFragment.ts":
/*!***********************************************!*\
  !*** ./Shaders/ShadersInclude/fogFragment.ts ***!
  \***********************************************/
/*! exports provided: fogFragment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fogFragment", function() { return fogFragment; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'fogFragment';
var shader = "#ifdef FOG\nfloat fog=CalcFogFactor();\ncolor.rgb=fog*color.rgb+(1.0-fog)*vFogColor;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var fogFragment = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/fogFragmentDeclaration.ts":
/*!**********************************************************!*\
  !*** ./Shaders/ShadersInclude/fogFragmentDeclaration.ts ***!
  \**********************************************************/
/*! exports provided: fogFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fogFragmentDeclaration", function() { return fogFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'fogFragmentDeclaration';
var shader = "#ifdef FOG\n#define FOGMODE_NONE 0.\n#define FOGMODE_EXP 1.\n#define FOGMODE_EXP2 2.\n#define FOGMODE_LINEAR 3.\n#define E 2.71828\nuniform vec4 vFogInfos;\nuniform vec3 vFogColor;\nvarying vec3 vFogDistance;\nfloat CalcFogFactor()\n{\nfloat fogCoeff=1.0;\nfloat fogStart=vFogInfos.y;\nfloat fogEnd=vFogInfos.z;\nfloat fogDensity=vFogInfos.w;\nfloat fogDistance=length(vFogDistance);\nif (FOGMODE_LINEAR == vFogInfos.x)\n{\nfogCoeff=(fogEnd-fogDistance)/(fogEnd-fogStart);\n}\nelse if (FOGMODE_EXP == vFogInfos.x)\n{\nfogCoeff=1.0/pow(E,fogDistance*fogDensity);\n}\nelse if (FOGMODE_EXP2 == vFogInfos.x)\n{\nfogCoeff=1.0/pow(E,fogDistance*fogDistance*fogDensity*fogDensity);\n}\nreturn clamp(fogCoeff,0.0,1.0);\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var fogFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/fogVertex.ts":
/*!*********************************************!*\
  !*** ./Shaders/ShadersInclude/fogVertex.ts ***!
  \*********************************************/
/*! exports provided: fogVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fogVertex", function() { return fogVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'fogVertex';
var shader = "#ifdef FOG\nvFogDistance=(view*worldPos).xyz;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var fogVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/fogVertexDeclaration.ts":
/*!********************************************************!*\
  !*** ./Shaders/ShadersInclude/fogVertexDeclaration.ts ***!
  \********************************************************/
/*! exports provided: fogVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fogVertexDeclaration", function() { return fogVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'fogVertexDeclaration';
var shader = "#ifdef FOG\nvarying vec3 vFogDistance;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var fogVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/fresnelFunction.ts":
/*!***************************************************!*\
  !*** ./Shaders/ShadersInclude/fresnelFunction.ts ***!
  \***************************************************/
/*! exports provided: fresnelFunction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fresnelFunction", function() { return fresnelFunction; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'fresnelFunction';
var shader = "#ifdef FRESNEL\nfloat computeFresnelTerm(vec3 viewDirection,vec3 worldNormal,float bias,float power)\n{\nfloat fresnelTerm=pow(bias+abs(dot(viewDirection,worldNormal)),power);\nreturn clamp(fresnelTerm,0.,1.);\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var fresnelFunction = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/harmonicsFunctions.ts":
/*!******************************************************!*\
  !*** ./Shaders/ShadersInclude/harmonicsFunctions.ts ***!
  \******************************************************/
/*! exports provided: harmonicsFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "harmonicsFunctions", function() { return harmonicsFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'harmonicsFunctions';
var shader = "#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\n\n\n\n\n\n\n\nvec3 computeEnvironmentIrradiance(vec3 normal) {\nreturn vSphericalL00\n+vSphericalL1_1*(normal.y)\n+vSphericalL10*(normal.z)\n+vSphericalL11*(normal.x)\n+vSphericalL2_2*(normal.y*normal.x)\n+vSphericalL2_1*(normal.y*normal.z)\n+vSphericalL20*((3.0*normal.z*normal.z)-1.0)\n+vSphericalL21*(normal.z*normal.x)\n+vSphericalL22*(normal.x*normal.x-(normal.y*normal.y));\n}\n#else\n\nvec3 computeEnvironmentIrradiance(vec3 normal) {\n\n\n\n\n\n\n\n\n\nfloat Nx=normal.x;\nfloat Ny=normal.y;\nfloat Nz=normal.z;\nvec3 C1=vSphericalZZ.rgb;\nvec3 Cx=vSphericalX.rgb;\nvec3 Cy=vSphericalY.rgb;\nvec3 Cz=vSphericalZ.rgb;\nvec3 Cxx_zz=vSphericalXX_ZZ.rgb;\nvec3 Cyy_zz=vSphericalYY_ZZ.rgb;\nvec3 Cxy=vSphericalXY.rgb;\nvec3 Cyz=vSphericalYZ.rgb;\nvec3 Czx=vSphericalZX.rgb;\nvec3 a1=Cyy_zz*Ny+Cy;\nvec3 a2=Cyz*Nz+a1;\nvec3 b1=Czx*Nz+Cx;\nvec3 b2=Cxy*Ny+b1;\nvec3 b3=Cxx_zz*Nx+b2;\nvec3 t1=Cz*Nz+C1;\nvec3 t2=a2*Ny+t1;\nvec3 t3=b3*Nx+t2;\nreturn t3;\n}\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var harmonicsFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/helperFunctions.ts":
/*!***************************************************!*\
  !*** ./Shaders/ShadersInclude/helperFunctions.ts ***!
  \***************************************************/
/*! exports provided: helperFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "helperFunctions", function() { return helperFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'helperFunctions';
var shader = "const float PI=3.1415926535897932384626433832795;\nconst float LinearEncodePowerApprox=2.2;\nconst float GammaEncodePowerApprox=1.0/LinearEncodePowerApprox;\nconst vec3 LuminanceEncodeApprox=vec3(0.2126,0.7152,0.0722);\nconst float Epsilon=0.0000001;\n#define saturate(x) clamp(x,0.0,1.0)\n#define absEps(x) abs(x)+Epsilon\n#define maxEps(x) max(x,Epsilon)\n#define saturateEps(x) clamp(x,Epsilon,1.0)\nmat3 transposeMat3(mat3 inMatrix) {\nvec3 i0=inMatrix[0];\nvec3 i1=inMatrix[1];\nvec3 i2=inMatrix[2];\nmat3 outMatrix=mat3(\nvec3(i0.x,i1.x,i2.x),\nvec3(i0.y,i1.y,i2.y),\nvec3(i0.z,i1.z,i2.z)\n);\nreturn outMatrix;\n}\n\nmat3 inverseMat3(mat3 inMatrix) {\nfloat a00=inMatrix[0][0],a01=inMatrix[0][1],a02=inMatrix[0][2];\nfloat a10=inMatrix[1][0],a11=inMatrix[1][1],a12=inMatrix[1][2];\nfloat a20=inMatrix[2][0],a21=inMatrix[2][1],a22=inMatrix[2][2];\nfloat b01=a22*a11-a12*a21;\nfloat b11=-a22*a10+a12*a20;\nfloat b21=a21*a10-a11*a20;\nfloat det=a00*b01+a01*b11+a02*b21;\nreturn mat3(b01,(-a22*a01+a02*a21),(a12*a01-a02*a11),\nb11,(a22*a00-a02*a20),(-a12*a00+a02*a10),\nb21,(-a21*a00+a01*a20),(a11*a00-a01*a10))/det;\n}\nvec3 toLinearSpace(vec3 color)\n{\nreturn pow(color,vec3(LinearEncodePowerApprox));\n}\nvec3 toGammaSpace(vec3 color)\n{\nreturn pow(color,vec3(GammaEncodePowerApprox));\n}\nfloat square(float value)\n{\nreturn value*value;\n}\nfloat pow5(float value) {\nfloat sq=value*value;\nreturn sq*sq*value;\n}\nfloat getLuminance(vec3 color)\n{\nreturn clamp(dot(color,LuminanceEncodeApprox),0.,1.);\n}\n\nfloat getRand(vec2 seed) {\nreturn fract(sin(dot(seed.xy ,vec2(12.9898,78.233)))*43758.5453);\n}\nfloat dither(vec2 seed,float varianceAmount) {\nfloat rand=getRand(seed);\nfloat dither=mix(-varianceAmount/255.0,varianceAmount/255.0,rand);\nreturn dither;\n}\n\nconst float rgbdMaxRange=255.0;\nvec4 toRGBD(vec3 color) {\nfloat maxRGB=maxEps(max(color.r,max(color.g,color.b)));\nfloat D=max(rgbdMaxRange/maxRGB,1.);\nD=clamp(floor(D)/255.0,0.,1.);\n\nvec3 rgb=color.rgb*D;\n\nrgb=toGammaSpace(rgb);\nreturn vec4(rgb,D);\n}\nvec3 fromRGBD(vec4 rgbd) {\n\nrgbd.rgb=toLinearSpace(rgbd.rgb);\n\nreturn rgbd.rgb/rgbd.a;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var helperFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts":
/*!**************************************************************!*\
  !*** ./Shaders/ShadersInclude/imageProcessingDeclaration.ts ***!
  \**************************************************************/
/*! exports provided: imageProcessingDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "imageProcessingDeclaration", function() { return imageProcessingDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'imageProcessingDeclaration';
var shader = "#ifdef EXPOSURE\nuniform float exposureLinear;\n#endif\n#ifdef CONTRAST\nuniform float contrast;\n#endif\n#ifdef VIGNETTE\nuniform vec2 vInverseScreenSize;\nuniform vec4 vignetteSettings1;\nuniform vec4 vignetteSettings2;\n#endif\n#ifdef COLORCURVES\nuniform vec4 vCameraColorCurveNegative;\nuniform vec4 vCameraColorCurveNeutral;\nuniform vec4 vCameraColorCurvePositive;\n#endif\n#ifdef COLORGRADING\n#ifdef COLORGRADING3D\nuniform highp sampler3D txColorTransform;\n#else\nuniform sampler2D txColorTransform;\n#endif\nuniform vec4 colorTransformSettings;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var imageProcessingDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/imageProcessingFunctions.ts":
/*!************************************************************!*\
  !*** ./Shaders/ShadersInclude/imageProcessingFunctions.ts ***!
  \************************************************************/
/*! exports provided: imageProcessingFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "imageProcessingFunctions", function() { return imageProcessingFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'imageProcessingFunctions';
var shader = "#if defined(COLORGRADING) && !defined(COLORGRADING3D)\n\nvec3 sampleTexture3D(sampler2D colorTransform,vec3 color,vec2 sampler3dSetting)\n{\nfloat sliceSize=2.0*sampler3dSetting.x;\n#ifdef SAMPLER3DGREENDEPTH\nfloat sliceContinuous=(color.g-sampler3dSetting.x)*sampler3dSetting.y;\n#else\nfloat sliceContinuous=(color.b-sampler3dSetting.x)*sampler3dSetting.y;\n#endif\nfloat sliceInteger=floor(sliceContinuous);\n\n\nfloat sliceFraction=sliceContinuous-sliceInteger;\n#ifdef SAMPLER3DGREENDEPTH\nvec2 sliceUV=color.rb;\n#else\nvec2 sliceUV=color.rg;\n#endif\nsliceUV.x*=sliceSize;\nsliceUV.x+=sliceInteger*sliceSize;\nsliceUV=saturate(sliceUV);\nvec4 slice0Color=texture2D(colorTransform,sliceUV);\nsliceUV.x+=sliceSize;\nsliceUV=saturate(sliceUV);\nvec4 slice1Color=texture2D(colorTransform,sliceUV);\nvec3 result=mix(slice0Color.rgb,slice1Color.rgb,sliceFraction);\n#ifdef SAMPLER3DBGRMAP\ncolor.rgb=result.rgb;\n#else\ncolor.rgb=result.bgr;\n#endif\nreturn color;\n}\n#endif\n#ifdef TONEMAPPING_ACES\n\n\n\n\n\nconst mat3 ACESInputMat=mat3(\nvec3(0.59719,0.07600,0.02840),\nvec3(0.35458,0.90834,0.13383),\nvec3(0.04823,0.01566,0.83777)\n);\n\nconst mat3 ACESOutputMat=mat3(\nvec3( 1.60475,-0.10208,-0.00327),\nvec3(-0.53108,1.10813,-0.07276),\nvec3(-0.07367,-0.00605,1.07602)\n);\nvec3 RRTAndODTFit(vec3 v)\n{\nvec3 a=v*(v+0.0245786)-0.000090537;\nvec3 b=v*(0.983729*v+0.4329510)+0.238081;\nreturn a/b;\n}\nvec3 ACESFitted(vec3 color)\n{\ncolor=ACESInputMat*color;\n\ncolor=RRTAndODTFit(color);\ncolor=ACESOutputMat*color;\n\ncolor=saturate(color);\nreturn color;\n}\n#endif\nvec4 applyImageProcessing(vec4 result) {\n#ifdef EXPOSURE\nresult.rgb*=exposureLinear;\n#endif\n#ifdef VIGNETTE\n\nvec2 viewportXY=gl_FragCoord.xy*vInverseScreenSize;\nviewportXY=viewportXY*2.0-1.0;\nvec3 vignetteXY1=vec3(viewportXY*vignetteSettings1.xy+vignetteSettings1.zw,1.0);\nfloat vignetteTerm=dot(vignetteXY1,vignetteXY1);\nfloat vignette=pow(vignetteTerm,vignetteSettings2.w);\n\nvec3 vignetteColor=vignetteSettings2.rgb;\n#ifdef VIGNETTEBLENDMODEMULTIPLY\nvec3 vignetteColorMultiplier=mix(vignetteColor,vec3(1,1,1),vignette);\nresult.rgb*=vignetteColorMultiplier;\n#endif\n#ifdef VIGNETTEBLENDMODEOPAQUE\nresult.rgb=mix(vignetteColor,result.rgb,vignette);\n#endif\n#endif\n#ifdef TONEMAPPING\n#ifdef TONEMAPPING_ACES\nresult.rgb=ACESFitted(result.rgb);\n#else\nconst float tonemappingCalibration=1.590579;\nresult.rgb=1.0-exp2(-tonemappingCalibration*result.rgb);\n#endif\n#endif\n\nresult.rgb=toGammaSpace(result.rgb);\nresult.rgb=saturate(result.rgb);\n#ifdef CONTRAST\n\nvec3 resultHighContrast=result.rgb*result.rgb*(3.0-2.0*result.rgb);\nif (contrast<1.0) {\n\nresult.rgb=mix(vec3(0.5,0.5,0.5),result.rgb,contrast);\n} else {\n\nresult.rgb=mix(result.rgb,resultHighContrast,contrast-1.0);\n}\n#endif\n\n#ifdef COLORGRADING\nvec3 colorTransformInput=result.rgb*colorTransformSettings.xxx+colorTransformSettings.yyy;\n#ifdef COLORGRADING3D\nvec3 colorTransformOutput=texture(txColorTransform,colorTransformInput).rgb;\n#else\nvec3 colorTransformOutput=sampleTexture3D(txColorTransform,colorTransformInput,colorTransformSettings.yz).rgb;\n#endif\nresult.rgb=mix(result.rgb,colorTransformOutput,colorTransformSettings.www);\n#endif\n#ifdef COLORCURVES\n\nfloat luma=getLuminance(result.rgb);\nvec2 curveMix=clamp(vec2(luma*3.0-1.5,luma*-3.0+1.5),vec2(0.0),vec2(1.0));\nvec4 colorCurve=vCameraColorCurveNeutral+curveMix.x*vCameraColorCurvePositive-curveMix.y*vCameraColorCurveNegative;\nresult.rgb*=colorCurve.rgb;\nresult.rgb=mix(vec3(luma),result.rgb,colorCurve.a);\n#endif\nreturn result;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var imageProcessingFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/instancesDeclaration.ts":
/*!********************************************************!*\
  !*** ./Shaders/ShadersInclude/instancesDeclaration.ts ***!
  \********************************************************/
/*! exports provided: instancesDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "instancesDeclaration", function() { return instancesDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'instancesDeclaration';
var shader = "#ifdef INSTANCES\nattribute vec4 world0;\nattribute vec4 world1;\nattribute vec4 world2;\nattribute vec4 world3;\n#else\nuniform mat4 world;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var instancesDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/instancesVertex.ts":
/*!***************************************************!*\
  !*** ./Shaders/ShadersInclude/instancesVertex.ts ***!
  \***************************************************/
/*! exports provided: instancesVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "instancesVertex", function() { return instancesVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'instancesVertex';
var shader = "#ifdef INSTANCES\nmat4 finalWorld=mat4(world0,world1,world2,world3);\n#else\nmat4 finalWorld=world;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var instancesVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/kernelBlurFragment.ts":
/*!******************************************************!*\
  !*** ./Shaders/ShadersInclude/kernelBlurFragment.ts ***!
  \******************************************************/
/*! exports provided: kernelBlurFragment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "kernelBlurFragment", function() { return kernelBlurFragment; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'kernelBlurFragment';
var shader = "#ifdef DOF\nfactor=sampleCoC(sampleCoord{X});\ncomputedWeight=KERNEL_WEIGHT{X}*factor;\nsumOfWeights+=computedWeight;\n#else\ncomputedWeight=KERNEL_WEIGHT{X};\n#endif\n#ifdef PACKEDFLOAT\nblend+=unpack(texture2D(textureSampler,sampleCoord{X}))*computedWeight;\n#else\nblend+=texture2D(textureSampler,sampleCoord{X})*computedWeight;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var kernelBlurFragment = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/kernelBlurFragment2.ts":
/*!*******************************************************!*\
  !*** ./Shaders/ShadersInclude/kernelBlurFragment2.ts ***!
  \*******************************************************/
/*! exports provided: kernelBlurFragment2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "kernelBlurFragment2", function() { return kernelBlurFragment2; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'kernelBlurFragment2';
var shader = "#ifdef DOF\nfactor=sampleCoC(sampleCenter+delta*KERNEL_DEP_OFFSET{X});\ncomputedWeight=KERNEL_DEP_WEIGHT{X}*factor;\nsumOfWeights+=computedWeight;\n#else\ncomputedWeight=KERNEL_DEP_WEIGHT{X};\n#endif\n#ifdef PACKEDFLOAT\nblend+=unpack(texture2D(textureSampler,sampleCenter+delta*KERNEL_DEP_OFFSET{X}))*computedWeight;\n#else\nblend+=texture2D(textureSampler,sampleCenter+delta*KERNEL_DEP_OFFSET{X})*computedWeight;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var kernelBlurFragment2 = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/kernelBlurVaryingDeclaration.ts":
/*!****************************************************************!*\
  !*** ./Shaders/ShadersInclude/kernelBlurVaryingDeclaration.ts ***!
  \****************************************************************/
/*! exports provided: kernelBlurVaryingDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "kernelBlurVaryingDeclaration", function() { return kernelBlurVaryingDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'kernelBlurVaryingDeclaration';
var shader = "varying vec2 sampleCoord{X};";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var kernelBlurVaryingDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/kernelBlurVertex.ts":
/*!****************************************************!*\
  !*** ./Shaders/ShadersInclude/kernelBlurVertex.ts ***!
  \****************************************************/
/*! exports provided: kernelBlurVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "kernelBlurVertex", function() { return kernelBlurVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'kernelBlurVertex';
var shader = "sampleCoord{X}=sampleCenter+delta*KERNEL_OFFSET{X};";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var kernelBlurVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/lightFragment.ts":
/*!*************************************************!*\
  !*** ./Shaders/ShadersInclude/lightFragment.ts ***!
  \*************************************************/
/*! exports provided: lightFragment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lightFragment", function() { return lightFragment; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'lightFragment';
var shader = "#ifdef LIGHT{X}\n#if defined(SHADOWONLY) || defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})\n\n#else\n#ifdef PBR\n\n#ifdef SPOTLIGHT{X}\npreInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(POINTLIGHT{X})\npreInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(HEMILIGHT{X})\npreInfo=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#elif defined(DIRLIGHT{X})\npreInfo=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n#endif\npreInfo.NdotV=NdotV;\n\n#ifdef SPOTLIGHT{X}\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\npreInfo.attenuation*=computeDirectionalLightFalloff_GLTF(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\npreInfo.attenuation*=computeDirectionalLightFalloff_Physical(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w);\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\npreInfo.attenuation*=computeDirectionalLightFalloff_Standard(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w);\n#else\npreInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\npreInfo.attenuation*=computeDirectionalLightFalloff(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n#endif\n#elif defined(POINTLIGHT{X})\n#ifdef LIGHT_FALLOFF_GLTF{X}\npreInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n#elif defined(LIGHT_FALLOFF_PHYSICAL{X})\npreInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n#elif defined(LIGHT_FALLOFF_STANDARD{X})\npreInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n#else\npreInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n#endif\n#else\npreInfo.attenuation=1.0;\n#endif\n\n\n#ifdef HEMILIGHT{X}\npreInfo.roughness=roughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(roughness,light{X}.vLightDiffuse.a,preInfo.lightDistance);\n#endif\n\n#ifdef HEMILIGHT{X}\ninfo.diffuse=computeHemisphericDiffuseLighting(preInfo,light{X}.vLightDiffuse.rgb,light{X}.vLightGround);\n#elif defined(SS_TRANSLUCENCY)\ninfo.diffuse=computeDiffuseAndTransmittedLighting(preInfo,light{X}.vLightDiffuse.rgb,transmittance);\n#else\ninfo.diffuse=computeDiffuseLighting(preInfo,light{X}.vLightDiffuse.rgb);\n#endif\n\n#ifdef SPECULARTERM\n#ifdef ANISOTROPIC\ninfo.specular=computeAnisotropicSpecularLighting(preInfo,viewDirectionW,normalW,anisotropicTangent,anisotropicBitangent,anisotropy,specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactors.x,light{X}.vLightDiffuse.rgb);\n#else\ninfo.specular=computeSpecularLighting(preInfo,normalW,specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactors.x,light{X}.vLightDiffuse.rgb);\n#endif\n#endif\n\n#ifdef SHEEN\n#ifdef SHEEN_LINKWITHALBEDO\n\npreInfo.roughness=sheenIntensity;\n#endif\ninfo.sheen=computeSheenLighting(preInfo,normalW,sheenColor,specularEnvironmentR90,AARoughnessFactors.x,light{X}.vLightDiffuse.rgb);\n#endif\n\n#ifdef CLEARCOAT\n\n#ifdef HEMILIGHT{X}\npreInfo.roughness=clearCoatRoughness;\n#else\npreInfo.roughness=adjustRoughnessFromLightProperties(clearCoatRoughness,light{X}.vLightDiffuse.a,preInfo.lightDistance);\n#endif\ninfo.clearCoat=computeClearCoatLighting(preInfo,clearCoatNormalW,clearCoatAARoughnessFactors.x,clearCoatIntensity,light{X}.vLightDiffuse.rgb);\n#ifdef CLEARCOAT_TINT\n\nabsorption=computeClearCoatLightingAbsorption(clearCoatNdotVRefract,preInfo.L,clearCoatNormalW,clearCoatColor,clearCoatThickness,clearCoatIntensity);\ninfo.diffuse*=absorption;\n#ifdef SPECULARTERM\ninfo.specular*=absorption;\n#endif\n#endif\n\ninfo.diffuse*=info.clearCoat.w;\n#ifdef SPECULARTERM\ninfo.specular*=info.clearCoat.w*info.clearCoat.w;\n#endif\n#ifdef SHEEN\ninfo.sheen*=info.clearCoat.w*info.clearCoat.w;\n#endif\n#endif\n#else\n#ifdef SPOTLIGHT{X}\ninfo=computeSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightDiffuse.a,glossiness);\n#elif defined(HEMILIGHT{X})\ninfo=computeHemisphericLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightGround,glossiness);\n#elif defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})\ninfo=computeLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular,light{X}.vLightDiffuse.a,glossiness);\n#endif\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\ninfo.diffuse*=texture2D(projectionLightSampler{X},computeProjectionTextureDiffuseLightingUV(textureProjectionMatrix{X})).rgb;\n#endif\n#endif\n#ifdef SHADOW{X}\n#ifdef SHADOWCLOSEESM{X}\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithCloseESMCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithCloseESM(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWESM{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithESMCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.depthValues);\n#else\nshadow=computeShadowWithESM(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.z,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPOISSON{X})\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowWithPoissonSamplingCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadowWithPoissonSampling(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCF{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithPCF1(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithPCF3(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithPCF5(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#elif defined(SHADOWPCSS{X})\n#if defined(SHADOWLOWQUALITY{X})\nshadow=computeShadowWithPCSS16(vPositionFromLight{X},vDepthMetric{X},depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#elif defined(SHADOWMEDIUMQUALITY{X})\nshadow=computeShadowWithPCSS32(vPositionFromLight{X},vDepthMetric{X},depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#else\nshadow=computeShadowWithPCSS64(vPositionFromLight{X},vDepthMetric{X},depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#else\n#if defined(SHADOWCUBE{X})\nshadow=computeShadowCube(light{X}.vLightData.xyz,shadowSampler{X},light{X}.shadowsInfo.x,light{X}.depthValues);\n#else\nshadow=computeShadow(vPositionFromLight{X},vDepthMetric{X},shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n#endif\n#endif\n#ifdef SHADOWONLY\n#ifndef SHADOWINUSE\n#define SHADOWINUSE\n#endif\nglobalShadow+=shadow;\nshadowLightCount+=1.0;\n#endif\n#else\nshadow=1.;\n#endif\n#ifndef SHADOWONLY\n#ifdef CUSTOMUSERLIGHTING\ndiffuseBase+=computeCustomDiffuseLighting(info,diffuseBase,shadow);\n#ifdef SPECULARTERM\nspecularBase+=computeCustomSpecularLighting(info,specularBase,shadow);\n#endif\n#elif defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X})\ndiffuseBase+=lightmapColor.rgb*shadow;\n#ifdef SPECULARTERM\n#ifndef LIGHTMAPNOSPECULAR{X}\nspecularBase+=info.specular*shadow*lightmapColor.rgb;\n#endif\n#endif\n#ifdef CLEARCOAT\n#ifndef LIGHTMAPNOSPECULAR{X}\nclearCoatBase+=info.clearCoat.rgb*shadow*lightmapColor.rgb;\n#endif\n#endif\n#ifdef SHEEN\n#ifndef LIGHTMAPNOSPECULAR{X}\nsheenBase+=info.sheen.rgb*shadow;\n#endif\n#endif\n#else\ndiffuseBase+=info.diffuse*shadow;\n#ifdef SPECULARTERM\nspecularBase+=info.specular*shadow;\n#endif\n#ifdef CLEARCOAT\nclearCoatBase+=info.clearCoat.rgb*shadow;\n#endif\n#ifdef SHEEN\nsheenBase+=info.sheen.rgb*shadow;\n#endif\n#endif\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var lightFragment = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts":
/*!************************************************************!*\
  !*** ./Shaders/ShadersInclude/lightFragmentDeclaration.ts ***!
  \************************************************************/
/*! exports provided: lightFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lightFragmentDeclaration", function() { return lightFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'lightFragmentDeclaration';
var shader = "#ifdef LIGHT{X}\nuniform vec4 vLightData{X};\nuniform vec4 vLightDiffuse{X};\n#ifdef SPECULARTERM\nuniform vec3 vLightSpecular{X};\n#else\nvec3 vLightSpecular{X}=vec3(0.);\n#endif\n#ifdef SHADOW{X}\n#if defined(SHADOWCUBE{X})\nuniform samplerCube shadowSampler{X};\n#else\nvarying vec4 vPositionFromLight{X};\nvarying float vDepthMetric{X};\n#if defined(SHADOWPCSS{X})\nuniform highp sampler2DShadow shadowSampler{X};\nuniform highp sampler2D depthSampler{X};\n#elif defined(SHADOWPCF{X})\nuniform highp sampler2DShadow shadowSampler{X};\n#else\nuniform sampler2D shadowSampler{X};\n#endif\nuniform mat4 lightMatrix{X};\n#endif\nuniform vec4 shadowsInfo{X};\nuniform vec2 depthValues{X};\n#endif\n#ifdef SPOTLIGHT{X}\nuniform vec4 vLightDirection{X};\nuniform vec4 vLightFalloff{X};\n#elif defined(POINTLIGHT{X})\nuniform vec4 vLightFalloff{X};\n#elif defined(HEMILIGHT{X})\nuniform vec3 vLightGround{X};\n#endif\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nuniform mat4 textureProjectionMatrix{X};\nuniform sampler2D projectionLightSampler{X};\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var lightFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/lightUboDeclaration.ts":
/*!*******************************************************!*\
  !*** ./Shaders/ShadersInclude/lightUboDeclaration.ts ***!
  \*******************************************************/
/*! exports provided: lightUboDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lightUboDeclaration", function() { return lightUboDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'lightUboDeclaration';
var shader = "#ifdef LIGHT{X}\nuniform Light{X}\n{\nvec4 vLightData;\nvec4 vLightDiffuse;\nvec3 vLightSpecular;\n#ifdef SPOTLIGHT{X}\nvec4 vLightDirection;\nvec4 vLightFalloff;\n#elif defined(POINTLIGHT{X})\nvec4 vLightFalloff;\n#elif defined(HEMILIGHT{X})\nvec3 vLightGround;\n#endif\nvec4 shadowsInfo;\nvec2 depthValues;\n} light{X};\n#ifdef PROJECTEDLIGHTTEXTURE{X}\nuniform mat4 textureProjectionMatrix{X};\nuniform sampler2D projectionLightSampler{X};\n#endif\n#ifdef SHADOW{X}\n#if defined(SHADOWCUBE{X})\nuniform samplerCube shadowSampler{X};\n#else\nvarying vec4 vPositionFromLight{X};\nvarying float vDepthMetric{X};\n#if defined(SHADOWPCSS{X})\nuniform highp sampler2DShadow shadowSampler{X};\nuniform highp sampler2D depthSampler{X};\n#elif defined(SHADOWPCF{X})\nuniform highp sampler2DShadow shadowSampler{X};\n#else\nuniform sampler2D shadowSampler{X};\n#endif\nuniform mat4 lightMatrix{X};\n#endif\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var lightUboDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/lightsFragmentFunctions.ts":
/*!***********************************************************!*\
  !*** ./Shaders/ShadersInclude/lightsFragmentFunctions.ts ***!
  \***********************************************************/
/*! exports provided: lightsFragmentFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lightsFragmentFunctions", function() { return lightsFragmentFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'lightsFragmentFunctions';
var shader = "\nstruct lightingInfo\n{\nvec3 diffuse;\n#ifdef SPECULARTERM\nvec3 specular;\n#endif\n#ifdef NDOTL\nfloat ndl;\n#endif\n};\nlightingInfo computeLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {\nlightingInfo result;\nvec3 lightVectorW;\nfloat attenuation=1.0;\nif (lightData.w == 0.)\n{\nvec3 direction=lightData.xyz-vPositionW;\nattenuation=max(0.,1.0-length(direction)/range);\nlightVectorW=normalize(direction);\n}\nelse\n{\nlightVectorW=normalize(-lightData.xyz);\n}\n\nfloat ndl=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\n\nvec3 angleW=normalize(viewDirectionW+lightVectorW);\nfloat specComp=max(0.,dot(vNormal,angleW));\nspecComp=pow(specComp,max(1.,glossiness));\nresult.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;\n}\nlightingInfo computeSpotLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec4 lightDirection,vec3 diffuseColor,vec3 specularColor,float range,float glossiness) {\nlightingInfo result;\nvec3 direction=lightData.xyz-vPositionW;\nvec3 lightVectorW=normalize(direction);\nfloat attenuation=max(0.,1.0-length(direction)/range);\n\nfloat cosAngle=max(0.,dot(lightDirection.xyz,-lightVectorW));\nif (cosAngle>=lightDirection.w)\n{\ncosAngle=max(0.,pow(cosAngle,lightData.w));\nattenuation*=cosAngle;\n\nfloat ndl=max(0.,dot(vNormal,lightVectorW));\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=ndl*diffuseColor*attenuation;\n#ifdef SPECULARTERM\n\nvec3 angleW=normalize(viewDirectionW+lightVectorW);\nfloat specComp=max(0.,dot(vNormal,angleW));\nspecComp=pow(specComp,max(1.,glossiness));\nresult.specular=specComp*specularColor*attenuation;\n#endif\nreturn result;\n}\nresult.diffuse=vec3(0.);\n#ifdef SPECULARTERM\nresult.specular=vec3(0.);\n#endif\n#ifdef NDOTL\nresult.ndl=0.;\n#endif\nreturn result;\n}\nlightingInfo computeHemisphericLighting(vec3 viewDirectionW,vec3 vNormal,vec4 lightData,vec3 diffuseColor,vec3 specularColor,vec3 groundColor,float glossiness) {\nlightingInfo result;\n\nfloat ndl=dot(vNormal,lightData.xyz)*0.5+0.5;\n#ifdef NDOTL\nresult.ndl=ndl;\n#endif\nresult.diffuse=mix(groundColor,diffuseColor,ndl);\n#ifdef SPECULARTERM\n\nvec3 angleW=normalize(viewDirectionW+lightData.xyz);\nfloat specComp=max(0.,dot(vNormal,angleW));\nspecComp=pow(specComp,max(1.,glossiness));\nresult.specular=specComp*specularColor;\n#endif\nreturn result;\n}\nvec2 computeProjectionTextureDiffuseLightingUV(mat4 textureProjectionMatrix){\nvec4 strq=textureProjectionMatrix*vec4(vPositionW,1.0);\nstrq/=strq.w;\nreturn strq.xy;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var lightsFragmentFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/logDepthDeclaration.ts":
/*!*******************************************************!*\
  !*** ./Shaders/ShadersInclude/logDepthDeclaration.ts ***!
  \*******************************************************/
/*! exports provided: logDepthDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logDepthDeclaration", function() { return logDepthDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'logDepthDeclaration';
var shader = "#ifdef LOGARITHMICDEPTH\nuniform float logarithmicDepthConstant;\nvarying float vFragmentDepth;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var logDepthDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/logDepthFragment.ts":
/*!****************************************************!*\
  !*** ./Shaders/ShadersInclude/logDepthFragment.ts ***!
  \****************************************************/
/*! exports provided: logDepthFragment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logDepthFragment", function() { return logDepthFragment; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'logDepthFragment';
var shader = "#ifdef LOGARITHMICDEPTH\ngl_FragDepthEXT=log2(vFragmentDepth)*logarithmicDepthConstant*0.5;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var logDepthFragment = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/logDepthVertex.ts":
/*!**************************************************!*\
  !*** ./Shaders/ShadersInclude/logDepthVertex.ts ***!
  \**************************************************/
/*! exports provided: logDepthVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logDepthVertex", function() { return logDepthVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'logDepthVertex';
var shader = "#ifdef LOGARITHMICDEPTH\nvFragmentDepth=1.0+gl_Position.w;\ngl_Position.z=log2(max(0.000001,vFragmentDepth))*logarithmicDepthConstant;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var logDepthVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/morphTargetsVertex.ts":
/*!******************************************************!*\
  !*** ./Shaders/ShadersInclude/morphTargetsVertex.ts ***!
  \******************************************************/
/*! exports provided: morphTargetsVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "morphTargetsVertex", function() { return morphTargetsVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'morphTargetsVertex';
var shader = "#ifdef MORPHTARGETS\npositionUpdated+=(position{X}-position)*morphTargetInfluences[{X}];\n#ifdef MORPHTARGETS_NORMAL\nnormalUpdated+=(normal{X}-normal)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_TANGENT\ntangentUpdated.xyz+=(tangent{X}-tangent.xyz)*morphTargetInfluences[{X}];\n#endif\n#ifdef MORPHTARGETS_UV\nuvUpdated+=(uv_{X}-uv)*morphTargetInfluences[{X}];\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var morphTargetsVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts":
/*!*****************************************************************!*\
  !*** ./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts ***!
  \*****************************************************************/
/*! exports provided: morphTargetsVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "morphTargetsVertexDeclaration", function() { return morphTargetsVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'morphTargetsVertexDeclaration';
var shader = "#ifdef MORPHTARGETS\nattribute vec3 position{X};\n#ifdef MORPHTARGETS_NORMAL\nattribute vec3 normal{X};\n#endif\n#ifdef MORPHTARGETS_TANGENT\nattribute vec3 tangent{X};\n#endif\n#ifdef MORPHTARGETS_UV\nattribute vec2 uv_{X};\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var morphTargetsVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts":
/*!***********************************************************************!*\
  !*** ./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts ***!
  \***********************************************************************/
/*! exports provided: morphTargetsVertexGlobalDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "morphTargetsVertexGlobalDeclaration", function() { return morphTargetsVertexGlobalDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'morphTargetsVertexGlobalDeclaration';
var shader = "#ifdef MORPHTARGETS\nuniform float morphTargetInfluences[NUM_MORPH_INFLUENCERS];\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var morphTargetsVertexGlobalDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/mrtFragmentDeclaration.ts":
/*!**********************************************************!*\
  !*** ./Shaders/ShadersInclude/mrtFragmentDeclaration.ts ***!
  \**********************************************************/
/*! exports provided: mrtFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mrtFragmentDeclaration", function() { return mrtFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'mrtFragmentDeclaration';
var shader = "#if __VERSION__>=200\nlayout(location=0) out vec4 glFragData[{X}];\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var mrtFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/packingFunctions.ts":
/*!****************************************************!*\
  !*** ./Shaders/ShadersInclude/packingFunctions.ts ***!
  \****************************************************/
/*! exports provided: packingFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "packingFunctions", function() { return packingFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'packingFunctions';
var shader = "vec4 pack(float depth)\n{\nconst vec4 bit_shift=vec4(255.0*255.0*255.0,255.0*255.0,255.0,1.0);\nconst vec4 bit_mask=vec4(0.0,1.0/255.0,1.0/255.0,1.0/255.0);\nvec4 res=fract(depth*bit_shift);\nres-=res.xxyz*bit_mask;\nreturn res;\n}\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var packingFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrBRDFFunctions.ts":
/*!****************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrBRDFFunctions.ts ***!
  \****************************************************/
/*! exports provided: pbrBRDFFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrBRDFFunctions", function() { return pbrBRDFFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrBRDFFunctions';
var shader = "\n#define FRESNEL_MAXIMUM_ON_ROUGH 0.25\n\n\n\n\n#ifdef MS_BRDF_ENERGY_CONSERVATION\n\n\nvec3 getEnergyConservationFactor(const vec3 specularEnvironmentR0,const vec3 environmentBrdf) {\nreturn 1.0+specularEnvironmentR0*(1.0/environmentBrdf.y-1.0);\n}\n#endif\n#ifdef ENVIRONMENTBRDF\nvec3 getBRDFLookup(float NdotV,float perceptualRoughness) {\n\nvec2 UV=vec2(NdotV,perceptualRoughness);\n\nvec4 brdfLookup=texture2D(environmentBrdfSampler,UV);\n#ifdef ENVIRONMENTBRDF_RGBD\nbrdfLookup.rgb=fromRGBD(brdfLookup.rgba);\n#endif\nreturn brdfLookup.rgb;\n}\nvec3 getReflectanceFromBRDFLookup(const vec3 specularEnvironmentR0,const vec3 environmentBrdf) {\n#ifdef BRDF_V_HEIGHT_CORRELATED\nvec3 reflectance=mix(environmentBrdf.xxx,environmentBrdf.yyy,specularEnvironmentR0);\n#else\nvec3 reflectance=specularEnvironmentR0*environmentBrdf.x+environmentBrdf.y;\n#endif\nreturn reflectance;\n}\n#endif\n#if !defined(ENVIRONMENTBRDF) || defined(REFLECTIONMAP_SKYBOX) || defined(ALPHAFRESNEL)\nvec3 getReflectanceFromAnalyticalBRDFLookup_Jones(float VdotN,vec3 reflectance0,vec3 reflectance90,float smoothness)\n{\n\nfloat weight=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);\nreturn reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));\n}\n#endif\n#if defined(SHEEN) && defined(REFLECTION)\n\nvec3 getSheenReflectanceFromBRDFLookup(const vec3 reflectance0,const vec3 environmentBrdf) {\nvec3 sheenEnvironmentReflectance=reflectance0*environmentBrdf.b;\nreturn sheenEnvironmentReflectance;\n}\n#endif\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvec3 fresnelSchlickGGX(float VdotH,vec3 reflectance0,vec3 reflectance90)\n{\nreturn reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);\n}\nfloat fresnelSchlickGGX(float VdotH,float reflectance0,float reflectance90)\n{\nreturn reflectance0+(reflectance90-reflectance0)*pow5(1.0-VdotH);\n}\n#ifdef CLEARCOAT\n\n\n\n\n\nvec3 getR0RemappedForClearCoat(vec3 f0) {\n#ifdef CLEARCOAT_DEFAULTIOR\n#ifdef MOBILE\nreturn saturate(f0*(f0*0.526868+0.529324)-0.0482256);\n#else\nreturn saturate(f0*(f0*(0.941892-0.263008*f0)+0.346479)-0.0285998);\n#endif\n#else\nvec3 s=sqrt(f0);\nvec3 t=(vClearCoatRefractionParams.z+vClearCoatRefractionParams.w*s)/(vClearCoatRefractionParams.w+vClearCoatRefractionParams.z*s);\nreturn t*t;\n#endif\n}\n#endif\n\n\n\n\n\n\nfloat normalDistributionFunction_TrowbridgeReitzGGX(float NdotH,float alphaG)\n{\n\n\n\nfloat a2=square(alphaG);\nfloat d=NdotH*NdotH*(a2-1.0)+1.0;\nreturn a2/(PI*d*d);\n}\n#ifdef SHEEN\n\nfloat normalDistributionFunction_CharlieSheen(float NdotH,float alphaG)\n{\nfloat invR=1./alphaG;\nfloat cos2h=NdotH*NdotH;\nfloat sin2h=1.-cos2h;\nreturn (2.+invR)*pow(sin2h,invR*.5)/(2.*PI);\n}\n#endif\n#ifdef ANISOTROPIC\n\n\nfloat normalDistributionFunction_BurleyGGX_Anisotropic(float NdotH,float TdotH,float BdotH,const vec2 alphaTB) {\nfloat a2=alphaTB.x*alphaTB.y;\nvec3 v=vec3(alphaTB.y*TdotH,alphaTB.x*BdotH,a2*NdotH);\nfloat v2=dot(v,v);\nfloat w2=a2/v2;\nreturn a2*w2*w2*RECIPROCAL_PI;\n}\n#endif\n\n\n\n\n#ifdef BRDF_V_HEIGHT_CORRELATED\n\n\n\nfloat smithVisibility_GGXCorrelated(float NdotL,float NdotV,float alphaG) {\n#ifdef MOBILE\n\nfloat GGXV=NdotL*(NdotV*(1.0-alphaG)+alphaG);\nfloat GGXL=NdotV*(NdotL*(1.0-alphaG)+alphaG);\nreturn 0.5/(GGXV+GGXL);\n#else\nfloat a2=alphaG*alphaG;\nfloat GGXV=NdotL*sqrt(NdotV*(NdotV-a2*NdotV)+a2);\nfloat GGXL=NdotV*sqrt(NdotL*(NdotL-a2*NdotL)+a2);\nreturn 0.5/(GGXV+GGXL);\n#endif\n}\n#else\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nfloat smithVisibilityG1_TrowbridgeReitzGGXFast(float dot,float alphaG)\n{\n#ifdef MOBILE\n\nreturn 1.0/(dot+alphaG+(1.0-alphaG)*dot ));\n#else\nfloat alphaSquared=alphaG*alphaG;\nreturn 1.0/(dot+sqrt(alphaSquared+(1.0-alphaSquared)*dot*dot));\n#endif\n}\nfloat smithVisibility_TrowbridgeReitzGGXFast(float NdotL,float NdotV,float alphaG)\n{\nfloat visibility=smithVisibilityG1_TrowbridgeReitzGGXFast(NdotL,alphaG)*smithVisibilityG1_TrowbridgeReitzGGXFast(NdotV,alphaG);\n\nreturn visibility;\n}\n#endif\n#ifdef ANISOTROPIC\n\n\nfloat smithVisibility_GGXCorrelated_Anisotropic(float NdotL,float NdotV,float TdotV,float BdotV,float TdotL,float BdotL,const vec2 alphaTB) {\nfloat lambdaV=NdotL*length(vec3(alphaTB.x*TdotV,alphaTB.y*BdotV,NdotV));\nfloat lambdaL=NdotV*length(vec3(alphaTB.x*TdotL,alphaTB.y*BdotL,NdotL));\nfloat v=0.5/(lambdaV+lambdaL);\nreturn v;\n}\n#endif\n#ifdef CLEARCOAT\nfloat visibility_Kelemen(float VdotH) {\n\n\n\nreturn 0.25/(VdotH*VdotH);\n}\n#endif\n#ifdef SHEEN\n\n\n\nfloat visibility_Ashikhmin(float NdotL,float NdotV)\n{\nreturn 1./(4.*(NdotL+NdotV-NdotL*NdotV));\n}\n#endif\n\n\n\n\n\n\n\nfloat diffuseBRDF_Burley(float NdotL,float NdotV,float VdotH,float roughness) {\n\n\nfloat diffuseFresnelNV=pow5(saturateEps(1.0-NdotL));\nfloat diffuseFresnelNL=pow5(saturateEps(1.0-NdotV));\nfloat diffuseFresnel90=0.5+2.0*VdotH*VdotH*roughness;\nfloat fresnel =\n(1.0+(diffuseFresnel90-1.0)*diffuseFresnelNL) *\n(1.0+(diffuseFresnel90-1.0)*diffuseFresnelNV);\nreturn fresnel/PI;\n}\n#ifdef SS_TRANSLUCENCY\n\n\nvec3 transmittanceBRDF_Burley(const vec3 tintColor,const vec3 diffusionDistance,float thickness) {\nvec3 S=1./maxEps(diffusionDistance);\nvec3 temp=exp((-0.333333333*thickness)*S);\nreturn tintColor.rgb*0.25*(temp*temp*temp+3.0*temp);\n}\n\n\nfloat computeWrappedDiffuseNdotL(float NdotL,float w) {\nfloat t=1.0+w;\nfloat invt2=1.0/square(t);\nreturn saturate((NdotL+w)*invt2);\n}\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrBRDFFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrDebug.ts":
/*!********************************************!*\
  !*** ./Shaders/ShadersInclude/pbrDebug.ts ***!
  \********************************************/
/*! exports provided: pbrDebug */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrDebug", function() { return pbrDebug; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrDebug';
var shader = "#if DEBUGMODE>0\nif (vClipSpacePosition.x/vClipSpacePosition.w<vDebugMode.x) {\nreturn;\n}\n\n#if DEBUGMODE == 1\ngl_FragColor.rgb=vPositionW.rgb;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 2 && defined(NORMAL)\ngl_FragColor.rgb=vNormalW.rgb;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 3 && (defined(BUMP) || defined(PARALLAX) || defined(ANISOTROPIC))\n\ngl_FragColor.rgb=TBN[0];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 4 && (defined(BUMP) || defined(PARALLAX) || defined(ANISOTROPIC))\n\ngl_FragColor.rgb=TBN[1];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 5\n\ngl_FragColor.rgb=normalW;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 6 && defined(MAINUV1)\ngl_FragColor.rgb=vec3(vMainUV1,0.0);\n#elif DEBUGMODE == 7 && defined(MAINUV2)\ngl_FragColor.rgb=vec3(vMainUV2,0.0);\n#elif DEBUGMODE == 8 && defined(CLEARCOAT) && defined(CLEARCOAT_BUMP)\n\ngl_FragColor.rgb=TBNClearCoat[0];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 9 && defined(CLEARCOAT) && defined(CLEARCOAT_BUMP)\n\ngl_FragColor.rgb=TBNClearCoat[1];\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 10 && defined(CLEARCOAT)\n\ngl_FragColor.rgb=clearCoatNormalW;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 11 && defined(ANISOTROPIC)\ngl_FragColor.rgb=anisotropicNormal;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 12 && defined(ANISOTROPIC)\ngl_FragColor.rgb=anisotropicTangent;\n#define DEBUGMODE_NORMALIZE\n#elif DEBUGMODE == 13 && defined(ANISOTROPIC)\ngl_FragColor.rgb=anisotropicBitangent;\n#define DEBUGMODE_NORMALIZE\n\n#elif DEBUGMODE == 20 && defined(ALBEDO)\ngl_FragColor.rgb=albedoTexture.rgb;\n#elif DEBUGMODE == 21 && defined(AMBIENT)\ngl_FragColor.rgb=ambientOcclusionColorMap.rgb;\n#elif DEBUGMODE == 22 && defined(OPACITY)\ngl_FragColor.rgb=opacityMap.rgb;\n#elif DEBUGMODE == 23 && defined(EMISSIVE)\ngl_FragColor.rgb=emissiveColorTex.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 24 && defined(LIGHTMAP)\ngl_FragColor.rgb=lightmapColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 25 && defined(REFLECTIVITY) && defined(METALLICWORKFLOW)\ngl_FragColor.rgb=surfaceMetallicColorMap.rgb;\n#elif DEBUGMODE == 26 && defined(REFLECTIVITY) && !defined(METALLICWORKFLOW)\ngl_FragColor.rgb=surfaceReflectivityColorMap.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 27 && defined(CLEARCOAT) && defined(CLEARCOAT_TEXTURE)\ngl_FragColor.rgb=vec3(clearCoatMapData.rg,0.0);\n#elif DEBUGMODE == 28 && defined(CLEARCOAT) && defined(CLEARCOAT_TINT) && defined(CLEARCOAT_TINT_TEXTURE)\ngl_FragColor.rgb=clearCoatTintMapData.rgb;\n#elif DEBUGMODE == 29 && defined(SHEEN) && defined(SHEEN_TEXTURE)\ngl_FragColor.rgb=sheenMapData.rgb;\n#elif DEBUGMODE == 30 && defined(ANISOTROPIC) && defined(ANISOTROPIC_TEXTURE)\ngl_FragColor.rgb=anisotropyMapData.rgb;\n#elif DEBUGMODE == 31 && defined(SUBSURFACE) && defined(SS_THICKNESSANDMASK_TEXTURE)\ngl_FragColor.rgb=thicknessMap.rgb;\n\n#elif DEBUGMODE == 40 && defined(SS_REFRACTION)\n\ngl_FragColor.rgb=environmentRefraction.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 41 && defined(REFLECTION)\ngl_FragColor.rgb=environmentRadiance.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 42 && defined(CLEARCOAT) && defined(REFLECTION)\ngl_FragColor.rgb=environmentClearCoatRadiance;\n#define DEBUGMODE_GAMMA\n\n#elif DEBUGMODE == 50\ngl_FragColor.rgb=diffuseBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 51 && defined(SPECULARTERM)\ngl_FragColor.rgb=specularBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 52 && defined(CLEARCOAT)\ngl_FragColor.rgb=clearCoatBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 53 && defined(SHEEN)\ngl_FragColor.rgb=sheenBase.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 54 && defined(REFLECTION)\ngl_FragColor.rgb=environmentIrradiance.rgb;\n#define DEBUGMODE_GAMMA\n\n#elif DEBUGMODE == 60\ngl_FragColor.rgb=surfaceAlbedo.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 61\ngl_FragColor.rgb=specularEnvironmentR0;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 62 && defined(METALLICWORKFLOW)\ngl_FragColor.rgb=vec3(metallicRoughness.r);\n#elif DEBUGMODE == 63\ngl_FragColor.rgb=vec3(roughness);\n#elif DEBUGMODE == 64\ngl_FragColor.rgb=vec3(alphaG);\n#elif DEBUGMODE == 65\ngl_FragColor.rgb=vec3(NdotV);\n#elif DEBUGMODE == 66 && defined(CLEARCOAT) && defined(CLEARCOAT_TINT)\ngl_FragColor.rgb=clearCoatColor.rgb;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 67 && defined(CLEARCOAT)\ngl_FragColor.rgb=vec3(clearCoatRoughness);\n#elif DEBUGMODE == 68 && defined(CLEARCOAT)\ngl_FragColor.rgb=vec3(clearCoatNdotV);\n#elif DEBUGMODE == 69 && defined(SUBSURFACE) && defined(SS_TRANSLUCENCY)\ngl_FragColor.rgb=transmittance;\n#elif DEBUGMODE == 70 && defined(SUBSURFACE) && defined(SS_REFRACTION)\ngl_FragColor.rgb=refractionTransmittance;\n\n#elif DEBUGMODE == 80 && defined(RADIANCEOCCLUSION)\ngl_FragColor.rgb=vec3(seo);\n#elif DEBUGMODE == 81 && defined(HORIZONOCCLUSION)\ngl_FragColor.rgb=vec3(eho);\n#elif DEBUGMODE == 82 && defined(MS_BRDF_ENERGY_CONSERVATION)\ngl_FragColor.rgb=vec3(energyConservationFactor);\n#elif DEBUGMODE == 83 && defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\ngl_FragColor.rgb=specularEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 84 && defined(CLEARCOAT) && defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\ngl_FragColor.rgb=clearCoatEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 85 && defined(SHEEN) && defined(REFLECTION)\ngl_FragColor.rgb=sheenEnvironmentReflectance;\n#define DEBUGMODE_GAMMA\n#elif DEBUGMODE == 86 && defined(ALPHABLEND)\ngl_FragColor.rgb=vec3(luminanceOverAlpha);\n#elif DEBUGMODE == 87\ngl_FragColor.rgb=vec3(alpha);\n#endif\ngl_FragColor.rgb*=vDebugMode.y;\n#ifdef DEBUGMODE_NORMALIZE\ngl_FragColor.rgb=normalize(gl_FragColor.rgb)*0.5+0.5;\n#endif\n#ifdef DEBUGMODE_GAMMA\ngl_FragColor.rgb=toGammaSpace(gl_FragColor.rgb);\n#endif\ngl_FragColor.a=1.0;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrDebug = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrDirectLightingFalloffFunctions.ts":
/*!*********************************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrDirectLightingFalloffFunctions.ts ***!
  \*********************************************************************/
/*! exports provided: pbrDirectLightingFalloffFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrDirectLightingFalloffFunctions", function() { return pbrDirectLightingFalloffFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrDirectLightingFalloffFunctions';
var shader = "float computeDistanceLightFalloff_Standard(vec3 lightOffset,float range)\n{\nreturn max(0.,1.0-length(lightOffset)/range);\n}\nfloat computeDistanceLightFalloff_Physical(float lightDistanceSquared)\n{\nreturn 1.0/maxEps(lightDistanceSquared);\n}\nfloat computeDistanceLightFalloff_GLTF(float lightDistanceSquared,float inverseSquaredRange)\n{\nfloat lightDistanceFalloff=1.0/maxEps(lightDistanceSquared);\nfloat factor=lightDistanceSquared*inverseSquaredRange;\nfloat attenuation=saturate(1.0-factor*factor);\nattenuation*=attenuation;\n\nlightDistanceFalloff*=attenuation;\nreturn lightDistanceFalloff;\n}\nfloat computeDistanceLightFalloff(vec3 lightOffset,float lightDistanceSquared,float range,float inverseSquaredRange)\n{\n#ifdef USEPHYSICALLIGHTFALLOFF\nreturn computeDistanceLightFalloff_Physical(lightDistanceSquared);\n#elif defined(USEGLTFLIGHTFALLOFF)\nreturn computeDistanceLightFalloff_GLTF(lightDistanceSquared,inverseSquaredRange);\n#else\nreturn computeDistanceLightFalloff_Standard(lightOffset,range);\n#endif\n}\nfloat computeDirectionalLightFalloff_Standard(vec3 lightDirection,vec3 directionToLightCenterW,float cosHalfAngle,float exponent)\n{\nfloat falloff=0.0;\nfloat cosAngle=maxEps(dot(-lightDirection,directionToLightCenterW));\nif (cosAngle>=cosHalfAngle)\n{\nfalloff=max(0.,pow(cosAngle,exponent));\n}\nreturn falloff;\n}\nfloat computeDirectionalLightFalloff_Physical(vec3 lightDirection,vec3 directionToLightCenterW,float cosHalfAngle)\n{\nconst float kMinusLog2ConeAngleIntensityRatio=6.64385618977;\n\n\n\n\n\nfloat concentrationKappa=kMinusLog2ConeAngleIntensityRatio/(1.0-cosHalfAngle);\n\n\nvec4 lightDirectionSpreadSG=vec4(-lightDirection*concentrationKappa,-concentrationKappa);\nfloat falloff=exp2(dot(vec4(directionToLightCenterW,1.0),lightDirectionSpreadSG));\nreturn falloff;\n}\nfloat computeDirectionalLightFalloff_GLTF(vec3 lightDirection,vec3 directionToLightCenterW,float lightAngleScale,float lightAngleOffset)\n{\n\n\n\nfloat cd=dot(-lightDirection,directionToLightCenterW);\nfloat falloff=saturate(cd*lightAngleScale+lightAngleOffset);\n\nfalloff*=falloff;\nreturn falloff;\n}\nfloat computeDirectionalLightFalloff(vec3 lightDirection,vec3 directionToLightCenterW,float cosHalfAngle,float exponent,float lightAngleScale,float lightAngleOffset)\n{\n#ifdef USEPHYSICALLIGHTFALLOFF\nreturn computeDirectionalLightFalloff_Physical(lightDirection,directionToLightCenterW,cosHalfAngle);\n#elif defined(USEGLTFLIGHTFALLOFF)\nreturn computeDirectionalLightFalloff_GLTF(lightDirection,directionToLightCenterW,lightAngleScale,lightAngleOffset);\n#else\nreturn computeDirectionalLightFalloff_Standard(lightDirection,directionToLightCenterW,cosHalfAngle,exponent);\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrDirectLightingFalloffFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrDirectLightingFunctions.ts":
/*!**************************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrDirectLightingFunctions.ts ***!
  \**************************************************************/
/*! exports provided: pbrDirectLightingFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrDirectLightingFunctions", function() { return pbrDirectLightingFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrDirectLightingFunctions';
var shader = "#define CLEARCOATREFLECTANCE90 1.0\n\nstruct lightingInfo\n{\nvec3 diffuse;\n#ifdef SPECULARTERM\nvec3 specular;\n#endif\n#ifdef CLEARCOAT\n\n\nvec4 clearCoat;\n#endif\n#ifdef SHEEN\nvec3 sheen;\n#endif\n};\n\nfloat adjustRoughnessFromLightProperties(float roughness,float lightRadius,float lightDistance) {\n#if defined(USEPHYSICALLIGHTFALLOFF) || defined(USEGLTFLIGHTFALLOFF)\n\nfloat lightRoughness=lightRadius/lightDistance;\n\nfloat totalRoughness=saturate(lightRoughness+roughness);\nreturn totalRoughness;\n#else\nreturn roughness;\n#endif\n}\nvec3 computeHemisphericDiffuseLighting(preLightingInfo info,vec3 lightColor,vec3 groundColor) {\nreturn mix(groundColor,lightColor,info.NdotL);\n}\nvec3 computeDiffuseLighting(preLightingInfo info,vec3 lightColor) {\nfloat diffuseTerm=diffuseBRDF_Burley(info.NdotL,info.NdotV,info.VdotH,info.roughness);\nreturn diffuseTerm*info.attenuation*info.NdotL*lightColor;\n}\nvec2 computeProjectionTextureDiffuseLightingUV(mat4 textureProjectionMatrix){\nvec4 strq=textureProjectionMatrix*vec4(vPositionW,1.0);\nstrq/=strq.w;\nreturn strq.xy;\n}\n#ifdef SS_TRANSLUCENCY\nvec3 computeDiffuseAndTransmittedLighting(preLightingInfo info,vec3 lightColor,vec3 transmittance) {\nfloat NdotL=absEps(info.NdotLUnclamped);\n\nfloat wrapNdotL=computeWrappedDiffuseNdotL(NdotL,0.02);\n\nfloat trAdapt=step(0.,info.NdotLUnclamped);\nvec3 transmittanceNdotL=mix(transmittance*wrapNdotL,vec3(wrapNdotL),trAdapt);\nfloat diffuseTerm=diffuseBRDF_Burley(NdotL,info.NdotV,info.VdotH,info.roughness);\nreturn diffuseTerm*transmittanceNdotL*info.attenuation*lightColor;\n}\n#endif\n#ifdef SPECULARTERM\nvec3 computeSpecularLighting(preLightingInfo info,vec3 N,vec3 reflectance0,vec3 reflectance90,float geometricRoughnessFactor,vec3 lightColor) {\nfloat NdotH=saturateEps(dot(N,info.H));\nfloat roughness=max(info.roughness,geometricRoughnessFactor);\nfloat alphaG=convertRoughnessToAverageSlope(roughness);\nvec3 fresnel=fresnelSchlickGGX(info.VdotH,reflectance0,reflectance90);\nfloat distribution=normalDistributionFunction_TrowbridgeReitzGGX(NdotH,alphaG);\n#ifdef BRDF_V_HEIGHT_CORRELATED\nfloat visibility=smithVisibility_GGXCorrelated(info.NdotL,info.NdotV,alphaG);\n#else\nfloat visibility=smithVisibility_TrowbridgeReitzGGXFast(info.NdotL,info.NdotV,alphaG);\n#endif\nvec3 specTerm=fresnel*distribution*visibility;\nreturn specTerm*info.attenuation*info.NdotL*lightColor;\n}\n#endif\n#ifdef ANISOTROPIC\nvec3 computeAnisotropicSpecularLighting(preLightingInfo info,vec3 V,vec3 N,vec3 T,vec3 B,float anisotropy,vec3 reflectance0,vec3 reflectance90,float geometricRoughnessFactor,vec3 lightColor) {\nfloat NdotH=saturateEps(dot(N,info.H));\nfloat TdotH=dot(T,info.H);\nfloat BdotH=dot(B,info.H);\nfloat TdotV=dot(T,V);\nfloat BdotV=dot(B,V);\nfloat TdotL=dot(T,info.L);\nfloat BdotL=dot(B,info.L);\nfloat alphaG=convertRoughnessToAverageSlope(info.roughness);\nvec2 alphaTB=getAnisotropicRoughness(alphaG,anisotropy);\nalphaTB=max(alphaTB,square(geometricRoughnessFactor));\nvec3 fresnel=fresnelSchlickGGX(info.VdotH,reflectance0,reflectance90);\nfloat distribution=normalDistributionFunction_BurleyGGX_Anisotropic(NdotH,TdotH,BdotH,alphaTB);\nfloat visibility=smithVisibility_GGXCorrelated_Anisotropic(info.NdotL,info.NdotV,TdotV,BdotV,TdotL,BdotL,alphaTB);\nvec3 specTerm=fresnel*distribution*visibility;\nreturn specTerm*info.attenuation*info.NdotL*lightColor;\n}\n#endif\n#ifdef CLEARCOAT\nvec4 computeClearCoatLighting(preLightingInfo info,vec3 Ncc,float geometricRoughnessFactor,float clearCoatIntensity,vec3 lightColor) {\nfloat NccdotL=saturateEps(dot(Ncc,info.L));\nfloat NccdotH=saturateEps(dot(Ncc,info.H));\nfloat clearCoatRoughness=max(info.roughness,geometricRoughnessFactor);\nfloat alphaG=convertRoughnessToAverageSlope(clearCoatRoughness);\nfloat fresnel=fresnelSchlickGGX(info.VdotH,vClearCoatRefractionParams.x,CLEARCOATREFLECTANCE90);\nfresnel*=clearCoatIntensity;\nfloat distribution=normalDistributionFunction_TrowbridgeReitzGGX(NccdotH,alphaG);\nfloat visibility=visibility_Kelemen(info.VdotH);\nfloat clearCoatTerm=fresnel*distribution*visibility;\nreturn vec4(\nclearCoatTerm*info.attenuation*NccdotL*lightColor,\n1.0-fresnel\n);\n}\nvec3 computeClearCoatLightingAbsorption(float NdotVRefract,vec3 L,vec3 Ncc,vec3 clearCoatColor,float clearCoatThickness,float clearCoatIntensity) {\nvec3 LRefract=-refract(L,Ncc,vClearCoatRefractionParams.y);\nfloat NdotLRefract=saturateEps(dot(Ncc,LRefract));\nvec3 absorption=computeClearCoatAbsorption(NdotVRefract,NdotLRefract,clearCoatColor,clearCoatThickness,clearCoatIntensity);\nreturn absorption;\n}\n#endif\n#ifdef SHEEN\nvec3 computeSheenLighting(preLightingInfo info,vec3 N,vec3 reflectance0,vec3 reflectance90,float geometricRoughnessFactor,vec3 lightColor) {\nfloat NdotH=saturateEps(dot(N,info.H));\nfloat roughness=max(info.roughness,geometricRoughnessFactor);\nfloat alphaG=convertRoughnessToAverageSlope(roughness);\n\n\nvec3 fresnel=reflectance0;\nfloat distribution=normalDistributionFunction_CharlieSheen(NdotH,alphaG);\nfloat visibility=visibility_Ashikhmin(info.NdotL,info.NdotV);\nvec3 sheenTerm=fresnel*distribution*visibility;\nreturn sheenTerm*info.attenuation*info.NdotL*lightColor;\n}\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrDirectLightingFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrDirectLightingSetupFunctions.ts":
/*!*******************************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrDirectLightingSetupFunctions.ts ***!
  \*******************************************************************/
/*! exports provided: pbrDirectLightingSetupFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrDirectLightingSetupFunctions", function() { return pbrDirectLightingSetupFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrDirectLightingSetupFunctions';
var shader = "\nstruct preLightingInfo\n{\n\nvec3 lightOffset;\nfloat lightDistanceSquared;\nfloat lightDistance;\n\nfloat attenuation;\n\nvec3 L;\nvec3 H;\nfloat NdotV;\nfloat NdotLUnclamped;\nfloat NdotL;\nfloat VdotH;\nfloat roughness;\n};\npreLightingInfo computePointAndSpotPreLightingInfo(vec4 lightData,vec3 V,vec3 N) {\npreLightingInfo result;\n\nresult.lightOffset=lightData.xyz-vPositionW;\nresult.lightDistanceSquared=dot(result.lightOffset,result.lightOffset);\n\nresult.lightDistance=sqrt(result.lightDistanceSquared);\n\nresult.L=normalize(result.lightOffset);\nresult.H=normalize(V+result.L);\nresult.VdotH=saturate(dot(V,result.H));\nresult.NdotLUnclamped=dot(N,result.L);\nresult.NdotL=saturateEps(result.NdotLUnclamped);\nreturn result;\n}\npreLightingInfo computeDirectionalPreLightingInfo(vec4 lightData,vec3 V,vec3 N) {\npreLightingInfo result;\n\nresult.lightDistance=length(-lightData.xyz);\n\nresult.L=normalize(-lightData.xyz);\nresult.H=normalize(V+result.L);\nresult.VdotH=saturate(dot(V,result.H));\nresult.NdotLUnclamped=dot(N,result.L);\nresult.NdotL=saturateEps(result.NdotLUnclamped);\nreturn result;\n}\npreLightingInfo computeHemisphericPreLightingInfo(vec4 lightData,vec3 V,vec3 N) {\npreLightingInfo result;\n\n\nresult.NdotL=dot(N,lightData.xyz)*0.5+0.5;\nresult.NdotL=saturateEps(result.NdotL);\nresult.NdotLUnclamped=result.NdotL;\n#ifdef SPECULARTERM\nresult.L=normalize(lightData.xyz);\nresult.H=normalize(V+result.L);\nresult.VdotH=saturate(dot(V,result.H));\n#endif\nreturn result;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrDirectLightingSetupFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrFragmentDeclaration.ts":
/*!**********************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrFragmentDeclaration.ts ***!
  \**********************************************************/
/*! exports provided: pbrFragmentDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrFragmentDeclaration", function() { return pbrFragmentDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrFragmentDeclaration';
var shader = "uniform vec3 vReflectionColor;\nuniform vec4 vAlbedoColor;\n\nuniform vec4 vLightingIntensity;\nuniform vec4 vReflectivityColor;\nuniform vec3 vEmissiveColor;\nuniform float visibility;\nuniform vec4 vEyePosition;\nuniform vec3 vAmbientColor;\n\n#ifdef ALBEDO\nuniform vec2 vAlbedoInfos;\n#endif\n#ifdef AMBIENT\nuniform vec4 vAmbientInfos;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform vec2 vTangentSpaceParams;\n#endif\n#ifdef OPACITY\nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\n#endif\n#ifdef REFLECTIVITY\nuniform vec3 vReflectivityInfos;\n#endif\n#ifdef MICROSURFACEMAP\nuniform vec2 vMicroSurfaceSamplerInfos;\n#endif\n\n#if defined(REFLECTIONMAP_SPHERICAL) || defined(REFLECTIONMAP_PROJECTION) || defined(SS_REFRACTION)\nuniform mat4 view;\n#endif\n\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\nuniform mat4 reflectionMatrix;\nuniform vec3 vReflectionMicrosurfaceInfos;\n#if defined(USE_LOCAL_REFLECTIONMAP_CUBIC) && defined(REFLECTIONMAP_CUBIC)\nuniform vec3 vReflectionPosition;\nuniform vec3 vReflectionSize;\n#endif\n#endif\n\n#ifdef CLEARCOAT\nuniform vec2 vClearCoatParams;\nuniform vec4 vClearCoatRefractionParams;\n#ifdef CLEARCOAT_TEXTURE\nuniform vec2 vClearCoatInfos;\nuniform mat4 clearCoatMatrix;\n#endif\n#ifdef CLEARCOAT_BUMP\nuniform vec2 vClearCoatBumpInfos;\nuniform vec2 vClearCoatTangentSpaceParams;\nuniform mat4 clearCoatBumpMatrix;\n#endif\n#ifdef CLEARCOAT_TINT\nuniform vec4 vClearCoatTintParams;\nuniform float clearCoatColorAtDistance;\n#ifdef CLEARCOAT_TINT_TEXTURE\nuniform vec2 vClearCoatTintInfos;\nuniform mat4 clearCoatTintMatrix;\n#endif\n#endif\n#endif\n\n#ifdef ANISOTROPIC\nuniform vec3 vAnisotropy;\n#ifdef ANISOTROPIC_TEXTURE\nuniform vec2 vAnisotropyInfos;\nuniform mat4 anisotropyMatrix;\n#endif\n#endif\n\n#ifdef SHEEN\nuniform vec4 vSheenColor;\n#ifdef SHEEN_TEXTURE\nuniform vec2 vSheenInfos;\nuniform mat4 sheenMatrix;\n#endif\n#endif\n\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\nuniform vec3 vRefractionMicrosurfaceInfos;\nuniform vec4 vRefractionInfos;\nuniform mat4 refractionMatrix;\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nuniform vec2 vThicknessInfos;\nuniform mat4 thicknessMatrix;;\n#endif\nuniform vec2 vThicknessParam;\nuniform vec3 vDiffusionDistance;\nuniform vec4 vTintColor;\nuniform vec3 vSubSurfaceIntensity;\n#endif\n#if DEBUGMODE>0\nuniform vec2 vDebugMode;\n#endif\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;\nuniform vec3 vSphericalL1_1;\nuniform vec3 vSphericalL10;\nuniform vec3 vSphericalL11;\nuniform vec3 vSphericalL2_2;\nuniform vec3 vSphericalL2_1;\nuniform vec3 vSphericalL20;\nuniform vec3 vSphericalL21;\nuniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;\nuniform vec3 vSphericalY;\nuniform vec3 vSphericalZ;\nuniform vec3 vSphericalXX_ZZ;\nuniform vec3 vSphericalYY_ZZ;\nuniform vec3 vSphericalZZ;\nuniform vec3 vSphericalXY;\nuniform vec3 vSphericalYZ;\nuniform vec3 vSphericalZX;\n#endif\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrFragmentDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrFragmentExtraDeclaration.ts":
/*!***************************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrFragmentExtraDeclaration.ts ***!
  \***************************************************************/
/*! exports provided: pbrFragmentExtraDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrFragmentExtraDeclaration", function() { return pbrFragmentExtraDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrFragmentExtraDeclaration';
var shader = "\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vec3 vEnvironmentIrradiance;\n#endif\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#if DEBUGMODE>0\nvarying vec4 vClipSpacePosition;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrFragmentExtraDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.ts":
/*!******************************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.ts ***!
  \******************************************************************/
/*! exports provided: pbrFragmentSamplersDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrFragmentSamplersDeclaration", function() { return pbrFragmentSamplersDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrFragmentSamplersDeclaration';
var shader = "#ifdef ENVIRONMENTBRDF\nuniform sampler2D environmentBrdfSampler;\n#endif\n\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\n#define sampleReflection(s,c) textureCube(s,c)\nuniform samplerCube reflectionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleReflectionLod(s,c,l) textureCubeLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;\nuniform samplerCube reflectionSamplerHigh;\n#endif\n#ifdef USEIRRADIANCEMAP\nuniform samplerCube irradianceSampler;\n#endif\n#else\n#define sampleReflection(s,c) texture2D(s,c)\nuniform sampler2D reflectionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleReflectionLod(s,c,l) texture2DLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;\nuniform samplerCube reflectionSamplerHigh;\n#endif\n#ifdef USEIRRADIANCEMAP\nuniform samplerCube irradianceSampler;\n#endif\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#endif\n#ifdef ALBEDO\n#if ALBEDODIRECTUV == 1\n#define vAlbedoUV vMainUV1\n#elif ALBEDODIRECTUV == 2\n#define vAlbedoUV vMainUV2\n#else\nvarying vec2 vAlbedoUV;\n#endif\nuniform sampler2D albedoSampler;\n#endif\n#ifdef REFLECTIVITY\n#if REFLECTIVITYDIRECTUV == 1\n#define vReflectivityUV vMainUV1\n#elif REFLECTIVITYDIRECTUV == 2\n#define vReflectivityUV vMainUV2\n#else\nvarying vec2 vReflectivityUV;\n#endif\nuniform sampler2D reflectivitySampler;\n#endif\n#ifdef AMBIENT\n#if AMBIENTDIRECTUV == 1\n#define vAmbientUV vMainUV1\n#elif AMBIENTDIRECTUV == 2\n#define vAmbientUV vMainUV2\n#else\nvarying vec2 vAmbientUV;\n#endif\nuniform sampler2D ambientSampler;\n#endif\n#ifdef EMISSIVE\n#if EMISSIVEDIRECTUV == 1\n#define vEmissiveUV vMainUV1\n#elif EMISSIVEDIRECTUV == 2\n#define vEmissiveUV vMainUV2\n#else\nvarying vec2 vEmissiveUV;\n#endif\nuniform sampler2D emissiveSampler;\n#endif\n#ifdef BUMP\n#if BUMPDIRECTUV == 1\n#define vBumpUV vMainUV1\n#elif BUMPDIRECTUV == 2\n#define vBumpUV vMainUV2\n#else\nvarying vec2 vBumpUV;\n#endif\nuniform sampler2D bumpSampler;\n#endif\n#ifdef OPACITY\n#if OPACITYDIRECTUV == 1\n#define vOpacityUV vMainUV1\n#elif OPACITYDIRECTUV == 2\n#define vOpacityUV vMainUV2\n#else\nvarying vec2 vOpacityUV;\n#endif\nuniform sampler2D opacitySampler;\n#endif\n#ifdef LIGHTMAP\n#if LIGHTMAPDIRECTUV == 1\n#define vLightmapUV vMainUV1\n#elif LIGHTMAPDIRECTUV == 2\n#define vLightmapUV vMainUV2\n#else\nvarying vec2 vLightmapUV;\n#endif\nuniform sampler2D lightmapSampler;\n#endif\n#ifdef MICROSURFACEMAP\n#if MICROSURFACEMAPDIRECTUV == 1\n#define vMicroSurfaceSamplerUV vMainUV1\n#elif MICROSURFACEMAPDIRECTUV == 2\n#define vMicroSurfaceSamplerUV vMainUV2\n#else\nvarying vec2 vMicroSurfaceSamplerUV;\n#endif\nuniform sampler2D microSurfaceSampler;\n#endif\n#ifdef CLEARCOAT\n#ifdef CLEARCOAT_TEXTURE\n#if CLEARCOAT_TEXTUREDIRECTUV == 1\n#define vClearCoatUV vMainUV1\n#elif CLEARCOAT_TEXTUREDIRECTUV == 2\n#define vClearCoatUV vMainUV2\n#else\nvarying vec2 vClearCoatUV;\n#endif\nuniform sampler2D clearCoatSampler;\n#endif\n#ifdef CLEARCOAT_BUMP\n#if CLEARCOAT_BUMPDIRECTUV == 1\n#define vClearCoatBumpUV vMainUV1\n#elif CLEARCOAT_BUMPDIRECTUV == 2\n#define vClearCoatBumpUV vMainUV2\n#else\nvarying vec2 vClearCoatBumpUV;\n#endif\nuniform sampler2D clearCoatBumpSampler;\n#endif\n#ifdef CLEARCOAT_TINT_TEXTURE\n#if CLEARCOAT_TINT_TEXTUREDIRECTUV == 1\n#define vClearCoatTintUV vMainUV1\n#elif CLEARCOAT_TINT_TEXTUREDIRECTUV == 2\n#define vClearCoatTintUV vMainUV2\n#else\nvarying vec2 vClearCoatTintUV;\n#endif\nuniform sampler2D clearCoatTintSampler;\n#endif\n#endif\n#ifdef SHEEN\n#ifdef SHEEN_TEXTURE\n#if SHEEN_TEXTUREDIRECTUV == 1\n#define vSheenUV vMainUV1\n#elif SHEEN_TEXTUREDIRECTUV == 2\n#define vSheenUV vMainUV2\n#else\nvarying vec2 vSheenUV;\n#endif\nuniform sampler2D sheenSampler;\n#endif\n#endif\n#ifdef ANISOTROPIC\n#ifdef ANISOTROPIC_TEXTURE\n#if ANISOTROPIC_TEXTUREDIRECTUV == 1\n#define vAnisotropyUV vMainUV1\n#elif ANISOTROPIC_TEXTUREDIRECTUV == 2\n#define vAnisotropyUV vMainUV2\n#else\nvarying vec2 vAnisotropyUV;\n#endif\nuniform sampler2D anisotropySampler;\n#endif\n#endif\n\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\n#ifdef SS_REFRACTIONMAP_3D\n#define sampleRefraction(s,c) textureCube(s,c)\nuniform samplerCube refractionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleRefractionLod(s,c,l) textureCubeLodEXT(s,c,l)\n#else\nuniform samplerCube refractionSamplerLow;\nuniform samplerCube refractionSamplerHigh;\n#endif\n#else\n#define sampleRefraction(s,c) texture2D(s,c)\nuniform sampler2D refractionSampler;\n#ifdef LODBASEDMICROSFURACE\n#define sampleRefractionLod(s,c,l) texture2DLodEXT(s,c,l)\n#else\nuniform samplerCube refractionSamplerLow;\nuniform samplerCube refractionSamplerHigh;\n#endif\n#endif\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\n#if SS_THICKNESSANDMASK_TEXTUREDIRECTUV == 1\n#define vThicknessUV vMainUV1\n#elif SS_THICKNESSANDMASK_TEXTUREDIRECTUV == 2\n#define vThicknessUV vMainUV2\n#else\nvarying vec2 vThicknessUV;\n#endif\nuniform sampler2D thicknessSampler;\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrFragmentSamplersDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrHelperFunctions.ts":
/*!******************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrHelperFunctions.ts ***!
  \******************************************************/
/*! exports provided: pbrHelperFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrHelperFunctions", function() { return pbrHelperFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrHelperFunctions';
var shader = "\n#define RECIPROCAL_PI2 0.15915494\n#define RECIPROCAL_PI 0.31830988618\n\n#define MINIMUMVARIANCE 0.0005\nfloat convertRoughnessToAverageSlope(float roughness)\n{\n\nreturn square(roughness)+MINIMUMVARIANCE;\n}\nfloat fresnelGrazingReflectance(float reflectance0) {\n\n\nfloat reflectance90=saturate(reflectance0*25.0);\nreturn reflectance90;\n}\nvec2 getAARoughnessFactors(vec3 normalVector) {\n#ifdef SPECULARAA\nvec3 nDfdx=dFdx(normalVector.xyz);\nvec3 nDfdy=dFdy(normalVector.xyz);\nfloat slopeSquare=max(dot(nDfdx,nDfdx),dot(nDfdy,nDfdy));\n\nfloat geometricRoughnessFactor=pow(saturate(slopeSquare),0.333);\n\nfloat geometricAlphaGFactor=sqrt(slopeSquare);\n\ngeometricAlphaGFactor*=0.75;\nreturn vec2(geometricRoughnessFactor,geometricAlphaGFactor);\n#else\nreturn vec2(0.);\n#endif\n}\n#ifdef ANISOTROPIC\n\n\nvec2 getAnisotropicRoughness(float alphaG,float anisotropy) {\nfloat alphaT=max(alphaG*(1.0+anisotropy),MINIMUMVARIANCE);\nfloat alphaB=max(alphaG*(1.0-anisotropy),MINIMUMVARIANCE);\nreturn vec2(alphaT,alphaB);\n}\n\n\nvec3 getAnisotropicBentNormals(const vec3 T,const vec3 B,const vec3 N,const vec3 V,float anisotropy) {\nvec3 anisotropicFrameDirection=anisotropy>=0.0 ? B : T;\nvec3 anisotropicFrameTangent=cross(normalize(anisotropicFrameDirection),V);\nvec3 anisotropicFrameNormal=cross(anisotropicFrameTangent,anisotropicFrameDirection);\nvec3 anisotropicNormal=normalize(mix(N,anisotropicFrameNormal,abs(anisotropy)));\nreturn anisotropicNormal;\n\n}\n#endif\n#if defined(CLEARCOAT) || defined(SS_REFRACTION)\n\n\n\nvec3 cocaLambert(vec3 alpha,float distance) {\nreturn exp(-alpha*distance);\n}\n\nvec3 cocaLambert(float NdotVRefract,float NdotLRefract,vec3 alpha,float thickness) {\nreturn cocaLambert(alpha,(thickness*((NdotLRefract+NdotVRefract)/(NdotLRefract*NdotVRefract))));\n}\n\nvec3 computeColorAtDistanceInMedia(vec3 color,float distance) {\nreturn -log(color)/distance;\n}\nvec3 computeClearCoatAbsorption(float NdotVRefract,float NdotLRefract,vec3 clearCoatColor,float clearCoatThickness,float clearCoatIntensity) {\nvec3 clearCoatAbsorption=mix(vec3(1.0),\ncocaLambert(NdotVRefract,NdotLRefract,clearCoatColor,clearCoatThickness),\nclearCoatIntensity);\nreturn clearCoatAbsorption;\n}\n#endif\n\n\n\n\n#ifdef MICROSURFACEAUTOMATIC\nfloat computeDefaultMicroSurface(float microSurface,vec3 reflectivityColor)\n{\nconst float kReflectivityNoAlphaWorkflow_SmoothnessMax=0.95;\nfloat reflectivityLuminance=getLuminance(reflectivityColor);\nfloat reflectivityLuma=sqrt(reflectivityLuminance);\nmicroSurface=reflectivityLuma*kReflectivityNoAlphaWorkflow_SmoothnessMax;\nreturn microSurface;\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrHelperFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrIBLFunctions.ts":
/*!***************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrIBLFunctions.ts ***!
  \***************************************************/
/*! exports provided: pbrIBLFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrIBLFunctions", function() { return pbrIBLFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrIBLFunctions';
var shader = "#if defined(REFLECTION) || defined(SS_REFRACTION)\nfloat getLodFromAlphaG(float cubeMapDimensionPixels,float microsurfaceAverageSlope) {\nfloat microsurfaceAverageSlopeTexels=cubeMapDimensionPixels*microsurfaceAverageSlope;\nfloat lod=log2(microsurfaceAverageSlopeTexels);\nreturn lod;\n}\nfloat getLinearLodFromRoughness(float cubeMapDimensionPixels,float roughness) {\nfloat lod=log2(cubeMapDimensionPixels)*roughness;\nreturn lod;\n}\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(RADIANCEOCCLUSION)\nfloat environmentRadianceOcclusion(float ambientOcclusion,float NdotVUnclamped) {\n\n\nfloat temp=NdotVUnclamped+ambientOcclusion;\nreturn saturate(square(temp)-1.0+ambientOcclusion);\n}\n#endif\n#if defined(ENVIRONMENTBRDF) && defined(HORIZONOCCLUSION)\nfloat environmentHorizonOcclusion(vec3 view,vec3 normal) {\n\nvec3 reflection=reflect(view,normal);\nfloat temp=saturate(1.0+1.1*dot(reflection,normal));\nreturn square(temp);\n}\n#endif\n\n\n\n\n#if defined(LODINREFLECTIONALPHA) || defined(SS_LODINREFRACTIONALPHA)\n\n\n#define UNPACK_LOD(x) (1.0-x)*255.0\nfloat getLodFromAlphaG(float cubeMapDimensionPixels,float alphaG,float NdotV) {\nfloat microsurfaceAverageSlope=alphaG;\n\n\n\n\n\n\nmicrosurfaceAverageSlope*=sqrt(abs(NdotV));\nreturn getLodFromAlphaG(cubeMapDimensionPixels,microsurfaceAverageSlope);\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrIBLFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrUboDeclaration.ts":
/*!*****************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrUboDeclaration.ts ***!
  \*****************************************************/
/*! exports provided: pbrUboDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrUboDeclaration", function() { return pbrUboDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrUboDeclaration';
var shader = "layout(std140,column_major) uniform;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nuniform Scene\n{\nmat4 viewProjection;\n#ifdef MULTIVIEW\nmat4 viewProjectionR;\n#endif\nmat4 view;\n};\nuniform Material\n{\nvec2 vAlbedoInfos;\nvec4 vAmbientInfos;\nvec2 vOpacityInfos;\nvec2 vEmissiveInfos;\nvec2 vLightmapInfos;\nvec3 vReflectivityInfos;\nvec2 vMicroSurfaceSamplerInfos;\nvec2 vReflectionInfos;\nvec3 vReflectionPosition;\nvec3 vReflectionSize;\nvec3 vBumpInfos;\nmat4 albedoMatrix;\nmat4 ambientMatrix;\nmat4 opacityMatrix;\nmat4 emissiveMatrix;\nmat4 lightmapMatrix;\nmat4 reflectivityMatrix;\nmat4 microSurfaceSamplerMatrix;\nmat4 bumpMatrix;\nvec2 vTangentSpaceParams;\nmat4 reflectionMatrix;\nvec3 vReflectionColor;\nvec4 vAlbedoColor;\nvec4 vLightingIntensity;\nvec3 vReflectionMicrosurfaceInfos;\nfloat pointSize;\nvec4 vReflectivityColor;\nvec3 vEmissiveColor;\nvec4 vEyePosition;\nvec3 vAmbientColor;\nvec2 vDebugMode;\nvec2 vClearCoatParams;\nvec4 vClearCoatRefractionParams;\nvec2 vClearCoatInfos;\nmat4 clearCoatMatrix;\nvec2 vClearCoatBumpInfos;\nvec2 vClearCoatTangentSpaceParams;\nmat4 clearCoatBumpMatrix;\nvec4 vClearCoatTintParams;\nfloat clearCoatColorAtDistance;\nvec2 vClearCoatTintInfos;\nmat4 clearCoatTintMatrix;\nvec3 vAnisotropy;\nvec2 vAnisotropyInfos;\nmat4 anisotropyMatrix;\nvec4 vSheenColor;\nvec2 vSheenInfos;\nmat4 sheenMatrix;\nvec3 vRefractionMicrosurfaceInfos;\nvec4 vRefractionInfos;\nmat4 refractionMatrix;\nvec2 vThicknessInfos;\nmat4 thicknessMatrix;\nvec2 vThicknessParam;\nvec3 vDiffusionDistance;\nvec4 vTintColor;\nvec3 vSubSurfaceIntensity;\nvec3 vSphericalL00;\nvec3 vSphericalL1_1;\nvec3 vSphericalL10;\nvec3 vSphericalL11;\nvec3 vSphericalL2_2;\nvec3 vSphericalL2_1;\nvec3 vSphericalL20;\nvec3 vSphericalL21;\nvec3 vSphericalL22;\nvec3 vSphericalX;\nvec3 vSphericalY;\nvec3 vSphericalZ;\nvec3 vSphericalXX_ZZ;\nvec3 vSphericalYY_ZZ;\nvec3 vSphericalZZ;\nvec3 vSphericalXY;\nvec3 vSphericalYZ;\nvec3 vSphericalZX;\n};\nuniform Mesh\n{\nmat4 world;\nfloat visibility;\n};";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrUboDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pbrVertexDeclaration.ts":
/*!********************************************************!*\
  !*** ./Shaders/ShadersInclude/pbrVertexDeclaration.ts ***!
  \********************************************************/
/*! exports provided: pbrVertexDeclaration */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrVertexDeclaration", function() { return pbrVertexDeclaration; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pbrVertexDeclaration';
var shader = "uniform mat4 view;\nuniform mat4 viewProjection;\nuniform mat4 world;\n#ifdef ALBEDO\nuniform mat4 albedoMatrix;\nuniform vec2 vAlbedoInfos;\n#endif\n#ifdef AMBIENT\nuniform mat4 ambientMatrix;\nuniform vec4 vAmbientInfos;\n#endif\n#ifdef OPACITY\nuniform mat4 opacityMatrix;\nuniform vec2 vOpacityInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\nuniform mat4 emissiveMatrix;\n#endif\n#ifdef LIGHTMAP\nuniform vec2 vLightmapInfos;\nuniform mat4 lightmapMatrix;\n#endif\n#ifdef REFLECTIVITY\nuniform vec3 vReflectivityInfos;\nuniform mat4 reflectivityMatrix;\n#endif\n#ifdef MICROSURFACEMAP\nuniform vec2 vMicroSurfaceSamplerInfos;\nuniform mat4 microSurfaceSamplerMatrix;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform mat4 bumpMatrix;\n#endif\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n\n#ifdef REFLECTION\nuniform vec2 vReflectionInfos;\nuniform mat4 reflectionMatrix;\n#endif\n\n#ifdef CLEARCOAT\n#ifdef CLEARCOAT_TEXTURE\nuniform vec2 vClearCoatInfos;\nuniform mat4 clearCoatMatrix;\n#endif\n#ifdef CLEARCOAT_BUMP\nuniform vec2 vClearCoatBumpInfos;\nuniform mat4 clearCoatBumpMatrix;\n#endif\n#ifdef CLEARCOAT_TINT_TEXTURE\nuniform vec2 vClearCoatTintInfos;\nuniform mat4 clearCoatTintMatrix;\n#endif\n#endif\n\n#ifdef ANISOTROPIC\n#ifdef ANISOTROPIC_TEXTURE\nuniform vec2 vAnisotropyInfos;\nuniform mat4 anisotropyMatrix;\n#endif\n#endif\n\n#ifdef SHEEN\n#ifdef SHEEN_TEXTURE\nuniform vec2 vSheenInfos;\nuniform mat4 sheenMatrix;\n#endif\n#endif\n\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\nuniform vec4 vRefractionInfos;\nuniform mat4 refractionMatrix;\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nuniform vec2 vThicknessInfos;\nuniform mat4 thicknessMatrix;;\n#endif\n#endif\n#ifdef NORMAL\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#ifdef SPHERICAL_HARMONICS\nuniform vec3 vSphericalL00;\nuniform vec3 vSphericalL1_1;\nuniform vec3 vSphericalL10;\nuniform vec3 vSphericalL11;\nuniform vec3 vSphericalL2_2;\nuniform vec3 vSphericalL2_1;\nuniform vec3 vSphericalL20;\nuniform vec3 vSphericalL21;\nuniform vec3 vSphericalL22;\n#else\nuniform vec3 vSphericalX;\nuniform vec3 vSphericalY;\nuniform vec3 vSphericalZ;\nuniform vec3 vSphericalXX_ZZ;\nuniform vec3 vSphericalYY_ZZ;\nuniform vec3 vSphericalZZ;\nuniform vec3 vSphericalXY;\nuniform vec3 vSphericalYZ;\nuniform vec3 vSphericalZX;\n#endif\n#endif\n#endif\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pbrVertexDeclaration = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/pointCloudVertex.ts":
/*!****************************************************!*\
  !*** ./Shaders/ShadersInclude/pointCloudVertex.ts ***!
  \****************************************************/
/*! exports provided: pointCloudVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pointCloudVertex", function() { return pointCloudVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'pointCloudVertex';
var shader = "#ifdef POINTSIZE\ngl_PointSize=pointSize;\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var pointCloudVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/reflectionFunction.ts":
/*!******************************************************!*\
  !*** ./Shaders/ShadersInclude/reflectionFunction.ts ***!
  \******************************************************/
/*! exports provided: reflectionFunction */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reflectionFunction", function() { return reflectionFunction; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'reflectionFunction';
var shader = "vec3 parallaxCorrectNormal( vec3 vertexPos,vec3 origVec,vec3 cubeSize,vec3 cubePos ) {\n\nvec3 invOrigVec=vec3(1.0,1.0,1.0)/origVec;\nvec3 halfSize=cubeSize*0.5;\nvec3 intersecAtMaxPlane=(cubePos+halfSize-vertexPos)*invOrigVec;\nvec3 intersecAtMinPlane=(cubePos-halfSize-vertexPos)*invOrigVec;\n\nvec3 largestIntersec=max(intersecAtMaxPlane,intersecAtMinPlane);\n\nfloat distance=min(min(largestIntersec.x,largestIntersec.y),largestIntersec.z);\n\nvec3 intersectPositionWS=vertexPos+origVec*distance;\n\nreturn intersectPositionWS-cubePos;\n}\nvec3 computeFixedEquirectangularCoords(vec4 worldPos,vec3 worldNormal,vec3 direction)\n{\nfloat lon=atan(direction.z,direction.x);\nfloat lat=acos(direction.y);\nvec2 sphereCoords=vec2(lon,lat)*RECIPROCAL_PI2*2.0;\nfloat s=sphereCoords.x*0.5+0.5;\nfloat t=sphereCoords.y;\nreturn vec3(s,t,0);\n}\nvec3 computeMirroredFixedEquirectangularCoords(vec4 worldPos,vec3 worldNormal,vec3 direction)\n{\nfloat lon=atan(direction.z,direction.x);\nfloat lat=acos(direction.y);\nvec2 sphereCoords=vec2(lon,lat)*RECIPROCAL_PI2*2.0;\nfloat s=sphereCoords.x*0.5+0.5;\nfloat t=sphereCoords.y;\nreturn vec3(1.0-s,t,0);\n}\nvec3 computeEquirectangularCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix)\n{\nvec3 cameraToVertex=normalize(worldPos.xyz-eyePosition);\nvec3 r=normalize(reflect(cameraToVertex,worldNormal));\nr=vec3(reflectionMatrix*vec4(r,0));\nfloat lon=atan(r.z,r.x);\nfloat lat=acos(r.y);\nvec2 sphereCoords=vec2(lon,lat)*RECIPROCAL_PI2*2.0;\nfloat s=sphereCoords.x*0.5+0.5;\nfloat t=sphereCoords.y;\nreturn vec3(s,t,0);\n}\nvec3 computeSphericalCoords(vec4 worldPos,vec3 worldNormal,mat4 view,mat4 reflectionMatrix)\n{\nvec3 viewDir=normalize(vec3(view*worldPos));\nvec3 viewNormal=normalize(vec3(view*vec4(worldNormal,0.0)));\nvec3 r=reflect(viewDir,viewNormal);\nr=vec3(reflectionMatrix*vec4(r,0));\nr.z=r.z-1.0;\nfloat m=2.0*length(r);\nreturn vec3(r.x/m+0.5,1.0-r.y/m-0.5,0);\n}\nvec3 computePlanarCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix)\n{\nvec3 viewDir=worldPos.xyz-eyePosition;\nvec3 coords=normalize(reflect(viewDir,worldNormal));\nreturn vec3(reflectionMatrix*vec4(coords,1));\n}\nvec3 computeCubicCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix)\n{\nvec3 viewDir=normalize(worldPos.xyz-eyePosition);\n\nvec3 coords=reflect(viewDir,worldNormal);\ncoords=vec3(reflectionMatrix*vec4(coords,0));\n#ifdef INVERTCUBICMAP\ncoords.y*=-1.0;\n#endif\nreturn coords;\n}\nvec3 computeCubicLocalCoords(vec4 worldPos,vec3 worldNormal,vec3 eyePosition,mat4 reflectionMatrix,vec3 reflectionSize,vec3 reflectionPosition)\n{\nvec3 viewDir=normalize(worldPos.xyz-eyePosition);\n\nvec3 coords=reflect(viewDir,worldNormal);\ncoords=parallaxCorrectNormal(worldPos.xyz,coords,reflectionSize,reflectionPosition);\ncoords=vec3(reflectionMatrix*vec4(coords,0));\n#ifdef INVERTCUBICMAP\ncoords.y*=-1.0;\n#endif\nreturn coords;\n}\nvec3 computeProjectionCoords(vec4 worldPos,mat4 view,mat4 reflectionMatrix)\n{\nreturn vec3(reflectionMatrix*(view*worldPos));\n}\nvec3 computeSkyBoxCoords(vec3 positionW,mat4 reflectionMatrix)\n{\nreturn vec3(reflectionMatrix*vec4(positionW,0));\n}\n#ifdef REFLECTION\nvec3 computeReflectionCoords(vec4 worldPos,vec3 worldNormal)\n{\n#ifdef REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED\nvec3 direction=normalize(vDirectionW);\nreturn computeMirroredFixedEquirectangularCoords(worldPos,worldNormal,direction);\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR_FIXED\nvec3 direction=normalize(vDirectionW);\nreturn computeFixedEquirectangularCoords(worldPos,worldNormal,direction);\n#endif\n#ifdef REFLECTIONMAP_EQUIRECTANGULAR\nreturn computeEquirectangularCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_SPHERICAL\nreturn computeSphericalCoords(worldPos,worldNormal,view,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_PLANAR\nreturn computePlanarCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_CUBIC\n#ifdef USE_LOCAL_REFLECTIONMAP_CUBIC\nreturn computeCubicLocalCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix,vReflectionSize,vReflectionPosition);\n#else\nreturn computeCubicCoords(worldPos,worldNormal,vEyePosition.xyz,reflectionMatrix);\n#endif\n#endif\n#ifdef REFLECTIONMAP_PROJECTION\nreturn computeProjectionCoords(worldPos,view,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nreturn computeSkyBoxCoords(vPositionUVW,reflectionMatrix);\n#endif\n#ifdef REFLECTIONMAP_EXPLICIT\nreturn vec3(0,0,0);\n#endif\n}\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var reflectionFunction = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/shadowsFragmentFunctions.ts":
/*!************************************************************!*\
  !*** ./Shaders/ShadersInclude/shadowsFragmentFunctions.ts ***!
  \************************************************************/
/*! exports provided: shadowsFragmentFunctions */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowsFragmentFunctions", function() { return shadowsFragmentFunctions; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'shadowsFragmentFunctions';
var shader = "#ifdef SHADOWS\n#ifndef SHADOWFLOAT\n\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}\n#endif\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{\nfloat mask=smoothstep(1.0-frustumEdgeFalloff,1.0,clamp(dot(clipSpace,clipSpace),0.,1.));\nreturn mix(value,1.0,mask);\n}\nfloat computeShadowCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nif (depth>shadow)\n{\nreturn darkness;\n}\nreturn 1.0;\n}\nfloat computeShadowWithPoissonSamplingCube(vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\nfloat visibility=1.;\nvec3 poissonDisk[4];\npoissonDisk[0]=vec3(-1.0,1.0,-1.0);\npoissonDisk[1]=vec3(1.0,-1.0,-1.0);\npoissonDisk[2]=vec3(-1.0,-1.0,-1.0);\npoissonDisk[3]=vec3(1.0,-1.0,1.0);\n\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);\n}\nfloat computeShadowWithESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn esm;\n}\nfloat computeShadowWithCloseESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn esm;\n}\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadow=texture2D(shadowSampler,uv).x;\n#endif\nif (shadowPixelDepth>shadow)\n{\nreturn computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff);\n}\nreturn 1.;\n}\nfloat computeShadowWithPoissonSampling(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\nfloat visibility=1.;\nvec2 poissonDisk[4];\npoissonDisk[0]=vec2(-0.94201624,-0.39906216);\npoissonDisk[1]=vec2(0.94558609,-0.76890725);\npoissonDisk[2]=vec2(-0.094184101,-0.92938870);\npoissonDisk[3]=vec2(0.34495938,0.29387760);\n\n#ifndef SHADOWFLOAT\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[0]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[1]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[2]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[3]*mapSize))<shadowPixelDepth) visibility-=0.25;\n#else\nif (texture2D(shadowSampler,uv+poissonDisk[0]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[1]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[2]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[3]*mapSize).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);\n}\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n#ifdef WEBGL2\n\nfloat computeShadowWithPCF1(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat shadow=texture2D(shadowSampler,uvDepth);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\nfloat computeShadowWithPCF3(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\nfloat computeShadowWithPCF5(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[1]),uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[2]),uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[2]),uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[2]),uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\nconst vec3 PoissonSamplers32[64]=vec3[64](\nvec3(0.06407013,0.05409927,0.),\nvec3(0.7366577,0.5789394,0.),\nvec3(-0.6270542,-0.5320278,0.),\nvec3(-0.4096107,0.8411095,0.),\nvec3(0.6849564,-0.4990818,0.),\nvec3(-0.874181,-0.04579735,0.),\nvec3(0.9989998,0.0009880066,0.),\nvec3(-0.004920578,-0.9151649,0.),\nvec3(0.1805763,0.9747483,0.),\nvec3(-0.2138451,0.2635818,0.),\nvec3(0.109845,0.3884785,0.),\nvec3(0.06876755,-0.3581074,0.),\nvec3(0.374073,-0.7661266,0.),\nvec3(0.3079132,-0.1216763,0.),\nvec3(-0.3794335,-0.8271583,0.),\nvec3(-0.203878,-0.07715034,0.),\nvec3(0.5912697,0.1469799,0.),\nvec3(-0.88069,0.3031784,0.),\nvec3(0.5040108,0.8283722,0.),\nvec3(-0.5844124,0.5494877,0.),\nvec3(0.6017799,-0.1726654,0.),\nvec3(-0.5554981,0.1559997,0.),\nvec3(-0.3016369,-0.3900928,0.),\nvec3(-0.5550632,-0.1723762,0.),\nvec3(0.925029,0.2995041,0.),\nvec3(-0.2473137,0.5538505,0.),\nvec3(0.9183037,-0.2862392,0.),\nvec3(0.2469421,0.6718712,0.),\nvec3(0.3916397,-0.4328209,0.),\nvec3(-0.03576927,-0.6220032,0.),\nvec3(-0.04661255,0.7995201,0.),\nvec3(0.4402924,0.3640312,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.)\n);\nconst vec3 PoissonSamplers64[64]=vec3[64](\nvec3(-0.613392,0.617481,0.),\nvec3(0.170019,-0.040254,0.),\nvec3(-0.299417,0.791925,0.),\nvec3(0.645680,0.493210,0.),\nvec3(-0.651784,0.717887,0.),\nvec3(0.421003,0.027070,0.),\nvec3(-0.817194,-0.271096,0.),\nvec3(-0.705374,-0.668203,0.),\nvec3(0.977050,-0.108615,0.),\nvec3(0.063326,0.142369,0.),\nvec3(0.203528,0.214331,0.),\nvec3(-0.667531,0.326090,0.),\nvec3(-0.098422,-0.295755,0.),\nvec3(-0.885922,0.215369,0.),\nvec3(0.566637,0.605213,0.),\nvec3(0.039766,-0.396100,0.),\nvec3(0.751946,0.453352,0.),\nvec3(0.078707,-0.715323,0.),\nvec3(-0.075838,-0.529344,0.),\nvec3(0.724479,-0.580798,0.),\nvec3(0.222999,-0.215125,0.),\nvec3(-0.467574,-0.405438,0.),\nvec3(-0.248268,-0.814753,0.),\nvec3(0.354411,-0.887570,0.),\nvec3(0.175817,0.382366,0.),\nvec3(0.487472,-0.063082,0.),\nvec3(-0.084078,0.898312,0.),\nvec3(0.488876,-0.783441,0.),\nvec3(0.470016,0.217933,0.),\nvec3(-0.696890,-0.549791,0.),\nvec3(-0.149693,0.605762,0.),\nvec3(0.034211,0.979980,0.),\nvec3(0.503098,-0.308878,0.),\nvec3(-0.016205,-0.872921,0.),\nvec3(0.385784,-0.393902,0.),\nvec3(-0.146886,-0.859249,0.),\nvec3(0.643361,0.164098,0.),\nvec3(0.634388,-0.049471,0.),\nvec3(-0.688894,0.007843,0.),\nvec3(0.464034,-0.188818,0.),\nvec3(-0.440840,0.137486,0.),\nvec3(0.364483,0.511704,0.),\nvec3(0.034028,0.325968,0.),\nvec3(0.099094,-0.308023,0.),\nvec3(0.693960,-0.366253,0.),\nvec3(0.678884,-0.204688,0.),\nvec3(0.001801,0.780328,0.),\nvec3(0.145177,-0.898984,0.),\nvec3(0.062655,-0.611866,0.),\nvec3(0.315226,-0.604297,0.),\nvec3(-0.780145,0.486251,0.),\nvec3(-0.371868,0.882138,0.),\nvec3(0.200476,0.494430,0.),\nvec3(-0.494552,-0.711051,0.),\nvec3(0.612476,0.705252,0.),\nvec3(-0.578845,-0.768792,0.),\nvec3(-0.772454,-0.090976,0.),\nvec3(0.504440,0.372295,0.),\nvec3(0.155736,0.065157,0.),\nvec3(0.391522,0.849605,0.),\nvec3(-0.620106,-0.328104,0.),\nvec3(0.789239,-0.419965,0.),\nvec3(-0.545396,0.538133,0.),\nvec3(-0.178564,-0.596057,0.)\n);\n\n\n\n\n\nfloat computeShadowWithPCSS(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)+AAOffset);\nfloat filterRadius=penumbraRatio*lightSizeUV*shadowMapSizeInverse;\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec3 offset=poissonSamplers[i];\n\noffset=vec3(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);\nshadow+=texture2D(shadowSampler,uvDepth+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,depthMetric-avgBlockerDepth);\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\nfloat computeShadowWithPCSS16(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);\n}\nfloat computeShadowWithPCSS32(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);\n}\nfloat computeShadowWithPCSS64(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);\n}\n#endif\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var shadowsFragmentFunctions = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ShadersInclude/shadowsVertex.ts":
/*!*************************************************!*\
  !*** ./Shaders/ShadersInclude/shadowsVertex.ts ***!
  \*************************************************/
/*! exports provided: shadowsVertex */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowsVertex", function() { return shadowsVertex; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../Materials/effect */ "./Materials/effect.ts");

var name = 'shadowsVertex';
var shader = "#ifdef SHADOWS\n#if defined(SHADOW{X}) && !defined(SHADOWCUBE{X})\nvPositionFromLight{X}=lightMatrix{X}*worldPos;\nvDepthMetric{X}=((vPositionFromLight{X}.z+light{X}.depthValues.x)/(light{X}.depthValues.y));\n#endif\n#endif";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].IncludesShadersStore[name] = shader;
/** @hidden */
var shadowsVertex = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/anaglyph.fragment.ts":
/*!**************************************!*\
  !*** ./Shaders/anaglyph.fragment.ts ***!
  \**************************************/
/*! exports provided: anaglyphPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "anaglyphPixelShader", function() { return anaglyphPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'anaglyphPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform sampler2D leftSampler;\nvoid main(void)\n{\nvec4 leftFrag=texture2D(leftSampler,vUV);\nleftFrag=vec4(1.0,leftFrag.g,leftFrag.b,1.0);\nvec4 rightFrag=texture2D(textureSampler,vUV);\nrightFrag=vec4(rightFrag.r,1.0,1.0,1.0);\ngl_FragColor=vec4(rightFrag.rgb*leftFrag.rgb,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var anaglyphPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/background.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/background.fragment.ts ***!
  \****************************************/
/*! exports provided: backgroundPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backgroundPixelShader", function() { return backgroundPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_backgroundFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/backgroundFragmentDeclaration */ "./Shaders/ShadersInclude/backgroundFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_backgroundUboDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/backgroundUboDeclaration */ "./Shaders/ShadersInclude/backgroundUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_reflectionFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/reflectionFunction */ "./Shaders/ShadersInclude/reflectionFunction.ts");
/* harmony import */ var _ShadersInclude_imageProcessingDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingDeclaration */ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightFragmentDeclaration__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/lightFragmentDeclaration */ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightUboDeclaration__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/lightUboDeclaration */ "./Shaders/ShadersInclude/lightUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_lightsFragmentFunctions__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/lightsFragmentFunctions */ "./Shaders/ShadersInclude/lightsFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_shadowsFragmentFunctions__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/shadowsFragmentFunctions */ "./Shaders/ShadersInclude/shadowsFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_imageProcessingFunctions__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingFunctions */ "./Shaders/ShadersInclude/imageProcessingFunctions.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragmentDeclaration__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragmentDeclaration */ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogFragmentDeclaration__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./ShadersInclude/fogFragmentDeclaration */ "./Shaders/ShadersInclude/fogFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragment__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragment */ "./Shaders/ShadersInclude/clipPlaneFragment.ts");
/* harmony import */ var _ShadersInclude_lightFragment__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ShadersInclude/lightFragment */ "./Shaders/ShadersInclude/lightFragment.ts");
/* harmony import */ var _ShadersInclude_fogFragment__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ShadersInclude/fogFragment */ "./Shaders/ShadersInclude/fogFragment.ts");
















var name = 'backgroundPixelShader';
var shader = "#ifdef TEXTURELODSUPPORT\n#extension GL_EXT_shader_texture_lod : enable\n#endif\nprecision highp float;\n#include<__decl__backgroundFragment>\n#define RECIPROCAL_PI2 0.15915494\n\nuniform vec3 vEyePosition;\n\nvarying vec3 vPositionW;\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef DIFFUSE\n#if DIFFUSEDIRECTUV == 1\n#define vDiffuseUV vMainUV1\n#elif DIFFUSEDIRECTUV == 2\n#define vDiffuseUV vMainUV2\n#else\nvarying vec2 vDiffuseUV;\n#endif\nuniform sampler2D diffuseSampler;\n#endif\n\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\n#define sampleReflection(s,c) textureCube(s,c)\nuniform samplerCube reflectionSampler;\n#ifdef TEXTURELODSUPPORT\n#define sampleReflectionLod(s,c,l) textureCubeLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;\nuniform samplerCube reflectionSamplerHigh;\n#endif\n#else\n#define sampleReflection(s,c) texture2D(s,c)\nuniform sampler2D reflectionSampler;\n#ifdef TEXTURELODSUPPORT\n#define sampleReflectionLod(s,c,l) texture2DLodEXT(s,c,l)\n#else\nuniform samplerCube reflectionSamplerLow;\nuniform samplerCube reflectionSamplerHigh;\n#endif\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE;\n#endif\n\n#ifndef SHADOWONLY\n#define SHADOWONLY;\n#endif\n#include<imageProcessingDeclaration>\n\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<helperFunctions>\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n#include<imageProcessingFunctions>\n#include<clipPlaneFragmentDeclaration>\n\n#include<fogFragmentDeclaration>\n#ifdef REFLECTIONFRESNEL\n#define FRESNEL_MAXIMUM_ON_ROUGH 0.25\nvec3 fresnelSchlickEnvironmentGGX(float VdotN,vec3 reflectance0,vec3 reflectance90,float smoothness)\n{\n\nfloat weight=mix(FRESNEL_MAXIMUM_ON_ROUGH,1.0,smoothness);\nreturn reflectance0+weight*(reflectance90-reflectance0)*pow5(saturate(1.0-VdotN));\n}\n#endif\nvoid main(void) {\n#include<clipPlaneFragment>\nvec3 viewDirectionW=normalize(vEyePosition-vPositionW);\n\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=vec3(0.0,1.0,0.0);\n#endif\n\nfloat shadow=1.;\nfloat globalShadow=0.;\nfloat shadowLightCount=0.;\n#include<lightFragment>[0..maxSimultaneousLights]\n#ifdef SHADOWINUSE\nglobalShadow/=shadowLightCount;\n#else\nglobalShadow=1.0;\n#endif\n\nvec4 reflectionColor=vec4(1.,1.,1.,1.);\n#ifdef REFLECTION\nvec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=reflectionVector;\n#else\nvec2 reflectionCoords=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\n#ifdef REFLECTIONBLUR\nfloat reflectionLOD=vReflectionInfos.y;\n#ifdef TEXTURELODSUPPORT\n\nreflectionLOD=reflectionLOD*log2(vReflectionMicrosurfaceInfos.x)*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\nreflectionColor=sampleReflectionLod(reflectionSampler,reflectionCoords,reflectionLOD);\n#else\nfloat lodReflectionNormalized=saturate(reflectionLOD);\nfloat lodReflectionNormalizedDoubled=lodReflectionNormalized*2.0;\nvec4 reflectionSpecularMid=sampleReflection(reflectionSampler,reflectionCoords);\nif(lodReflectionNormalizedDoubled<1.0){\nreflectionColor=mix(\nsampleReflection(reflectionSamplerHigh,reflectionCoords),\nreflectionSpecularMid,\nlodReflectionNormalizedDoubled\n);\n} else {\nreflectionColor=mix(\nreflectionSpecularMid,\nsampleReflection(reflectionSamplerLow,reflectionCoords),\nlodReflectionNormalizedDoubled-1.0\n);\n}\n#endif\n#else\nvec4 reflectionSample=sampleReflection(reflectionSampler,reflectionCoords);\nreflectionColor=reflectionSample;\n#endif\n#ifdef RGBDREFLECTION\nreflectionColor.rgb=fromRGBD(reflectionColor);\n#endif\n#ifdef GAMMAREFLECTION\nreflectionColor.rgb=toLinearSpace(reflectionColor.rgb);\n#endif\n#ifdef REFLECTIONBGR\nreflectionColor.rgb=reflectionColor.bgr;\n#endif\n\nreflectionColor.rgb*=vReflectionInfos.x;\n#endif\n\nvec3 diffuseColor=vec3(1.,1.,1.);\nfloat finalAlpha=alpha;\n#ifdef DIFFUSE\nvec4 diffuseMap=texture2D(diffuseSampler,vDiffuseUV);\n#ifdef GAMMADIFFUSE\ndiffuseMap.rgb=toLinearSpace(diffuseMap.rgb);\n#endif\n\ndiffuseMap.rgb*=vDiffuseInfos.y;\n#ifdef DIFFUSEHASALPHA\nfinalAlpha*=diffuseMap.a;\n#endif\ndiffuseColor=diffuseMap.rgb;\n#endif\n\n#ifdef REFLECTIONFRESNEL\nvec3 colorBase=diffuseColor;\n#else\nvec3 colorBase=reflectionColor.rgb*diffuseColor;\n#endif\ncolorBase=max(colorBase,0.0);\n\n#ifdef USERGBCOLOR\nvec3 finalColor=colorBase;\n#else\n#ifdef USEHIGHLIGHTANDSHADOWCOLORS\nvec3 mainColor=mix(vPrimaryColorShadow.rgb,vPrimaryColor.rgb,colorBase);\n#else\nvec3 mainColor=vPrimaryColor.rgb;\n#endif\nvec3 finalColor=colorBase*mainColor;\n#endif\n\n#ifdef REFLECTIONFRESNEL\nvec3 reflectionAmount=vReflectionControl.xxx;\nvec3 reflectionReflectance0=vReflectionControl.yyy;\nvec3 reflectionReflectance90=vReflectionControl.zzz;\nfloat VdotN=dot(normalize(vEyePosition),normalW);\nvec3 planarReflectionFresnel=fresnelSchlickEnvironmentGGX(saturate(VdotN),reflectionReflectance0,reflectionReflectance90,1.0);\nreflectionAmount*=planarReflectionFresnel;\n#ifdef REFLECTIONFALLOFF\nfloat reflectionDistanceFalloff=1.0-saturate(length(vPositionW.xyz-vBackgroundCenter)*vReflectionControl.w);\nreflectionDistanceFalloff*=reflectionDistanceFalloff;\nreflectionAmount*=reflectionDistanceFalloff;\n#endif\nfinalColor=mix(finalColor,reflectionColor.rgb,saturate(reflectionAmount));\n#endif\n#ifdef OPACITYFRESNEL\nfloat viewAngleToFloor=dot(normalW,normalize(vEyePosition-vBackgroundCenter));\n\nconst float startAngle=0.1;\nfloat fadeFactor=saturate(viewAngleToFloor/startAngle);\nfinalAlpha*=fadeFactor*fadeFactor;\n#endif\n\n#ifdef SHADOWINUSE\nfinalColor=mix(finalColor*shadowLevel,finalColor,globalShadow);\n#endif\n\nvec4 color=vec4(finalColor,finalAlpha);\n#include<fogFragment>\n#ifdef IMAGEPROCESSINGPOSTPROCESS\n\n\ncolor.rgb=clamp(color.rgb,0.,30.0);\n#else\n\ncolor=applyImageProcessing(color);\n#endif\n#ifdef PREMULTIPLYALPHA\n\ncolor.rgb*=color.a;\n#endif\n#ifdef NOISE\ncolor.rgb+=dither(vPositionW.xy,0.5);\ncolor=max(color,0.0);\n#endif\ngl_FragColor=color;\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var backgroundPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/background.vertex.ts":
/*!**************************************!*\
  !*** ./Shaders/background.vertex.ts ***!
  \**************************************/
/*! exports provided: backgroundVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backgroundVertexShader", function() { return backgroundVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_backgroundVertexDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/backgroundVertexDeclaration */ "./Shaders/ShadersInclude/backgroundVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_backgroundUboDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/backgroundUboDeclaration */ "./Shaders/ShadersInclude/backgroundUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertexDeclaration__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertexDeclaration */ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogVertexDeclaration__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/fogVertexDeclaration */ "./Shaders/ShadersInclude/fogVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightFragmentDeclaration__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/lightFragmentDeclaration */ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightUboDeclaration__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/lightUboDeclaration */ "./Shaders/ShadersInclude/lightUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertex__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertex */ "./Shaders/ShadersInclude/clipPlaneVertex.ts");
/* harmony import */ var _ShadersInclude_fogVertex__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ShadersInclude/fogVertex */ "./Shaders/ShadersInclude/fogVertex.ts");
/* harmony import */ var _ShadersInclude_shadowsVertex__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ShadersInclude/shadowsVertex */ "./Shaders/ShadersInclude/shadowsVertex.ts");















var name = 'backgroundVertexShader';
var shader = "precision highp float;\n#include<__decl__backgroundVertex>\n#include<helperFunctions>\n\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#include<bonesDeclaration>\n\n#include<instancesDeclaration>\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nvarying vec2 vDiffuseUV;\n#endif\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\nvoid main(void) {\n#ifdef REFLECTIONMAP_SKYBOX\n#ifdef REFLECTIONMAP_SKYBOX_TRANSFORMED\nvPositionUVW=(reflectionMatrix*vec4(position,1.0)).xyz;\n#else\nvPositionUVW=position;\n#endif\n#endif\n#include<instancesVertex>\n#include<bonesVertex>\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR == 0u) {\ngl_Position=viewProjection*finalWorld*vec4(position,1.0);\n} else {\ngl_Position=viewProjectionR*finalWorld*vec4(position,1.0);\n}\n#else\ngl_Position=viewProjection*finalWorld*vec4(position,1.0);\n#endif\nvec4 worldPos=finalWorld*vec4(position,1.0);\nvPositionW=vec3(worldPos);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normal);\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(position,0.0)));\n#ifdef EQUIRECTANGULAR_RELFECTION_FOV\nmat3 screenToWorld=inverseMat3(mat3(finalWorld*viewProjection));\nvec3 segment=mix(vDirectionW,screenToWorld*vec3(0.0,0.0,1.0),abs(fFovMultiplier-1.0));\nif (fFovMultiplier<=1.0) {\nvDirectionW=normalize(segment);\n} else {\nvDirectionW=normalize(vDirectionW+(vDirectionW-segment));\n}\n#endif\n#endif\n#ifndef UV1\nvec2 uv=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uv;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nif (vDiffuseInfos.x == 0.)\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n\n#include<clipPlaneVertex>\n\n#include<fogVertex>\n\n#include<shadowsVertex>[0..maxSimultaneousLights]\n\n#ifdef VERTEXCOLOR\nvColor=color;\n#endif\n\n#ifdef POINTSIZE\ngl_PointSize=pointSize;\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var backgroundVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/blackAndWhite.fragment.ts":
/*!*******************************************!*\
  !*** ./Shaders/blackAndWhite.fragment.ts ***!
  \*******************************************/
/*! exports provided: blackAndWhitePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "blackAndWhitePixelShader", function() { return blackAndWhitePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'blackAndWhitePixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform float degree;\nvoid main(void)\n{\nvec3 color=texture2D(textureSampler,vUV).rgb;\nfloat luminance=dot(color,vec3(0.3,0.59,0.11));\nvec3 blackAndWhite=vec3(luminance,luminance,luminance);\ngl_FragColor=vec4(color-((color-blackAndWhite)*degree),1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var blackAndWhitePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/bloomMerge.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/bloomMerge.fragment.ts ***!
  \****************************************/
/*! exports provided: bloomMergePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bloomMergePixelShader", function() { return bloomMergePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'bloomMergePixelShader';
var shader = "uniform sampler2D textureSampler;\nuniform sampler2D bloomBlur;\nvarying vec2 vUV;\nuniform float bloomWeight;\nvoid main(void)\n{\ngl_FragColor=texture2D(textureSampler,vUV);\nvec3 blurred=texture2D(bloomBlur,vUV).rgb;\ngl_FragColor.rgb=gl_FragColor.rgb+(blurred.rgb*bloomWeight);\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var bloomMergePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/chromaticAberration.fragment.ts":
/*!*************************************************!*\
  !*** ./Shaders/chromaticAberration.fragment.ts ***!
  \*************************************************/
/*! exports provided: chromaticAberrationPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "chromaticAberrationPixelShader", function() { return chromaticAberrationPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'chromaticAberrationPixelShader';
var shader = "\nuniform sampler2D textureSampler;\n\nuniform float chromatic_aberration;\nuniform float radialIntensity;\nuniform vec2 direction;\nuniform vec2 centerPosition;\nuniform float screen_width;\nuniform float screen_height;\n\nvarying vec2 vUV;\nvoid main(void)\n{\nvec2 centered_screen_pos=vec2(vUV.x-centerPosition.x,vUV.y-centerPosition.y);\nvec2 directionOfEffect=direction;\nif(directionOfEffect.x == 0. && directionOfEffect.y == 0.){\ndirectionOfEffect=normalize(centered_screen_pos);\n}\nfloat radius2=centered_screen_pos.x*centered_screen_pos.x\n+centered_screen_pos.y*centered_screen_pos.y;\nfloat radius=sqrt(radius2);\nvec4 original=texture2D(textureSampler,vUV);\n\nvec3 ref_indices=vec3(-0.3,0.0,0.3);\nfloat ref_shiftX=chromatic_aberration*pow(radius,radialIntensity)*directionOfEffect.x/screen_width;\nfloat ref_shiftY=chromatic_aberration*pow(radius,radialIntensity)*directionOfEffect.y/screen_height;\n\nvec2 ref_coords_r=vec2(vUV.x+ref_indices.r*ref_shiftX,vUV.y+ref_indices.r*ref_shiftY*0.5);\nvec2 ref_coords_g=vec2(vUV.x+ref_indices.g*ref_shiftX,vUV.y+ref_indices.g*ref_shiftY*0.5);\nvec2 ref_coords_b=vec2(vUV.x+ref_indices.b*ref_shiftX,vUV.y+ref_indices.b*ref_shiftY*0.5);\noriginal.r=texture2D(textureSampler,ref_coords_r).r;\noriginal.g=texture2D(textureSampler,ref_coords_g).g;\noriginal.b=texture2D(textureSampler,ref_coords_b).b;\noriginal.a=clamp(texture2D(textureSampler,ref_coords_r).a+texture2D(textureSampler,ref_coords_g).a+texture2D(textureSampler,ref_coords_b).a,0.,1.);\ngl_FragColor=original;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var chromaticAberrationPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/circleOfConfusion.fragment.ts":
/*!***********************************************!*\
  !*** ./Shaders/circleOfConfusion.fragment.ts ***!
  \***********************************************/
/*! exports provided: circleOfConfusionPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "circleOfConfusionPixelShader", function() { return circleOfConfusionPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'circleOfConfusionPixelShader';
var shader = "\nuniform sampler2D depthSampler;\n\nvarying vec2 vUV;\n\nuniform vec2 cameraMinMaxZ;\n\nuniform float focusDistance;\nuniform float cocPrecalculation;\nvoid main(void)\n{\nfloat depth=texture2D(depthSampler,vUV).r;\nfloat pixelDistance=(cameraMinMaxZ.x+(cameraMinMaxZ.y-cameraMinMaxZ.x)*depth)*1000.0;\nfloat coc=abs(cocPrecalculation* ((focusDistance-pixelDistance)/pixelDistance));\ncoc=clamp(coc,0.0,1.0);\ngl_FragColor=vec4(coc,depth,coc,1.0);\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var circleOfConfusionPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/color.fragment.ts":
/*!***********************************!*\
  !*** ./Shaders/color.fragment.ts ***!
  \***********************************/
/*! exports provided: colorPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "colorPixelShader", function() { return colorPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragmentDeclaration */ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragment */ "./Shaders/ShadersInclude/clipPlaneFragment.ts");



var name = 'colorPixelShader';
var shader = "#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#else\nuniform vec4 color;\n#endif\n#include<clipPlaneFragmentDeclaration>\nvoid main(void) {\n#include<clipPlaneFragment>\n#ifdef VERTEXCOLOR\ngl_FragColor=vColor;\n#else\ngl_FragColor=color;\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var colorPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/color.vertex.ts":
/*!*********************************!*\
  !*** ./Shaders/color.vertex.ts ***!
  \*********************************/
/*! exports provided: colorVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "colorVertexShader", function() { return colorVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertexDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertexDeclaration */ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertex */ "./Shaders/ShadersInclude/clipPlaneVertex.ts");







var name = 'colorVertexShader';
var shader = "\nattribute vec3 position;\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<bonesDeclaration>\n#include<clipPlaneVertexDeclaration>\n\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\n\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\nvoid main(void) {\n#include<instancesVertex>\n#include<bonesVertex>\nvec4 worldPos=finalWorld*vec4(position,1.0);\ngl_Position=viewProjection*worldPos;\n#include<clipPlaneVertex>\n#ifdef VERTEXCOLOR\n\nvColor=color;\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var colorVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/colorCorrection.fragment.ts":
/*!*********************************************!*\
  !*** ./Shaders/colorCorrection.fragment.ts ***!
  \*********************************************/
/*! exports provided: colorCorrectionPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "colorCorrectionPixelShader", function() { return colorCorrectionPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'colorCorrectionPixelShader';
var shader = "\nuniform sampler2D textureSampler;\nuniform sampler2D colorTable;\n\nvarying vec2 vUV;\n\nconst float SLICE_COUNT=16.0;\n\nvec4 sampleAs3DTexture(sampler2D textureSampler,vec3 uv,float width) {\nfloat sliceSize=1.0/width;\nfloat slicePixelSize=sliceSize/width;\nfloat sliceInnerSize=slicePixelSize*(width-1.0);\nfloat zSlice0=min(floor(uv.z*width),width-1.0);\nfloat zSlice1=min(zSlice0+1.0,width-1.0);\nfloat xOffset=slicePixelSize*0.5+uv.x*sliceInnerSize;\nfloat s0=xOffset+(zSlice0*sliceSize);\nfloat s1=xOffset+(zSlice1*sliceSize);\nvec4 slice0Color=texture2D(textureSampler,vec2(s0,uv.y));\nvec4 slice1Color=texture2D(textureSampler,vec2(s1,uv.y));\nfloat zOffset=mod(uv.z*width,1.0);\nvec4 result=mix(slice0Color,slice1Color,zOffset);\nreturn result;\n}\nvoid main(void)\n{\nvec4 screen_color=texture2D(textureSampler,vUV);\ngl_FragColor=sampleAs3DTexture(colorTable,screen_color.rgb,SLICE_COUNT);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var colorCorrectionPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/convolution.fragment.ts":
/*!*****************************************!*\
  !*** ./Shaders/convolution.fragment.ts ***!
  \*****************************************/
/*! exports provided: convolutionPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "convolutionPixelShader", function() { return convolutionPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'convolutionPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform vec2 screenSize;\nuniform float kernel[9];\nvoid main(void)\n{\nvec2 onePixel=vec2(1.0,1.0)/screenSize;\nvec4 colorSum =\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,-1))*kernel[0] +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,-1))*kernel[1] +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,-1))*kernel[2] +\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,0))*kernel[3] +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,0))*kernel[4] +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,0))*kernel[5] +\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,1))*kernel[6] +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,1))*kernel[7] +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,1))*kernel[8];\nfloat kernelWeight =\nkernel[0] +\nkernel[1] +\nkernel[2] +\nkernel[3] +\nkernel[4] +\nkernel[5] +\nkernel[6] +\nkernel[7] +\nkernel[8];\nif (kernelWeight<=0.0) {\nkernelWeight=1.0;\n}\ngl_FragColor=vec4((colorSum/kernelWeight).rgb,1);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var convolutionPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/default.fragment.ts":
/*!*************************************!*\
  !*** ./Shaders/default.fragment.ts ***!
  \*************************************/
/*! exports provided: defaultPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultPixelShader", function() { return defaultPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_defaultFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/defaultFragmentDeclaration */ "./Shaders/ShadersInclude/defaultFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_defaultUboDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/defaultUboDeclaration */ "./Shaders/ShadersInclude/defaultUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_lightFragmentDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/lightFragmentDeclaration */ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightUboDeclaration__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/lightUboDeclaration */ "./Shaders/ShadersInclude/lightUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightsFragmentFunctions__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/lightsFragmentFunctions */ "./Shaders/ShadersInclude/lightsFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_shadowsFragmentFunctions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/shadowsFragmentFunctions */ "./Shaders/ShadersInclude/shadowsFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_fresnelFunction__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/fresnelFunction */ "./Shaders/ShadersInclude/fresnelFunction.ts");
/* harmony import */ var _ShadersInclude_reflectionFunction__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/reflectionFunction */ "./Shaders/ShadersInclude/reflectionFunction.ts");
/* harmony import */ var _ShadersInclude_imageProcessingDeclaration__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingDeclaration */ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts");
/* harmony import */ var _ShadersInclude_imageProcessingFunctions__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingFunctions */ "./Shaders/ShadersInclude/imageProcessingFunctions.ts");
/* harmony import */ var _ShadersInclude_bumpFragmentFunctions__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./ShadersInclude/bumpFragmentFunctions */ "./Shaders/ShadersInclude/bumpFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragmentDeclaration__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragmentDeclaration */ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_logDepthDeclaration__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ShadersInclude/logDepthDeclaration */ "./Shaders/ShadersInclude/logDepthDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogFragmentDeclaration__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ShadersInclude/fogFragmentDeclaration */ "./Shaders/ShadersInclude/fogFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragment__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragment */ "./Shaders/ShadersInclude/clipPlaneFragment.ts");
/* harmony import */ var _ShadersInclude_bumpFragment__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./ShadersInclude/bumpFragment */ "./Shaders/ShadersInclude/bumpFragment.ts");
/* harmony import */ var _ShadersInclude_depthPrePass__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./ShadersInclude/depthPrePass */ "./Shaders/ShadersInclude/depthPrePass.ts");
/* harmony import */ var _ShadersInclude_lightFragment__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./ShadersInclude/lightFragment */ "./Shaders/ShadersInclude/lightFragment.ts");
/* harmony import */ var _ShadersInclude_logDepthFragment__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./ShadersInclude/logDepthFragment */ "./Shaders/ShadersInclude/logDepthFragment.ts");
/* harmony import */ var _ShadersInclude_fogFragment__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./ShadersInclude/fogFragment */ "./Shaders/ShadersInclude/fogFragment.ts");






















var name = 'defaultPixelShader';
var shader = "#include<__decl__defaultFragment>\n#if defined(BUMP) || !defined(NORMAL)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#define CUSTOM_FRAGMENT_BEGIN\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n\n#define RECIPROCAL_PI2 0.15915494\nuniform vec3 vEyePosition;\nuniform vec3 vAmbientColor;\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n\n#include<helperFunctions>\n\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<lightsFragmentFunctions>\n#include<shadowsFragmentFunctions>\n\n#ifdef DIFFUSE\n#if DIFFUSEDIRECTUV == 1\n#define vDiffuseUV vMainUV1\n#elif DIFFUSEDIRECTUV == 2\n#define vDiffuseUV vMainUV2\n#else\nvarying vec2 vDiffuseUV;\n#endif\nuniform sampler2D diffuseSampler;\n#endif\n#ifdef AMBIENT\n#if AMBIENTDIRECTUV == 1\n#define vAmbientUV vMainUV1\n#elif AMBIENTDIRECTUV == 2\n#define vAmbientUV vMainUV2\n#else\nvarying vec2 vAmbientUV;\n#endif\nuniform sampler2D ambientSampler;\n#endif\n#ifdef OPACITY\n#if OPACITYDIRECTUV == 1\n#define vOpacityUV vMainUV1\n#elif OPACITYDIRECTUV == 2\n#define vOpacityUV vMainUV2\n#else\nvarying vec2 vOpacityUV;\n#endif\nuniform sampler2D opacitySampler;\n#endif\n#ifdef EMISSIVE\n#if EMISSIVEDIRECTUV == 1\n#define vEmissiveUV vMainUV1\n#elif EMISSIVEDIRECTUV == 2\n#define vEmissiveUV vMainUV2\n#else\nvarying vec2 vEmissiveUV;\n#endif\nuniform sampler2D emissiveSampler;\n#endif\n#ifdef LIGHTMAP\n#if LIGHTMAPDIRECTUV == 1\n#define vLightmapUV vMainUV1\n#elif LIGHTMAPDIRECTUV == 2\n#define vLightmapUV vMainUV2\n#else\nvarying vec2 vLightmapUV;\n#endif\nuniform sampler2D lightmapSampler;\n#endif\n#ifdef REFRACTION\n#ifdef REFRACTIONMAP_3D\nuniform samplerCube refractionCubeSampler;\n#else\nuniform sampler2D refraction2DSampler;\n#endif\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\n#if SPECULARDIRECTUV == 1\n#define vSpecularUV vMainUV1\n#elif SPECULARDIRECTUV == 2\n#define vSpecularUV vMainUV2\n#else\nvarying vec2 vSpecularUV;\n#endif\nuniform sampler2D specularSampler;\n#endif\n#ifdef ALPHATEST\nuniform float alphaCutOff;\n#endif\n\n#include<fresnelFunction>\n\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nuniform samplerCube reflectionCubeSampler;\n#else\nuniform sampler2D reflection2DSampler;\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#include<reflectionFunction>\n#endif\n#include<imageProcessingDeclaration>\n#include<imageProcessingFunctions>\n#include<bumpFragmentFunctions>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n#define CUSTOM_FRAGMENT_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\nvec3 viewDirectionW=normalize(vEyePosition-vPositionW);\n\nvec4 baseColor=vec4(1.,1.,1.,1.);\nvec3 diffuseColor=vDiffuseColor.rgb;\n\nfloat alpha=vDiffuseColor.a;\n\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=normalize(-cross(dFdx(vPositionW),dFdy(vPositionW)));\n#endif\n#include<bumpFragment>\n#ifdef TWOSIDEDLIGHTING\nnormalW=gl_FrontFacing ? normalW : -normalW;\n#endif\n#ifdef DIFFUSE\nbaseColor=texture2D(diffuseSampler,vDiffuseUV+uvOffset);\n#ifdef ALPHATEST\nif (baseColor.a<alphaCutOff)\ndiscard;\n#endif\n#ifdef ALPHAFROMDIFFUSE\nalpha*=baseColor.a;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\nbaseColor.rgb*=vDiffuseInfos.y;\n#endif\n#include<depthPrePass>\n#ifdef VERTEXCOLOR\nbaseColor.rgb*=vColor.rgb;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE\n\nvec3 baseAmbientColor=vec3(1.,1.,1.);\n#ifdef AMBIENT\nbaseAmbientColor=texture2D(ambientSampler,vAmbientUV+uvOffset).rgb*vAmbientInfos.y;\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\n\n#ifdef SPECULARTERM\nfloat glossiness=vSpecularColor.a;\nvec3 specularColor=vSpecularColor.rgb;\n#ifdef SPECULAR\nvec4 specularMapColor=texture2D(specularSampler,vSpecularUV+uvOffset);\nspecularColor=specularMapColor.rgb;\n#ifdef GLOSSINESS\nglossiness=glossiness*specularMapColor.a;\n#endif\n#endif\n#else\nfloat glossiness=0.;\n#endif\n\nvec3 diffuseBase=vec3(0.,0.,0.);\nlightingInfo info;\n#ifdef SPECULARTERM\nvec3 specularBase=vec3(0.,0.,0.);\n#endif\nfloat shadow=1.;\n#ifdef LIGHTMAP\nvec3 lightmapColor=texture2D(lightmapSampler,vLightmapUV+uvOffset).rgb*vLightmapInfos.y;\n#endif\n#include<lightFragment>[0..maxSimultaneousLights]\n\nvec3 refractionColor=vec3(0.,0.,0.);\n#ifdef REFRACTION\nvec3 refractionVector=normalize(refract(-viewDirectionW,normalW,vRefractionInfos.y));\n#ifdef REFRACTIONMAP_3D\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;\nif (dot(refractionVector,viewDirectionW)<1.0) {\nrefractionColor=textureCube(refractionCubeSampler,refractionVector).rgb;\n}\n#else\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*vRefractionInfos.z,1.0)));\nvec2 refractionCoords=vRefractionUVW.xy/vRefractionUVW.z;\nrefractionCoords.y=1.0-refractionCoords.y;\nrefractionColor=texture2D(refraction2DSampler,refractionCoords).rgb;\n#endif\n#ifdef IS_REFRACTION_LINEAR\nrefractionColor=toGammaSpace(refractionColor);\n#endif\nrefractionColor*=vRefractionInfos.x;\n#endif\n\nvec3 reflectionColor=vec3(0.,0.,0.);\n#ifdef REFLECTION\nvec3 vReflectionUVW=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_3D\n#ifdef ROUGHNESS\nfloat bias=vReflectionInfos.y;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\n#ifdef GLOSSINESS\nbias*=(1.0-specularMapColor.a);\n#endif\n#endif\n#endif\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW,bias).rgb;\n#else\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW).rgb;\n#endif\n#else\nvec2 coords=vReflectionUVW.xy;\n#ifdef REFLECTIONMAP_PROJECTION\ncoords/=vReflectionUVW.z;\n#endif\ncoords.y=1.0-coords.y;\nreflectionColor=texture2D(reflection2DSampler,coords).rgb;\n#endif\n#ifdef IS_REFLECTION_LINEAR\nreflectionColor=toGammaSpace(reflectionColor);\n#endif\nreflectionColor*=vReflectionInfos.x;\n#ifdef REFLECTIONFRESNEL\nfloat reflectionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,reflectionRightColor.a,reflectionLeftColor.a);\n#ifdef REFLECTIONFRESNELFROMSPECULAR\n#ifdef SPECULARTERM\nreflectionColor*=specularColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#else\nreflectionColor*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#else\nreflectionColor*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#endif\n#endif\n#ifdef REFRACTIONFRESNEL\nfloat refractionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,refractionRightColor.a,refractionLeftColor.a);\nrefractionColor*=refractionLeftColor.rgb*(1.0-refractionFresnelTerm)+refractionFresnelTerm*refractionRightColor.rgb;\n#endif\n#ifdef OPACITY\nvec4 opacityMap=texture2D(opacitySampler,vOpacityUV+uvOffset);\n#ifdef OPACITYRGB\nopacityMap.rgb=opacityMap.rgb*vec3(0.3,0.59,0.11);\nalpha*=(opacityMap.x+opacityMap.y+opacityMap.z)* vOpacityInfos.y;\n#else\nalpha*=opacityMap.a*vOpacityInfos.y;\n#endif\n#endif\n#ifdef VERTEXALPHA\nalpha*=vColor.a;\n#endif\n#ifdef OPACITYFRESNEL\nfloat opacityFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,opacityParts.z,opacityParts.w);\nalpha+=opacityParts.x*(1.0-opacityFresnelTerm)+opacityFresnelTerm*opacityParts.y;\n#endif\n\nvec3 emissiveColor=vEmissiveColor;\n#ifdef EMISSIVE\nemissiveColor+=texture2D(emissiveSampler,vEmissiveUV+uvOffset).rgb*vEmissiveInfos.y;\n#endif\n#ifdef EMISSIVEFRESNEL\nfloat emissiveFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,emissiveRightColor.a,emissiveLeftColor.a);\nemissiveColor*=emissiveLeftColor.rgb*(1.0-emissiveFresnelTerm)+emissiveFresnelTerm*emissiveRightColor.rgb;\n#endif\n\n#ifdef DIFFUSEFRESNEL\nfloat diffuseFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,diffuseRightColor.a,diffuseLeftColor.a);\ndiffuseBase*=diffuseLeftColor.rgb*(1.0-diffuseFresnelTerm)+diffuseFresnelTerm*diffuseRightColor.rgb;\n#endif\n\n#ifdef EMISSIVEASILLUMINATION\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\n#ifdef LINKEMISSIVEWITHDIFFUSE\nvec3 finalDiffuse=clamp((diffuseBase+emissiveColor)*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#endif\n#endif\n#ifdef SPECULARTERM\nvec3 finalSpecular=specularBase*specularColor;\n#ifdef SPECULAROVERALPHA\nalpha=clamp(alpha+dot(finalSpecular,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n#else\nvec3 finalSpecular=vec3(0.0);\n#endif\n#ifdef REFLECTIONOVERALPHA\nalpha=clamp(alpha+dot(reflectionColor,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n\n#ifdef EMISSIVEASILLUMINATION\nvec4 color=vec4(clamp(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor+emissiveColor+refractionColor,0.0,1.0),alpha);\n#else\nvec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor+refractionColor,alpha);\n#endif\n\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\ncolor.rgb*=lightmapColor;\n#else\ncolor.rgb+=lightmapColor;\n#endif\n#endif\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FOG\ncolor.rgb=max(color.rgb,0.);\n#include<logDepthFragment>\n#include<fogFragment>\n\n\n#ifdef IMAGEPROCESSINGPOSTPROCESS\ncolor.rgb=toLinearSpace(color.rgb);\n#else\n#ifdef IMAGEPROCESSING\ncolor.rgb=toLinearSpace(color.rgb);\ncolor=applyImageProcessing(color);\n#endif\n#endif\ncolor.a*=visibility;\n#ifdef PREMULTIPLYALPHA\n\ncolor.rgb*=color.a;\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\ngl_FragColor=color;\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var defaultPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/default.vertex.ts":
/*!***********************************!*\
  !*** ./Shaders/default.vertex.ts ***!
  \***********************************/
/*! exports provided: defaultVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultVertexShader", function() { return defaultVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_defaultVertexDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/defaultVertexDeclaration */ "./Shaders/ShadersInclude/defaultVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_defaultUboDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/defaultUboDeclaration */ "./Shaders/ShadersInclude/defaultUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_bumpVertexDeclaration__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/bumpVertexDeclaration */ "./Shaders/ShadersInclude/bumpVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertexDeclaration__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertexDeclaration */ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogVertexDeclaration__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/fogVertexDeclaration */ "./Shaders/ShadersInclude/fogVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightFragmentDeclaration__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/lightFragmentDeclaration */ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightUboDeclaration__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ShadersInclude/lightUboDeclaration */ "./Shaders/ShadersInclude/lightUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_logDepthDeclaration__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ShadersInclude/logDepthDeclaration */ "./Shaders/ShadersInclude/logDepthDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");
/* harmony import */ var _ShadersInclude_bumpVertex__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./ShadersInclude/bumpVertex */ "./Shaders/ShadersInclude/bumpVertex.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertex__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertex */ "./Shaders/ShadersInclude/clipPlaneVertex.ts");
/* harmony import */ var _ShadersInclude_fogVertex__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./ShadersInclude/fogVertex */ "./Shaders/ShadersInclude/fogVertex.ts");
/* harmony import */ var _ShadersInclude_shadowsVertex__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./ShadersInclude/shadowsVertex */ "./Shaders/ShadersInclude/shadowsVertex.ts");
/* harmony import */ var _ShadersInclude_pointCloudVertex__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./ShadersInclude/pointCloudVertex */ "./Shaders/ShadersInclude/pointCloudVertex.ts");
/* harmony import */ var _ShadersInclude_logDepthVertex__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./ShadersInclude/logDepthVertex */ "./Shaders/ShadersInclude/logDepthVertex.ts");























var name = 'defaultVertexShader';
var shader = "#include<__decl__defaultVertex>\n\n#define CUSTOM_VERTEX_BEGIN\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include<helperFunctions>\n#include<bonesDeclaration>\n\n#include<instancesDeclaration>\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nvarying vec2 vDiffuseUV;\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nvarying vec2 vAmbientUV;\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nvarying vec2 vOpacityUV;\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nvarying vec2 vEmissiveUV;\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nvarying vec2 vLightmapUV;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM) && SPECULARDIRECTUV == 0\nvarying vec2 vSpecularUV;\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nvarying vec2 vBumpUV;\n#endif\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#ifdef NORMAL\nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\n#ifdef REFLECTIONMAP_SKYBOX_TRANSFORMED\nvPositionUVW=(reflectionMatrix*vec4(positionUpdated,1.0)).xyz;\n#else\nvPositionUVW=positionUpdated;\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#include<bonesVertex>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR == 0u) {\ngl_Position=viewProjection*worldPos;\n} else {\ngl_Position=viewProjectionR*worldPos;\n}\n#else\ngl_Position=viewProjection*worldPos;\n#endif\nvPositionW=vec3(worldPos);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n\n#ifndef UV1\nvec2 uvUpdated=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uvUpdated;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nif (vDiffuseInfos.x == 0.)\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nif (vAmbientInfos.x == 0.)\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nif (vOpacityInfos.x == 0.)\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nif (vEmissiveInfos.x == 0.)\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nif (vLightmapInfos.x == 0.)\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM) && SPECULARDIRECTUV == 0\nif (vSpecularInfos.x == 0.)\n{\nvSpecularUV=vec2(specularMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvSpecularUV=vec2(specularMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nif (vBumpInfos.x == 0.)\n{\nvBumpUV=vec2(bumpMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvBumpUV=vec2(bumpMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#include<bumpVertex>\n#include<clipPlaneVertex>\n#include<fogVertex>\n#include<shadowsVertex>[0..maxSimultaneousLights]\n#ifdef VERTEXCOLOR\n\nvColor=color;\n#endif\n#include<pointCloudVertex>\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var defaultVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/depth.fragment.ts":
/*!***********************************!*\
  !*** ./Shaders/depth.fragment.ts ***!
  \***********************************/
/*! exports provided: depthPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthPixelShader", function() { return depthPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_packingFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/packingFunctions */ "./Shaders/ShadersInclude/packingFunctions.ts");


var name = 'depthPixelShader';
var shader = "#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform sampler2D diffuseSampler;\n#endif\nvarying float vDepthMetric;\n#ifdef PACKED\n#include<packingFunctions>\n#endif\nvoid main(void)\n{\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\n#ifdef NONLINEARDEPTH\n#ifdef PACKED\ngl_FragColor=pack(gl_FragCoord.z);\n#else\ngl_FragColor=vec4(gl_FragCoord.z,0.0,0.0,0.0);\n#endif\n#else\n#ifdef PACKED\ngl_FragColor=pack(vDepthMetric);\n#else\ngl_FragColor=vec4(vDepthMetric,0.0,0.0,1.0);\n#endif\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var depthPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/depth.vertex.ts":
/*!*********************************!*\
  !*** ./Shaders/depth.vertex.ts ***!
  \*********************************/
/*! exports provided: depthVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthVertexShader", function() { return depthVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");








var name = 'depthVertexShader';
var shader = "\nattribute vec3 position;\n#include<bonesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\nuniform vec2 depthValues;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;\nuniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\nvarying float vDepthMetric;\nvoid main(void)\n{\nvec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\nvDepthMetric=((gl_Position.z+depthValues.x)/(depthValues.y));\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var depthVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/depthBoxBlur.fragment.ts":
/*!******************************************!*\
  !*** ./Shaders/depthBoxBlur.fragment.ts ***!
  \******************************************/
/*! exports provided: depthBoxBlurPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthBoxBlurPixelShader", function() { return depthBoxBlurPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'depthBoxBlurPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n\nuniform vec2 screenSize;\nvoid main(void)\n{\nvec4 colorDepth=vec4(0.0);\nfor (int x=-OFFSET; x<=OFFSET; x++)\nfor (int y=-OFFSET; y<=OFFSET; y++)\ncolorDepth+=texture2D(textureSampler,vUV+vec2(x,y)/screenSize);\ngl_FragColor=(colorDepth/float((OFFSET*2+1)*(OFFSET*2+1)));\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var depthBoxBlurPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/depthOfField.fragment.ts":
/*!******************************************!*\
  !*** ./Shaders/depthOfField.fragment.ts ***!
  \******************************************/
/*! exports provided: depthOfFieldPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthOfFieldPixelShader", function() { return depthOfFieldPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'depthOfFieldPixelShader';
var shader = "\n\n\n\n\nuniform sampler2D textureSampler;\nuniform sampler2D highlightsSampler;\nuniform sampler2D depthSampler;\nuniform sampler2D grainSampler;\n\nuniform float grain_amount;\nuniform bool blur_noise;\nuniform float screen_width;\nuniform float screen_height;\nuniform float distortion;\nuniform bool dof_enabled;\n\nuniform float screen_distance;\nuniform float aperture;\nuniform float darken;\nuniform float edge_blur;\nuniform bool highlights;\n\nuniform float near;\nuniform float far;\n\nvarying vec2 vUV;\n\n#define PI 3.14159265\n#define TWOPI 6.28318530\n#define inverse_focal_length 0.1\n\nvec2 centered_screen_pos;\nvec2 distorted_coords;\nfloat radius2;\nfloat radius;\n\nvec2 rand(vec2 co)\n{\nfloat noise1=(fract(sin(dot(co,vec2(12.9898,78.233)))*43758.5453));\nfloat noise2=(fract(sin(dot(co,vec2(12.9898,78.233)*2.0))*43758.5453));\nreturn clamp(vec2(noise1,noise2),0.0,1.0);\n}\n\nvec2 getDistortedCoords(vec2 coords) {\nif (distortion == 0.0) { return coords; }\nvec2 direction=1.0*normalize(centered_screen_pos);\nvec2 dist_coords=vec2(0.5,0.5);\ndist_coords.x=0.5+direction.x*radius2*1.0;\ndist_coords.y=0.5+direction.y*radius2*1.0;\nfloat dist_amount=clamp(distortion*0.23,0.0,1.0);\ndist_coords=mix(coords,dist_coords,dist_amount);\nreturn dist_coords;\n}\n\nfloat sampleScreen(inout vec4 color,const in vec2 offset,const in float weight) {\n\nvec2 coords=distorted_coords;\nfloat angle=rand(coords*100.0).x*TWOPI;\ncoords+=vec2(offset.x*cos(angle)-offset.y*sin(angle),offset.x*sin(angle)+offset.y*cos(angle));\ncolor+=texture2D(textureSampler,coords)*weight;\nreturn weight;\n}\n\nfloat getBlurLevel(float size) {\nreturn min(3.0,ceil(size/1.0));\n}\n\nvec4 getBlurColor(float size) {\nvec4 col=texture2D(textureSampler,distorted_coords);\nif (size == 0.0) { return col; }\n\n\nfloat blur_level=getBlurLevel(size);\nfloat w=(size/screen_width);\nfloat h=(size/screen_height);\nfloat total_weight=1.0;\nvec2 sample_coords;\ntotal_weight+=sampleScreen(col,vec2(-0.50*w,0.24*h),0.93);\ntotal_weight+=sampleScreen(col,vec2(0.30*w,-0.75*h),0.90);\ntotal_weight+=sampleScreen(col,vec2(0.36*w,0.96*h),0.87);\ntotal_weight+=sampleScreen(col,vec2(-1.08*w,-0.55*h),0.85);\ntotal_weight+=sampleScreen(col,vec2(1.33*w,-0.37*h),0.83);\ntotal_weight+=sampleScreen(col,vec2(-0.82*w,1.31*h),0.80);\ntotal_weight+=sampleScreen(col,vec2(-0.31*w,-1.67*h),0.78);\ntotal_weight+=sampleScreen(col,vec2(1.47*w,1.11*h),0.76);\ntotal_weight+=sampleScreen(col,vec2(-1.97*w,0.19*h),0.74);\ntotal_weight+=sampleScreen(col,vec2(1.42*w,-1.57*h),0.72);\nif (blur_level>1.0) {\ntotal_weight+=sampleScreen(col,vec2(0.01*w,2.25*h),0.70);\ntotal_weight+=sampleScreen(col,vec2(-1.62*w,-1.74*h),0.67);\ntotal_weight+=sampleScreen(col,vec2(2.49*w,0.20*h),0.65);\ntotal_weight+=sampleScreen(col,vec2(-2.07*w,1.61*h),0.63);\ntotal_weight+=sampleScreen(col,vec2(0.46*w,-2.70*h),0.61);\ntotal_weight+=sampleScreen(col,vec2(1.55*w,2.40*h),0.59);\ntotal_weight+=sampleScreen(col,vec2(-2.88*w,-0.75*h),0.56);\ntotal_weight+=sampleScreen(col,vec2(2.73*w,-1.44*h),0.54);\ntotal_weight+=sampleScreen(col,vec2(-1.08*w,3.02*h),0.52);\ntotal_weight+=sampleScreen(col,vec2(-1.28*w,-3.05*h),0.49);\n}\nif (blur_level>2.0) {\ntotal_weight+=sampleScreen(col,vec2(3.11*w,1.43*h),0.46);\ntotal_weight+=sampleScreen(col,vec2(-3.36*w,1.08*h),0.44);\ntotal_weight+=sampleScreen(col,vec2(1.80*w,-3.16*h),0.41);\ntotal_weight+=sampleScreen(col,vec2(0.83*w,3.65*h),0.38);\ntotal_weight+=sampleScreen(col,vec2(-3.16*w,-2.19*h),0.34);\ntotal_weight+=sampleScreen(col,vec2(3.92*w,-0.53*h),0.31);\ntotal_weight+=sampleScreen(col,vec2(-2.59*w,3.12*h),0.26);\ntotal_weight+=sampleScreen(col,vec2(-0.20*w,-4.15*h),0.22);\ntotal_weight+=sampleScreen(col,vec2(3.02*w,3.00*h),0.15);\n}\ncol/=total_weight;\n\nif (darken>0.0) {\ncol.rgb*=clamp(0.3,1.0,1.05-size*0.5*darken);\n}\n\n\n\n\nreturn col;\n}\nvoid main(void)\n{\n\ncentered_screen_pos=vec2(vUV.x-0.5,vUV.y-0.5);\nradius2=centered_screen_pos.x*centered_screen_pos.x+centered_screen_pos.y*centered_screen_pos.y;\nradius=sqrt(radius2);\ndistorted_coords=getDistortedCoords(vUV);\nvec2 texels_coords=vec2(vUV.x*screen_width,vUV.y*screen_height);\nfloat depth=texture2D(depthSampler,distorted_coords).r;\nfloat distance=near+(far-near)*depth;\nvec4 color=texture2D(textureSampler,vUV);\n\n\nfloat coc=abs(aperture*(screen_distance*(inverse_focal_length-1.0/distance)-1.0));\n\nif (dof_enabled == false || coc<0.07) { coc=0.0; }\n\nfloat edge_blur_amount=0.0;\nif (edge_blur>0.0) {\nedge_blur_amount=clamp((radius*2.0-1.0+0.15*edge_blur)*1.5,0.0,1.0)*1.3;\n}\n\nfloat blur_amount=max(edge_blur_amount,coc);\n\nif (blur_amount == 0.0) {\ngl_FragColor=texture2D(textureSampler,distorted_coords);\n}\nelse {\n\ngl_FragColor=getBlurColor(blur_amount*1.7);\n\nif (highlights) {\ngl_FragColor.rgb+=clamp(coc,0.0,1.0)*texture2D(highlightsSampler,distorted_coords).rgb;\n}\nif (blur_noise) {\n\nvec2 noise=rand(distorted_coords)*0.01*blur_amount;\nvec2 blurred_coord=vec2(distorted_coords.x+noise.x,distorted_coords.y+noise.y);\ngl_FragColor=0.04*texture2D(textureSampler,blurred_coord)+0.96*gl_FragColor;\n}\n}\n\nif (grain_amount>0.0) {\nvec4 grain_color=texture2D(grainSampler,texels_coords*0.003);\ngl_FragColor.rgb+=(-0.5+grain_color.rgb)*0.30*grain_amount;\n}\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var depthOfFieldPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/depthOfFieldMerge.fragment.ts":
/*!***********************************************!*\
  !*** ./Shaders/depthOfFieldMerge.fragment.ts ***!
  \***********************************************/
/*! exports provided: depthOfFieldMergePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthOfFieldMergePixelShader", function() { return depthOfFieldMergePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'depthOfFieldMergePixelShader';
var shader = "uniform sampler2D textureSampler;\nvarying vec2 vUV;\nuniform sampler2D circleOfConfusionSampler;\nuniform sampler2D blurStep0;\n#if BLUR_LEVEL>0\nuniform sampler2D blurStep1;\n#endif\n#if BLUR_LEVEL>1\nuniform sampler2D blurStep2;\n#endif\nvoid main(void)\n{\nfloat coc=texture2D(circleOfConfusionSampler,vUV).r;\n#if BLUR_LEVEL == 0\nvec4 original=texture2D(textureSampler,vUV);\nvec4 blurred0=texture2D(blurStep0,vUV);\ngl_FragColor=mix(original,blurred0,coc);\n#endif\n#if BLUR_LEVEL == 1\nif(coc<0.5){\nvec4 original=texture2D(textureSampler,vUV);\nvec4 blurred1=texture2D(blurStep1,vUV);\ngl_FragColor=mix(original,blurred1,coc/0.5);\n}else{\nvec4 blurred0=texture2D(blurStep0,vUV);\nvec4 blurred1=texture2D(blurStep1,vUV);\ngl_FragColor=mix(blurred1,blurred0,(coc-0.5)/0.5);\n}\n#endif\n#if BLUR_LEVEL == 2\nif(coc<0.33){\nvec4 original=texture2D(textureSampler,vUV);\nvec4 blurred2=texture2D(blurStep2,vUV);\ngl_FragColor=mix(original,blurred2,coc/0.33);\n}else if(coc<0.66){\nvec4 blurred1=texture2D(blurStep1,vUV);\nvec4 blurred2=texture2D(blurStep2,vUV);\ngl_FragColor=mix(blurred2,blurred1,(coc-0.33)/0.33);\n}else{\nvec4 blurred0=texture2D(blurStep0,vUV);\nvec4 blurred1=texture2D(blurStep1,vUV);\ngl_FragColor=mix(blurred1,blurred0,(coc-0.66)/0.34);\n}\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var depthOfFieldMergePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/displayPass.fragment.ts":
/*!*****************************************!*\
  !*** ./Shaders/displayPass.fragment.ts ***!
  \*****************************************/
/*! exports provided: displayPassPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "displayPassPixelShader", function() { return displayPassPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'displayPassPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform sampler2D passSampler;\nvoid main(void)\n{\ngl_FragColor=texture2D(passSampler,vUV);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var displayPassPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/extractHighlights.fragment.ts":
/*!***********************************************!*\
  !*** ./Shaders/extractHighlights.fragment.ts ***!
  \***********************************************/
/*! exports provided: extractHighlightsPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "extractHighlightsPixelShader", function() { return extractHighlightsPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");


var name = 'extractHighlightsPixelShader';
var shader = "#include<helperFunctions>\n\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform float threshold;\nuniform float exposure;\nvoid main(void)\n{\ngl_FragColor=texture2D(textureSampler,vUV);\nfloat luma=getLuminance(gl_FragColor.rgb*exposure);\ngl_FragColor.rgb=step(threshold,luma)*gl_FragColor.rgb;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var extractHighlightsPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/filter.fragment.ts":
/*!************************************!*\
  !*** ./Shaders/filter.fragment.ts ***!
  \************************************/
/*! exports provided: filterPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "filterPixelShader", function() { return filterPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'filterPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform mat4 kernelMatrix;\nvoid main(void)\n{\nvec3 baseColor=texture2D(textureSampler,vUV).rgb;\nvec3 updatedColor=(kernelMatrix*vec4(baseColor,1.0)).rgb;\ngl_FragColor=vec4(updatedColor,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var filterPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/fxaa.fragment.ts":
/*!**********************************!*\
  !*** ./Shaders/fxaa.fragment.ts ***!
  \**********************************/
/*! exports provided: fxaaPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fxaaPixelShader", function() { return fxaaPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'fxaaPixelShader';
var shader = "uniform sampler2D textureSampler;\nuniform vec2 texelSize;\nvarying vec2 vUV;\nvarying vec2 sampleCoordS;\nvarying vec2 sampleCoordE;\nvarying vec2 sampleCoordN;\nvarying vec2 sampleCoordW;\nvarying vec2 sampleCoordNW;\nvarying vec2 sampleCoordSE;\nvarying vec2 sampleCoordNE;\nvarying vec2 sampleCoordSW;\nconst float fxaaQualitySubpix=1.0;\nconst float fxaaQualityEdgeThreshold=0.166;\nconst float fxaaQualityEdgeThresholdMin=0.0833;\nconst vec3 kLumaCoefficients=vec3(0.2126,0.7152,0.0722);\n#define FxaaLuma(rgba) dot(rgba.rgb,kLumaCoefficients)\nvoid main(){\nvec2 posM;\nposM.x=vUV.x;\nposM.y=vUV.y;\nvec4 rgbyM=texture2D(textureSampler,vUV,0.0);\nfloat lumaM=FxaaLuma(rgbyM);\nfloat lumaS=FxaaLuma(texture2D(textureSampler,sampleCoordS,0.0));\nfloat lumaE=FxaaLuma(texture2D(textureSampler,sampleCoordE,0.0));\nfloat lumaN=FxaaLuma(texture2D(textureSampler,sampleCoordN,0.0));\nfloat lumaW=FxaaLuma(texture2D(textureSampler,sampleCoordW,0.0));\nfloat maxSM=max(lumaS,lumaM);\nfloat minSM=min(lumaS,lumaM);\nfloat maxESM=max(lumaE,maxSM);\nfloat minESM=min(lumaE,minSM);\nfloat maxWN=max(lumaN,lumaW);\nfloat minWN=min(lumaN,lumaW);\nfloat rangeMax=max(maxWN,maxESM);\nfloat rangeMin=min(minWN,minESM);\nfloat rangeMaxScaled=rangeMax*fxaaQualityEdgeThreshold;\nfloat range=rangeMax-rangeMin;\nfloat rangeMaxClamped=max(fxaaQualityEdgeThresholdMin,rangeMaxScaled);\n#ifndef MALI\nif(range<rangeMaxClamped)\n{\ngl_FragColor=rgbyM;\nreturn;\n}\n#endif\nfloat lumaNW=FxaaLuma(texture2D(textureSampler,sampleCoordNW,0.0));\nfloat lumaSE=FxaaLuma(texture2D(textureSampler,sampleCoordSE,0.0));\nfloat lumaNE=FxaaLuma(texture2D(textureSampler,sampleCoordNE,0.0));\nfloat lumaSW=FxaaLuma(texture2D(textureSampler,sampleCoordSW,0.0));\nfloat lumaNS=lumaN+lumaS;\nfloat lumaWE=lumaW+lumaE;\nfloat subpixRcpRange=1.0/range;\nfloat subpixNSWE=lumaNS+lumaWE;\nfloat edgeHorz1=(-2.0*lumaM)+lumaNS;\nfloat edgeVert1=(-2.0*lumaM)+lumaWE;\nfloat lumaNESE=lumaNE+lumaSE;\nfloat lumaNWNE=lumaNW+lumaNE;\nfloat edgeHorz2=(-2.0*lumaE)+lumaNESE;\nfloat edgeVert2=(-2.0*lumaN)+lumaNWNE;\nfloat lumaNWSW=lumaNW+lumaSW;\nfloat lumaSWSE=lumaSW+lumaSE;\nfloat edgeHorz4=(abs(edgeHorz1)*2.0)+abs(edgeHorz2);\nfloat edgeVert4=(abs(edgeVert1)*2.0)+abs(edgeVert2);\nfloat edgeHorz3=(-2.0*lumaW)+lumaNWSW;\nfloat edgeVert3=(-2.0*lumaS)+lumaSWSE;\nfloat edgeHorz=abs(edgeHorz3)+edgeHorz4;\nfloat edgeVert=abs(edgeVert3)+edgeVert4;\nfloat subpixNWSWNESE=lumaNWSW+lumaNESE;\nfloat lengthSign=texelSize.x;\nbool horzSpan=edgeHorz>=edgeVert;\nfloat subpixA=subpixNSWE*2.0+subpixNWSWNESE;\nif (!horzSpan)\n{\nlumaN=lumaW;\n}\nif (!horzSpan)\n{\nlumaS=lumaE;\n}\nif (horzSpan)\n{\nlengthSign=texelSize.y;\n}\nfloat subpixB=(subpixA*(1.0/12.0))-lumaM;\nfloat gradientN=lumaN-lumaM;\nfloat gradientS=lumaS-lumaM;\nfloat lumaNN=lumaN+lumaM;\nfloat lumaSS=lumaS+lumaM;\nbool pairN=abs(gradientN)>=abs(gradientS);\nfloat gradient=max(abs(gradientN),abs(gradientS));\nif (pairN)\n{\nlengthSign=-lengthSign;\n}\nfloat subpixC=clamp(abs(subpixB)*subpixRcpRange,0.0,1.0);\nvec2 posB;\nposB.x=posM.x;\nposB.y=posM.y;\nvec2 offNP;\noffNP.x=(!horzSpan) ? 0.0 : texelSize.x;\noffNP.y=(horzSpan) ? 0.0 : texelSize.y;\nif (!horzSpan)\n{\nposB.x+=lengthSign*0.5;\n}\nif (horzSpan)\n{\nposB.y+=lengthSign*0.5;\n}\nvec2 posN;\nposN.x=posB.x-offNP.x*1.5;\nposN.y=posB.y-offNP.y*1.5;\nvec2 posP;\nposP.x=posB.x+offNP.x*1.5;\nposP.y=posB.y+offNP.y*1.5;\nfloat subpixD=((-2.0)*subpixC)+3.0;\nfloat lumaEndN=FxaaLuma(texture2D(textureSampler,posN,0.0));\nfloat subpixE=subpixC*subpixC;\nfloat lumaEndP=FxaaLuma(texture2D(textureSampler,posP,0.0));\nif (!pairN)\n{\nlumaNN=lumaSS;\n}\nfloat gradientScaled=gradient*1.0/4.0;\nfloat lumaMM=lumaM-lumaNN*0.5;\nfloat subpixF=subpixD*subpixE;\nbool lumaMLTZero=lumaMM<0.0;\nlumaEndN-=lumaNN*0.5;\nlumaEndP-=lumaNN*0.5;\nbool doneN=abs(lumaEndN)>=gradientScaled;\nbool doneP=abs(lumaEndP)>=gradientScaled;\nif (!doneN)\n{\nposN.x-=offNP.x*3.0;\n}\nif (!doneN)\n{\nposN.y-=offNP.y*3.0;\n}\nbool doneNP=(!doneN) || (!doneP);\nif (!doneP)\n{\nposP.x+=offNP.x*3.0;\n}\nif (!doneP)\n{\nposP.y+=offNP.y*3.0;\n}\nif (doneNP)\n{\nif (!doneN) lumaEndN=FxaaLuma(texture2D(textureSampler,posN.xy,0.0));\nif (!doneP) lumaEndP=FxaaLuma(texture2D(textureSampler,posP.xy,0.0));\nif (!doneN) lumaEndN=lumaEndN-lumaNN*0.5;\nif (!doneP) lumaEndP=lumaEndP-lumaNN*0.5;\ndoneN=abs(lumaEndN)>=gradientScaled;\ndoneP=abs(lumaEndP)>=gradientScaled;\nif (!doneN) posN.x-=offNP.x*12.0;\nif (!doneN) posN.y-=offNP.y*12.0;\ndoneNP=(!doneN) || (!doneP);\nif (!doneP) posP.x+=offNP.x*12.0;\nif (!doneP) posP.y+=offNP.y*12.0;\n}\nfloat dstN=posM.x-posN.x;\nfloat dstP=posP.x-posM.x;\nif (!horzSpan)\n{\ndstN=posM.y-posN.y;\n}\nif (!horzSpan)\n{\ndstP=posP.y-posM.y;\n}\nbool goodSpanN=(lumaEndN<0.0) != lumaMLTZero;\nfloat spanLength=(dstP+dstN);\nbool goodSpanP=(lumaEndP<0.0) != lumaMLTZero;\nfloat spanLengthRcp=1.0/spanLength;\nbool directionN=dstN<dstP;\nfloat dst=min(dstN,dstP);\nbool goodSpan=directionN ? goodSpanN : goodSpanP;\nfloat subpixG=subpixF*subpixF;\nfloat pixelOffset=(dst*(-spanLengthRcp))+0.5;\nfloat subpixH=subpixG*fxaaQualitySubpix;\nfloat pixelOffsetGood=goodSpan ? pixelOffset : 0.0;\nfloat pixelOffsetSubpix=max(pixelOffsetGood,subpixH);\nif (!horzSpan)\n{\nposM.x+=pixelOffsetSubpix*lengthSign;\n}\nif (horzSpan)\n{\nposM.y+=pixelOffsetSubpix*lengthSign;\n}\n#ifdef MALI\nif(range<rangeMaxClamped)\n{\ngl_FragColor=rgbyM;\n}\nelse\n{\ngl_FragColor=texture2D(textureSampler,posM,0.0);\n}\n#else\ngl_FragColor=texture2D(textureSampler,posM,0.0);\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var fxaaPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/fxaa.vertex.ts":
/*!********************************!*\
  !*** ./Shaders/fxaa.vertex.ts ***!
  \********************************/
/*! exports provided: fxaaVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fxaaVertexShader", function() { return fxaaVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'fxaaVertexShader';
var shader = "\nattribute vec2 position;\nuniform vec2 texelSize;\n\nvarying vec2 vUV;\nvarying vec2 sampleCoordS;\nvarying vec2 sampleCoordE;\nvarying vec2 sampleCoordN;\nvarying vec2 sampleCoordW;\nvarying vec2 sampleCoordNW;\nvarying vec2 sampleCoordSE;\nvarying vec2 sampleCoordNE;\nvarying vec2 sampleCoordSW;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nvUV=(position*madd+madd);\nsampleCoordS=vUV+vec2( 0.0,1.0)*texelSize;\nsampleCoordE=vUV+vec2( 1.0,0.0)*texelSize;\nsampleCoordN=vUV+vec2( 0.0,-1.0)*texelSize;\nsampleCoordW=vUV+vec2(-1.0,0.0)*texelSize;\nsampleCoordNW=vUV+vec2(-1.0,-1.0)*texelSize;\nsampleCoordSE=vUV+vec2( 1.0,1.0)*texelSize;\nsampleCoordNE=vUV+vec2( 1.0,-1.0)*texelSize;\nsampleCoordSW=vUV+vec2(-1.0,1.0)*texelSize;\ngl_Position=vec4(position,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var fxaaVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/geometry.fragment.ts":
/*!**************************************!*\
  !*** ./Shaders/geometry.fragment.ts ***!
  \**************************************/
/*! exports provided: geometryPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "geometryPixelShader", function() { return geometryPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_mrtFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/mrtFragmentDeclaration */ "./Shaders/ShadersInclude/mrtFragmentDeclaration.ts");


var name = 'geometryPixelShader';
var shader = "#extension GL_EXT_draw_buffers : require\nprecision highp float;\nprecision highp int;\nvarying vec3 vNormalV;\nvarying vec4 vViewPos;\n#ifdef POSITION\nvarying vec3 vPosition;\n#endif\n#ifdef VELOCITY\nvarying vec4 vCurrentPosition;\nvarying vec4 vPreviousPosition;\n#endif\n#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform sampler2D diffuseSampler;\n#endif\n#include<mrtFragmentDeclaration>[RENDER_TARGET_COUNT]\nvoid main() {\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\ngl_FragData[0]=vec4(vViewPos.z/vViewPos.w,0.0,0.0,1.0);\n\ngl_FragData[1]=vec4(normalize(vNormalV),1.0);\n\n#ifdef POSITION\ngl_FragData[POSITION_INDEX]=vec4(vPosition,1.0);\n#endif\n#ifdef VELOCITY\nvec2 a=(vCurrentPosition.xy/vCurrentPosition.w)*0.5+0.5;\nvec2 b=(vPreviousPosition.xy/vPreviousPosition.w)*0.5+0.5;\nvec2 velocity=abs(a-b);\nvelocity=vec2(pow(velocity.x,1.0/3.0),pow(velocity.y,1.0/3.0))*sign(a-b)*0.5+0.5;\ngl_FragData[VELOCITY_INDEX]=vec4(velocity,0.0,1.0);\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var geometryPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/geometry.vertex.ts":
/*!************************************!*\
  !*** ./Shaders/geometry.vertex.ts ***!
  \************************************/
/*! exports provided: geometryVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "geometryVertexShader", function() { return geometryVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");








var name = 'geometryVertexShader';
var shader = "precision highp float;\nprecision highp int;\n#include<bonesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<instancesDeclaration>\nattribute vec3 position;\nattribute vec3 normal;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;\nuniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n\nuniform mat4 viewProjection;\nuniform mat4 view;\nvarying vec3 vNormalV;\nvarying vec4 vViewPos;\n#ifdef POSITION\nvarying vec3 vPosition;\n#endif\n#ifdef VELOCITY\nuniform mat4 previousWorld;\nuniform mat4 previousViewProjection;\n#ifdef BONES_VELOCITY_ENABLED\n#if NUM_BONE_INFLUENCERS>0\nuniform mat4 mPreviousBones[BonesPerMesh];\n#endif\n#endif\nvarying vec4 vCurrentPosition;\nvarying vec4 vPreviousPosition;\n#endif\nvoid main(void)\n{\nvec3 positionUpdated=position;\nvec3 normalUpdated=normal;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#if defined(VELOCITY) && !defined(BONES_VELOCITY_ENABLED)\n\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);\nvPreviousPosition=previousViewProjection*previousWorld*vec4(positionUpdated,1.0);\n#endif\n#include<bonesVertex>\nvec4 pos=vec4(finalWorld*vec4(positionUpdated,1.0));\nvNormalV=normalize(vec3((view*finalWorld)*vec4(normalUpdated,0.0)));\nvViewPos=view*pos;\n#if defined(VELOCITY) && defined(BONES_VELOCITY_ENABLED)\nvCurrentPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n#if NUM_BONE_INFLUENCERS>0\nmat4 previousInfluence;\npreviousInfluence=mPreviousBones[int(matricesIndices[0])]*matricesWeights[0];\n#if NUM_BONE_INFLUENCERS>1\npreviousInfluence+=mPreviousBones[int(matricesIndices[1])]*matricesWeights[1];\n#endif\n#if NUM_BONE_INFLUENCERS>2\npreviousInfluence+=mPreviousBones[int(matricesIndices[2])]*matricesWeights[2];\n#endif\n#if NUM_BONE_INFLUENCERS>3\npreviousInfluence+=mPreviousBones[int(matricesIndices[3])]*matricesWeights[3];\n#endif\n#if NUM_BONE_INFLUENCERS>4\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[0])]*matricesWeightsExtra[0];\n#endif\n#if NUM_BONE_INFLUENCERS>5\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[1])]*matricesWeightsExtra[1];\n#endif\n#if NUM_BONE_INFLUENCERS>6\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[2])]*matricesWeightsExtra[2];\n#endif\n#if NUM_BONE_INFLUENCERS>7\npreviousInfluence+=mPreviousBones[int(matricesIndicesExtra[3])]*matricesWeightsExtra[3];\n#endif\nvPreviousPosition=previousViewProjection*previousWorld*previousInfluence*vec4(positionUpdated,1.0);\n#else\nvPreviousPosition=previousViewProjection*previousWorld*vec4(positionUpdated,1.0);\n#endif\n#endif\n#ifdef POSITION\nvPosition=pos.xyz/pos.w;\n#endif\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var geometryVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/glowBlurPostProcess.fragment.ts":
/*!*************************************************!*\
  !*** ./Shaders/glowBlurPostProcess.fragment.ts ***!
  \*************************************************/
/*! exports provided: glowBlurPostProcessPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "glowBlurPostProcessPixelShader", function() { return glowBlurPostProcessPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'glowBlurPostProcessPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n\nuniform vec2 screenSize;\nuniform vec2 direction;\nuniform float blurWidth;\n\nfloat getLuminance(vec3 color)\n{\nreturn dot(color,vec3(0.2126,0.7152,0.0722));\n}\nvoid main(void)\n{\nfloat weights[7];\nweights[0]=0.05;\nweights[1]=0.1;\nweights[2]=0.2;\nweights[3]=0.3;\nweights[4]=0.2;\nweights[5]=0.1;\nweights[6]=0.05;\nvec2 texelSize=vec2(1.0/screenSize.x,1.0/screenSize.y);\nvec2 texelStep=texelSize*direction*blurWidth;\nvec2 start=vUV-3.0*texelStep;\nvec4 baseColor=vec4(0.,0.,0.,0.);\nvec2 texelOffset=vec2(0.,0.);\nfor (int i=0; i<7; i++)\n{\n\nvec4 texel=texture2D(textureSampler,start+texelOffset);\nbaseColor.a+=texel.a*weights[i];\n\nfloat luminance=getLuminance(baseColor.rgb);\nfloat luminanceTexel=getLuminance(texel.rgb);\nfloat choice=step(luminanceTexel,luminance);\nbaseColor.rgb=choice*baseColor.rgb+(1.0-choice)*texel.rgb;\ntexelOffset+=texelStep;\n}\ngl_FragColor=baseColor;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var glowBlurPostProcessPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/glowMapGeneration.fragment.ts":
/*!***********************************************!*\
  !*** ./Shaders/glowMapGeneration.fragment.ts ***!
  \***********************************************/
/*! exports provided: glowMapGenerationPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "glowMapGenerationPixelShader", function() { return glowMapGenerationPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'glowMapGenerationPixelShader';
var shader = "#ifdef DIFFUSE\nvarying vec2 vUVDiffuse;\nuniform sampler2D diffuseSampler;\n#endif\n#ifdef OPACITY\nvarying vec2 vUVOpacity;\nuniform sampler2D opacitySampler;\nuniform float opacityIntensity;\n#endif\n#ifdef EMISSIVE\nvarying vec2 vUVEmissive;\nuniform sampler2D emissiveSampler;\n#endif\n#ifdef VERTEXALPHA\nvarying vec4 vColor;\n#endif\nuniform vec4 glowColor;\nvoid main(void)\n{\nvec4 finalColor=glowColor;\n\n#ifdef DIFFUSE\nvec4 albedoTexture=texture2D(diffuseSampler,vUVDiffuse);\nfinalColor.a*=albedoTexture.a;\n#endif\n#ifdef OPACITY\nvec4 opacityMap=texture2D(opacitySampler,vUVOpacity);\n#ifdef OPACITYRGB\nfinalColor.a*=getLuminance(opacityMap.rgb);\n#else\nfinalColor.a*=opacityMap.a;\n#endif\nfinalColor.a*=opacityIntensity;\n#endif\n#ifdef VERTEXALPHA\nfinalColor.a*=vColor.a;\n#endif\n#ifdef ALPHATEST\nif (finalColor.a<ALPHATESTVALUE)\ndiscard;\n#endif\n#ifdef EMISSIVE\ngl_FragColor=texture2D(emissiveSampler,vUVEmissive)*finalColor;\n#else\ngl_FragColor=finalColor;\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var glowMapGenerationPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/glowMapGeneration.vertex.ts":
/*!*********************************************!*\
  !*** ./Shaders/glowMapGeneration.vertex.ts ***!
  \*********************************************/
/*! exports provided: glowMapGenerationVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "glowMapGenerationVertexShader", function() { return glowMapGenerationVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");








var name = 'glowMapGenerationVertexShader';
var shader = "\nattribute vec3 position;\n#include<bonesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\nvarying vec4 vPosition;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef DIFFUSE\nvarying vec2 vUVDiffuse;\nuniform mat4 diffuseMatrix;\n#endif\n#ifdef OPACITY\nvarying vec2 vUVOpacity;\nuniform mat4 opacityMatrix;\n#endif\n#ifdef EMISSIVE\nvarying vec2 vUVEmissive;\nuniform mat4 emissiveMatrix;\n#endif\n#ifdef VERTEXALPHA\nattribute vec4 color;\nvarying vec4 vColor;\n#endif\nvoid main(void)\n{\nvec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#ifdef CUBEMAP\nvPosition=finalWorld*vec4(positionUpdated,1.0);\ngl_Position=viewProjection*finalWorld*vec4(position,1.0);\n#else\nvPosition=viewProjection*finalWorld*vec4(positionUpdated,1.0);\ngl_Position=vPosition;\n#endif\n#ifdef DIFFUSE\n#ifdef DIFFUSEUV1\nvUVDiffuse=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef DIFFUSEUV2\nvUVDiffuse=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n#ifdef OPACITY\n#ifdef OPACITYUV1\nvUVOpacity=vec2(opacityMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef OPACITYUV2\nvUVOpacity=vec2(opacityMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n#ifdef EMISSIVE\n#ifdef EMISSIVEUV1\nvUVEmissive=vec2(emissiveMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef EMISSIVEUV2\nvUVEmissive=vec2(emissiveMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n#ifdef VERTEXALPHA\nvColor=color;\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var glowMapGenerationVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/glowMapMerge.fragment.ts":
/*!******************************************!*\
  !*** ./Shaders/glowMapMerge.fragment.ts ***!
  \******************************************/
/*! exports provided: glowMapMergePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "glowMapMergePixelShader", function() { return glowMapMergePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'glowMapMergePixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n#ifdef EMISSIVE\nuniform sampler2D textureSampler2;\n#endif\n\nuniform float offset;\nvoid main(void) {\nvec4 baseColor=texture2D(textureSampler,vUV);\n#ifdef EMISSIVE\nbaseColor+=texture2D(textureSampler2,vUV);\nbaseColor*=offset;\n#else\nbaseColor.a=abs(offset-baseColor.a);\n#ifdef STROKE\nfloat alpha=smoothstep(.0,.1,baseColor.a);\nbaseColor.a=alpha;\nbaseColor.rgb=baseColor.rgb*alpha;\n#endif\n#endif\ngl_FragColor=baseColor;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var glowMapMergePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/glowMapMerge.vertex.ts":
/*!****************************************!*\
  !*** ./Shaders/glowMapMerge.vertex.ts ***!
  \****************************************/
/*! exports provided: glowMapMergeVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "glowMapMergeVertexShader", function() { return glowMapMergeVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'glowMapMergeVertexShader';
var shader = "\nattribute vec2 position;\n\nvarying vec2 vUV;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nvUV=position*madd+madd;\ngl_Position=vec4(position,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var glowMapMergeVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/gpuRenderParticles.fragment.ts":
/*!************************************************!*\
  !*** ./Shaders/gpuRenderParticles.fragment.ts ***!
  \************************************************/
/*! exports provided: gpuRenderParticlesPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gpuRenderParticlesPixelShader", function() { return gpuRenderParticlesPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragmentDeclaration2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragmentDeclaration2 */ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration2.ts");
/* harmony import */ var _ShadersInclude_imageProcessingDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingDeclaration */ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_imageProcessingFunctions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingFunctions */ "./Shaders/ShadersInclude/imageProcessingFunctions.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragment__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragment */ "./Shaders/ShadersInclude/clipPlaneFragment.ts");






var name = 'gpuRenderParticlesPixelShader';
var shader = "#version 300 es\nuniform sampler2D textureSampler;\nin vec2 vUV;\nin vec4 vColor;\nout vec4 outFragColor;\n#include<clipPlaneFragmentDeclaration2>\n#include<imageProcessingDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\nvoid main() {\n#include<clipPlaneFragment>\nvec4 textureColor=texture(textureSampler,vUV);\noutFragColor=textureColor*vColor;\n#ifdef BLENDMULTIPLYMODE\nfloat alpha=vColor.a*textureColor.a;\noutFragColor.rgb=outFragColor.rgb*alpha+vec3(1.0)*(1.0-alpha);\n#endif\n\n\n#ifdef IMAGEPROCESSINGPOSTPROCESS\noutFragColor.rgb=toLinearSpace(outFragColor.rgb);\n#else\n#ifdef IMAGEPROCESSING\noutFragColor.rgb=toLinearSpace(outFragColor.rgb);\noutFragColor=applyImageProcessing(outFragColor);\n#endif\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var gpuRenderParticlesPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/gpuRenderParticles.vertex.ts":
/*!**********************************************!*\
  !*** ./Shaders/gpuRenderParticles.vertex.ts ***!
  \**********************************************/
/*! exports provided: gpuRenderParticlesVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gpuRenderParticlesVertexShader", function() { return gpuRenderParticlesVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertexDeclaration2__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertexDeclaration2 */ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration2.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertex */ "./Shaders/ShadersInclude/clipPlaneVertex.ts");



var name = 'gpuRenderParticlesVertexShader';
var shader = "#version 300 es\nuniform mat4 view;\nuniform mat4 projection;\nuniform vec2 translationPivot;\nuniform vec3 worldOffset;\n\nin vec3 position;\nin float age;\nin float life;\nin vec3 size;\n#ifndef BILLBOARD\nin vec3 initialDirection;\n#endif\n#ifdef BILLBOARDSTRETCHED\nin vec3 direction;\n#endif\nin float angle;\n#ifdef ANIMATESHEET\nin float cellIndex;\n#endif\nin vec2 offset;\nin vec2 uv;\nout vec2 vUV;\nout vec4 vColor;\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4)\nuniform mat4 invView;\n#endif\n#include<clipPlaneVertexDeclaration2>\n#ifdef COLORGRADIENTS\nuniform sampler2D colorGradientSampler;\n#else\nuniform vec4 colorDead;\nin vec4 color;\n#endif\n#ifdef ANIMATESHEET\nuniform vec3 sheetInfos;\n#endif\n#ifdef BILLBOARD\nuniform vec3 eyePosition;\n#endif\nvec3 rotate(vec3 yaxis,vec3 rotatedCorner) {\nvec3 xaxis=normalize(cross(vec3(0.,1.0,0.),yaxis));\nvec3 zaxis=normalize(cross(yaxis,xaxis));\nvec3 row0=vec3(xaxis.x,xaxis.y,xaxis.z);\nvec3 row1=vec3(yaxis.x,yaxis.y,yaxis.z);\nvec3 row2=vec3(zaxis.x,zaxis.y,zaxis.z);\nmat3 rotMatrix=mat3(row0,row1,row2);\nvec3 alignedCorner=rotMatrix*rotatedCorner;\nreturn (position+worldOffset)+alignedCorner;\n}\n#ifdef BILLBOARDSTRETCHED\nvec3 rotateAlign(vec3 toCamera,vec3 rotatedCorner) {\nvec3 normalizedToCamera=normalize(toCamera);\nvec3 normalizedCrossDirToCamera=normalize(cross(normalize(direction),normalizedToCamera));\nvec3 crossProduct=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\nvec3 row0=vec3(normalizedCrossDirToCamera.x,normalizedCrossDirToCamera.y,normalizedCrossDirToCamera.z);\nvec3 row1=vec3(crossProduct.x,crossProduct.y,crossProduct.z);\nvec3 row2=vec3(normalizedToCamera.x,normalizedToCamera.y,normalizedToCamera.z);\nmat3 rotMatrix=mat3(row0,row1,row2);\nvec3 alignedCorner=rotMatrix*rotatedCorner;\nreturn (position+worldOffset)+alignedCorner;\n}\n#endif\nvoid main() {\n#ifdef ANIMATESHEET\nfloat rowOffset=floor(cellIndex/sheetInfos.z);\nfloat columnOffset=cellIndex-rowOffset*sheetInfos.z;\nvec2 uvScale=sheetInfos.xy;\nvec2 uvOffset=vec2(uv.x ,1.0-uv.y);\nvUV=(uvOffset+vec2(columnOffset,rowOffset))*uvScale;\n#else\nvUV=uv;\n#endif\nfloat ratio=age/life;\n#ifdef COLORGRADIENTS\nvColor=texture(colorGradientSampler,vec2(ratio,0));\n#else\nvColor=color*vec4(1.0-ratio)+colorDead*vec4(ratio);\n#endif\nvec2 cornerPos=(offset-translationPivot)*size.yz*size.x+translationPivot;\n#ifdef BILLBOARD\nvec4 rotatedCorner;\nrotatedCorner.w=0.;\n#ifdef BILLBOARDY\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.y=0.;\nvec3 yaxis=(position+worldOffset)-eyePosition;\nyaxis.y=0.;\nvec3 worldPos=rotate(normalize(yaxis),rotatedCorner.xyz);\nvec4 viewPosition=(view*vec4(worldPos,1.0));\n#elif defined(BILLBOARDSTRETCHED)\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.z=0.;\nvec3 toCamera=(position+worldOffset)-eyePosition;\nvec3 worldPos=rotateAlign(toCamera,rotatedCorner.xyz);\nvec4 viewPosition=(view*vec4(worldPos,1.0));\n#else\n\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.z=0.;\n\nvec4 viewPosition=view*vec4((position+worldOffset),1.0)+rotatedCorner;\n#endif\n#else\n\nvec3 rotatedCorner;\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.y=0.;\nrotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nvec3 yaxis=normalize(initialDirection);\nvec3 worldPos=rotate(yaxis,rotatedCorner);\n\nvec4 viewPosition=view*vec4(worldPos,1.0);\n#endif\ngl_Position=projection*viewPosition;\n\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4)\nvec4 worldPos=invView*viewPosition;\n#endif\n#include<clipPlaneVertex>\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var gpuRenderParticlesVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/gpuUpdateParticles.fragment.ts":
/*!************************************************!*\
  !*** ./Shaders/gpuUpdateParticles.fragment.ts ***!
  \************************************************/
/*! exports provided: gpuUpdateParticlesPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gpuUpdateParticlesPixelShader", function() { return gpuUpdateParticlesPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'gpuUpdateParticlesPixelShader';
var shader = "#version 300 es\nvoid main() {\ndiscard;\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var gpuUpdateParticlesPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/gpuUpdateParticles.vertex.ts":
/*!**********************************************!*\
  !*** ./Shaders/gpuUpdateParticles.vertex.ts ***!
  \**********************************************/
/*! exports provided: gpuUpdateParticlesVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gpuUpdateParticlesVertexShader", function() { return gpuUpdateParticlesVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'gpuUpdateParticlesVertexShader';
var shader = "#version 300 es\n#define PI 3.14159\nuniform float currentCount;\nuniform float timeDelta;\nuniform float stopFactor;\nuniform mat4 emitterWM;\nuniform vec2 lifeTime;\nuniform vec2 emitPower;\nuniform vec2 sizeRange;\nuniform vec4 scaleRange;\n#ifndef COLORGRADIENTS\nuniform vec4 color1;\nuniform vec4 color2;\n#endif\nuniform vec3 gravity;\nuniform sampler2D randomSampler;\nuniform sampler2D randomSampler2;\nuniform vec4 angleRange;\n#ifdef BOXEMITTER\nuniform vec3 direction1;\nuniform vec3 direction2;\nuniform vec3 minEmitBox;\nuniform vec3 maxEmitBox;\n#endif\n#ifdef POINTEMITTER\nuniform vec3 direction1;\nuniform vec3 direction2;\n#endif\n#ifdef HEMISPHERICEMITTER\nuniform float radius;\nuniform float radiusRange;\nuniform float directionRandomizer;\n#endif\n#ifdef SPHEREEMITTER\nuniform float radius;\nuniform float radiusRange;\n#ifdef DIRECTEDSPHEREEMITTER\nuniform vec3 direction1;\nuniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CYLINDEREMITTER\nuniform float radius;\nuniform float height;\nuniform float radiusRange;\n#ifdef DIRECTEDCYLINDEREMITTER\nuniform vec3 direction1;\nuniform vec3 direction2;\n#else\nuniform float directionRandomizer;\n#endif\n#endif\n#ifdef CONEEMITTER\nuniform vec2 radius;\nuniform float coneAngle;\nuniform vec2 height;\nuniform float directionRandomizer;\n#endif\n\nin vec3 position;\nin float age;\nin float life;\nin vec4 seed;\nin vec3 size;\n#ifndef COLORGRADIENTS\nin vec4 color;\n#endif\nin vec3 direction;\n#ifndef BILLBOARD\nin vec3 initialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nin float angle;\n#else\nin vec2 angle;\n#endif\n#ifdef ANIMATESHEET\nin float cellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nin float cellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nin vec3 noiseCoordinates1;\nin vec3 noiseCoordinates2;\n#endif\n\nout vec3 outPosition;\nout float outAge;\nout float outLife;\nout vec4 outSeed;\nout vec3 outSize;\n#ifndef COLORGRADIENTS\nout vec4 outColor;\n#endif\nout vec3 outDirection;\n#ifndef BILLBOARD\nout vec3 outInitialDirection;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nout float outAngle;\n#else\nout vec2 outAngle;\n#endif\n#ifdef ANIMATESHEET\nout float outCellIndex;\n#ifdef ANIMATESHEETRANDOMSTART\nout float outCellStartOffset;\n#endif\n#endif\n#ifdef NOISE\nout vec3 outNoiseCoordinates1;\nout vec3 outNoiseCoordinates2;\n#endif\n#ifdef SIZEGRADIENTS\nuniform sampler2D sizeGradientSampler;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nuniform sampler2D angularSpeedGradientSampler;\n#endif\n#ifdef VELOCITYGRADIENTS\nuniform sampler2D velocityGradientSampler;\n#endif\n#ifdef LIMITVELOCITYGRADIENTS\nuniform sampler2D limitVelocityGradientSampler;\nuniform float limitVelocityDamping;\n#endif\n#ifdef DRAGGRADIENTS\nuniform sampler2D dragGradientSampler;\n#endif\n#ifdef NOISE\nuniform vec3 noiseStrength;\nuniform sampler2D noiseSampler;\n#endif\n#ifdef ANIMATESHEET\nuniform vec3 cellInfos;\n#endif\nvec3 getRandomVec3(float offset) {\nreturn texture(randomSampler2,vec2(float(gl_VertexID)*offset/currentCount,0)).rgb;\n}\nvec4 getRandomVec4(float offset) {\nreturn texture(randomSampler,vec2(float(gl_VertexID)*offset/currentCount,0));\n}\nvoid main() {\nfloat newAge=age+timeDelta;\n\nif (newAge>=life && stopFactor != 0.) {\nvec3 position;\nvec3 direction;\n\nvec4 randoms=getRandomVec4(seed.x);\n\noutLife=lifeTime.x+(lifeTime.y-lifeTime.x)*randoms.r;\noutAge=mod(newAge,outLife);\n\noutSeed=seed;\n\n#ifdef SIZEGRADIENTS\noutSize.x=texture(sizeGradientSampler,vec2(0,0)).r;\n#else\noutSize.x=sizeRange.x+(sizeRange.y-sizeRange.x)*randoms.g;\n#endif\noutSize.y=scaleRange.x+(scaleRange.y-scaleRange.x)*randoms.b;\noutSize.z=scaleRange.z+(scaleRange.w-scaleRange.z)*randoms.a;\n#ifndef COLORGRADIENTS\n\noutColor=color1+(color2-color1)*randoms.b;\n#endif\n\n#ifndef ANGULARSPEEDGRADIENTS\noutAngle.y=angleRange.x+(angleRange.y-angleRange.x)*randoms.a;\noutAngle.x=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#else\noutAngle=angleRange.z+(angleRange.w-angleRange.z)*randoms.r;\n#endif\n\n#ifdef POINTEMITTER\nvec3 randoms2=getRandomVec3(seed.y);\nvec3 randoms3=getRandomVec3(seed.z);\nposition=vec3(0,0,0);\ndirection=direction1+(direction2-direction1)*randoms3;\n#elif defined(BOXEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);\nvec3 randoms3=getRandomVec3(seed.z);\nposition=minEmitBox+(maxEmitBox-minEmitBox)*randoms2;\ndirection=direction1+(direction2-direction1)*randoms3;\n#elif defined(HEMISPHERICEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);\nvec3 randoms3=getRandomVec3(seed.z);\n\nfloat phi=2.0*PI*randoms2.x;\nfloat theta=acos(2.0*randoms2.y-1.0);\nfloat randX=cos(phi)*sin(theta);\nfloat randY=cos(theta);\nfloat randZ=sin(phi)*sin(theta);\nposition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,abs(randY),randZ);\ndirection=position+directionRandomizer*randoms3;\n#elif defined(SPHEREEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);\nvec3 randoms3=getRandomVec3(seed.z);\n\nfloat phi=2.0*PI*randoms2.x;\nfloat theta=acos(2.0*randoms2.y-1.0);\nfloat randX=cos(phi)*sin(theta);\nfloat randY=cos(theta);\nfloat randZ=sin(phi)*sin(theta);\nposition=(radius-(radius*radiusRange*randoms2.z))*vec3(randX,randY,randZ);\n#ifdef DIRECTEDSPHEREEMITTER\ndirection=direction1+(direction2-direction1)*randoms3;\n#else\n\ndirection=position+directionRandomizer*randoms3;\n#endif\n#elif defined(CYLINDEREMITTER)\nvec3 randoms2=getRandomVec3(seed.y);\nvec3 randoms3=getRandomVec3(seed.z);\n\nfloat yPos=(randoms2.x-0.5)*height;\nfloat angle=randoms2.y*PI*2.;\nfloat inverseRadiusRangeSquared=((1.-radiusRange)*(1.-radiusRange));\nfloat positionRadius=radius*sqrt(inverseRadiusRangeSquared+(randoms2.z*(1.-inverseRadiusRangeSquared)));\nfloat xPos=positionRadius*cos(angle);\nfloat zPos=positionRadius*sin(angle);\nposition=vec3(xPos,yPos,zPos);\n#ifdef DIRECTEDCYLINDEREMITTER\ndirection=direction1+(direction2-direction1)*randoms3;\n#else\n\nangle=angle+((randoms3.x-0.5)*PI);\ndirection=vec3(cos(angle),randoms3.y-0.5,sin(angle));\ndirection=normalize(direction);\n#endif\n#elif defined(CONEEMITTER)\nvec3 randoms2=getRandomVec3(seed.y);\nfloat s=2.0*PI*randoms2.x;\n#ifdef CONEEMITTERSPAWNPOINT\nfloat h=0.0001;\n#else\nfloat h=randoms2.y*height.y;\n\nh=1.-h*h;\n#endif\nfloat lRadius=radius.x-radius.x*randoms2.z*radius.y;\nlRadius=lRadius*h;\nfloat randX=lRadius*sin(s);\nfloat randZ=lRadius*cos(s);\nfloat randY=h*height.x;\nposition=vec3(randX,randY,randZ);\n\nif (abs(cos(coneAngle)) == 1.0) {\ndirection=vec3(0.,1.0,0.);\n} else {\nvec3 randoms3=getRandomVec3(seed.z);\ndirection=normalize(position+directionRandomizer*randoms3);\n}\n#else\n\nposition=vec3(0.,0.,0.);\n\ndirection=2.0*(getRandomVec3(seed.w)-vec3(0.5,0.5,0.5));\n#endif\nfloat power=emitPower.x+(emitPower.y-emitPower.x)*randoms.a;\noutPosition=(emitterWM*vec4(position,1.)).xyz;\nvec3 initial=(emitterWM*vec4(direction,0.)).xyz;\noutDirection=initial*power;\n#ifndef BILLBOARD\noutInitialDirection=initial;\n#endif\n#ifdef ANIMATESHEET\noutCellIndex=cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=randoms.a*outLife;\n#endif\n#endif\n#ifdef NOISE\noutNoiseCoordinates1=noiseCoordinates1;\noutNoiseCoordinates2=noiseCoordinates2;\n#endif\n} else {\nfloat directionScale=timeDelta;\noutAge=newAge;\nfloat ageGradient=newAge/life;\n#ifdef VELOCITYGRADIENTS\ndirectionScale*=texture(velocityGradientSampler,vec2(ageGradient,0)).r;\n#endif\n#ifdef DRAGGRADIENTS\ndirectionScale*=1.0-texture(dragGradientSampler,vec2(ageGradient,0)).r;\n#endif\noutPosition=position+direction*directionScale;\noutLife=life;\noutSeed=seed;\n#ifndef COLORGRADIENTS\noutColor=color;\n#endif\n#ifdef SIZEGRADIENTS\noutSize.x=texture(sizeGradientSampler,vec2(ageGradient,0)).r;\noutSize.yz=size.yz;\n#else\noutSize=size;\n#endif\n#ifndef BILLBOARD\noutInitialDirection=initialDirection;\n#endif\nvec3 updatedDirection=direction+gravity*timeDelta;\n#ifdef LIMITVELOCITYGRADIENTS\nfloat limitVelocity=texture(limitVelocityGradientSampler,vec2(ageGradient,0)).r;\nfloat currentVelocity=length(updatedDirection);\nif (currentVelocity>limitVelocity) {\nupdatedDirection=updatedDirection*limitVelocityDamping;\n}\n#endif\noutDirection=updatedDirection;\n#ifdef NOISE\nvec3 localPosition=outPosition-emitterWM[3].xyz;\nfloat fetchedR=texture(noiseSampler,vec2(noiseCoordinates1.x,noiseCoordinates1.y)*vec2(0.5)+vec2(0.5)).r;\nfloat fetchedG=texture(noiseSampler,vec2(noiseCoordinates1.z,noiseCoordinates2.x)*vec2(0.5)+vec2(0.5)).r;\nfloat fetchedB=texture(noiseSampler,vec2(noiseCoordinates2.y,noiseCoordinates2.z)*vec2(0.5)+vec2(0.5)).r;\nvec3 force=vec3(2.*fetchedR-1.,2.*fetchedG-1.,2.*fetchedB-1.)*noiseStrength;\noutDirection=outDirection+force*timeDelta;\noutNoiseCoordinates1=noiseCoordinates1;\noutNoiseCoordinates2=noiseCoordinates2;\n#endif\n#ifdef ANGULARSPEEDGRADIENTS\nfloat angularSpeed=texture(angularSpeedGradientSampler,vec2(ageGradient,0)).r;\noutAngle=angle+angularSpeed*timeDelta;\n#else\noutAngle=vec2(angle.x+angle.y*timeDelta,angle.y);\n#endif\n#ifdef ANIMATESHEET\nfloat offsetAge=outAge;\nfloat dist=cellInfos.y-cellInfos.x;\n#ifdef ANIMATESHEETRANDOMSTART\noutCellStartOffset=cellStartOffset;\noffsetAge+=cellStartOffset;\n#endif\nfloat ratio=clamp(mod(offsetAge*cellInfos.z,life)/life,0.,1.0);\noutCellIndex=float(int(cellInfos.x+ratio*dist));\n#endif\n}\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var gpuUpdateParticlesVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/grain.fragment.ts":
/*!***********************************!*\
  !*** ./Shaders/grain.fragment.ts ***!
  \***********************************/
/*! exports provided: grainPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "grainPixelShader", function() { return grainPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");


var name = 'grainPixelShader';
var shader = "#include<helperFunctions>\n\nuniform sampler2D textureSampler;\n\nuniform float intensity;\nuniform float animatedSeed;\n\nvarying vec2 vUV;\nvoid main(void)\n{\ngl_FragColor=texture2D(textureSampler,vUV);\nvec2 seed=vUV*(animatedSeed);\nfloat grain=dither(seed,intensity);\n\nfloat lum=getLuminance(gl_FragColor.rgb);\nfloat grainAmount=(cos(-PI+(lum*PI*2.))+1.)/2.;\ngl_FragColor.rgb+=grain*grainAmount;\ngl_FragColor.rgb=max(gl_FragColor.rgb,0.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var grainPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/highlights.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/highlights.fragment.ts ***!
  \****************************************/
/*! exports provided: highlightsPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "highlightsPixelShader", function() { return highlightsPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'highlightsPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nconst vec3 RGBLuminanceCoefficients=vec3(0.2126,0.7152,0.0722);\nvoid main(void)\n{\nvec4 tex=texture2D(textureSampler,vUV);\nvec3 c=tex.rgb;\nfloat luma=dot(c.rgb,RGBLuminanceCoefficients);\n\n\ngl_FragColor=vec4(pow(c,vec3(25.0-luma*15.0)),tex.a);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var highlightsPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/imageProcessing.fragment.ts":
/*!*********************************************!*\
  !*** ./Shaders/imageProcessing.fragment.ts ***!
  \*********************************************/
/*! exports provided: imageProcessingPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "imageProcessingPixelShader", function() { return imageProcessingPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_imageProcessingDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingDeclaration */ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_imageProcessingFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingFunctions */ "./Shaders/ShadersInclude/imageProcessingFunctions.ts");




var name = 'imageProcessingPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n#include<imageProcessingDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\nvoid main(void)\n{\nvec4 result=texture2D(textureSampler,vUV);\n#ifdef IMAGEPROCESSING\n#ifndef FROMLINEARSPACE\n\nresult.rgb=toLinearSpace(result.rgb);\n#endif\nresult=applyImageProcessing(result);\n#else\n\n#ifdef FROMLINEARSPACE\nresult=applyImageProcessing(result);\n#endif\n#endif\ngl_FragColor=result;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var imageProcessingPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/kernelBlur.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/kernelBlur.fragment.ts ***!
  \****************************************/
/*! exports provided: kernelBlurPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "kernelBlurPixelShader", function() { return kernelBlurPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_kernelBlurVaryingDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/kernelBlurVaryingDeclaration */ "./Shaders/ShadersInclude/kernelBlurVaryingDeclaration.ts");
/* harmony import */ var _ShadersInclude_packingFunctions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/packingFunctions */ "./Shaders/ShadersInclude/packingFunctions.ts");
/* harmony import */ var _ShadersInclude_kernelBlurFragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/kernelBlurFragment */ "./Shaders/ShadersInclude/kernelBlurFragment.ts");
/* harmony import */ var _ShadersInclude_kernelBlurFragment2__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/kernelBlurFragment2 */ "./Shaders/ShadersInclude/kernelBlurFragment2.ts");





var name = 'kernelBlurPixelShader';
var shader = "\nuniform sampler2D textureSampler;\nuniform vec2 delta;\n\nvarying vec2 sampleCenter;\n#ifdef DOF\nuniform sampler2D circleOfConfusionSampler;\nuniform vec2 cameraMinMaxZ;\nfloat sampleDistance(const in vec2 offset) {\nfloat depth=texture2D(circleOfConfusionSampler,offset).g;\nreturn cameraMinMaxZ.x+(cameraMinMaxZ.y-cameraMinMaxZ.x)*depth;\n}\nfloat sampleCoC(const in vec2 offset) {\nfloat coc=texture2D(circleOfConfusionSampler,offset).r;\nreturn coc;\n}\n#endif\n#include<kernelBlurVaryingDeclaration>[0..varyingCount]\n#ifdef PACKEDFLOAT\n#include<packingFunctions>\n#endif\nvoid main(void)\n{\nfloat computedWeight=0.0;\n#ifdef PACKEDFLOAT\nfloat blend=0.;\n#else\nvec4 blend=vec4(0.);\n#endif\n#ifdef DOF\nfloat sumOfWeights=CENTER_WEIGHT;\nfloat factor=0.0;\n\n#ifdef PACKEDFLOAT\nblend+=unpack(texture2D(textureSampler,sampleCenter))*CENTER_WEIGHT;\n#else\nblend+=texture2D(textureSampler,sampleCenter)*CENTER_WEIGHT;\n#endif\n#endif\n#include<kernelBlurFragment>[0..varyingCount]\n#include<kernelBlurFragment2>[0..depCount]\n#ifdef PACKEDFLOAT\ngl_FragColor=pack(blend);\n#else\ngl_FragColor=blend;\n#endif\n#ifdef DOF\ngl_FragColor/=sumOfWeights;\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var kernelBlurPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/kernelBlur.vertex.ts":
/*!**************************************!*\
  !*** ./Shaders/kernelBlur.vertex.ts ***!
  \**************************************/
/*! exports provided: kernelBlurVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "kernelBlurVertexShader", function() { return kernelBlurVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_kernelBlurVaryingDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/kernelBlurVaryingDeclaration */ "./Shaders/ShadersInclude/kernelBlurVaryingDeclaration.ts");
/* harmony import */ var _ShadersInclude_kernelBlurVertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/kernelBlurVertex */ "./Shaders/ShadersInclude/kernelBlurVertex.ts");



var name = 'kernelBlurVertexShader';
var shader = "\nattribute vec2 position;\n\nuniform vec2 delta;\n\nvarying vec2 sampleCenter;\n#include<kernelBlurVaryingDeclaration>[0..varyingCount]\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nsampleCenter=(position*madd+madd);\n#include<kernelBlurVertex>[0..varyingCount]\ngl_Position=vec4(position,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var kernelBlurVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/layer.fragment.ts":
/*!***********************************!*\
  !*** ./Shaders/layer.fragment.ts ***!
  \***********************************/
/*! exports provided: layerPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "layerPixelShader", function() { return layerPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'layerPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n\nuniform vec4 color;\nvoid main(void) {\nvec4 baseColor=texture2D(textureSampler,vUV);\n#ifdef ALPHATEST\nif (baseColor.a<0.4)\ndiscard;\n#endif\ngl_FragColor=baseColor*color;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var layerPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/layer.vertex.ts":
/*!*********************************!*\
  !*** ./Shaders/layer.vertex.ts ***!
  \*********************************/
/*! exports provided: layerVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "layerVertexShader", function() { return layerVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'layerVertexShader';
var shader = "\nattribute vec2 position;\n\nuniform vec2 scale;\nuniform vec2 offset;\nuniform mat4 textureMatrix;\n\nvarying vec2 vUV;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nvec2 shiftedPosition=position*scale+offset;\nvUV=vec2(textureMatrix*vec4(shiftedPosition*madd+madd,1.0,0.0));\ngl_Position=vec4(shiftedPosition,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var layerVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/lensFlare.fragment.ts":
/*!***************************************!*\
  !*** ./Shaders/lensFlare.fragment.ts ***!
  \***************************************/
/*! exports provided: lensFlarePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lensFlarePixelShader", function() { return lensFlarePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'lensFlarePixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n\nuniform vec4 color;\nvoid main(void) {\nvec4 baseColor=texture2D(textureSampler,vUV);\ngl_FragColor=baseColor*color;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var lensFlarePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/lensFlare.vertex.ts":
/*!*************************************!*\
  !*** ./Shaders/lensFlare.vertex.ts ***!
  \*************************************/
/*! exports provided: lensFlareVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lensFlareVertexShader", function() { return lensFlareVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'lensFlareVertexShader';
var shader = "\nattribute vec2 position;\n\nuniform mat4 viewportMatrix;\n\nvarying vec2 vUV;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nvUV=position*madd+madd;\ngl_Position=viewportMatrix*vec4(position,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var lensFlareVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/lensHighlights.fragment.ts":
/*!********************************************!*\
  !*** ./Shaders/lensHighlights.fragment.ts ***!
  \********************************************/
/*! exports provided: lensHighlightsPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lensHighlightsPixelShader", function() { return lensHighlightsPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'lensHighlightsPixelShader';
var shader = "\nuniform sampler2D textureSampler;\n\nuniform float gain;\nuniform float threshold;\nuniform float screen_width;\nuniform float screen_height;\n\nvarying vec2 vUV;\n\nvec4 highlightColor(vec4 color) {\nvec4 highlight=color;\nfloat luminance=dot(highlight.rgb,vec3(0.2125,0.7154,0.0721));\nfloat lum_threshold;\nif (threshold>1.0) { lum_threshold=0.94+0.01*threshold; }\nelse { lum_threshold=0.5+0.44*threshold; }\nluminance=clamp((luminance-lum_threshold)*(1.0/(1.0-lum_threshold)),0.0,1.0);\nhighlight*=luminance*gain;\nhighlight.a=1.0;\nreturn highlight;\n}\nvoid main(void)\n{\nvec4 original=texture2D(textureSampler,vUV);\n\nif (gain == -1.0) {\ngl_FragColor=vec4(0.0,0.0,0.0,1.0);\nreturn;\n}\nfloat w=2.0/screen_width;\nfloat h=2.0/screen_height;\nfloat weight=1.0;\n\nvec4 blurred=vec4(0.0,0.0,0.0,0.0);\n#ifdef PENTAGON\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.84*w,0.43*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.48*w,-1.29*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.61*w,1.51*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.55*w,-0.74*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.71*w,-0.52*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.94*w,1.59*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.40*w,-1.87*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.62*w,1.16*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.09*w,0.25*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.46*w,-1.71*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.08*w,2.42*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.85*w,-1.89*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.89*w,0.16*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.29*w,1.88*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.40*w,-2.81*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.54*w,2.26*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.60*w,-0.61*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.31*w,-1.30*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.83*w,2.53*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.12*w,-2.48*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.60*w,1.11*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.82*w,0.99*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.50*w,-2.81*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.85*w,3.33*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.94*w,-1.92*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.27*w,-0.53*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.95*w,2.48*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.23*w,-3.04*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.17*w,2.05*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.97*w,-0.04*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.25*w,-2.00*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.31*w,3.08*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.94*w,-2.59*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.37*w,0.64*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-3.13*w,1.93*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.03*w,-3.65*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.60*w,3.17*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-3.14*w,-1.19*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.00*w,-1.19*h)));\n#else\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.85*w,0.36*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.52*w,-1.14*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.46*w,1.42*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.46*w,-0.83*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.79*w,-0.42*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.11*w,1.62*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.29*w,-2.07*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.69*w,1.39*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.28*w,0.12*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.65*w,-1.69*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.08*w,2.44*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.63*w,-1.90*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.55*w,0.31*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.13*w,1.52*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.56*w,-2.61*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.38*w,2.34*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.64*w,-0.81*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.53*w,-1.21*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.06*w,2.63*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.00*w,-2.69*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.59*w,1.32*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.82*w,0.78*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.57*w,-2.50*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(0.54*w,2.93*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.39*w,-1.81*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.01*w,-0.28*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.04*w,2.25*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.02*w,-3.05*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.09*w,2.25*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-3.07*w,-0.25*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.44*w,-1.90*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-0.52*w,3.05*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-1.68*w,-2.61*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(3.01*w,0.79*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.76*w,1.46*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.05*w,-2.94*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(1.21*w,2.88*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(-2.84*w,-1.30*h)));\nblurred+=highlightColor(texture2D(textureSampler,vUV+vec2(2.98*w,-0.96*h)));\n#endif\nblurred/=39.0;\ngl_FragColor=blurred;\n\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var lensHighlightsPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/line.fragment.ts":
/*!**********************************!*\
  !*** ./Shaders/line.fragment.ts ***!
  \**********************************/
/*! exports provided: linePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linePixelShader", function() { return linePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'linePixelShader';
var shader = "uniform vec4 color;\nvoid main(void) {\ngl_FragColor=color;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var linePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/line.vertex.ts":
/*!********************************!*\
  !*** ./Shaders/line.vertex.ts ***!
  \********************************/
/*! exports provided: lineVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lineVertexShader", function() { return lineVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'lineVertexShader';
var shader = "\nattribute vec3 position;\nattribute vec4 normal;\n\nuniform mat4 worldViewProjection;\nuniform float width;\nuniform float aspectRatio;\nvoid main(void) {\nvec4 viewPosition=worldViewProjection*vec4(position,1.0);\nvec4 viewPositionNext=worldViewProjection*vec4(normal.xyz,1.0);\nvec2 currentScreen=viewPosition.xy/viewPosition.w;\nvec2 nextScreen=viewPositionNext.xy/viewPositionNext.w;\ncurrentScreen.x*=aspectRatio;\nnextScreen.x*=aspectRatio;\nvec2 dir=normalize(nextScreen-currentScreen);\nvec2 normalDir=vec2(-dir.y,dir.x);\nnormalDir*=width/2.0;\nnormalDir.x/=aspectRatio;\nvec4 offset=vec4(normalDir*normal.w,0.0,0.0);\ngl_Position=viewPosition+offset;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var lineVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/motionBlur.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/motionBlur.fragment.ts ***!
  \****************************************/
/*! exports provided: motionBlurPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "motionBlurPixelShader", function() { return motionBlurPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'motionBlurPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform sampler2D velocitySampler;\nuniform float motionStrength;\nuniform float motionScale;\nuniform vec2 screenSize;\nvoid main(void)\n{\n#ifdef GEOMETRY_SUPPORTED\nvec2 texelSize=1.0/screenSize;\nvec2 velocityColor=texture2D(velocitySampler,vUV).rg*2.0-1.0;\nvec2 velocity=vec2(pow(velocityColor.r,3.0),pow(velocityColor.g,3.0));\nvelocity*=motionScale*motionStrength;\nfloat speed=length(velocity/texelSize);\nint samplesCount=int(clamp(speed,1.0,SAMPLES));\nvelocity=normalize(velocity)*texelSize;\nfloat hlim=float(-samplesCount)*0.5+0.5;\nvec4 result=texture2D(textureSampler,vUV);\nfor (int i=1; i<int(SAMPLES); ++i)\n{\nif (i>=samplesCount)\nbreak;\nvec2 offset=vUV+velocity*(hlim+float(i));\nresult+=texture2D(textureSampler,offset);\n}\ngl_FragColor=result/float(samplesCount);\ngl_FragColor.a=1.0;\n#else\ngl_FragColor=texture2D(textureSampler,vUV);\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var motionBlurPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/noise.fragment.ts":
/*!***********************************!*\
  !*** ./Shaders/noise.fragment.ts ***!
  \***********************************/
/*! exports provided: noisePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "noisePixelShader", function() { return noisePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'noisePixelShader';
var shader = "\n\nuniform float brightness;\nuniform float persistence;\nuniform float timeScale;\n\nvarying vec2 vUV;\n\nvec2 hash22(vec2 p)\n{\np=p*mat2(127.1,311.7,269.5,183.3);\np=-1.0+2.0*fract(sin(p)*43758.5453123);\nreturn sin(p*6.283+timeScale);\n}\nfloat interpolationNoise(vec2 p)\n{\nvec2 pi=floor(p);\nvec2 pf=p-pi;\nvec2 w=pf*pf*(3.-2.*pf);\nfloat f00=dot(hash22(pi+vec2(.0,.0)),pf-vec2(.0,.0));\nfloat f01=dot(hash22(pi+vec2(.0,1.)),pf-vec2(.0,1.));\nfloat f10=dot(hash22(pi+vec2(1.0,0.)),pf-vec2(1.0,0.));\nfloat f11=dot(hash22(pi+vec2(1.0,1.)),pf-vec2(1.0,1.));\nfloat xm1=mix(f00,f10,w.x);\nfloat xm2=mix(f01,f11,w.x);\nfloat ym=mix(xm1,xm2,w.y);\nreturn ym;\n}\nfloat perlinNoise2D(float x,float y)\n{\nfloat sum=0.0;\nfloat frequency=0.0;\nfloat amplitude=0.0;\nfor(int i=0; i<OCTAVES; i++)\n{\nfrequency=pow(2.0,float(i));\namplitude=pow(persistence,float(i));\nsum=sum+interpolationNoise(vec2(x*frequency,y*frequency))*amplitude;\n}\nreturn sum;\n}\n\nvoid main(void)\n{\nfloat x=abs(vUV.x);\nfloat y=abs(vUV.y);\nfloat noise=brightness+(1.0-brightness)*perlinNoise2D(x,y);\ngl_FragColor=vec4(noise,noise,noise,1.0);\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var noisePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/outline.fragment.ts":
/*!*************************************!*\
  !*** ./Shaders/outline.fragment.ts ***!
  \*************************************/
/*! exports provided: outlinePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "outlinePixelShader", function() { return outlinePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_logDepthDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/logDepthDeclaration */ "./Shaders/ShadersInclude/logDepthDeclaration.ts");
/* harmony import */ var _ShadersInclude_logDepthFragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/logDepthFragment */ "./Shaders/ShadersInclude/logDepthFragment.ts");



var name = 'outlinePixelShader';
var shader = "#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\nuniform vec4 color;\n#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform sampler2D diffuseSampler;\n#endif\n#include<logDepthDeclaration>\nvoid main(void) {\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\n#include<logDepthFragment>\ngl_FragColor=color;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var outlinePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/outline.vertex.ts":
/*!***********************************!*\
  !*** ./Shaders/outline.vertex.ts ***!
  \***********************************/
/*! exports provided: outlineVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "outlineVertexShader", function() { return outlineVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_logDepthDeclaration__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/logDepthDeclaration */ "./Shaders/ShadersInclude/logDepthDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");
/* harmony import */ var _ShadersInclude_logDepthVertex__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/logDepthVertex */ "./Shaders/ShadersInclude/logDepthVertex.ts");










var name = 'outlineVertexShader';
var shader = "\nattribute vec3 position;\nattribute vec3 normal;\n#include<bonesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n\nuniform float offset;\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\n#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\n#include<logDepthDeclaration>\nvoid main(void)\n{\nvec3 positionUpdated=position;\nvec3 normalUpdated=normal;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\nvec3 offsetPosition=positionUpdated+(normalUpdated*offset);\n#include<instancesVertex>\n#include<bonesVertex>\ngl_Position=viewProjection*finalWorld*vec4(offsetPosition,1.0);\n#ifdef ALPHATEST\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n#include<logDepthVertex>\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var outlineVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/particles.fragment.ts":
/*!***************************************!*\
  !*** ./Shaders/particles.fragment.ts ***!
  \***************************************/
/*! exports provided: particlesPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "particlesPixelShader", function() { return particlesPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragmentDeclaration */ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_imageProcessingDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingDeclaration */ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_imageProcessingFunctions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingFunctions */ "./Shaders/ShadersInclude/imageProcessingFunctions.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragment__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragment */ "./Shaders/ShadersInclude/clipPlaneFragment.ts");






var name = 'particlesPixelShader';
var shader = "\nvarying vec2 vUV;\nvarying vec4 vColor;\nuniform vec4 textureMask;\nuniform sampler2D diffuseSampler;\n#include<clipPlaneFragmentDeclaration>\n#include<imageProcessingDeclaration>\n#include<helperFunctions>\n#include<imageProcessingFunctions>\n#ifdef RAMPGRADIENT\nvarying vec4 remapRanges;\nuniform sampler2D rampSampler;\n#endif\nvoid main(void) {\n#include<clipPlaneFragment>\nvec4 textureColor=texture2D(diffuseSampler,vUV);\nvec4 baseColor=(textureColor*textureMask+(vec4(1.,1.,1.,1.)-textureMask))*vColor;\n#ifdef RAMPGRADIENT\nfloat alpha=baseColor.a;\nfloat remappedColorIndex=clamp((alpha-remapRanges.x)/remapRanges.y,0.0,1.0);\nvec4 rampColor=texture2D(rampSampler,vec2(1.0-remappedColorIndex,0.));\nbaseColor.rgb*=rampColor.rgb;\n\nfloat finalAlpha=baseColor.a;\nbaseColor.a=clamp((alpha*rampColor.a-remapRanges.z)/remapRanges.w,0.0,1.0);\n#endif\n#ifdef BLENDMULTIPLYMODE\nfloat sourceAlpha=vColor.a*textureColor.a;\nbaseColor.rgb=baseColor.rgb*sourceAlpha+vec3(1.0)*(1.0-sourceAlpha);\n#endif\n\n\n#ifdef IMAGEPROCESSINGPOSTPROCESS\nbaseColor.rgb=toLinearSpace(baseColor.rgb);\n#else\n#ifdef IMAGEPROCESSING\nbaseColor.rgb=toLinearSpace(baseColor.rgb);\nbaseColor=applyImageProcessing(baseColor);\n#endif\n#endif\ngl_FragColor=baseColor;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var particlesPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/particles.vertex.ts":
/*!*************************************!*\
  !*** ./Shaders/particles.vertex.ts ***!
  \*************************************/
/*! exports provided: particlesVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "particlesVertexShader", function() { return particlesVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertexDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertexDeclaration */ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertex */ "./Shaders/ShadersInclude/clipPlaneVertex.ts");



var name = 'particlesVertexShader';
var shader = "\nattribute vec3 position;\nattribute vec4 color;\nattribute float angle;\nattribute vec2 size;\n#ifdef ANIMATESHEET\nattribute float cellIndex;\n#endif\n#ifndef BILLBOARD\nattribute vec3 direction;\n#endif\n#ifdef BILLBOARDSTRETCHED\nattribute vec3 direction;\n#endif\n#ifdef RAMPGRADIENT\nattribute vec4 remapData;\n#endif\nattribute vec2 offset;\n\nuniform mat4 view;\nuniform mat4 projection;\nuniform vec2 translationPivot;\n#ifdef ANIMATESHEET\nuniform vec3 particlesInfos;\n#endif\n\nvarying vec2 vUV;\nvarying vec4 vColor;\n#ifdef RAMPGRADIENT\nvarying vec4 remapRanges;\n#endif\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4)\nuniform mat4 invView;\n#endif\n#include<clipPlaneVertexDeclaration>\n#ifdef BILLBOARD\nuniform vec3 eyePosition;\n#endif\nvec3 rotate(vec3 yaxis,vec3 rotatedCorner) {\nvec3 xaxis=normalize(cross(vec3(0.,1.0,0.),yaxis));\nvec3 zaxis=normalize(cross(yaxis,xaxis));\nvec3 row0=vec3(xaxis.x,xaxis.y,xaxis.z);\nvec3 row1=vec3(yaxis.x,yaxis.y,yaxis.z);\nvec3 row2=vec3(zaxis.x,zaxis.y,zaxis.z);\nmat3 rotMatrix=mat3(row0,row1,row2);\nvec3 alignedCorner=rotMatrix*rotatedCorner;\nreturn position+alignedCorner;\n}\n#ifdef BILLBOARDSTRETCHED\nvec3 rotateAlign(vec3 toCamera,vec3 rotatedCorner) {\nvec3 normalizedToCamera=normalize(toCamera);\nvec3 normalizedCrossDirToCamera=normalize(cross(normalize(direction),normalizedToCamera));\nvec3 crossProduct=normalize(cross(normalizedToCamera,normalizedCrossDirToCamera));\nvec3 row0=vec3(normalizedCrossDirToCamera.x,normalizedCrossDirToCamera.y,normalizedCrossDirToCamera.z);\nvec3 row1=vec3(crossProduct.x,crossProduct.y,crossProduct.z);\nvec3 row2=vec3(normalizedToCamera.x,normalizedToCamera.y,normalizedToCamera.z);\nmat3 rotMatrix=mat3(row0,row1,row2);\nvec3 alignedCorner=rotMatrix*rotatedCorner;\nreturn position+alignedCorner;\n}\n#endif\nvoid main(void) {\nvec2 cornerPos;\ncornerPos=(vec2(offset.x-0.5,offset.y-0.5)-translationPivot)*size+translationPivot;\n#ifdef BILLBOARD\n\nvec3 rotatedCorner;\n#ifdef BILLBOARDY\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.y=0.;\nvec3 yaxis=position-eyePosition;\nyaxis.y=0.;\nvec3 worldPos=rotate(normalize(yaxis),rotatedCorner);\nvec3 viewPos=(view*vec4(worldPos,1.0)).xyz;\n#elif defined(BILLBOARDSTRETCHED)\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.z=0.;\nvec3 toCamera=position-eyePosition;\nvec3 worldPos=rotateAlign(toCamera,rotatedCorner);\nvec3 viewPos=(view*vec4(worldPos,1.0)).xyz;\n#else\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.z=0.;\nvec3 viewPos=(view*vec4(position,1.0)).xyz+rotatedCorner;\n#endif\n#ifdef RAMPGRADIENT\nremapRanges=remapData;\n#endif\n\ngl_Position=projection*vec4(viewPos,1.0);\n#else\n\nvec3 rotatedCorner;\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.z=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.y=0.;\nvec3 yaxis=normalize(direction);\nvec3 worldPos=rotate(yaxis,rotatedCorner);\ngl_Position=projection*view*vec4(worldPos,1.0);\n#endif\nvColor=color;\n#ifdef ANIMATESHEET\nfloat rowOffset=floor(cellIndex/particlesInfos.z);\nfloat columnOffset=cellIndex-rowOffset*particlesInfos.z;\nvec2 uvScale=particlesInfos.xy;\nvec2 uvOffset=vec2(offset.x ,1.0-offset.y);\nvUV=(uvOffset+vec2(columnOffset,rowOffset))*uvScale;\n#else\nvUV=offset;\n#endif\n\n#if defined(CLIPPLANE) || defined(CLIPPLANE2) || defined(CLIPPLANE3) || defined(CLIPPLANE4)\nvec4 worldPos=invView*vec4(viewPos,1.0);\n#endif\n#include<clipPlaneVertex>\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var particlesVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/pass.fragment.ts":
/*!**********************************!*\
  !*** ./Shaders/pass.fragment.ts ***!
  \**********************************/
/*! exports provided: passPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "passPixelShader", function() { return passPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'passPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nvoid main(void)\n{\ngl_FragColor=texture2D(textureSampler,vUV);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var passPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/passCube.fragment.ts":
/*!**************************************!*\
  !*** ./Shaders/passCube.fragment.ts ***!
  \**************************************/
/*! exports provided: passCubePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "passCubePixelShader", function() { return passCubePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'passCubePixelShader';
var shader = "\nvarying vec2 vUV;\nuniform samplerCube textureSampler;\nvoid main(void)\n{\nvec2 uv=vUV*2.0-1.0;\n#ifdef POSITIVEX\ngl_FragColor=textureCube(textureSampler,vec3(1.001,uv.y,uv.x));\n#endif\n#ifdef NEGATIVEX\ngl_FragColor=textureCube(textureSampler,vec3(-1.001,uv.y,uv.x));\n#endif\n#ifdef POSITIVEY\ngl_FragColor=textureCube(textureSampler,vec3(uv.y,1.001,uv.x));\n#endif\n#ifdef NEGATIVEY\ngl_FragColor=textureCube(textureSampler,vec3(uv.y,-1.001,uv.x));\n#endif\n#ifdef POSITIVEZ\ngl_FragColor=textureCube(textureSampler,vec3(uv,1.001));\n#endif\n#ifdef NEGATIVEZ\ngl_FragColor=textureCube(textureSampler,vec3(uv,-1.001));\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var passCubePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/pbr.fragment.ts":
/*!*********************************!*\
  !*** ./Shaders/pbr.fragment.ts ***!
  \*********************************/
/*! exports provided: pbrPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrPixelShader", function() { return pbrPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_pbrFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/pbrFragmentDeclaration */ "./Shaders/ShadersInclude/pbrFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_pbrUboDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/pbrUboDeclaration */ "./Shaders/ShadersInclude/pbrUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_pbrFragmentExtraDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/pbrFragmentExtraDeclaration */ "./Shaders/ShadersInclude/pbrFragmentExtraDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightFragmentDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/lightFragmentDeclaration */ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightUboDeclaration__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/lightUboDeclaration */ "./Shaders/ShadersInclude/lightUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_pbrFragmentSamplersDeclaration__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/pbrFragmentSamplersDeclaration */ "./Shaders/ShadersInclude/pbrFragmentSamplersDeclaration.ts");
/* harmony import */ var _ShadersInclude_imageProcessingDeclaration__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingDeclaration */ "./Shaders/ShadersInclude/imageProcessingDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragmentDeclaration__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragmentDeclaration */ "./Shaders/ShadersInclude/clipPlaneFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_logDepthDeclaration__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/logDepthDeclaration */ "./Shaders/ShadersInclude/logDepthDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogFragmentDeclaration__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ShadersInclude/fogFragmentDeclaration */ "./Shaders/ShadersInclude/fogFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_pbrHelperFunctions__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./ShadersInclude/pbrHelperFunctions */ "./Shaders/ShadersInclude/pbrHelperFunctions.ts");
/* harmony import */ var _ShadersInclude_imageProcessingFunctions__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ShadersInclude/imageProcessingFunctions */ "./Shaders/ShadersInclude/imageProcessingFunctions.ts");
/* harmony import */ var _ShadersInclude_shadowsFragmentFunctions__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ShadersInclude/shadowsFragmentFunctions */ "./Shaders/ShadersInclude/shadowsFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_harmonicsFunctions__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ShadersInclude/harmonicsFunctions */ "./Shaders/ShadersInclude/harmonicsFunctions.ts");
/* harmony import */ var _ShadersInclude_pbrDirectLightingSetupFunctions__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ShadersInclude/pbrDirectLightingSetupFunctions */ "./Shaders/ShadersInclude/pbrDirectLightingSetupFunctions.ts");
/* harmony import */ var _ShadersInclude_pbrDirectLightingFalloffFunctions__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./ShadersInclude/pbrDirectLightingFalloffFunctions */ "./Shaders/ShadersInclude/pbrDirectLightingFalloffFunctions.ts");
/* harmony import */ var _ShadersInclude_pbrBRDFFunctions__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./ShadersInclude/pbrBRDFFunctions */ "./Shaders/ShadersInclude/pbrBRDFFunctions.ts");
/* harmony import */ var _ShadersInclude_pbrDirectLightingFunctions__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./ShadersInclude/pbrDirectLightingFunctions */ "./Shaders/ShadersInclude/pbrDirectLightingFunctions.ts");
/* harmony import */ var _ShadersInclude_pbrIBLFunctions__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./ShadersInclude/pbrIBLFunctions */ "./Shaders/ShadersInclude/pbrIBLFunctions.ts");
/* harmony import */ var _ShadersInclude_bumpFragmentFunctions__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./ShadersInclude/bumpFragmentFunctions */ "./Shaders/ShadersInclude/bumpFragmentFunctions.ts");
/* harmony import */ var _ShadersInclude_reflectionFunction__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./ShadersInclude/reflectionFunction */ "./Shaders/ShadersInclude/reflectionFunction.ts");
/* harmony import */ var _ShadersInclude_clipPlaneFragment__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneFragment */ "./Shaders/ShadersInclude/clipPlaneFragment.ts");
/* harmony import */ var _ShadersInclude_bumpFragment__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./ShadersInclude/bumpFragment */ "./Shaders/ShadersInclude/bumpFragment.ts");
/* harmony import */ var _ShadersInclude_depthPrePass__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./ShadersInclude/depthPrePass */ "./Shaders/ShadersInclude/depthPrePass.ts");
/* harmony import */ var _ShadersInclude_lightFragment__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./ShadersInclude/lightFragment */ "./Shaders/ShadersInclude/lightFragment.ts");
/* harmony import */ var _ShadersInclude_logDepthFragment__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./ShadersInclude/logDepthFragment */ "./Shaders/ShadersInclude/logDepthFragment.ts");
/* harmony import */ var _ShadersInclude_fogFragment__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./ShadersInclude/fogFragment */ "./Shaders/ShadersInclude/fogFragment.ts");
/* harmony import */ var _ShadersInclude_pbrDebug__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./ShadersInclude/pbrDebug */ "./Shaders/ShadersInclude/pbrDebug.ts");






























var name = 'pbrPixelShader';
var shader = "#if defined(BUMP) || !defined(NORMAL) || defined(FORCENORMALFORWARD) || defined(SPECULARAA) || defined(CLEARCOAT_BUMP) || defined(ANISOTROPIC)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#ifdef LODBASEDMICROSFURACE\n#extension GL_EXT_shader_texture_lod : enable\n#endif\n#define CUSTOM_FRAGMENT_BEGIN\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\nprecision highp float;\n\n#ifndef FROMLINEARSPACE\n#define FROMLINEARSPACE\n#endif\n\n#include<__decl__pbrFragment>\n#include<pbrFragmentExtraDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<pbrFragmentSamplersDeclaration>\n#include<imageProcessingDeclaration>\n#include<clipPlaneFragmentDeclaration>\n#include<logDepthDeclaration>\n#include<fogFragmentDeclaration>\n\n#include<helperFunctions>\n#include<pbrHelperFunctions>\n#include<imageProcessingFunctions>\n#include<shadowsFragmentFunctions>\n#include<harmonicsFunctions>\n#include<pbrDirectLightingSetupFunctions>\n#include<pbrDirectLightingFalloffFunctions>\n#include<pbrBRDFFunctions>\n#include<pbrDirectLightingFunctions>\n#include<pbrIBLFunctions>\n#include<bumpFragmentFunctions>\n#ifdef REFLECTION\n#include<reflectionFunction>\n#endif\n#define CUSTOM_FRAGMENT_DEFINITIONS\n\nvoid main(void) {\n#define CUSTOM_FRAGMENT_MAIN_BEGIN\n#include<clipPlaneFragment>\n\nvec3 viewDirectionW=normalize(vEyePosition.xyz-vPositionW);\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=normalize(cross(dFdx(vPositionW),dFdy(vPositionW)))*vEyePosition.w;\n#endif\n#ifdef CLEARCOAT\n\nvec3 clearCoatNormalW=normalW;\n#endif\n#include<bumpFragment>\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nvec3 faceNormal=normalize(cross(dFdx(vPositionW),dFdy(vPositionW)))*vEyePosition.w;\n#if defined(TWOSIDEDLIGHTING)\nfaceNormal=gl_FrontFacing ? faceNormal : -faceNormal;\n#endif\nnormalW*=sign(dot(normalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\nnormalW=gl_FrontFacing ? normalW : -normalW;\n#endif\n\n\nvec3 surfaceAlbedo=vAlbedoColor.rgb;\n\nfloat alpha=vAlbedoColor.a;\n#ifdef ALBEDO\nvec4 albedoTexture=texture2D(albedoSampler,vAlbedoUV+uvOffset);\n#if defined(ALPHAFROMALBEDO) || defined(ALPHATEST)\nalpha*=albedoTexture.a;\n#endif\nsurfaceAlbedo*=toLinearSpace(albedoTexture.rgb);\nsurfaceAlbedo*=vAlbedoInfos.y;\n#endif\n#ifdef VERTEXCOLOR\nsurfaceAlbedo*=vColor.rgb;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALBEDO\n\n#ifdef OPACITY\nvec4 opacityMap=texture2D(opacitySampler,vOpacityUV+uvOffset);\n#ifdef OPACITYRGB\nalpha=getLuminance(opacityMap.rgb);\n#else\nalpha*=opacityMap.a;\n#endif\nalpha*=vOpacityInfos.y;\n#endif\n#ifdef VERTEXALPHA\nalpha*=vColor.a;\n#endif\n#if !defined(SS_LINKREFRACTIONTOTRANSPARENCY) && !defined(ALPHAFRESNEL)\n#ifdef ALPHATEST\nif (alpha<ALPHATESTVALUE)\ndiscard;\n#ifndef ALPHABLEND\n\nalpha=1.0;\n#endif\n#endif\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_ALPHA\n#include<depthPrePass>\n#define CUSTOM_FRAGMENT_BEFORE_LIGHTS\n\nvec3 ambientOcclusionColor=vec3(1.,1.,1.);\n#ifdef AMBIENT\nvec3 ambientOcclusionColorMap=texture2D(ambientSampler,vAmbientUV+uvOffset).rgb*vAmbientInfos.y;\n#ifdef AMBIENTINGRAYSCALE\nambientOcclusionColorMap=vec3(ambientOcclusionColorMap.r,ambientOcclusionColorMap.r,ambientOcclusionColorMap.r);\n#endif\nambientOcclusionColor=mix(ambientOcclusionColor,ambientOcclusionColorMap,vAmbientInfos.z);\n#endif\n#ifdef UNLIT\nvec3 diffuseBase=vec3(1.,1.,1.);\n#else\n\nfloat microSurface=vReflectivityColor.a;\nvec3 surfaceReflectivityColor=vReflectivityColor.rgb;\n#ifdef METALLICWORKFLOW\nvec2 metallicRoughness=surfaceReflectivityColor.rg;\n#ifdef REFLECTIVITY\nvec4 surfaceMetallicColorMap=texture2D(reflectivitySampler,vReflectivityUV+uvOffset);\n#ifdef AOSTOREINMETALMAPRED\nvec3 aoStoreInMetalMap=vec3(surfaceMetallicColorMap.r,surfaceMetallicColorMap.r,surfaceMetallicColorMap.r);\nambientOcclusionColor=mix(ambientOcclusionColor,aoStoreInMetalMap,vReflectivityInfos.z);\n#endif\n#ifdef METALLNESSSTOREINMETALMAPBLUE\nmetallicRoughness.r*=surfaceMetallicColorMap.b;\n#else\nmetallicRoughness.r*=surfaceMetallicColorMap.r;\n#endif\n#ifdef ROUGHNESSSTOREINMETALMAPALPHA\nmetallicRoughness.g*=surfaceMetallicColorMap.a;\n#else\n#ifdef ROUGHNESSSTOREINMETALMAPGREEN\nmetallicRoughness.g*=surfaceMetallicColorMap.g;\n#endif\n#endif\n#endif\n#ifdef MICROSURFACEMAP\nvec4 microSurfaceTexel=texture2D(microSurfaceSampler,vMicroSurfaceSamplerUV+uvOffset)*vMicroSurfaceSamplerInfos.y;\nmetallicRoughness.g*=microSurfaceTexel.r;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_METALLICROUGHNESS\n\nmicroSurface=1.0-metallicRoughness.g;\n\nvec3 baseColor=surfaceAlbedo;\n#ifdef REFLECTANCE\n\n\n\n\n\nsurfaceAlbedo=baseColor.rgb*(1.0-metallicRoughness.r);\n\nsurfaceReflectivityColor=mix(0.16*reflectance*reflectance,baseColor,metallicRoughness.r);\n#else\n\n\n\nconst vec3 DefaultSpecularReflectanceDielectric=vec3(0.04,0.04,0.04);\n\nsurfaceAlbedo=mix(baseColor.rgb*(1.0-DefaultSpecularReflectanceDielectric.r),vec3(0.,0.,0.),metallicRoughness.r);\n\nsurfaceReflectivityColor=mix(DefaultSpecularReflectanceDielectric,baseColor,metallicRoughness.r);\n#endif\n#else\n#ifdef REFLECTIVITY\nvec4 surfaceReflectivityColorMap=texture2D(reflectivitySampler,vReflectivityUV+uvOffset);\nsurfaceReflectivityColor*=toLinearSpace(surfaceReflectivityColorMap.rgb);\nsurfaceReflectivityColor*=vReflectivityInfos.y;\n#ifdef MICROSURFACEFROMREFLECTIVITYMAP\nmicroSurface*=surfaceReflectivityColorMap.a;\nmicroSurface*=vReflectivityInfos.z;\n#else\n#ifdef MICROSURFACEAUTOMATIC\nmicroSurface*=computeDefaultMicroSurface(microSurface,surfaceReflectivityColor);\n#endif\n#ifdef MICROSURFACEMAP\nvec4 microSurfaceTexel=texture2D(microSurfaceSampler,vMicroSurfaceSamplerUV+uvOffset)*vMicroSurfaceSamplerInfos.y;\nmicroSurface*=microSurfaceTexel.r;\n#endif\n#define CUSTOM_FRAGMENT_UPDATE_MICROSURFACE\n#endif\n#endif\n#endif\n\nmicroSurface=saturate(microSurface);\n\nfloat roughness=1.-microSurface;\n\n#ifdef ALPHAFRESNEL\n#if defined(ALPHATEST) || defined(ALPHABLEND)\n\n\n\nfloat opacityPerceptual=alpha;\n#ifdef LINEARALPHAFRESNEL\nfloat opacity0=opacityPerceptual;\n#else\nfloat opacity0=opacityPerceptual*opacityPerceptual;\n#endif\nfloat opacity90=fresnelGrazingReflectance(opacity0);\nvec3 normalForward=faceforward(normalW,-viewDirectionW,normalW);\n\nalpha=getReflectanceFromAnalyticalBRDFLookup_Jones(saturate(dot(viewDirectionW,normalForward)),vec3(opacity0),vec3(opacity90),sqrt(microSurface)).x;\n#ifdef ALPHATEST\nif (alpha<ALPHATESTVALUE)\ndiscard;\n#ifndef ALPHABLEND\n\nalpha=1.0;\n#endif\n#endif\n#endif\n#endif\n\nfloat NdotVUnclamped=dot(normalW,viewDirectionW);\n\nfloat NdotV=absEps(NdotVUnclamped);\nfloat alphaG=convertRoughnessToAverageSlope(roughness);\nvec2 AARoughnessFactors=getAARoughnessFactors(normalW.xyz);\n#ifdef SPECULARAA\n\nalphaG+=AARoughnessFactors.y;\n#endif\n#ifdef ANISOTROPIC\nfloat anisotropy=vAnisotropy.b;\nvec3 anisotropyDirection=vec3(vAnisotropy.xy,0.);\n#ifdef ANISOTROPIC_TEXTURE\nvec3 anisotropyMapData=texture2D(anisotropySampler,vAnisotropyUV+uvOffset).rgb*vAnisotropyInfos.y;\nanisotropy*=anisotropyMapData.b;\nanisotropyDirection.rg*=anisotropyMapData.rg*2.0-1.0;\n#endif\nmat3 anisoTBN=mat3(normalize(TBN[0]),normalize(TBN[1]),normalize(TBN[2]));\nvec3 anisotropicTangent=normalize(anisoTBN*anisotropyDirection);\nvec3 anisotropicBitangent=normalize(cross(anisoTBN[2],anisotropicTangent));\nvec3 anisotropicNormal=getAnisotropicBentNormals(anisotropicTangent,anisotropicBitangent,normalW,viewDirectionW,anisotropy);\n#endif\n\n#ifdef SS_REFRACTION\nvec4 environmentRefraction=vec4(0.,0.,0.,0.);\n#ifdef ANISOTROPIC\nvec3 refractionVector=refract(-viewDirectionW,anisotropicNormal,vRefractionInfos.y);\n#else\nvec3 refractionVector=refract(-viewDirectionW,normalW,vRefractionInfos.y);\n#endif\n#ifdef SS_REFRACTIONMAP_OPPOSITEZ\nrefractionVector.z*=-1.0;\n#endif\n\n#ifdef SS_REFRACTIONMAP_3D\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;\nvec3 refractionCoords=refractionVector;\nrefractionCoords=vec3(refractionMatrix*vec4(refractionCoords,0));\n#else\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*vRefractionInfos.z,1.0)));\nvec2 refractionCoords=vRefractionUVW.xy/vRefractionUVW.z;\nrefractionCoords.y=1.0-refractionCoords.y;\n#endif\n#ifdef SS_LODINREFRACTIONALPHA\nfloat refractionLOD=getLodFromAlphaG(vRefractionMicrosurfaceInfos.x,alphaG,NdotVUnclamped);\n#elif defined(SS_LINEARSPECULARREFRACTION)\nfloat refractionLOD=getLinearLodFromRoughness(vRefractionMicrosurfaceInfos.x,roughness);\n#else\nfloat refractionLOD=getLodFromAlphaG(vRefractionMicrosurfaceInfos.x,alphaG);\n#endif\n#ifdef LODBASEDMICROSFURACE\n\nrefractionLOD=refractionLOD*vRefractionMicrosurfaceInfos.y+vRefractionMicrosurfaceInfos.z;\n#ifdef SS_LODINREFRACTIONALPHA\n\n\n\n\n\n\n\n\n\nfloat automaticRefractionLOD=UNPACK_LOD(sampleRefraction(refractionSampler,refractionCoords).a);\nfloat requestedRefractionLOD=max(automaticRefractionLOD,refractionLOD);\n#else\nfloat requestedRefractionLOD=refractionLOD;\n#endif\nenvironmentRefraction=sampleRefractionLod(refractionSampler,refractionCoords,requestedRefractionLOD);\n#else\nfloat lodRefractionNormalized=saturate(refractionLOD/log2(vRefractionMicrosurfaceInfos.x));\nfloat lodRefractionNormalizedDoubled=lodRefractionNormalized*2.0;\nvec4 environmentRefractionMid=sampleRefraction(refractionSampler,refractionCoords);\nif(lodRefractionNormalizedDoubled<1.0){\nenvironmentRefraction=mix(\nsampleRefraction(refractionSamplerHigh,refractionCoords),\nenvironmentRefractionMid,\nlodRefractionNormalizedDoubled\n);\n}else{\nenvironmentRefraction=mix(\nenvironmentRefractionMid,\nsampleRefraction(refractionSamplerLow,refractionCoords),\nlodRefractionNormalizedDoubled-1.0\n);\n}\n#endif\n#ifdef SS_RGBDREFRACTION\nenvironmentRefraction.rgb=fromRGBD(environmentRefraction);\n#endif\n#ifdef SS_GAMMAREFRACTION\nenvironmentRefraction.rgb=toLinearSpace(environmentRefraction.rgb);\n#endif\n\nenvironmentRefraction.rgb*=vRefractionInfos.x;\n#endif\n\n#ifdef REFLECTION\nvec4 environmentRadiance=vec4(0.,0.,0.,0.);\nvec3 environmentIrradiance=vec3(0.,0.,0.);\n#ifdef ANISOTROPIC\nvec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),anisotropicNormal);\n#else\nvec3 reflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\n\n#ifdef REFLECTIONMAP_3D\nvec3 reflectionCoords=reflectionVector;\n#else\nvec2 reflectionCoords=reflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nreflectionCoords/=reflectionVector.z;\n#endif\nreflectionCoords.y=1.0-reflectionCoords.y;\n#endif\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG,NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nfloat refractionLOD=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,roughness);\n#else\nfloat reflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,alphaG);\n#endif\n#ifdef LODBASEDMICROSFURACE\n\nreflectionLOD=reflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\n#ifdef LODINREFLECTIONALPHA\n\n\n\n\n\n\n\n\n\nfloat automaticReflectionLOD=UNPACK_LOD(sampleReflection(reflectionSampler,reflectionCoords).a);\nfloat requestedReflectionLOD=max(automaticReflectionLOD,reflectionLOD);\n#else\nfloat requestedReflectionLOD=reflectionLOD;\n#endif\nenvironmentRadiance=sampleReflectionLod(reflectionSampler,reflectionCoords,requestedReflectionLOD);\n#else\nfloat lodReflectionNormalized=saturate(reflectionLOD/log2(vReflectionMicrosurfaceInfos.x));\nfloat lodReflectionNormalizedDoubled=lodReflectionNormalized*2.0;\nvec4 environmentSpecularMid=sampleReflection(reflectionSampler,reflectionCoords);\nif(lodReflectionNormalizedDoubled<1.0){\nenvironmentRadiance=mix(\nsampleReflection(reflectionSamplerHigh,reflectionCoords),\nenvironmentSpecularMid,\nlodReflectionNormalizedDoubled\n);\n}else{\nenvironmentRadiance=mix(\nenvironmentSpecularMid,\nsampleReflection(reflectionSamplerLow,reflectionCoords),\nlodReflectionNormalizedDoubled-1.0\n);\n}\n#endif\n#ifdef RGBDREFLECTION\nenvironmentRadiance.rgb=fromRGBD(environmentRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentRadiance.rgb=toLinearSpace(environmentRadiance.rgb);\n#endif\n\n#ifdef USESPHERICALFROMREFLECTIONMAP\n#if defined(NORMAL) && defined(USESPHERICALINVERTEX)\nenvironmentIrradiance=vEnvironmentIrradiance;\n#else\n#ifdef ANISOTROPIC\nvec3 irradianceVector=vec3(reflectionMatrix*vec4(anisotropicNormal,0)).xyz;\n#else\nvec3 irradianceVector=vec3(reflectionMatrix*vec4(normalW,0)).xyz;\n#endif\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;\n#endif\nenvironmentIrradiance=computeEnvironmentIrradiance(irradianceVector);\n#endif\n#elif defined(USEIRRADIANCEMAP)\nenvironmentIrradiance=sampleReflection(irradianceSampler,reflectionCoords).rgb;\n#ifdef RGBDREFLECTION\nenvironmentIrradiance.rgb=fromRGBD(environmentIrradiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentIrradiance.rgb=toLinearSpace(environmentIrradiance.rgb);\n#endif\n#endif\n\nenvironmentRadiance.rgb*=vReflectionInfos.x;\nenvironmentRadiance.rgb*=vReflectionColor.rgb;\nenvironmentIrradiance*=vReflectionColor.rgb;\n#endif\n\nfloat reflectance=max(max(surfaceReflectivityColor.r,surfaceReflectivityColor.g),surfaceReflectivityColor.b);\nfloat reflectance90=fresnelGrazingReflectance(reflectance);\nvec3 specularEnvironmentR0=surfaceReflectivityColor.rgb;\nvec3 specularEnvironmentR90=vec3(1.0,1.0,1.0)*reflectance90;\n\n#ifdef SHEEN\nfloat sheenIntensity=vSheenColor.a;\n#ifdef SHEEN_TEXTURE\nvec4 sheenMapData=texture2D(sheenSampler,vSheenUV+uvOffset)*vSheenInfos.y;\nsheenIntensity*=sheenMapData.a;\n#endif\n#ifdef SHEEN_LINKWITHALBEDO\nfloat sheenFactor=pow5(1.0-sheenIntensity);\nvec3 sheenColor=baseColor.rgb*(1.0-sheenFactor);\nfloat sheenRoughness=sheenIntensity;\n\nsurfaceAlbedo.rgb*=sheenFactor;\n#else\nvec3 sheenColor=vSheenColor.rgb;\n#ifdef SHEEN_TEXTURE\nsheenColor.rgb*=toLinearSpace(sheenMapData.rgb);\n#endif\nfloat sheenRoughness=roughness;\n\nsheenIntensity*=(1.-reflectance);\n\nsheenColor*=sheenIntensity;\n#endif\n\n#if defined(REFLECTION)\nfloat sheenAlphaG=convertRoughnessToAverageSlope(sheenRoughness);\n#ifdef SPECULARAA\n\nsheenAlphaG+=AARoughnessFactors.y;\n#endif\nvec4 environmentSheenRadiance=vec4(0.,0.,0.,0.);\n\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nfloat sheenReflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,sheenAlphaG,NdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nfloat sheenReflectionLOD=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,sheenRoughness);\n#else\nfloat sheenReflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,sheenAlphaG);\n#endif\n#ifdef LODBASEDMICROSFURACE\n\nsheenReflectionLOD=sheenReflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\nenvironmentSheenRadiance=sampleReflectionLod(reflectionSampler,reflectionCoords,sheenReflectionLOD);\n#else\nfloat lodSheenReflectionNormalized=saturate(sheenReflectionLOD/log2(vReflectionMicrosurfaceInfos.x));\nfloat lodSheenReflectionNormalizedDoubled=lodSheenReflectionNormalized*2.0;\nvec4 environmentSheenMid=sampleReflection(reflectionSampler,reflectionCoords);\nif(lodSheenReflectionNormalizedDoubled<1.0){\nenvironmentSheenRadiance=mix(\nsampleReflection(reflectionSamplerHigh,reflectionCoords),\nenvironmentSheenMid,\nlodSheenReflectionNormalizedDoubled\n);\n}else{\nenvironmentSheenRadiance=mix(\nenvironmentSheenMid,\nsampleReflection(reflectionSamplerLow,reflectionCoords),\nlodSheenReflectionNormalizedDoubled-1.0\n);\n}\n#endif\n#ifdef RGBDREFLECTION\nenvironmentSheenRadiance.rgb=fromRGBD(environmentSheenRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentSheenRadiance.rgb=toLinearSpace(environmentSheenRadiance.rgb);\n#endif\n\nenvironmentSheenRadiance.rgb*=vReflectionInfos.x;\nenvironmentSheenRadiance.rgb*=vReflectionColor.rgb;\n#endif\n#endif\n\n#ifdef CLEARCOAT\n\nfloat clearCoatIntensity=vClearCoatParams.x;\nfloat clearCoatRoughness=vClearCoatParams.y;\n#ifdef CLEARCOAT_TEXTURE\nvec2 clearCoatMapData=texture2D(clearCoatSampler,vClearCoatUV+uvOffset).rg*vClearCoatInfos.y;\nclearCoatIntensity*=clearCoatMapData.x;\nclearCoatRoughness*=clearCoatMapData.y;\n#endif\n#ifdef CLEARCOAT_TINT\nvec3 clearCoatColor=vClearCoatTintParams.rgb;\nfloat clearCoatThickness=vClearCoatTintParams.a;\n#ifdef CLEARCOAT_TINT_TEXTURE\nvec4 clearCoatTintMapData=texture2D(clearCoatTintSampler,vClearCoatTintUV+uvOffset);\nclearCoatColor*=toLinearSpace(clearCoatTintMapData.rgb);\nclearCoatThickness*=clearCoatTintMapData.a;\n#endif\nclearCoatColor=computeColorAtDistanceInMedia(clearCoatColor,clearCoatColorAtDistance);\n#endif\n\n\n\n\nvec3 specularEnvironmentR0Updated=getR0RemappedForClearCoat(specularEnvironmentR0);\nspecularEnvironmentR0=mix(specularEnvironmentR0,specularEnvironmentR0Updated,clearCoatIntensity);\n#ifdef CLEARCOAT_BUMP\n#ifdef NORMALXYSCALE\nfloat clearCoatNormalScale=1.0;\n#else\nfloat clearCoatNormalScale=vClearCoatBumpInfos.y;\n#endif\n#if defined(TANGENT) && defined(NORMAL)\nmat3 TBNClearCoat=vTBN;\n#else\nmat3 TBNClearCoat=cotangent_frame(clearCoatNormalW*clearCoatNormalScale,vPositionW,vClearCoatBumpUV,vClearCoatTangentSpaceParams);\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\nclearCoatNormalW=normalize(texture2D(clearCoatBumpSampler,vClearCoatBumpUV+uvOffset).xyz*2.0-1.0);\nclearCoatNormalW=normalize(mat3(normalMatrix)*clearCoatNormalW);\n#else\nclearCoatNormalW=perturbNormal(TBN,texture2D(clearCoatBumpSampler,vClearCoatBumpUV+uvOffset).xyz,vClearCoatBumpInfos.y);\n#endif\n#endif\n#if defined(FORCENORMALFORWARD) && defined(NORMAL)\nclearCoatNormalW*=sign(dot(clearCoatNormalW,faceNormal));\n#endif\n#if defined(TWOSIDEDLIGHTING) && defined(NORMAL)\nclearCoatNormalW=gl_FrontFacing ? clearCoatNormalW : -clearCoatNormalW;\n#endif\n\nvec2 clearCoatAARoughnessFactors=getAARoughnessFactors(clearCoatNormalW.xyz);\n\nfloat clearCoatNdotVUnclamped=dot(clearCoatNormalW,viewDirectionW);\n\nfloat clearCoatNdotV=absEps(clearCoatNdotVUnclamped);\n\n#if defined(REFLECTION)\nfloat clearCoatAlphaG=convertRoughnessToAverageSlope(clearCoatRoughness);\n#ifdef SPECULARAA\n\nclearCoatAlphaG+=clearCoatAARoughnessFactors.y;\n#endif\nvec4 environmentClearCoatRadiance=vec4(0.,0.,0.,0.);\nvec3 clearCoatReflectionVector=computeReflectionCoords(vec4(vPositionW,1.0),clearCoatNormalW);\n#ifdef REFLECTIONMAP_OPPOSITEZ\nclearCoatReflectionVector.z*=-1.0;\n#endif\n\n#ifdef REFLECTIONMAP_3D\nvec3 clearCoatReflectionCoords=clearCoatReflectionVector;\n#else\nvec2 clearCoatReflectionCoords=clearCoatReflectionVector.xy;\n#ifdef REFLECTIONMAP_PROJECTION\nclearCoatReflectionCoords/=clearCoatReflectionVector.z;\n#endif\nclearCoatReflectionCoords.y=1.0-clearCoatReflectionCoords.y;\n#endif\n#if defined(LODINREFLECTIONALPHA) && !defined(REFLECTIONMAP_SKYBOX)\nfloat clearCoatReflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,clearCoatAlphaG,clearCoatNdotVUnclamped);\n#elif defined(LINEARSPECULARREFLECTION)\nfloat sheenReflectionLOD=getLinearLodFromRoughness(vReflectionMicrosurfaceInfos.x,clearCoatRoughness);\n#else\nfloat clearCoatReflectionLOD=getLodFromAlphaG(vReflectionMicrosurfaceInfos.x,clearCoatAlphaG);\n#endif\n#ifdef LODBASEDMICROSFURACE\n\nclearCoatReflectionLOD=clearCoatReflectionLOD*vReflectionMicrosurfaceInfos.y+vReflectionMicrosurfaceInfos.z;\nfloat requestedClearCoatReflectionLOD=clearCoatReflectionLOD;\nenvironmentClearCoatRadiance=sampleReflectionLod(reflectionSampler,clearCoatReflectionCoords,requestedClearCoatReflectionLOD);\n#else\nfloat lodClearCoatReflectionNormalized=saturate(clearCoatReflectionLOD/log2(vReflectionMicrosurfaceInfos.x));\nfloat lodClearCoatReflectionNormalizedDoubled=lodClearCoatReflectionNormalized*2.0;\nvec4 environmentClearCoatMid=sampleReflection(reflectionSampler,reflectionCoords);\nif(lodClearCoatReflectionNormalizedDoubled<1.0){\nenvironmentClearCoatRadiance=mix(\nsampleReflection(reflectionSamplerHigh,clearCoatReflectionCoords),\nenvironmentClearCoatMid,\nlodClearCoatReflectionNormalizedDoubled\n);\n}else{\nenvironmentClearCoatRadiance=mix(\nenvironmentClearCoatMid,\nsampleReflection(reflectionSamplerLow,clearCoatReflectionCoords),\nlodClearCoatReflectionNormalizedDoubled-1.0\n);\n}\n#endif\n#ifdef RGBDREFLECTION\nenvironmentClearCoatRadiance.rgb=fromRGBD(environmentClearCoatRadiance);\n#endif\n#ifdef GAMMAREFLECTION\nenvironmentClearCoatRadiance.rgb=toLinearSpace(environmentClearCoatRadiance.rgb);\n#endif\n#ifdef CLEARCOAT_TINT\n\nvec3 clearCoatVRefract=-refract(vPositionW,clearCoatNormalW,vClearCoatRefractionParams.y);\n\nfloat clearCoatNdotVRefract=absEps(dot(clearCoatNormalW,clearCoatVRefract));\nvec3 absorption=vec3(0.);\n#endif\n\nenvironmentClearCoatRadiance.rgb*=vReflectionInfos.x;\nenvironmentClearCoatRadiance.rgb*=vReflectionColor.rgb;\n#endif\n#endif\n\n#if defined(ENVIRONMENTBRDF)\n\nvec3 environmentBrdf=getBRDFLookup(NdotV,roughness);\n#ifdef MS_BRDF_ENERGY_CONSERVATION\nvec3 energyConservationFactor=getEnergyConservationFactor(specularEnvironmentR0,environmentBrdf);\n#endif\n#endif\n\n#ifdef SUBSURFACE\n#ifdef SS_REFRACTION\nfloat refractionIntensity=vSubSurfaceIntensity.x;\n#ifdef SS_LINKREFRACTIONTOTRANSPARENCY\nrefractionIntensity*=(1.0-alpha);\n\nalpha=1.0;\n#endif\n#endif\n#ifdef SS_TRANSLUCENCY\nfloat translucencyIntensity=vSubSurfaceIntensity.y;\n#endif\n#ifdef SS_SCATTERING\nfloat scatteringIntensity=vSubSurfaceIntensity.z;\n#endif\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvec4 thicknessMap=texture2D(thicknessSampler,vThicknessUV+uvOffset);\nfloat thickness=thicknessMap.r*vThicknessParam.y+vThicknessParam.x;\n#ifdef SS_MASK_FROM_THICKNESS_TEXTURE\n#ifdef SS_REFRACTION\nrefractionIntensity*=thicknessMap.g;\n#endif\n#ifdef SS_TRANSLUCENCY\ntranslucencyIntensity*=thicknessMap.b;\n#endif\n#ifdef SS_SCATTERING\nscatteringIntensity*=thicknessMap.a;\n#endif\n#endif\n#else\nfloat thickness=vThicknessParam.y;\n#endif\n#ifdef SS_TRANSLUCENCY\nthickness=maxEps(thickness);\nvec3 transmittance=transmittanceBRDF_Burley(vTintColor.rgb,vDiffusionDistance,thickness);\ntransmittance*=translucencyIntensity;\n#endif\n#endif\n\n\nvec3 diffuseBase=vec3(0.,0.,0.);\n#ifdef SPECULARTERM\nvec3 specularBase=vec3(0.,0.,0.);\n#endif\n#ifdef CLEARCOAT\nvec3 clearCoatBase=vec3(0.,0.,0.);\n#endif\n#ifdef SHEEN\nvec3 sheenBase=vec3(0.,0.,0.);\n#endif\n#ifdef LIGHTMAP\nvec4 lightmapColor=texture2D(lightmapSampler,vLightmapUV+uvOffset);\n#ifdef RGBDLIGHTMAP\nlightmapColor.rgb=fromRGBD(lightmapColor);\n#endif\n#ifdef GAMMALIGHTMAP\nlightmapColor.rgb=toLinearSpace(lightmapColor.rgb);\n#endif\nlightmapColor.rgb*=vLightmapInfos.y;\n#endif\n\npreLightingInfo preInfo;\nlightingInfo info;\nfloat shadow=1.;\n#include<lightFragment>[0..maxSimultaneousLights]\n\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\nvec3 specularEnvironmentReflectance=getReflectanceFromBRDFLookup(specularEnvironmentR0,environmentBrdf);\n#ifdef RADIANCEOCCLUSION\n#ifdef AMBIENTINGRAYSCALE\nfloat ambientMonochrome=ambientOcclusionColor.r;\n#else\nfloat ambientMonochrome=getLuminance(ambientOcclusionColor);\n#endif\nfloat seo=environmentRadianceOcclusion(ambientMonochrome,NdotVUnclamped);\nspecularEnvironmentReflectance*=seo;\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nfloat eho=environmentHorizonOcclusion(-viewDirectionW,normalW);\nspecularEnvironmentReflectance*=eho;\n#endif\n#endif\n#endif\n#else\n\nvec3 specularEnvironmentReflectance=getReflectanceFromAnalyticalBRDFLookup_Jones(NdotV,specularEnvironmentR0,specularEnvironmentR90,sqrt(microSurface));\n#endif\n\n#if defined(SHEEN) && defined(REFLECTION)\nvec3 sheenEnvironmentReflectance=getSheenReflectanceFromBRDFLookup(sheenColor,environmentBrdf);\n#ifdef RADIANCEOCCLUSION\nsheenEnvironmentReflectance*=seo;\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nsheenEnvironmentReflectance*=eho;\n#endif\n#endif\n#endif\n#endif\n\n#ifdef CLEARCOAT\n#if defined(ENVIRONMENTBRDF) && !defined(REFLECTIONMAP_SKYBOX)\n\nvec3 environmentClearCoatBrdf=getBRDFLookup(clearCoatNdotV,clearCoatRoughness);\nvec3 clearCoatEnvironmentReflectance=getReflectanceFromBRDFLookup(vec3(vClearCoatRefractionParams.x),environmentClearCoatBrdf);\n#ifdef RADIANCEOCCLUSION\nfloat clearCoatSeo=environmentRadianceOcclusion(ambientMonochrome,clearCoatNdotVUnclamped);\nclearCoatEnvironmentReflectance*=clearCoatSeo;\n#endif\n#ifdef HORIZONOCCLUSION\n#ifdef BUMP\n#ifdef REFLECTIONMAP_3D\nfloat clearCoatEho=environmentHorizonOcclusion(-viewDirectionW,clearCoatNormalW);\nclearCoatEnvironmentReflectance*=clearCoatEho;\n#endif\n#endif\n#endif\n#else\n\nvec3 clearCoatEnvironmentReflectance=getReflectanceFromAnalyticalBRDFLookup_Jones(clearCoatNdotV,vec3(1.),vec3(1.),sqrt(1.-clearCoatRoughness));\n#endif\nclearCoatEnvironmentReflectance*=clearCoatIntensity;\n#if defined(REFLECTION) && defined(CLEARCOAT_TINT)\n\nabsorption=computeClearCoatAbsorption(clearCoatNdotVRefract,clearCoatNdotVRefract,clearCoatColor,clearCoatThickness,clearCoatIntensity);\n#ifdef REFLECTION\nenvironmentIrradiance*=absorption;\n#endif\n#ifdef SHEEN\nsheenEnvironmentReflectance*=absorption;\n#endif\nspecularEnvironmentReflectance*=absorption;\n#endif\n\nfloat fresnelIBLClearCoat=fresnelSchlickGGX(clearCoatNdotV,vClearCoatRefractionParams.x,CLEARCOATREFLECTANCE90);\nfresnelIBLClearCoat*=clearCoatIntensity;\nfloat conservationFactor=(1.-fresnelIBLClearCoat);\n#ifdef REFLECTION\nenvironmentIrradiance*=conservationFactor;\n#endif\n#ifdef SHEEN\nsheenEnvironmentReflectance*=(conservationFactor*conservationFactor);\n#endif\nspecularEnvironmentReflectance*=(conservationFactor*conservationFactor);\n#endif\n\n#ifdef SS_REFRACTION\nvec3 refractionTransmittance=vec3(refractionIntensity);\n#ifdef SS_THICKNESSANDMASK_TEXTURE\nvec3 volumeAlbedo=computeColorAtDistanceInMedia(vTintColor.rgb,vTintColor.w);\n\n\n\n\n\nrefractionTransmittance*=cocaLambert(volumeAlbedo,thickness);\n#elif defined(SS_LINKREFRACTIONTOTRANSPARENCY)\n\nfloat maxChannel=max(max(surfaceAlbedo.r,surfaceAlbedo.g),surfaceAlbedo.b);\nvec3 volumeAlbedo=saturate(maxChannel*surfaceAlbedo);\n\nenvironmentRefraction.rgb*=volumeAlbedo;\n#else\n\nvec3 volumeAlbedo=computeColorAtDistanceInMedia(vTintColor.rgb,vTintColor.w);\nrefractionTransmittance*=cocaLambert(volumeAlbedo,vThicknessParam.y);\n#endif\n\nsurfaceAlbedo*=(1.-refractionIntensity);\n#ifdef REFLECTION\n\nenvironmentIrradiance*=(1.-refractionIntensity);\n#endif\n\nvec3 bounceSpecularEnvironmentReflectance=(2.0*specularEnvironmentReflectance)/(1.0+specularEnvironmentReflectance);\nspecularEnvironmentReflectance=mix(bounceSpecularEnvironmentReflectance,specularEnvironmentReflectance,refractionIntensity);\n\nrefractionTransmittance*=1.0-specularEnvironmentReflectance;\n#endif\n\n#if defined(REFLECTION) && defined(SS_TRANSLUCENCY)\n#if defined(USESPHERICALINVERTEX)\nvec3 irradianceVector=vec3(reflectionMatrix*vec4(normalW,0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nirradianceVector.z*=-1.0;\n#endif\n#endif\n#if defined(USESPHERICALFROMREFLECTIONMAP)\nvec3 refractionIrradiance=computeEnvironmentIrradiance(-irradianceVector);\n#elif defined(USEIRRADIANCEMAP)\nvec3 refractionIrradiance=sampleReflection(irradianceSampler,-irradianceVector).rgb;\n#ifdef RGBDREFLECTION\nrefractionIrradiance.rgb=fromRGBD(refractionIrradiance);\n#endif\n#ifdef GAMMAREFLECTION\nrefractionIrradiance.rgb=toLinearSpace(refractionIrradiance.rgb);\n#endif\n#else\nvec3 refractionIrradiance=vec3(0.);\n#endif\nrefractionIrradiance*=transmittance;\n#endif\n\n\n\n#ifndef METALLICWORKFLOW\nsurfaceAlbedo.rgb=(1.-reflectance)*surfaceAlbedo.rgb;\n#endif\n\n#ifdef REFLECTION\nvec3 finalIrradiance=environmentIrradiance;\n#if defined(SS_TRANSLUCENCY)\nfinalIrradiance+=refractionIrradiance;\n#endif\nfinalIrradiance*=surfaceAlbedo.rgb;\n#endif\n\n#ifdef SPECULARTERM\nvec3 finalSpecular=specularBase;\nfinalSpecular=max(finalSpecular,0.0);\n\nvec3 finalSpecularScaled=finalSpecular*vLightingIntensity.x*vLightingIntensity.w;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalSpecularScaled*=energyConservationFactor;\n#endif\n#endif\n\n#ifdef REFLECTION\nvec3 finalRadiance=environmentRadiance.rgb;\nfinalRadiance*=specularEnvironmentReflectance;\n\nvec3 finalRadianceScaled=finalRadiance*vLightingIntensity.z;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalRadianceScaled*=energyConservationFactor;\n#endif\n#endif\n\n#ifdef SS_REFRACTION\nvec3 finalRefraction=environmentRefraction.rgb;\nfinalRefraction*=refractionTransmittance;\n#endif\n\n#ifdef CLEARCOAT\nvec3 finalClearCoat=clearCoatBase;\nfinalClearCoat=max(finalClearCoat,0.0);\n\nvec3 finalClearCoatScaled=finalClearCoat*vLightingIntensity.x*vLightingIntensity.w;\n#if defined(ENVIRONMENTBRDF) && defined(MS_BRDF_ENERGY_CONSERVATION)\nfinalClearCoatScaled*=energyConservationFactor;\n#endif\n\n#ifdef REFLECTION\nvec3 finalClearCoatRadiance=environmentClearCoatRadiance.rgb;\nfinalClearCoatRadiance*=clearCoatEnvironmentReflectance;\n\nvec3 finalClearCoatRadianceScaled=finalClearCoatRadiance*vLightingIntensity.z;\n#endif\n#ifdef SS_REFRACTION\nfinalRefraction*=(conservationFactor*conservationFactor);\n#ifdef CLEARCOAT_TINT\nfinalRefraction*=absorption;\n#endif\n#endif\n#endif\n\n#ifdef SHEEN\nvec3 finalSheen=sheenBase*sheenColor;\nfinalSheen=max(finalSheen,0.0);\nvec3 finalSheenScaled=finalSheen*vLightingIntensity.x*vLightingIntensity.w;\n\n\n\n\n\n#ifdef REFLECTION\nvec3 finalSheenRadiance=environmentSheenRadiance.rgb;\nfinalSheenRadiance*=sheenEnvironmentReflectance;\n\nvec3 finalSheenRadianceScaled=finalSheenRadiance*vLightingIntensity.z;\n#endif\n#endif\n\n#ifdef ALPHABLEND\nfloat luminanceOverAlpha=0.0;\n#if defined(REFLECTION) && defined(RADIANCEOVERALPHA)\nluminanceOverAlpha+=getLuminance(finalRadianceScaled);\n#if defined(CLEARCOAT)\nluminanceOverAlpha+=getLuminance(finalClearCoatRadianceScaled);\n#endif\n#endif\n#if defined(SPECULARTERM) && defined(SPECULAROVERALPHA)\nluminanceOverAlpha+=getLuminance(finalSpecularScaled);\n#endif\n#if defined(CLEARCOAT) && defined(CLEARCOATOVERALPHA)\nluminanceOverAlpha+=getLuminance(finalClearCoatScaled);\n#endif\n#if defined(RADIANCEOVERALPHA) || defined(SPECULAROVERALPHA)\nalpha=saturate(alpha+luminanceOverAlpha*luminanceOverAlpha);\n#endif\n#endif\n#endif\n\n\nvec3 finalDiffuse=diffuseBase;\nfinalDiffuse*=surfaceAlbedo.rgb;\nfinalDiffuse=max(finalDiffuse,0.0);\n\nvec3 finalAmbient=vAmbientColor;\nfinalAmbient*=surfaceAlbedo.rgb;\n\nvec3 finalEmissive=vEmissiveColor;\n#ifdef EMISSIVE\nvec3 emissiveColorTex=texture2D(emissiveSampler,vEmissiveUV+uvOffset).rgb;\nfinalEmissive*=toLinearSpace(emissiveColorTex.rgb);\nfinalEmissive*=vEmissiveInfos.y;\n#endif\n\n#ifdef AMBIENT\nvec3 ambientOcclusionForDirectDiffuse=mix(vec3(1.),ambientOcclusionColor,vAmbientInfos.w);\n#else\nvec3 ambientOcclusionForDirectDiffuse=ambientOcclusionColor;\n#endif\n\n\n\nvec4 finalColor=vec4(\nfinalAmbient*ambientOcclusionColor +\nfinalDiffuse*ambientOcclusionForDirectDiffuse*vLightingIntensity.x +\n#ifndef UNLIT\n#ifdef REFLECTION\nfinalIrradiance*ambientOcclusionColor*vLightingIntensity.z +\n#endif\n#ifdef SPECULARTERM\n\n\nfinalSpecularScaled +\n#endif\n#ifdef CLEARCOAT\n\n\nfinalClearCoatScaled +\n#endif\n#ifdef SHEEN\n\n\nfinalSheenScaled +\n#endif\n#ifdef REFLECTION\n\n\nfinalRadianceScaled +\n#ifdef CLEARCOAT\n\n\nfinalClearCoatRadianceScaled +\n#endif\n#ifdef SHEEN\n\n\nfinalSheenRadianceScaled +\n#endif\n#endif\n#ifdef SS_REFRACTION\nfinalRefraction*vLightingIntensity.z +\n#endif\n#endif\nfinalEmissive*vLightingIntensity.y,\nalpha);\n\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\nfinalColor.rgb*=lightmapColor.rgb;\n#else\nfinalColor.rgb+=lightmapColor.rgb;\n#endif\n#endif\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FOG\n\nfinalColor=max(finalColor,0.0);\n#include<logDepthFragment>\n#include<fogFragment>(color,finalColor)\n#ifdef IMAGEPROCESSINGPOSTPROCESS\n\n\nfinalColor.rgb=clamp(finalColor.rgb,0.,30.0);\n#else\n\nfinalColor=applyImageProcessing(finalColor);\n#endif\nfinalColor.a*=visibility;\n#ifdef PREMULTIPLYALPHA\n\nfinalColor.rgb*=finalColor.a;\n#endif\n#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR\ngl_FragColor=finalColor;\n#include<pbrDebug>\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var pbrPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/pbr.vertex.ts":
/*!*******************************!*\
  !*** ./Shaders/pbr.vertex.ts ***!
  \*******************************/
/*! exports provided: pbrVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pbrVertexShader", function() { return pbrVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_pbrVertexDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/pbrVertexDeclaration */ "./Shaders/ShadersInclude/pbrVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_pbrUboDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/pbrUboDeclaration */ "./Shaders/ShadersInclude/pbrUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_harmonicsFunctions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/harmonicsFunctions */ "./Shaders/ShadersInclude/harmonicsFunctions.ts");
/* harmony import */ var _ShadersInclude_bumpVertexDeclaration__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/bumpVertexDeclaration */ "./Shaders/ShadersInclude/bumpVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertexDeclaration__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertexDeclaration */ "./Shaders/ShadersInclude/clipPlaneVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogVertexDeclaration__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/fogVertexDeclaration */ "./Shaders/ShadersInclude/fogVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightFragmentDeclaration__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ShadersInclude/lightFragmentDeclaration */ "./Shaders/ShadersInclude/lightFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_lightUboDeclaration__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./ShadersInclude/lightUboDeclaration */ "./Shaders/ShadersInclude/lightUboDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_logDepthDeclaration__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ShadersInclude/logDepthDeclaration */ "./Shaders/ShadersInclude/logDepthDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");
/* harmony import */ var _ShadersInclude_bumpVertex__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./ShadersInclude/bumpVertex */ "./Shaders/ShadersInclude/bumpVertex.ts");
/* harmony import */ var _ShadersInclude_clipPlaneVertex__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./ShadersInclude/clipPlaneVertex */ "./Shaders/ShadersInclude/clipPlaneVertex.ts");
/* harmony import */ var _ShadersInclude_fogVertex__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./ShadersInclude/fogVertex */ "./Shaders/ShadersInclude/fogVertex.ts");
/* harmony import */ var _ShadersInclude_shadowsVertex__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./ShadersInclude/shadowsVertex */ "./Shaders/ShadersInclude/shadowsVertex.ts");
/* harmony import */ var _ShadersInclude_logDepthVertex__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./ShadersInclude/logDepthVertex */ "./Shaders/ShadersInclude/logDepthVertex.ts");






















var name = 'pbrVertexShader';
var shader = "precision highp float;\n#include<__decl__pbrVertex>\n#define CUSTOM_VERTEX_BEGIN\n\nattribute vec3 position;\n\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#ifdef INSTANCES\nattribute vec4 world0;\nattribute vec4 world1;\nattribute vec4 world2;\nattribute vec4 world3;\n#endif\n#include<helperFunctions>\n#include<bonesDeclaration>\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvarying vec3 vEnvironmentIrradiance;\n#include<harmonicsFunctions>\n#endif\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if DEBUGMODE>0\nvarying vec4 vClipSpacePosition;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#if defined(ALBEDO) && ALBEDODIRECTUV == 0\nvarying vec2 vAlbedoUV;\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nvarying vec2 vAmbientUV;\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nvarying vec2 vOpacityUV;\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nvarying vec2 vEmissiveUV;\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nvarying vec2 vLightmapUV;\n#endif\n#if defined(REFLECTIVITY) && REFLECTIVITYDIRECTUV == 0\nvarying vec2 vReflectivityUV;\n#endif\n#if defined(MICROSURFACEMAP) && MICROSURFACEMAPDIRECTUV == 0\nvarying vec2 vMicroSurfaceSamplerUV;\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nvarying vec2 vBumpUV;\n#endif\n#ifdef CLEARCOAT\n#if defined(CLEARCOAT_TEXTURE) && CLEARCOAT_TEXTUREDIRECTUV == 0\nvarying vec2 vClearCoatUV;\n#endif\n#if defined(CLEARCOAT_BUMP) && CLEARCOAT_BUMPDIRECTUV == 0\nvarying vec2 vClearCoatBumpUV;\n#endif\n#if defined(CLEARCOAT_TINT_TEXTURE) && CLEARCOAT_TINT_TEXTUREDIRECTUV == 0\nvarying vec2 vClearCoatTintUV;\n#endif\n#endif\n#ifdef SHEEN\n#if defined(SHEEN_TEXTURE) && SHEEN_TEXTUREDIRECTUV == 0\nvarying vec2 vSheenUV;\n#endif\n#endif\n#ifdef ANISOTROPIC\n#if defined(ANISOTROPIC_TEXTURE) && ANISOTROPIC_TEXTUREDIRECTUV == 0\nvarying vec2 vAnisotropyUV;\n#endif\n#endif\n#ifdef SUBSURFACE\n#if defined(SS_THICKNESSANDMASK_TEXTURE) && SS_THICKNESSANDMASK_TEXTUREDIRECTUV == 0\nvarying vec2 vThicknessUV;\n#endif\n#endif\n#include<bumpVertexDeclaration>\n#include<clipPlaneVertexDeclaration>\n#include<fogVertexDeclaration>\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n#include<logDepthDeclaration>\n#define CUSTOM_VERTEX_DEFINITIONS\nvoid main(void) {\n#define CUSTOM_VERTEX_MAIN_BEGIN\nvec3 positionUpdated=position;\n#ifdef NORMAL\nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\n#ifdef REFLECTIONMAP_SKYBOX_TRANSFORMED\nvPositionUVW=(reflectionMatrix*vec4(positionUpdated,1.0)).xyz;\n#else\nvPositionUVW=positionUpdated;\n#endif\n#endif\n#define CUSTOM_VERTEX_UPDATE_POSITION\n#define CUSTOM_VERTEX_UPDATE_NORMAL\n#include<instancesVertex>\n#include<bonesVertex>\n#ifdef MULTIVIEW\nif (gl_ViewID_OVR == 0u) {\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n} else {\ngl_Position=viewProjectionR*finalWorld*vec4(positionUpdated,1.0);\n}\n#else\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\n#endif\n#if DEBUGMODE>0\nvClipSpacePosition=gl_Position;\n#endif\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\nvPositionW=vec3(worldPos);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#if defined(USESPHERICALFROMREFLECTIONMAP) && defined(USESPHERICALINVERTEX)\nvec3 reflectionVector=vec3(reflectionMatrix*vec4(vNormalW,0)).xyz;\n#ifdef REFLECTIONMAP_OPPOSITEZ\nreflectionVector.z*=-1.0;\n#endif\nvEnvironmentIrradiance=computeEnvironmentIrradiance(reflectionVector);\n#endif\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n\n#ifndef UV1\nvec2 uvUpdated=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uvUpdated;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2;\n#endif\n#if defined(ALBEDO) && ALBEDODIRECTUV == 0\nif (vAlbedoInfos.x == 0.)\n{\nvAlbedoUV=vec2(albedoMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvAlbedoUV=vec2(albedoMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nif (vAmbientInfos.x == 0.)\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nif (vOpacityInfos.x == 0.)\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nif (vEmissiveInfos.x == 0.)\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nif (vLightmapInfos.x == 0.)\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(REFLECTIVITY) && REFLECTIVITYDIRECTUV == 0\nif (vReflectivityInfos.x == 0.)\n{\nvReflectivityUV=vec2(reflectivityMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvReflectivityUV=vec2(reflectivityMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(MICROSURFACEMAP) && MICROSURFACEMAPDIRECTUV == 0\nif (vMicroSurfaceSamplerInfos.x == 0.)\n{\nvMicroSurfaceSamplerUV=vec2(microSurfaceSamplerMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvMicroSurfaceSamplerUV=vec2(microSurfaceSamplerMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nif (vBumpInfos.x == 0.)\n{\nvBumpUV=vec2(bumpMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvBumpUV=vec2(bumpMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#ifdef CLEARCOAT\n#if defined(CLEARCOAT_TEXTURE) && CLEARCOAT_TEXTUREDIRECTUV == 0\nif (vClearCoatInfos.x == 0.)\n{\nvClearCoatUV=vec2(clearCoatMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvClearCoatUV=vec2(clearCoatMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(CLEARCOAT_BUMP) && CLEARCOAT_BUMPDIRECTUV == 0\nif (vClearCoatBumpInfos.x == 0.)\n{\nvClearCoatBumpUV=vec2(clearCoatBumpMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvClearCoatBumpUV=vec2(clearCoatBumpMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(CLEARCOAT_TINT_TEXTURE) && CLEARCOAT_TINT_TEXTUREDIRECTUV == 0\nif (vClearCoatTintInfos.x == 0.)\n{\nvClearCoatTintUV=vec2(clearCoatTintMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvClearCoatTintUV=vec2(clearCoatTintMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#endif\n#ifdef SHEEN\n#if defined(SHEEN_TEXTURE) && SHEEN_TEXTUREDIRECTUV == 0\nif (vSheenInfos.x == 0.)\n{\nvSheenUV=vec2(sheenMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvSheenUV=vec2(sheenMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#endif\n#ifdef ANISOTROPIC\n#if defined(ANISOTROPIC_TEXTURE) && ANISOTROPIC_TEXTUREDIRECTUV == 0\nif (vAnisotropyInfos.x == 0.)\n{\nvAnisotropyUV=vec2(anisotropyMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvAnisotropyUV=vec2(anisotropyMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#endif\n#ifdef SUBSURFACE\n#if defined(SS_THICKNESSANDMASK_TEXTURE) && SS_THICKNESSANDMASK_TEXTUREDIRECTUV == 0\nif (vThicknessInfos.x == 0.)\n{\nvThicknessUV=vec2(thicknessMatrix*vec4(uvUpdated,1.0,0.0));\n}\nelse\n{\nvThicknessUV=vec2(thicknessMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#endif\n\n#include<bumpVertex>\n\n#include<clipPlaneVertex>\n\n#include<fogVertex>\n\n#include<shadowsVertex>[0..maxSimultaneousLights]\n\n#ifdef VERTEXCOLOR\nvColor=color;\n#endif\n\n#ifdef POINTSIZE\ngl_PointSize=pointSize;\n#endif\n\n#include<logDepthVertex>\n#define CUSTOM_VERTEX_MAIN_END\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var pbrVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/postprocess.vertex.ts":
/*!***************************************!*\
  !*** ./Shaders/postprocess.vertex.ts ***!
  \***************************************/
/*! exports provided: postprocessVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "postprocessVertexShader", function() { return postprocessVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'postprocessVertexShader';
var shader = "\nattribute vec2 position;\nuniform vec2 scale;\n\nvarying vec2 vUV;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nvUV=(position*madd+madd)*scale;\ngl_Position=vec4(position,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var postprocessVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/procedural.vertex.ts":
/*!**************************************!*\
  !*** ./Shaders/procedural.vertex.ts ***!
  \**************************************/
/*! exports provided: proceduralVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "proceduralVertexShader", function() { return proceduralVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'proceduralVertexShader';
var shader = "\nattribute vec2 position;\n\nvarying vec2 vPosition;\nvarying vec2 vUV;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) {\nvPosition=position;\nvUV=position*madd+madd;\ngl_Position=vec4(position,0.0,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var proceduralVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/refraction.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/refraction.fragment.ts ***!
  \****************************************/
/*! exports provided: refractionPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "refractionPixelShader", function() { return refractionPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'refractionPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform sampler2D refractionSampler;\n\nuniform vec3 baseColor;\nuniform float depth;\nuniform float colorLevel;\nvoid main() {\nfloat ref=1.0-texture2D(refractionSampler,vUV).r;\nvec2 uv=vUV-vec2(0.5);\nvec2 offset=uv*depth*ref;\nvec3 sourceColor=texture2D(textureSampler,vUV-offset).rgb;\ngl_FragColor=vec4(sourceColor+sourceColor*ref*colorLevel,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var refractionPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/rgbdDecode.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/rgbdDecode.fragment.ts ***!
  \****************************************/
/*! exports provided: rgbdDecodePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rgbdDecodePixelShader", function() { return rgbdDecodePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");


var name = 'rgbdDecodePixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n#include<helperFunctions>\nvoid main(void)\n{\ngl_FragColor=vec4(fromRGBD(texture2D(textureSampler,vUV)),1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var rgbdDecodePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/rgbdEncode.fragment.ts":
/*!****************************************!*\
  !*** ./Shaders/rgbdEncode.fragment.ts ***!
  \****************************************/
/*! exports provided: rgbdEncodePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rgbdEncodePixelShader", function() { return rgbdEncodePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");


var name = 'rgbdEncodePixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n#include<helperFunctions>\nvoid main(void)\n{\ngl_FragColor=toRGBD(texture2D(textureSampler,vUV).rgb);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var rgbdEncodePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/shadowMap.fragment.ts":
/*!***************************************!*\
  !*** ./Shaders/shadowMap.fragment.ts ***!
  \***************************************/
/*! exports provided: shadowMapPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowMapPixelShader", function() { return shadowMapPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_packingFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/packingFunctions */ "./Shaders/ShadersInclude/packingFunctions.ts");


var name = 'shadowMapPixelShader';
var shader = "#ifndef FLOAT\n#include<packingFunctions>\n#endif\nvarying float vDepthMetric;\n#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform sampler2D diffuseSampler;\n#endif\nuniform vec3 biasAndScale;\nuniform vec2 depthValues;\nvoid main(void)\n{\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\nfloat depth=vDepthMetric;\n#ifdef ESM\ndepth=clamp(exp(-min(87.,biasAndScale.z*depth)),0.,1.);\n#endif\n#ifdef FLOAT\ngl_FragColor=vec4(depth,1.0,1.0,1.0);\n#else\ngl_FragColor=pack(depth);\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var shadowMapPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/shadowMap.vertex.ts":
/*!*************************************!*\
  !*** ./Shaders/shadowMap.vertex.ts ***!
  \*************************************/
/*! exports provided: shadowMapVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shadowMapVertexShader", function() { return shadowMapVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_helperFunctions__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/helperFunctions */ "./Shaders/ShadersInclude/helperFunctions.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");









var name = 'shadowMapVertexShader';
var shader = "\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\nuniform vec3 lightData;\n#endif\n#include<bonesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n\n#include<instancesDeclaration>\n#include<helperFunctions>\nuniform mat4 viewProjection;\nuniform vec3 biasAndScale;\nuniform vec2 depthValues;\nvarying float vDepthMetric;\n#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\nvoid main(void)\n{\nvec3 positionUpdated=position;\n#ifdef UV1\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\n\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvec3 worldNor=normalize(normalWorld*normal);\n#ifdef DIRECTIONINLIGHTDATA\nvec3 worldLightDir=normalize(-lightData.xyz);\n#else\nvec3 directionToLight=lightData.xyz-worldPos.xyz;\nvec3 worldLightDir=normalize(directionToLight);\n#endif\nfloat ndl=dot(worldNor,worldLightDir);\nfloat sinNL=sqrt(1.0-ndl*ndl);\nfloat normalBias=biasAndScale.y*sinNL;\nworldPos.xyz-=worldNor*normalBias;\n#endif\n\ngl_Position=viewProjection*worldPos;\n#ifdef DEPTHTEXTURE\n\ngl_Position.z+=biasAndScale.x*gl_Position.w;\n#endif\n\nvDepthMetric=((gl_Position.z+depthValues.x)/(depthValues.y))+biasAndScale.x;\n#ifdef ALPHATEST\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var shadowMapVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/sharpen.fragment.ts":
/*!*************************************!*\
  !*** ./Shaders/sharpen.fragment.ts ***!
  \*************************************/
/*! exports provided: sharpenPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sharpenPixelShader", function() { return sharpenPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'sharpenPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform vec2 screenSize;\nuniform vec2 sharpnessAmounts;\nvoid main(void)\n{\nvec2 onePixel=vec2(1.0,1.0)/screenSize;\nvec4 color=texture2D(textureSampler,vUV);\nvec4 edgeDetection=texture2D(textureSampler,vUV+onePixel*vec2(0,-1)) +\ntexture2D(textureSampler,vUV+onePixel*vec2(-1,0)) +\ntexture2D(textureSampler,vUV+onePixel*vec2(1,0)) +\ntexture2D(textureSampler,vUV+onePixel*vec2(0,1)) -\ncolor*4.0;\ngl_FragColor=max(vec4(color.rgb*sharpnessAmounts.y,color.a)-(sharpnessAmounts.x*vec4(edgeDetection.rgb,0)),0.);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var sharpenPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/sprites.fragment.ts":
/*!*************************************!*\
  !*** ./Shaders/sprites.fragment.ts ***!
  \*************************************/
/*! exports provided: spritesPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spritesPixelShader", function() { return spritesPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_fogFragmentDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/fogFragmentDeclaration */ "./Shaders/ShadersInclude/fogFragmentDeclaration.ts");
/* harmony import */ var _ShadersInclude_fogFragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/fogFragment */ "./Shaders/ShadersInclude/fogFragment.ts");



var name = 'spritesPixelShader';
var shader = "uniform bool alphaTest;\nvarying vec4 vColor;\n\nvarying vec2 vUV;\nuniform sampler2D diffuseSampler;\n\n#include<fogFragmentDeclaration>\nvoid main(void) {\nvec4 color=texture2D(diffuseSampler,vUV);\nif (alphaTest)\n{\nif (color.a<0.95)\ndiscard;\n}\ncolor*=vColor;\n#include<fogFragment>\ngl_FragColor=color;\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var spritesPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/sprites.vertex.ts":
/*!***********************************!*\
  !*** ./Shaders/sprites.vertex.ts ***!
  \***********************************/
/*! exports provided: spritesVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spritesVertexShader", function() { return spritesVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_fogVertexDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/fogVertexDeclaration */ "./Shaders/ShadersInclude/fogVertexDeclaration.ts");


var name = 'spritesVertexShader';
var shader = "\nattribute vec4 position;\nattribute vec4 options;\nattribute vec2 inverts;\nattribute vec4 cellInfo;\nattribute vec4 color;\n\nuniform mat4 view;\nuniform mat4 projection;\n\nvarying vec2 vUV;\nvarying vec4 vColor;\n#include<fogVertexDeclaration>\nvoid main(void) {\nvec3 viewPos=(view*vec4(position.xyz,1.0)).xyz;\nvec2 cornerPos;\nfloat angle=position.w;\nvec2 size=vec2(options.x,options.y);\nvec2 offset=options.zw;\ncornerPos=vec2(offset.x-0.5,offset.y-0.5)*size;\n\nvec3 rotatedCorner;\nrotatedCorner.x=cornerPos.x*cos(angle)-cornerPos.y*sin(angle);\nrotatedCorner.y=cornerPos.x*sin(angle)+cornerPos.y*cos(angle);\nrotatedCorner.z=0.;\n\nviewPos+=rotatedCorner;\ngl_Position=projection*vec4(viewPos,1.0);\n\nvColor=color;\n\nvec2 uvOffset=vec2(abs(offset.x-inverts.x),abs(1.0-offset.y-inverts.y));\nvec2 uvPlace=cellInfo.xy;\nvec2 uvSize=cellInfo.zw;\nvUV.x=uvPlace.x+uvSize.x*uvOffset.x;\nvUV.y=uvPlace.y+uvSize.y*uvOffset.y;\n\n#ifdef FOG\nvFogDistance=viewPos;\n#endif\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var spritesVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ssao.fragment.ts":
/*!**********************************!*\
  !*** ./Shaders/ssao.fragment.ts ***!
  \**********************************/
/*! exports provided: ssaoPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ssaoPixelShader", function() { return ssaoPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'ssaoPixelShader';
var shader = "\nuniform sampler2D textureSampler;\nvarying vec2 vUV;\n#ifdef SSAO\nuniform sampler2D randomSampler;\nuniform float randTextureTiles;\nuniform float samplesFactor;\nuniform vec3 sampleSphere[SAMPLES];\nuniform float totalStrength;\nuniform float radius;\nuniform float area;\nuniform float fallOff;\nuniform float base;\nvec3 normalFromDepth(float depth,vec2 coords)\n{\nvec2 offset1=vec2(0.0,radius);\nvec2 offset2=vec2(radius,0.0);\nfloat depth1=texture2D(textureSampler,coords+offset1).r;\nfloat depth2=texture2D(textureSampler,coords+offset2).r;\nvec3 p1=vec3(offset1,depth1-depth);\nvec3 p2=vec3(offset2,depth2-depth);\nvec3 normal=cross(p1,p2);\nnormal.z=-normal.z;\nreturn normalize(normal);\n}\nvoid main()\n{\nvec3 random=normalize(texture2D(randomSampler,vUV*randTextureTiles).rgb);\nfloat depth=texture2D(textureSampler,vUV).r;\nvec3 position=vec3(vUV,depth);\nvec3 normal=normalFromDepth(depth,vUV);\nfloat radiusDepth=radius/depth;\nfloat occlusion=0.0;\nvec3 ray;\nvec3 hemiRay;\nfloat occlusionDepth;\nfloat difference;\nfor (int i=0; i<SAMPLES; i++)\n{\nray=radiusDepth*reflect(sampleSphere[i],random);\nhemiRay=position+sign(dot(ray,normal))*ray;\nocclusionDepth=texture2D(textureSampler,clamp(hemiRay.xy,vec2(0.001,0.001),vec2(0.999,0.999))).r;\ndifference=depth-occlusionDepth;\nocclusion+=step(fallOff,difference)*(1.0-smoothstep(fallOff,area,difference));\n}\nfloat ao=1.0-totalStrength*occlusion*samplesFactor;\nfloat result=clamp(ao+base,0.0,1.0);\ngl_FragColor.r=result;\ngl_FragColor.g=result;\ngl_FragColor.b=result;\ngl_FragColor.a=1.0;\n}\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var ssaoPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ssao2.fragment.ts":
/*!***********************************!*\
  !*** ./Shaders/ssao2.fragment.ts ***!
  \***********************************/
/*! exports provided: ssao2PixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ssao2PixelShader", function() { return ssao2PixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'ssao2PixelShader';
var shader = "\nprecision highp float;\nuniform sampler2D textureSampler;\nuniform float near;\nuniform float far;\nuniform float radius;\nfloat scales[16]=float[16](\n0.1,\n0.11406250000000001,\n0.131640625,\n0.15625,\n0.187890625,\n0.2265625,\n0.272265625,\n0.325,\n0.384765625,\n0.4515625,\n0.525390625,\n0.60625,\n0.694140625,\n0.7890625,\n0.891015625,\n1.0\n);\nvarying vec2 vUV;\nfloat perspectiveDepthToViewZ( const in float invClipZ,const in float near,const in float far ) {\nreturn ( near*far )/( ( far-near )*invClipZ-far );\n}\nfloat viewZToPerspectiveDepth( const in float viewZ,const in float near,const in float far ) {\nreturn ( near*far/viewZ+far)/( far-near );\n}\nfloat viewZToOrthographicDepth( const in float viewZ,const in float near,const in float far ) {\nreturn ( viewZ+near )/( near-far );\n}\n#ifdef SSAO\nuniform sampler2D randomSampler;\nuniform sampler2D normalSampler;\nuniform float randTextureTiles;\nuniform float samplesFactor;\nuniform vec3 sampleSphere[SAMPLES];\nuniform float totalStrength;\nuniform float base;\nuniform float xViewport;\nuniform float yViewport;\nuniform float maxZ;\nuniform float minZAspect;\nuniform vec2 texelSize;\nuniform mat4 projection;\nvoid main()\n{\nvec3 random=texture2D(randomSampler,vUV*randTextureTiles).rgb;\nfloat depth=texture2D(textureSampler,vUV).r;\nfloat depthSign=depth/abs(depth);\ndepth=depth*depthSign;\nvec3 normal=texture2D(normalSampler,vUV).rgb;\nfloat occlusion=0.0;\nfloat correctedRadius=min(radius,minZAspect*depth/near);\nvec3 vViewRay=vec3((vUV.x*2.0-1.0)*xViewport,(vUV.y*2.0-1.0)*yViewport,depthSign);\nvec3 origin=vViewRay*depth;\nvec3 rvec=random*2.0-1.0;\nrvec.z=0.0;\n\nfloat dotProduct=dot(rvec,normal);\nrvec=1.0-abs(dotProduct)>1e-2 ? rvec : vec3(-rvec.y,0.0,rvec.x);\nvec3 tangent=normalize(rvec-normal*dot(rvec,normal));\nvec3 bitangent=cross(normal,tangent);\nmat3 tbn=mat3(tangent,bitangent,normal);\nfloat difference;\nfor (int i=0; i<SAMPLES; ++i) {\n\nvec3 samplePosition=scales[(i+int(random.x*16.0)) % 16]*tbn*sampleSphere[(i+int(random.y*16.0)) % 16];\nsamplePosition=samplePosition*correctedRadius+origin;\n\nvec4 offset=vec4(samplePosition,1.0);\noffset=projection*offset;\noffset.xyz/=offset.w;\noffset.xy=offset.xy*0.5+0.5;\nif (offset.x<0.0 || offset.y<0.0 || offset.x>1.0 || offset.y>1.0) {\ncontinue;\n}\n\nfloat sampleDepth=abs(texture2D(textureSampler,offset.xy).r);\n\ndifference=depthSign*samplePosition.z-sampleDepth;\nfloat rangeCheck=1.0-smoothstep(correctedRadius*0.5,correctedRadius,difference);\nocclusion+=(difference>=0.0 ? 1.0 : 0.0)*rangeCheck;\n}\nocclusion=occlusion*(1.0-smoothstep(maxZ*0.75,maxZ,depth));\nfloat ao=1.0-totalStrength*occlusion*samplesFactor;\nfloat result=clamp(ao+base,0.0,1.0);\ngl_FragColor=vec4(vec3(result),1.0);\n}\n#endif\n#ifdef BILATERAL_BLUR\nuniform sampler2D depthSampler;\nuniform float outSize;\nuniform float samplerOffsets[SAMPLES];\nvec4 blur9(sampler2D image,vec2 uv,float resolution,vec2 direction) {\nvec4 color=vec4(0.0);\nvec2 off1=vec2(1.3846153846)*direction;\nvec2 off2=vec2(3.2307692308)*direction;\ncolor+=texture2D(image,uv)*0.2270270270;\ncolor+=texture2D(image,uv+(off1/resolution))*0.3162162162;\ncolor+=texture2D(image,uv-(off1/resolution))*0.3162162162;\ncolor+=texture2D(image,uv+(off2/resolution))*0.0702702703;\ncolor+=texture2D(image,uv-(off2/resolution))*0.0702702703;\nreturn color;\n}\nvec4 blur13(sampler2D image,vec2 uv,float resolution,vec2 direction) {\nvec4 color=vec4(0.0);\nvec2 off1=vec2(1.411764705882353)*direction;\nvec2 off2=vec2(3.2941176470588234)*direction;\nvec2 off3=vec2(5.176470588235294)*direction;\ncolor+=texture2D(image,uv)*0.1964825501511404;\ncolor+=texture2D(image,uv+(off1/resolution))*0.2969069646728344;\ncolor+=texture2D(image,uv-(off1/resolution))*0.2969069646728344;\ncolor+=texture2D(image,uv+(off2/resolution))*0.09447039785044732;\ncolor+=texture2D(image,uv-(off2/resolution))*0.09447039785044732;\ncolor+=texture2D(image,uv+(off3/resolution))*0.010381362401148057;\ncolor+=texture2D(image,uv-(off3/resolution))*0.010381362401148057;\nreturn color;\n}\nvec4 blur13Bilateral(sampler2D image,vec2 uv,float resolution,vec2 direction) {\nvec4 color=vec4(0.0);\nvec2 off1=vec2(1.411764705882353)*direction;\nvec2 off2=vec2(3.2941176470588234)*direction;\nvec2 off3=vec2(5.176470588235294)*direction;\nfloat compareDepth=abs(texture2D(depthSampler,uv).r);\nfloat sampleDepth;\nfloat weight;\nfloat weightSum=30.0;\ncolor+=texture2D(image,uv)*30.0;\nsampleDepth=abs(texture2D(depthSampler,uv+(off1/resolution)).r);\nweight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);\nweightSum+=weight;\ncolor+=texture2D(image,uv+(off1/resolution))*weight;\nsampleDepth=abs(texture2D(depthSampler,uv-(off1/resolution)).r);\nweight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);\nweightSum+=weight;\ncolor+=texture2D(image,uv-(off1/resolution))*weight;\nsampleDepth=abs(texture2D(depthSampler,uv+(off2/resolution)).r);\nweight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);\nweightSum+=weight;\ncolor+=texture2D(image,uv+(off2/resolution))*weight;\nsampleDepth=abs(texture2D(depthSampler,uv-(off2/resolution)).r);\nweight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);\nweightSum+=weight;\ncolor+=texture2D(image,uv-(off2/resolution))*weight;\nsampleDepth=abs(texture2D(depthSampler,uv+(off3/resolution)).r);\nweight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);\nweightSum+=weight;\ncolor+=texture2D(image,uv+(off3/resolution))*weight;\nsampleDepth=abs(texture2D(depthSampler,uv-(off3/resolution)).r);\nweight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30.0);\nweightSum+=weight;\ncolor+=texture2D(image,uv-(off3/resolution))*weight;\nreturn color/weightSum;\n}\nvoid main()\n{\n#if EXPENSIVE\nfloat compareDepth=abs(texture2D(depthSampler,vUV).r);\nfloat texelsize=1.0/outSize;\nfloat result=0.0;\nfloat weightSum=0.0;\nfor (int i=0; i<SAMPLES; ++i)\n{\n#ifdef BILATERAL_BLUR_H\nvec2 direction=vec2(1.0,0.0);\nvec2 sampleOffset=vec2(texelsize*samplerOffsets[i],0.0);\n#else\nvec2 direction=vec2(0.0,1.0);\nvec2 sampleOffset=vec2(0.0,texelsize*samplerOffsets[i]);\n#endif\nvec2 samplePos=vUV+sampleOffset;\nfloat sampleDepth=abs(texture2D(depthSampler,samplePos).r);\nfloat weight=clamp(1.0/( 0.003+abs(compareDepth-sampleDepth)),0.0,30000.0);\nresult+=texture2D(textureSampler,samplePos).r*weight;\nweightSum+=weight;\n}\nresult/=weightSum;\ngl_FragColor.rgb=vec3(result);\ngl_FragColor.a=1.0;\n#else\nvec4 color;\n#ifdef BILATERAL_BLUR_H\nvec2 direction=vec2(1.0,0.0);\ncolor=blur13Bilateral(textureSampler,vUV,outSize,direction);\n#else\nvec2 direction=vec2(0.0,1.0);\ncolor=blur13Bilateral(textureSampler,vUV,outSize,direction);\n#endif\ngl_FragColor.rgb=vec3(color.r);\ngl_FragColor.a=1.0;\n#endif\n}\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var ssao2PixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/ssaoCombine.fragment.ts":
/*!*****************************************!*\
  !*** ./Shaders/ssaoCombine.fragment.ts ***!
  \*****************************************/
/*! exports provided: ssaoCombinePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ssaoCombinePixelShader", function() { return ssaoCombinePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'ssaoCombinePixelShader';
var shader = "uniform sampler2D textureSampler;\nuniform sampler2D originalColor;\nuniform vec4 viewport;\nvarying vec2 vUV;\nvoid main(void) {\nvec4 ssaoColor=texture2D(textureSampler,viewport.xy+vUV*viewport.zw);\nvec4 sceneColor=texture2D(originalColor,vUV);\ngl_FragColor=sceneColor*ssaoColor;\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var ssaoCombinePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/standard.fragment.ts":
/*!**************************************!*\
  !*** ./Shaders/standard.fragment.ts ***!
  \**************************************/
/*! exports provided: standardPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "standardPixelShader", function() { return standardPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_packingFunctions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/packingFunctions */ "./Shaders/ShadersInclude/packingFunctions.ts");


var name = 'standardPixelShader';
var shader = "uniform sampler2D textureSampler;\nvarying vec2 vUV;\n#if defined(PASS_POST_PROCESS)\nvoid main(void)\n{\nvec4 color=texture2D(textureSampler,vUV);\ngl_FragColor=color;\n}\n#endif\n#if defined(DOWN_SAMPLE_X4)\nuniform vec2 dsOffsets[16];\nvoid main(void)\n{\nvec4 average=vec4(0.0,0.0,0.0,0.0);\naverage=texture2D(textureSampler,vUV+dsOffsets[0]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[1]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[2]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[3]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[4]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[5]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[6]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[7]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[8]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[9]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[10]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[11]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[12]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[13]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[14]);\naverage+=texture2D(textureSampler,vUV+dsOffsets[15]);\naverage/=16.0;\ngl_FragColor=average;\n}\n#endif\n#if defined(BRIGHT_PASS)\nuniform vec2 dsOffsets[4];\nuniform float brightThreshold;\nvoid main(void)\n{\nvec4 average=vec4(0.0,0.0,0.0,0.0);\naverage=texture2D(textureSampler,vUV+vec2(dsOffsets[0].x,dsOffsets[0].y));\naverage+=texture2D(textureSampler,vUV+vec2(dsOffsets[1].x,dsOffsets[1].y));\naverage+=texture2D(textureSampler,vUV+vec2(dsOffsets[2].x,dsOffsets[2].y));\naverage+=texture2D(textureSampler,vUV+vec2(dsOffsets[3].x,dsOffsets[3].y));\naverage*=0.25;\nfloat luminance=length(average.rgb);\nif (luminance<brightThreshold) {\naverage=vec4(0.0,0.0,0.0,1.0);\n}\ngl_FragColor=average;\n}\n#endif\n#if defined(TEXTURE_ADDER)\nuniform sampler2D otherSampler;\nuniform sampler2D lensSampler;\nuniform float exposure;\nvoid main(void)\n{\nvec3 colour=texture2D(textureSampler,vUV).rgb;\ncolour*=exposure;\nvec3 X=max(vec3(0.0,0.0,0.0),colour-0.004);\nvec3 retColor=(X*(6.2*X+0.5))/(X*(6.2*X+1.7)+0.06);\ncolour=retColor*retColor;\ncolour+=colour*texture2D(lensSampler,vUV).rgb;\nvec4 finalColor=vec4(colour.rgb,1.0)+texture2D(otherSampler,vUV);\ngl_FragColor=finalColor;\n}\n#endif\n#if defined(VLS)\n#define PI 3.1415926535897932384626433832795\nuniform mat4 shadowViewProjection;\nuniform mat4 lightWorld;\nuniform vec3 cameraPosition;\nuniform vec3 sunDirection;\nuniform vec3 sunColor;\nuniform vec2 depthValues;\nuniform float scatteringCoefficient;\nuniform float scatteringPower;\nuniform sampler2D shadowMapSampler;\nuniform sampler2D positionSampler;\nfloat computeScattering(float lightDotView)\n{\nfloat result=1.0-scatteringCoefficient*scatteringCoefficient;\nresult/=(4.0*PI*pow(1.0+scatteringCoefficient*scatteringCoefficient-(2.0*scatteringCoefficient)*lightDotView,1.5));\nreturn result;\n}\nvoid main(void)\n{\n\nvec3 worldPos=texture2D(positionSampler,vUV).rgb;\nvec3 startPosition=cameraPosition;\nvec3 rayVector=worldPos-startPosition;\nfloat rayLength=length(rayVector);\nvec3 rayDirection=rayVector/rayLength;\nfloat stepLength=rayLength/NB_STEPS;\nvec3 stepL=rayDirection*stepLength;\nvec3 currentPosition=startPosition;\nvec3 accumFog=vec3(0.0);\nfor (int i=0; i<int(NB_STEPS); i++)\n{\nvec4 worldInShadowCameraSpace=shadowViewProjection*vec4(currentPosition,1.0);\nfloat depthMetric=(worldInShadowCameraSpace.z+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depthMetric,0.0,1.0);\nworldInShadowCameraSpace.xyz/=worldInShadowCameraSpace.w;\nworldInShadowCameraSpace.xyz=0.5*worldInShadowCameraSpace.xyz+vec3(0.5);\nfloat shadowMapValue=texture2D(shadowMapSampler,worldInShadowCameraSpace.xy).r;\nif (shadowMapValue>shadowPixelDepth)\naccumFog+=sunColor*computeScattering(dot(rayDirection,sunDirection));\ncurrentPosition+=stepL;\n}\naccumFog/=NB_STEPS;\nvec3 color=accumFog*scatteringPower;\ngl_FragColor=vec4(color*exp(color) ,1.0);\n}\n#endif\n#if defined(VLSMERGE)\nuniform sampler2D originalSampler;\nvoid main(void)\n{\ngl_FragColor=texture2D(originalSampler,vUV)+texture2D(textureSampler,vUV);\n}\n#endif\n#if defined(LUMINANCE)\nuniform vec2 lumOffsets[4];\nvoid main()\n{\nfloat average=0.0;\nvec4 color=vec4(0.0);\nfloat maximum=-1e20;\nvec3 weight=vec3(0.299,0.587,0.114);\nfor (int i=0; i<4; i++)\n{\ncolor=texture2D(textureSampler,vUV+ lumOffsets[i]);\n\nfloat GreyValue=dot(color.rgb,vec3(0.33,0.33,0.33));\n\n#ifdef WEIGHTED_AVERAGE\nfloat GreyValue=dot(color.rgb,weight);\n#endif\n#ifdef BRIGHTNESS\nfloat GreyValue=max(color.r,max(color.g,color.b));\n#endif\n#ifdef HSL_COMPONENT\nfloat GreyValue=0.5*(max(color.r,max(color.g,color.b))+min(color.r,min(color.g,color.b)));\n#endif\n#ifdef MAGNITUDE\nfloat GreyValue=length(color.rgb);\n#endif\nmaximum=max(maximum,GreyValue);\naverage+=(0.25*log(1e-5+GreyValue));\n}\naverage=exp(average);\ngl_FragColor=vec4(average,maximum,0.0,1.0);\n}\n#endif\n#if defined(LUMINANCE_DOWN_SAMPLE)\nuniform vec2 dsOffsets[9];\nuniform float halfDestPixelSize;\n#ifdef FINAL_DOWN_SAMPLER\n#include<packingFunctions>\n#endif\nvoid main()\n{\nvec4 color=vec4(0.0);\nfloat average=0.0;\nfor (int i=0; i<9; i++)\n{\ncolor=texture2D(textureSampler,vUV+vec2(halfDestPixelSize,halfDestPixelSize)+dsOffsets[i]);\naverage+=color.r;\n}\naverage/=9.0;\n#ifdef FINAL_DOWN_SAMPLER\ngl_FragColor=pack(average);\n#else\ngl_FragColor=vec4(average,average,0.0,1.0);\n#endif\n}\n#endif\n#if defined(HDR)\nuniform sampler2D textureAdderSampler;\nuniform float averageLuminance;\nvoid main()\n{\nvec4 color=texture2D(textureAdderSampler,vUV);\n#ifndef AUTO_EXPOSURE\nvec4 adjustedColor=color/averageLuminance;\ncolor=adjustedColor;\ncolor.a=1.0;\n#endif\ngl_FragColor=color;\n}\n#endif\n#if defined(LENS_FLARE)\n#define GHOSTS 3\nuniform sampler2D lensColorSampler;\nuniform float strength;\nuniform float ghostDispersal;\nuniform float haloWidth;\nuniform vec2 resolution;\nuniform float distortionStrength;\nfloat hash(vec2 p)\n{\nfloat h=dot(p,vec2(127.1,311.7));\nreturn -1.0+2.0*fract(sin(h)*43758.5453123);\n}\nfloat noise(in vec2 p)\n{\nvec2 i=floor(p);\nvec2 f=fract(p);\nvec2 u=f*f*(3.0-2.0*f);\nreturn mix(mix(hash(i+vec2(0.0,0.0)),\nhash(i+vec2(1.0,0.0)),u.x),\nmix(hash(i+vec2(0.0,1.0)),\nhash(i+vec2(1.0,1.0)),u.x),u.y);\n}\nfloat fbm(vec2 p)\n{\nfloat f=0.0;\nf+=0.5000*noise(p); p*=2.02;\nf+=0.2500*noise(p); p*=2.03;\nf+=0.1250*noise(p); p*=2.01;\nf+=0.0625*noise(p); p*=2.04;\nf/=0.9375;\nreturn f;\n}\nvec3 pattern(vec2 uv)\n{\nvec2 p=-1.0+2.0*uv;\nfloat p2=dot(p,p);\nfloat f=fbm(vec2(15.0*p2))/2.0;\nfloat r=0.2+0.6*sin(12.5*length(uv-vec2(0.5)));\nfloat g=0.2+0.6*sin(20.5*length(uv-vec2(0.5)));\nfloat b=0.2+0.6*sin(17.2*length(uv-vec2(0.5)));\nreturn (1.0-f)*vec3(r,g,b);\n}\nfloat luminance(vec3 color)\n{\nreturn dot(color.rgb,vec3(0.2126,0.7152,0.0722));\n}\nvec4 textureDistorted(sampler2D tex,vec2 texcoord,vec2 direction,vec3 distortion)\n{\nreturn vec4(\ntexture2D(tex,texcoord+direction*distortion.r).r,\ntexture2D(tex,texcoord+direction*distortion.g).g,\ntexture2D(tex,texcoord+direction*distortion.b).b,\n1.0\n);\n}\nvoid main(void)\n{\nvec2 uv=-vUV+vec2(1.0);\nvec2 ghostDir=(vec2(0.5)-uv)*ghostDispersal;\nvec2 texelSize=1.0/resolution;\nvec3 distortion=vec3(-texelSize.x*distortionStrength,0.0,texelSize.x*distortionStrength);\nvec4 result=vec4(0.0);\nfloat ghostIndice=1.0;\nfor (int i=0; i<GHOSTS; ++i)\n{\nvec2 offset=fract(uv+ghostDir*ghostIndice);\nfloat weight=length(vec2(0.5)-offset)/length(vec2(0.5));\nweight=pow(1.0-weight,10.0);\nresult+=textureDistorted(textureSampler,offset,normalize(ghostDir),distortion)*weight*strength;\nghostIndice+=1.0;\n}\nvec2 haloVec=normalize(ghostDir)*haloWidth;\nfloat weight=length(vec2(0.5)-fract(uv+haloVec))/length(vec2(0.5));\nweight=pow(1.0-weight,10.0);\nresult+=textureDistorted(textureSampler,fract(uv+haloVec),normalize(ghostDir),distortion)*weight*strength;\nresult*=texture2D(lensColorSampler,vec2(length(vec2(0.5)-uv)/length(vec2(0.5))));\ngl_FragColor=result;\n}\n#endif\n#if defined(LENS_FLARE_COMPOSE)\nuniform sampler2D otherSampler;\nuniform sampler2D lensDirtSampler;\nuniform sampler2D lensStarSampler;\nuniform mat4 lensStarMatrix;\nvoid main(void)\n{\nvec2 lensFlareCoords=(lensStarMatrix*vec4(vUV,1.0,1.0)).xy;\nvec4 lensMod=texture2D(lensDirtSampler,vUV);\nlensMod+=texture2D(lensStarSampler,vUV);\nvec4 result=texture2D(textureSampler,vUV)*lensMod;\ngl_FragColor=texture2D(otherSampler,vUV)+result;\n}\n#endif\n#if defined(DEPTH_OF_FIELD)\nuniform sampler2D otherSampler;\nuniform sampler2D depthSampler;\nuniform float distance;\nvoid main(void)\n{\nvec4 sharp=texture2D(otherSampler,vUV);\nvec4 blur=texture2D(textureSampler,vUV);\nfloat dist=clamp(texture2D(depthSampler,vUV).r*distance,0.0,1.0);\nfloat factor=0.0;\nif (dist<0.05)\nfactor=1.0;\nelse if (dist<0.1)\nfactor=20.0*(0.1-dist);\nelse if (dist<0.5)\nfactor=0.0;\nelse\nfactor=2.0*(dist-0.5);\nfactor=clamp(factor,0.0,0.90);\ngl_FragColor=mix(sharp,blur,factor);\n}\n#endif\n#if defined(MOTION_BLUR)\nuniform mat4 inverseViewProjection;\nuniform mat4 prevViewProjection;\nuniform vec2 screenSize;\nuniform float motionScale;\nuniform float motionStrength;\nuniform sampler2D depthSampler;\nvoid main(void)\n{\nvec2 texelSize=1.0/screenSize;\nfloat depth=texture2D(depthSampler,vUV).r;\nvec4 cpos=vec4(vUV*2.0-1.0,depth,1.0);\ncpos=cpos*inverseViewProjection;\nvec4 ppos=cpos*prevViewProjection;\nppos.xyz/=ppos.w;\nppos.xy=ppos.xy*0.5+0.5;\nvec2 velocity=(ppos.xy-vUV)*motionScale*motionStrength;\nfloat speed=length(velocity/texelSize);\nint nSamples=int(clamp(speed,1.0,MAX_MOTION_SAMPLES));\nvec4 result=texture2D(textureSampler,vUV);\nfor (int i=1; i<int(MAX_MOTION_SAMPLES); ++i) {\nif (i>=nSamples)\nbreak;\nvec2 offset1=vUV+velocity*(float(i)/float(nSamples-1)-0.5);\nresult+=texture2D(textureSampler,offset1);\n}\ngl_FragColor=result/float(nSamples);\n}\n#endif\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var standardPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/stereoscopicInterlace.fragment.ts":
/*!***************************************************!*\
  !*** ./Shaders/stereoscopicInterlace.fragment.ts ***!
  \***************************************************/
/*! exports provided: stereoscopicInterlacePixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stereoscopicInterlacePixelShader", function() { return stereoscopicInterlacePixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'stereoscopicInterlacePixelShader';
var shader = "const vec3 TWO=vec3(2.0,2.0,2.0);\nvarying vec2 vUV;\nuniform sampler2D camASampler;\nuniform sampler2D textureSampler;\nuniform vec2 stepSize;\nvoid main(void)\n{\nbool useCamB;\nvec2 texCoord1;\nvec2 texCoord2;\nvec3 frag1;\nvec3 frag2;\n#ifdef IS_STEREOSCOPIC_HORIZ\nuseCamB=vUV.x>0.5;\ntexCoord1=vec2(useCamB ? (vUV.x-0.5)*2.0 : vUV.x*2.0,vUV.y);\ntexCoord2=vec2(texCoord1.x+stepSize.x,vUV.y);\n#else\nuseCamB=vUV.y>0.5;\ntexCoord1=vec2(vUV.x,useCamB ? (vUV.y-0.5)*2.0 : vUV.y*2.0);\ntexCoord2=vec2(vUV.x,texCoord1.y+stepSize.y);\n#endif\n\nif (useCamB){\nfrag1=texture2D(textureSampler,texCoord1).rgb;\nfrag2=texture2D(textureSampler,texCoord2).rgb;\n}else{\nfrag1=texture2D(camASampler ,texCoord1).rgb;\nfrag2=texture2D(camASampler ,texCoord2).rgb;\n}\ngl_FragColor=vec4((frag1+frag2)/TWO,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var stereoscopicInterlacePixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/tonemap.fragment.ts":
/*!*************************************!*\
  !*** ./Shaders/tonemap.fragment.ts ***!
  \*************************************/
/*! exports provided: tonemapPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tonemapPixelShader", function() { return tonemapPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'tonemapPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\n\nuniform float _ExposureAdjustment;\n#if defined(HABLE_TONEMAPPING)\nconst float A=0.15;\nconst float B=0.50;\nconst float C=0.10;\nconst float D=0.20;\nconst float E=0.02;\nconst float F=0.30;\nconst float W=11.2;\n#endif\nfloat Luminance(vec3 c)\n{\nreturn dot(c,vec3(0.22,0.707,0.071));\n}\nvoid main(void)\n{\nvec3 colour=texture2D(textureSampler,vUV).rgb;\n#if defined(REINHARD_TONEMAPPING)\nfloat lum=Luminance(colour.rgb);\nfloat lumTm=lum*_ExposureAdjustment;\nfloat scale=lumTm/(1.0+lumTm);\ncolour*=scale/lum;\n#elif defined(HABLE_TONEMAPPING)\ncolour*=_ExposureAdjustment;\nconst float ExposureBias=2.0;\nvec3 x=ExposureBias*colour;\nvec3 curr=((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;\nx=vec3(W,W,W);\nvec3 whiteScale=1.0/(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F);\ncolour=curr*whiteScale;\n#elif defined(OPTIMIZED_HEJIDAWSON_TONEMAPPING)\ncolour*=_ExposureAdjustment;\nvec3 X=max(vec3(0.0,0.0,0.0),colour-0.004);\nvec3 retColor=(X*(6.2*X+0.5))/(X*(6.2*X+1.7)+0.06);\ncolour=retColor*retColor;\n#elif defined(PHOTOGRAPHIC_TONEMAPPING)\ncolour=vec3(1.0,1.0,1.0)-exp2(-_ExposureAdjustment*colour);\n#endif\ngl_FragColor=vec4(colour.rgb,1.0);\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var tonemapPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/volumetricLightScattering.fragment.ts":
/*!*******************************************************!*\
  !*** ./Shaders/volumetricLightScattering.fragment.ts ***!
  \*******************************************************/
/*! exports provided: volumetricLightScatteringPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "volumetricLightScatteringPixelShader", function() { return volumetricLightScatteringPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'volumetricLightScatteringPixelShader';
var shader = "uniform sampler2D textureSampler;\nuniform sampler2D lightScatteringSampler;\nuniform float decay;\nuniform float exposure;\nuniform float weight;\nuniform float density;\nuniform vec2 meshPositionOnScreen;\nvarying vec2 vUV;\nvoid main(void) {\nvec2 tc=vUV;\nvec2 deltaTexCoord=(tc-meshPositionOnScreen.xy);\ndeltaTexCoord*=1.0/float(NUM_SAMPLES)*density;\nfloat illuminationDecay=1.0;\nvec4 color=texture2D(lightScatteringSampler,tc)*0.4;\nfor(int i=0; i<NUM_SAMPLES; i++) {\ntc-=deltaTexCoord;\nvec4 dataSample=texture2D(lightScatteringSampler,tc)*0.4;\ndataSample*=illuminationDecay*weight;\ncolor+=dataSample;\nilluminationDecay*=decay;\n}\nvec4 realColor=texture2D(textureSampler,vUV);\ngl_FragColor=((vec4((vec3(color.r,color.g,color.b)*exposure),1))+(realColor*(1.5-0.4)));\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var volumetricLightScatteringPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/volumetricLightScatteringPass.fragment.ts":
/*!***********************************************************!*\
  !*** ./Shaders/volumetricLightScatteringPass.fragment.ts ***!
  \***********************************************************/
/*! exports provided: volumetricLightScatteringPassPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "volumetricLightScatteringPassPixelShader", function() { return volumetricLightScatteringPassPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'volumetricLightScatteringPassPixelShader';
var shader = "#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;\n#endif\n#if defined(ALPHATEST)\nuniform sampler2D diffuseSampler;\n#endif\nvoid main(void)\n{\n#if defined(ALPHATEST)\nvec4 diffuseColor=texture2D(diffuseSampler,vUV);\nif (diffuseColor.a<0.4)\ndiscard;\n#endif\ngl_FragColor=vec4(0.0,0.0,0.0,1.0);\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var volumetricLightScatteringPassPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/volumetricLightScatteringPass.vertex.ts":
/*!*********************************************************!*\
  !*** ./Shaders/volumetricLightScatteringPass.vertex.ts ***!
  \*********************************************************/
/*! exports provided: volumetricLightScatteringPassVertexShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "volumetricLightScatteringPassVertexShader", function() { return volumetricLightScatteringPassVertexShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");
/* harmony import */ var _ShadersInclude_bonesDeclaration__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ShadersInclude/bonesDeclaration */ "./Shaders/ShadersInclude/bonesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexGlobalDeclaration__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexGlobalDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexGlobalDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertexDeclaration__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertexDeclaration */ "./Shaders/ShadersInclude/morphTargetsVertexDeclaration.ts");
/* harmony import */ var _ShadersInclude_instancesDeclaration__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./ShadersInclude/instancesDeclaration */ "./Shaders/ShadersInclude/instancesDeclaration.ts");
/* harmony import */ var _ShadersInclude_morphTargetsVertex__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./ShadersInclude/morphTargetsVertex */ "./Shaders/ShadersInclude/morphTargetsVertex.ts");
/* harmony import */ var _ShadersInclude_instancesVertex__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./ShadersInclude/instancesVertex */ "./Shaders/ShadersInclude/instancesVertex.ts");
/* harmony import */ var _ShadersInclude_bonesVertex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./ShadersInclude/bonesVertex */ "./Shaders/ShadersInclude/bonesVertex.ts");








var name = 'volumetricLightScatteringPassVertexShader';
var shader = "\nattribute vec3 position;\n#include<bonesDeclaration>\n#include<morphTargetsVertexGlobalDeclaration>\n#include<morphTargetsVertexDeclaration>[0..maxSimultaneousMorphTargets]\n\n#include<instancesDeclaration>\nuniform mat4 viewProjection;\nuniform vec2 depthValues;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;\nuniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\nvoid main(void)\n{\nvec3 positionUpdated=position;\n#if (defined(ALPHATEST) || defined(NEED_UV)) && defined(UV1)\nvec2 uvUpdated=uv;\n#endif\n#include<morphTargetsVertex>[0..maxSimultaneousMorphTargets]\n#include<instancesVertex>\n#include<bonesVertex>\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uvUpdated,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n}\n";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var volumetricLightScatteringPassVertexShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/vrDistortionCorrection.fragment.ts":
/*!****************************************************!*\
  !*** ./Shaders/vrDistortionCorrection.fragment.ts ***!
  \****************************************************/
/*! exports provided: vrDistortionCorrectionPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "vrDistortionCorrectionPixelShader", function() { return vrDistortionCorrectionPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'vrDistortionCorrectionPixelShader';
var shader = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nuniform vec2 LensCenter;\nuniform vec2 Scale;\nuniform vec2 ScaleIn;\nuniform vec4 HmdWarpParam;\nvec2 HmdWarp(vec2 in01) {\nvec2 theta=(in01-LensCenter)*ScaleIn;\nfloat rSq=theta.x*theta.x+theta.y*theta.y;\nvec2 rvector=theta*(HmdWarpParam.x+HmdWarpParam.y*rSq+HmdWarpParam.z*rSq*rSq+HmdWarpParam.w*rSq*rSq*rSq);\nreturn LensCenter+Scale*rvector;\n}\nvoid main(void)\n{\nvec2 tc=HmdWarp(vUV);\nif (tc.x <0.0 || tc.x>1.0 || tc.y<0.0 || tc.y>1.0)\ngl_FragColor=vec4(0.0,0.0,0.0,0.0);\nelse{\ngl_FragColor=texture2D(textureSampler,tc);\n}\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var vrDistortionCorrectionPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Shaders/vrMultiviewToSingleview.fragment.ts":
/*!*****************************************************!*\
  !*** ./Shaders/vrMultiviewToSingleview.fragment.ts ***!
  \*****************************************************/
/*! exports provided: vrMultiviewToSingleviewPixelShader */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "vrMultiviewToSingleviewPixelShader", function() { return vrMultiviewToSingleviewPixelShader; });
/* harmony import */ var _Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Materials/effect */ "./Materials/effect.ts");

var name = 'vrMultiviewToSingleviewPixelShader';
var shader = "precision mediump sampler2DArray;\nvarying vec2 vUV;\nuniform sampler2DArray multiviewSampler;\nuniform int imageIndex;\nvoid main(void)\n{\ngl_FragColor=texture(multiviewSampler,vec3(vUV,imageIndex));\n}";
_Materials_effect__WEBPACK_IMPORTED_MODULE_0__["Effect"].ShadersStore[name] = shader;
/** @hidden */
var vrMultiviewToSingleviewPixelShader = { name: name, shader: shader };


/***/ }),

/***/ "./Sprites/index.ts":
/*!**************************!*\
  !*** ./Sprites/index.ts ***!
  \**************************/
/*! exports provided: Sprite, SpriteManager, SpritePackedManager, SpriteSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _sprite__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./sprite */ "./Sprites/sprite.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return _sprite__WEBPACK_IMPORTED_MODULE_0__["Sprite"]; });

/* harmony import */ var _spriteManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./spriteManager */ "./Sprites/spriteManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpriteManager", function() { return _spriteManager__WEBPACK_IMPORTED_MODULE_1__["SpriteManager"]; });

/* harmony import */ var _spritePackedManager__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./spritePackedManager */ "./Sprites/spritePackedManager.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpritePackedManager", function() { return _spritePackedManager__WEBPACK_IMPORTED_MODULE_2__["SpritePackedManager"]; });

/* harmony import */ var _spriteSceneComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./spriteSceneComponent */ "./Sprites/spriteSceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpriteSceneComponent", function() { return _spriteSceneComponent__WEBPACK_IMPORTED_MODULE_3__["SpriteSceneComponent"]; });







/***/ }),

/***/ "./Sprites/sprite.ts":
/*!***************************!*\
  !*** ./Sprites/sprite.ts ***!
  \***************************/
/*! exports provided: Sprite */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return Sprite; });
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Maths/math.color */ "./Maths/math.color.ts");


/**
 * Class used to represent a sprite
 * @see http://doc.babylonjs.com/babylon101/sprites
 */
var Sprite = /** @class */ (function () {
    /**
     * Creates a new Sprite
     * @param name defines the name
     * @param manager defines the manager
     */
    function Sprite(
    /** defines the name */
    name, manager) {
        this.name = name;
        /** Gets or sets the main color */
        this.color = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_1__["Color4"](1.0, 1.0, 1.0, 1.0);
        /** Gets or sets the width */
        this.width = 1.0;
        /** Gets or sets the height */
        this.height = 1.0;
        /** Gets or sets rotation angle */
        this.angle = 0;
        /** Gets or sets a boolean indicating if UV coordinates should be inverted in U axis */
        this.invertU = 0;
        /** Gets or sets a boolean indicating if UV coordinates should be inverted in B axis */
        this.invertV = 0;
        /** Gets the list of attached animations */
        this.animations = new Array();
        /** Gets or sets a boolean indicating if the sprite can be picked */
        this.isPickable = false;
        this._animationStarted = false;
        this._loopAnimation = false;
        this._fromIndex = 0;
        this._toIndex = 0;
        this._delay = 0;
        this._direction = 1;
        this._time = 0;
        /**
         * Gets or sets a boolean indicating if the sprite is visible (renderable). Default is true
         */
        this.isVisible = true;
        this._manager = manager;
        this._manager.sprites.push(this);
        this.position = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero();
    }
    Object.defineProperty(Sprite.prototype, "size", {
        /**
         * Gets or sets the sprite size
         */
        get: function () {
            return this.width;
        },
        set: function (value) {
            this.width = value;
            this.height = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Starts an animation
     * @param from defines the initial key
     * @param to defines the end key
     * @param loop defines if the animation must loop
     * @param delay defines the start delay (in ms)
     * @param onAnimationEnd defines a callback to call when animation ends
     */
    Sprite.prototype.playAnimation = function (from, to, loop, delay, onAnimationEnd) {
        this._fromIndex = from;
        this._toIndex = to;
        this._loopAnimation = loop;
        this._delay = delay;
        this._animationStarted = true;
        if (from < to) {
            this._direction = 1;
        }
        else {
            this._direction = -1;
            this._toIndex = from;
            this._fromIndex = to;
        }
        this.cellIndex = from;
        this._time = 0;
        this._onAnimationEnd = onAnimationEnd;
    };
    /** Stops current animation (if any) */
    Sprite.prototype.stopAnimation = function () {
        this._animationStarted = false;
    };
    /** @hidden */
    Sprite.prototype._animate = function (deltaTime) {
        if (!this._animationStarted) {
            return;
        }
        this._time += deltaTime;
        if (this._time > this._delay) {
            this._time = this._time % this._delay;
            this.cellIndex += this._direction;
            if (this._direction > 0 && this.cellIndex > this._toIndex || this._direction < 0 && this.cellIndex < this._fromIndex) {
                if (this._loopAnimation) {
                    this.cellIndex = this._direction > 0 ? this._fromIndex : this._toIndex;
                }
                else {
                    this.cellIndex = this._toIndex;
                    this._animationStarted = false;
                    if (this._onAnimationEnd) {
                        this._onAnimationEnd();
                    }
                    if (this.disposeWhenFinishedAnimating) {
                        this.dispose();
                    }
                }
            }
        }
    };
    /** Release associated resources */
    Sprite.prototype.dispose = function () {
        for (var i = 0; i < this._manager.sprites.length; i++) {
            if (this._manager.sprites[i] == this) {
                this._manager.sprites.splice(i, 1);
            }
        }
    };
    return Sprite;
}());



/***/ }),

/***/ "./Sprites/spriteManager.ts":
/*!**********************************!*\
  !*** ./Sprites/spriteManager.ts ***!
  \**********************************/
/*! exports provided: SpriteManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteManager", function() { return SpriteManager; });
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Meshes/buffer */ "./Meshes/buffer.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _spriteSceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./spriteSceneComponent */ "./Sprites/spriteSceneComponent.ts");
/* harmony import */ var _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Collisions/pickingInfo */ "./Collisions/pickingInfo.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");
/* harmony import */ var _Materials_material__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../Materials/material */ "./Materials/material.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Shaders_sprites_fragment__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../Shaders/sprites.fragment */ "./Shaders/sprites.fragment.ts");
/* harmony import */ var _Shaders_sprites_vertex__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../Shaders/sprites.vertex */ "./Shaders/sprites.vertex.ts");














/**
 * Class used to manage multiple sprites on the same spritesheet
 * @see http://doc.babylonjs.com/babylon101/sprites
 */
var SpriteManager = /** @class */ (function () {
    /**
     * Creates a new sprite manager
     * @param name defines the manager's name
     * @param imgUrl defines the sprite sheet url
     * @param capacity defines the maximum allowed number of sprites
     * @param cellSize defines the size of a sprite cell
     * @param scene defines the hosting scene
     * @param epsilon defines the epsilon value to align texture (0.01 by default)
     * @param samplingMode defines the smapling mode to use with spritesheet
     * @param fromPacked set to false; do not alter
     * @param spriteJSON null otherwise a JSON object defining sprite sheet data; do not alter
     */
    function SpriteManager(
    /** defines the manager's name */
    name, imgUrl, capacity, cellSize, scene, epsilon, samplingMode, fromPacked, spriteJSON) {
        if (epsilon === void 0) { epsilon = 0.01; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].TRILINEAR_SAMPLINGMODE; }
        if (fromPacked === void 0) { fromPacked = false; }
        if (spriteJSON === void 0) { spriteJSON = null; }
        this.name = name;
        /** Gets the list of sprites */
        this.sprites = new Array();
        /** Gets or sets the rendering group id (0 by default) */
        this.renderingGroupId = 0;
        /** Gets or sets camera layer mask */
        this.layerMask = 0x0FFFFFFF;
        /** Gets or sets a boolean indicating if the manager must consider scene fog when rendering */
        this.fogEnabled = true;
        /** Gets or sets a boolean indicating if the sprites are pickable */
        this.isPickable = false;
        /** True when packed cell data from JSON file is ready*/
        this._packedAndReady = false;
        /**
        * An event triggered when the manager is disposed.
        */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_1__["Observable"]();
        this._vertexBuffers = {};
        if (!scene._getComponent(_sceneComponent__WEBPACK_IMPORTED_MODULE_8__["SceneComponentConstants"].NAME_SPRITE)) {
            scene._addComponent(new _spriteSceneComponent__WEBPACK_IMPORTED_MODULE_4__["SpriteSceneComponent"](scene));
        }
        this._capacity = capacity;
        this._fromPacked = fromPacked;
        this._spriteTexture = new _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"](imgUrl, scene, true, false, samplingMode);
        this._spriteTexture.wrapU = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].CLAMP_ADDRESSMODE;
        this._spriteTexture.wrapV = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_6__["Texture"].CLAMP_ADDRESSMODE;
        if (cellSize.width && cellSize.height) {
            this.cellWidth = cellSize.width;
            this.cellHeight = cellSize.height;
        }
        else if (cellSize !== undefined) {
            this.cellWidth = cellSize;
            this.cellHeight = cellSize;
        }
        else {
            return;
        }
        this._epsilon = epsilon;
        this._scene = scene;
        this._scene.spriteManagers.push(this);
        var indices = [];
        var index = 0;
        for (var count = 0; count < capacity; count++) {
            indices.push(index);
            indices.push(index + 1);
            indices.push(index + 2);
            indices.push(index);
            indices.push(index + 2);
            indices.push(index + 3);
            index += 4;
        }
        this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
        // VBO
        // 18 floats per sprite (x, y, z, angle, sizeX, sizeY, offsetX, offsetY, invertU, invertV, cellLeft, cellTop, cellWidth, cellHeight, color r, color g, color b, color a)
        this._vertexData = new Float32Array(capacity * 18 * 4);
        this._buffer = new _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["Buffer"](scene.getEngine(), this._vertexData, true, 18);
        var positions = this._buffer.createVertexBuffer(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, 0, 4);
        var options = this._buffer.createVertexBuffer("options", 4, 4);
        var inverts = this._buffer.createVertexBuffer("inverts", 8, 2);
        var cellInfo = this._buffer.createVertexBuffer("cellInfo", 10, 4);
        var colors = this._buffer.createVertexBuffer(_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind, 14, 4);
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind] = positions;
        this._vertexBuffers["options"] = options;
        this._vertexBuffers["inverts"] = inverts;
        this._vertexBuffers["cellInfo"] = cellInfo;
        this._vertexBuffers[_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind] = colors;
        // Effects
        this._effectBase = this._scene.getEngine().createEffect("sprites", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, "options", "inverts", "cellInfo", _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind], ["view", "projection", "textureInfos", "alphaTest"], ["diffuseSampler"], "");
        this._effectFog = this._scene.getEngine().createEffect("sprites", [_Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].PositionKind, "options", "inverts", "cellInfo", _Meshes_buffer__WEBPACK_IMPORTED_MODULE_2__["VertexBuffer"].ColorKind], ["view", "projection", "textureInfos", "alphaTest", "vFogInfos", "vFogColor"], ["diffuseSampler"], "#define FOG");
        if (this._fromPacked) {
            this._makePacked(imgUrl, spriteJSON);
        }
    }
    Object.defineProperty(SpriteManager.prototype, "onDispose", {
        /**
         * Callback called when the manager is disposed
         */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(SpriteManager.prototype, "texture", {
        /**
         * Gets or sets the spritesheet texture
         */
        get: function () {
            return this._spriteTexture;
        },
        set: function (value) {
            this._spriteTexture = value;
        },
        enumerable: true,
        configurable: true
    });
    SpriteManager.prototype._makePacked = function (imgUrl, spriteJSON) {
        var _this = this;
        if (spriteJSON !== null) {
            try {
                var celldata = JSON.parse(spriteJSON);
                var spritemap = Reflect.ownKeys(celldata.frames);
                this._spriteMap = spritemap;
                this._packedAndReady = true;
                this._cellData = celldata.frames;
            }
            catch (e) {
                this._fromPacked = false;
                this._packedAndReady = false;
                throw new Error("Invalid JSON from string. Spritesheet managed with constant cell size.");
            }
        }
        else {
            var re = /\./g;
            var li = void 0;
            do {
                li = re.lastIndex;
                re.test(imgUrl);
            } while (re.lastIndex > 0);
            var jsonUrl = imgUrl.substring(0, li - 1) + ".json";
            var xmlhttp_1 = new XMLHttpRequest();
            xmlhttp_1.open("GET", jsonUrl, true);
            xmlhttp_1.onerror = function () {
                _Misc_logger__WEBPACK_IMPORTED_MODULE_10__["Logger"].Error("Unable to Load Sprite JSON Data. Spritesheet managed with constant cell size.");
                _this._fromPacked = false;
                _this._packedAndReady = false;
            };
            xmlhttp_1.onload = function () {
                try {
                    var celldata = JSON.parse(xmlhttp_1.response);
                    var spritemap = Reflect.ownKeys(celldata.frames);
                    _this._spriteMap = spritemap;
                    _this._packedAndReady = true;
                    _this._cellData = celldata.frames;
                }
                catch (e) {
                    _this._fromPacked = false;
                    _this._packedAndReady = false;
                    throw new Error("Invalid JSON from file. Spritesheet managed with constant cell size.");
                }
            };
            xmlhttp_1.send();
        }
    };
    SpriteManager.prototype._appendSpriteVertex = function (index, sprite, offsetX, offsetY, baseSize) {
        var arrayOffset = index * 18;
        if (offsetX === 0) {
            offsetX = this._epsilon;
        }
        else if (offsetX === 1) {
            offsetX = 1 - this._epsilon;
        }
        if (offsetY === 0) {
            offsetY = this._epsilon;
        }
        else if (offsetY === 1) {
            offsetY = 1 - this._epsilon;
        }
        // Positions
        this._vertexData[arrayOffset] = sprite.position.x;
        this._vertexData[arrayOffset + 1] = sprite.position.y;
        this._vertexData[arrayOffset + 2] = sprite.position.z;
        this._vertexData[arrayOffset + 3] = sprite.angle;
        // Options
        this._vertexData[arrayOffset + 4] = sprite.width;
        this._vertexData[arrayOffset + 5] = sprite.height;
        this._vertexData[arrayOffset + 6] = offsetX;
        this._vertexData[arrayOffset + 7] = offsetY;
        // Inverts
        this._vertexData[arrayOffset + 8] = sprite.invertU ? 1 : 0;
        this._vertexData[arrayOffset + 9] = sprite.invertV ? 1 : 0;
        // CellIfo
        if (this._packedAndReady) {
            if (!sprite.cellRef) {
                sprite.cellIndex = 0;
            }
            var num = sprite.cellIndex;
            if (typeof (num) === "number" && isFinite(num) && Math.floor(num) === num) {
                sprite.cellRef = this._spriteMap[sprite.cellIndex];
            }
            this._vertexData[arrayOffset + 10] = this._cellData[sprite.cellRef].frame.x / baseSize.width;
            this._vertexData[arrayOffset + 11] = this._cellData[sprite.cellRef].frame.y / baseSize.height;
            this._vertexData[arrayOffset + 12] = this._cellData[sprite.cellRef].frame.w / baseSize.width;
            this._vertexData[arrayOffset + 13] = this._cellData[sprite.cellRef].frame.h / baseSize.height;
        }
        else {
            if (!sprite.cellIndex) {
                sprite.cellIndex = 0;
            }
            var rowSize = baseSize.width / this.cellWidth;
            var offset = (sprite.cellIndex / rowSize) >> 0;
            this._vertexData[arrayOffset + 10] = (sprite.cellIndex - offset * rowSize) * this.cellWidth / baseSize.width;
            this._vertexData[arrayOffset + 11] = offset * this.cellHeight / baseSize.height;
            this._vertexData[arrayOffset + 12] = this.cellWidth / baseSize.width;
            this._vertexData[arrayOffset + 13] = this.cellHeight / baseSize.height;
        }
        // Color
        this._vertexData[arrayOffset + 14] = sprite.color.r;
        this._vertexData[arrayOffset + 15] = sprite.color.g;
        this._vertexData[arrayOffset + 16] = sprite.color.b;
        this._vertexData[arrayOffset + 17] = sprite.color.a;
    };
    /**
     * Intersects the sprites with a ray
     * @param ray defines the ray to intersect with
     * @param camera defines the current active camera
     * @param predicate defines a predicate used to select candidate sprites
     * @param fastCheck defines if a fast check only must be done (the first potential sprite is will be used and not the closer)
     * @returns null if no hit or a PickingInfo
     */
    SpriteManager.prototype.intersects = function (ray, camera, predicate, fastCheck) {
        var count = Math.min(this._capacity, this.sprites.length);
        var min = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        var max = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        var distance = Number.MAX_VALUE;
        var currentSprite = null;
        var pickedPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0];
        var cameraSpacePosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1];
        var cameraView = camera.getViewMatrix();
        for (var index = 0; index < count; index++) {
            var sprite = this.sprites[index];
            if (!sprite) {
                continue;
            }
            if (predicate) {
                if (!predicate(sprite)) {
                    continue;
                }
            }
            else if (!sprite.isPickable) {
                continue;
            }
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(sprite.position, cameraView, cameraSpacePosition);
            min.copyFromFloats(cameraSpacePosition.x - sprite.width / 2, cameraSpacePosition.y - sprite.height / 2, cameraSpacePosition.z);
            max.copyFromFloats(cameraSpacePosition.x + sprite.width / 2, cameraSpacePosition.y + sprite.height / 2, cameraSpacePosition.z);
            if (ray.intersectsBoxMinMax(min, max)) {
                var currentDistance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Distance(cameraSpacePosition, ray.origin);
                if (distance > currentDistance) {
                    distance = currentDistance;
                    currentSprite = sprite;
                    if (fastCheck) {
                        break;
                    }
                }
            }
        }
        if (currentSprite) {
            var result = new _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_5__["PickingInfo"]();
            cameraView.invertToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
            result.hit = true;
            result.pickedSprite = currentSprite;
            result.distance = distance;
            // Get picked point
            var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[2];
            direction.copyFrom(ray.direction);
            direction.normalize();
            direction.scaleInPlace(distance);
            ray.origin.addToRef(direction, pickedPoint);
            result.pickedPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinates(pickedPoint, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
            return result;
        }
        return null;
    };
    /**
     * Intersects the sprites with a ray
     * @param ray defines the ray to intersect with
     * @param camera defines the current active camera
     * @param predicate defines a predicate used to select candidate sprites
     * @returns null if no hit or a PickingInfo array
     */
    SpriteManager.prototype.multiIntersects = function (ray, camera, predicate) {
        var count = Math.min(this._capacity, this.sprites.length);
        var min = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        var max = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Zero();
        var distance;
        var results = [];
        var pickedPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[0].copyFromFloats(0, 0, 0);
        var cameraSpacePosition = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[1].copyFromFloats(0, 0, 0);
        var cameraView = camera.getViewMatrix();
        for (var index = 0; index < count; index++) {
            var sprite = this.sprites[index];
            if (!sprite) {
                continue;
            }
            if (predicate) {
                if (!predicate(sprite)) {
                    continue;
                }
            }
            else if (!sprite.isPickable) {
                continue;
            }
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(sprite.position, cameraView, cameraSpacePosition);
            min.copyFromFloats(cameraSpacePosition.x - sprite.width / 2, cameraSpacePosition.y - sprite.height / 2, cameraSpacePosition.z);
            max.copyFromFloats(cameraSpacePosition.x + sprite.width / 2, cameraSpacePosition.y + sprite.height / 2, cameraSpacePosition.z);
            if (ray.intersectsBoxMinMax(min, max)) {
                distance = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].Distance(cameraSpacePosition, ray.origin);
                var result = new _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_5__["PickingInfo"]();
                results.push(result);
                cameraView.invertToRef(_Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
                result.hit = true;
                result.pickedSprite = sprite;
                result.distance = distance;
                // Get picked point
                var direction = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Vector3[2];
                direction.copyFrom(ray.direction);
                direction.normalize();
                direction.scaleInPlace(distance);
                ray.origin.addToRef(direction, pickedPoint);
                result.pickedPoint = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinates(pickedPoint, _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["TmpVectors"].Matrix[0]);
            }
        }
        return results;
    };
    /**
     * Render all child sprites
     */
    SpriteManager.prototype.render = function () {
        // Check
        if (!this._effectBase.isReady() || !this._effectFog.isReady() || !this._spriteTexture
            || !this._spriteTexture.isReady() || !this.sprites.length) {
            return;
        }
        if (this._fromPacked && (!this._packedAndReady || !this._spriteMap || !this._cellData)) {
            return;
        }
        var engine = this._scene.getEngine();
        var baseSize = this._spriteTexture.getBaseSize();
        // Sprites
        var deltaTime = engine.getDeltaTime();
        var max = Math.min(this._capacity, this.sprites.length);
        var offset = 0;
        var noSprite = true;
        for (var index = 0; index < max; index++) {
            var sprite = this.sprites[index];
            if (!sprite || !sprite.isVisible) {
                continue;
            }
            noSprite = false;
            sprite._animate(deltaTime);
            this._appendSpriteVertex(offset++, sprite, 0, 0, baseSize);
            this._appendSpriteVertex(offset++, sprite, 1, 0, baseSize);
            this._appendSpriteVertex(offset++, sprite, 1, 1, baseSize);
            this._appendSpriteVertex(offset++, sprite, 0, 1, baseSize);
        }
        if (noSprite) {
            return;
        }
        this._buffer.update(this._vertexData);
        // Render
        var effect = this._effectBase;
        if (this._scene.fogEnabled && this._scene.fogMode !== _scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].FOGMODE_NONE && this.fogEnabled) {
            effect = this._effectFog;
        }
        engine.enableEffect(effect);
        var viewMatrix = this._scene.getViewMatrix();
        effect.setTexture("diffuseSampler", this._spriteTexture);
        effect.setMatrix("view", viewMatrix);
        effect.setMatrix("projection", this._scene.getProjectionMatrix());
        // Fog
        if (this._scene.fogEnabled && this._scene.fogMode !== _scene__WEBPACK_IMPORTED_MODULE_0__["Scene"].FOGMODE_NONE && this.fogEnabled) {
            effect.setFloat4("vFogInfos", this._scene.fogMode, this._scene.fogStart, this._scene.fogEnd, this._scene.fogDensity);
            effect.setColor3("vFogColor", this._scene.fogColor);
        }
        // VBOs
        engine.bindBuffers(this._vertexBuffers, this._indexBuffer, effect);
        // Draw order
        engine.setDepthFunctionToLessOrEqual();
        effect.setBool("alphaTest", true);
        engine.setColorWrite(false);
        engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFillMode, 0, (offset / 4) * 6);
        engine.setColorWrite(true);
        effect.setBool("alphaTest", false);
        engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_9__["Constants"].ALPHA_COMBINE);
        engine.drawElementsType(_Materials_material__WEBPACK_IMPORTED_MODULE_7__["Material"].TriangleFillMode, 0, (offset / 4) * 6);
        engine.setAlphaMode(_Engines_constants__WEBPACK_IMPORTED_MODULE_9__["Constants"].ALPHA_DISABLE);
    };
    /**
     * Release associated resources
     */
    SpriteManager.prototype.dispose = function () {
        if (this._buffer) {
            this._buffer.dispose();
            this._buffer = null;
        }
        if (this._indexBuffer) {
            this._scene.getEngine()._releaseBuffer(this._indexBuffer);
            this._indexBuffer = null;
        }
        if (this._spriteTexture) {
            this._spriteTexture.dispose();
            this._spriteTexture = null;
        }
        // Remove from scene
        var index = this._scene.spriteManagers.indexOf(this);
        this._scene.spriteManagers.splice(index, 1);
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
    };
    return SpriteManager;
}());



/***/ }),

/***/ "./Sprites/spritePackedManager.ts":
/*!****************************************!*\
  !*** ./Sprites/spritePackedManager.ts ***!
  \****************************************/
/*! exports provided: SpritePackedManager */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpritePackedManager", function() { return SpritePackedManager; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _spriteManager__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./spriteManager */ "./Sprites/spriteManager.ts");
/* harmony import */ var _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Materials/Textures/texture */ "./Materials/Textures/texture.ts");



/**
 * Class used to manage multiple sprites of different sizes on the same spritesheet
 * @see http://doc.babylonjs.com/babylon101/sprites
 */
var SpritePackedManager = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SpritePackedManager, _super);
    /**
     * Creates a new sprite manager from a packed sprite sheet
     * @param name defines the manager's name
     * @param imgUrl defines the sprite sheet url
     * @param capacity defines the maximum allowed number of sprites
     * @param scene defines the hosting scene
     * @param spriteJSON null otherwise a JSON object defining sprite sheet data
     * @param epsilon defines the epsilon value to align texture (0.01 by default)
     * @param samplingMode defines the smapling mode to use with spritesheet
     * @param fromPacked set to true; do not alter
     */
    function SpritePackedManager(
    /** defines the packed manager's name */
    name, imgUrl, capacity, scene, spriteJSON, epsilon, samplingMode) {
        if (spriteJSON === void 0) { spriteJSON = null; }
        if (epsilon === void 0) { epsilon = 0.01; }
        if (samplingMode === void 0) { samplingMode = _Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_2__["Texture"].TRILINEAR_SAMPLINGMODE; }
        var _this =
        //the cellSize parameter is not used when built from JSON which provides individual cell data, defaults to 64 if JSON load fails
        _super.call(this, name, imgUrl, capacity, 64, scene, epsilon, samplingMode, true, spriteJSON) || this;
        _this.name = name;
        return _this;
    }
    return SpritePackedManager;
}(_spriteManager__WEBPACK_IMPORTED_MODULE_1__["SpriteManager"]));



/***/ }),

/***/ "./Sprites/spriteSceneComponent.ts":
/*!*****************************************!*\
  !*** ./Sprites/spriteSceneComponent.ts ***!
  \*****************************************/
/*! exports provided: SpriteSceneComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpriteSceneComponent", function() { return SpriteSceneComponent; });
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scene */ "./scene.ts");
/* harmony import */ var _Culling_ray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Culling/ray */ "./Culling/ray.ts");
/* harmony import */ var _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Collisions/pickingInfo */ "./Collisions/pickingInfo.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Actions/actionEvent */ "./Actions/actionEvent.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");







_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype._internalPickSprites = function (ray, predicate, fastCheck, camera) {
    if (!_Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_3__["PickingInfo"]) {
        return null;
    }
    var pickingInfo = null;
    if (!camera) {
        if (!this.activeCamera) {
            return null;
        }
        camera = this.activeCamera;
    }
    if (this.spriteManagers.length > 0) {
        for (var spriteIndex = 0; spriteIndex < this.spriteManagers.length; spriteIndex++) {
            var spriteManager = this.spriteManagers[spriteIndex];
            if (!spriteManager.isPickable) {
                continue;
            }
            var result = spriteManager.intersects(ray, camera, predicate, fastCheck);
            if (!result || !result.hit) {
                continue;
            }
            if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
                continue;
            }
            pickingInfo = result;
            if (fastCheck) {
                break;
            }
        }
    }
    return pickingInfo || new _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_3__["PickingInfo"]();
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype._internalMultiPickSprites = function (ray, predicate, camera) {
    if (!_Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_3__["PickingInfo"]) {
        return null;
    }
    var pickingInfos = new Array();
    if (!camera) {
        if (!this.activeCamera) {
            return null;
        }
        camera = this.activeCamera;
    }
    if (this.spriteManagers.length > 0) {
        for (var spriteIndex = 0; spriteIndex < this.spriteManagers.length; spriteIndex++) {
            var spriteManager = this.spriteManagers[spriteIndex];
            if (!spriteManager.isPickable) {
                continue;
            }
            var results = spriteManager.multiIntersects(ray, camera, predicate);
            if (results !== null) {
                pickingInfos = pickingInfos.concat(results);
            }
        }
    }
    return pickingInfos;
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.pickSprite = function (x, y, predicate, fastCheck, camera) {
    this.createPickingRayInCameraSpaceToRef(x, y, this._tempSpritePickingRay, camera);
    return this._internalPickSprites(this._tempSpritePickingRay, predicate, fastCheck, camera);
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.pickSpriteWithRay = function (ray, predicate, fastCheck, camera) {
    if (!this._tempSpritePickingRay) {
        return null;
    }
    if (!camera) {
        if (!this.activeCamera) {
            return null;
        }
        camera = this.activeCamera;
    }
    _Culling_ray__WEBPACK_IMPORTED_MODULE_2__["Ray"].TransformToRef(ray, camera.getViewMatrix(), this._tempSpritePickingRay);
    return this._internalPickSprites(this._tempSpritePickingRay, predicate, fastCheck, camera);
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.multiPickSprite = function (x, y, predicate, camera) {
    this.createPickingRayInCameraSpaceToRef(x, y, this._tempSpritePickingRay, camera);
    return this._internalMultiPickSprites(this._tempSpritePickingRay, predicate, camera);
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.multiPickSpriteWithRay = function (ray, predicate, camera) {
    if (!this._tempSpritePickingRay) {
        return null;
    }
    if (!camera) {
        if (!this.activeCamera) {
            return null;
        }
        camera = this.activeCamera;
    }
    _Culling_ray__WEBPACK_IMPORTED_MODULE_2__["Ray"].TransformToRef(ray, camera.getViewMatrix(), this._tempSpritePickingRay);
    return this._internalMultiPickSprites(this._tempSpritePickingRay, predicate, camera);
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.setPointerOverSprite = function (sprite) {
    if (this._pointerOverSprite === sprite) {
        return;
    }
    if (this._pointerOverSprite && this._pointerOverSprite.actionManager) {
        this._pointerOverSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnPointerOutTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(this._pointerOverSprite, this));
    }
    this._pointerOverSprite = sprite;
    if (this._pointerOverSprite && this._pointerOverSprite.actionManager) {
        this._pointerOverSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnPointerOverTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(this._pointerOverSprite, this));
    }
};
_scene__WEBPACK_IMPORTED_MODULE_1__["Scene"].prototype.getPointerOverSprite = function () {
    return this._pointerOverSprite;
};
/**
 * Defines the sprite scene component responsible to manage sprites
 * in a given scene.
 */
var SpriteSceneComponent = /** @class */ (function () {
    /**
     * Creates a new instance of the component for the given scene
     * @param scene Defines the scene to register the component in
     */
    function SpriteSceneComponent(scene) {
        /**
         * The component name helpfull to identify the component in the list of scene components.
         */
        this.name = _sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].NAME_SPRITE;
        this.scene = scene;
        this.scene.spriteManagers = new Array();
        this.scene._tempSpritePickingRay = _Culling_ray__WEBPACK_IMPORTED_MODULE_2__["Ray"] ? _Culling_ray__WEBPACK_IMPORTED_MODULE_2__["Ray"].Zero() : null;
        this.scene.onBeforeSpritesRenderingObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this.scene.onAfterSpritesRenderingObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
        this._spritePredicate = function (sprite) {
            if (!sprite.actionManager) {
                return false;
            }
            return sprite.isPickable && sprite.actionManager.hasPointerTriggers;
        };
    }
    /**
     * Registers the component in a given scene
     */
    SpriteSceneComponent.prototype.register = function () {
        this.scene._pointerMoveStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].STEP_POINTERMOVE_SPRITE, this, this._pointerMove);
        this.scene._pointerDownStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].STEP_POINTERDOWN_SPRITE, this, this._pointerDown);
        this.scene._pointerUpStage.registerStep(_sceneComponent__WEBPACK_IMPORTED_MODULE_4__["SceneComponentConstants"].STEP_POINTERUP_SPRITE, this, this._pointerUp);
    };
    /**
     * Rebuilds the elements related to this component in case of
     * context lost for instance.
     */
    SpriteSceneComponent.prototype.rebuild = function () {
        /** Nothing to do for sprites */
    };
    /**
     * Disposes the component and the associated ressources.
     */
    SpriteSceneComponent.prototype.dispose = function () {
        this.scene.onBeforeSpritesRenderingObservable.clear();
        this.scene.onAfterSpritesRenderingObservable.clear();
        var spriteManagers = this.scene.spriteManagers;
        while (spriteManagers.length) {
            spriteManagers[0].dispose();
        }
    };
    SpriteSceneComponent.prototype._pickSpriteButKeepRay = function (originalPointerInfo, x, y, fastCheck, camera) {
        var result = this.scene.pickSprite(x, y, this._spritePredicate, fastCheck, camera);
        if (result) {
            result.ray = originalPointerInfo ? originalPointerInfo.ray : null;
        }
        return result;
    };
    SpriteSceneComponent.prototype._pointerMove = function (unTranslatedPointerX, unTranslatedPointerY, pickResult, isMeshPicked, canvas) {
        var scene = this.scene;
        if (isMeshPicked) {
            scene.setPointerOverSprite(null);
        }
        else {
            pickResult = this._pickSpriteButKeepRay(pickResult, unTranslatedPointerX, unTranslatedPointerY, false, scene.cameraToUseForPointers || undefined);
            if (pickResult && pickResult.hit && pickResult.pickedSprite) {
                scene.setPointerOverSprite(pickResult.pickedSprite);
                if (scene._pointerOverSprite && scene._pointerOverSprite.actionManager && scene._pointerOverSprite.actionManager.hoverCursor) {
                    canvas.style.cursor = scene._pointerOverSprite.actionManager.hoverCursor;
                }
                else {
                    canvas.style.cursor = scene.hoverCursor;
                }
            }
            else {
                scene.setPointerOverSprite(null);
            }
        }
        return pickResult;
    };
    SpriteSceneComponent.prototype._pointerDown = function (unTranslatedPointerX, unTranslatedPointerY, pickResult, evt) {
        var scene = this.scene;
        scene._pickedDownSprite = null;
        if (scene.spriteManagers.length > 0) {
            pickResult = scene.pickSprite(unTranslatedPointerX, unTranslatedPointerY, this._spritePredicate, false, scene.cameraToUseForPointers || undefined);
            if (pickResult && pickResult.hit && pickResult.pickedSprite) {
                if (pickResult.pickedSprite.actionManager) {
                    scene._pickedDownSprite = pickResult.pickedSprite;
                    switch (evt.button) {
                        case 0:
                            pickResult.pickedSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnLeftPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(pickResult.pickedSprite, scene, evt));
                            break;
                        case 1:
                            pickResult.pickedSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnCenterPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(pickResult.pickedSprite, scene, evt));
                            break;
                        case 2:
                            pickResult.pickedSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnRightPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(pickResult.pickedSprite, scene, evt));
                            break;
                    }
                    if (pickResult.pickedSprite.actionManager) {
                        pickResult.pickedSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnPickDownTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(pickResult.pickedSprite, scene, evt));
                    }
                }
            }
        }
        return pickResult;
    };
    SpriteSceneComponent.prototype._pointerUp = function (unTranslatedPointerX, unTranslatedPointerY, pickResult, evt) {
        var scene = this.scene;
        if (scene.spriteManagers.length > 0) {
            var spritePickResult = scene.pickSprite(unTranslatedPointerX, unTranslatedPointerY, this._spritePredicate, false, scene.cameraToUseForPointers || undefined);
            if (spritePickResult) {
                if (spritePickResult.hit && spritePickResult.pickedSprite) {
                    if (spritePickResult.pickedSprite.actionManager) {
                        spritePickResult.pickedSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnPickUpTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(spritePickResult.pickedSprite, scene, evt));
                        if (spritePickResult.pickedSprite.actionManager) {
                            if (!this.scene._inputManager._isPointerSwiping()) {
                                spritePickResult.pickedSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnPickTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(spritePickResult.pickedSprite, scene, evt));
                            }
                        }
                    }
                }
                if (scene._pickedDownSprite && scene._pickedDownSprite.actionManager && scene._pickedDownSprite !== spritePickResult.pickedSprite) {
                    scene._pickedDownSprite.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_6__["Constants"].ACTION_OnPickOutTrigger, _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_5__["ActionEvent"].CreateNewFromSprite(scene._pickedDownSprite, scene, evt));
                }
            }
        }
        return pickResult;
    };
    return SpriteSceneComponent;
}());



/***/ }),

/***/ "./States/alphaCullingState.ts":
/*!*************************************!*\
  !*** ./States/alphaCullingState.ts ***!
  \*************************************/
/*! exports provided: _AlphaState */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_AlphaState", function() { return _AlphaState; });
/**
 * @hidden
 **/
var _AlphaState = /** @class */ (function () {
    /**
     * Initializes the state.
     */
    function _AlphaState() {
        this._blendFunctionParameters = new Array(4);
        this._blendEquationParameters = new Array(2);
        this._blendConstants = new Array(4);
        this._isBlendConstantsDirty = false;
        this._alphaBlend = false;
        this._isAlphaBlendDirty = false;
        this._isBlendFunctionParametersDirty = false;
        this._isBlendEquationParametersDirty = false;
        this.reset();
    }
    Object.defineProperty(_AlphaState.prototype, "isDirty", {
        get: function () {
            return this._isAlphaBlendDirty || this._isBlendFunctionParametersDirty;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_AlphaState.prototype, "alphaBlend", {
        get: function () {
            return this._alphaBlend;
        },
        set: function (value) {
            if (this._alphaBlend === value) {
                return;
            }
            this._alphaBlend = value;
            this._isAlphaBlendDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    _AlphaState.prototype.setAlphaBlendConstants = function (r, g, b, a) {
        if (this._blendConstants[0] === r &&
            this._blendConstants[1] === g &&
            this._blendConstants[2] === b &&
            this._blendConstants[3] === a) {
            return;
        }
        this._blendConstants[0] = r;
        this._blendConstants[1] = g;
        this._blendConstants[2] = b;
        this._blendConstants[3] = a;
        this._isBlendConstantsDirty = true;
    };
    _AlphaState.prototype.setAlphaBlendFunctionParameters = function (value0, value1, value2, value3) {
        if (this._blendFunctionParameters[0] === value0 &&
            this._blendFunctionParameters[1] === value1 &&
            this._blendFunctionParameters[2] === value2 &&
            this._blendFunctionParameters[3] === value3) {
            return;
        }
        this._blendFunctionParameters[0] = value0;
        this._blendFunctionParameters[1] = value1;
        this._blendFunctionParameters[2] = value2;
        this._blendFunctionParameters[3] = value3;
        this._isBlendFunctionParametersDirty = true;
    };
    _AlphaState.prototype.setAlphaEquationParameters = function (rgb, alpha) {
        if (this._blendEquationParameters[0] === rgb &&
            this._blendEquationParameters[1] === alpha) {
            return;
        }
        this._blendEquationParameters[0] = rgb;
        this._blendEquationParameters[1] = alpha;
        this._isBlendEquationParametersDirty = true;
    };
    _AlphaState.prototype.reset = function () {
        this._alphaBlend = false;
        this._blendFunctionParameters[0] = null;
        this._blendFunctionParameters[1] = null;
        this._blendFunctionParameters[2] = null;
        this._blendFunctionParameters[3] = null;
        this._blendEquationParameters[0] = null;
        this._blendEquationParameters[1] = null;
        this._blendConstants[0] = null;
        this._blendConstants[1] = null;
        this._blendConstants[2] = null;
        this._blendConstants[3] = null;
        this._isAlphaBlendDirty = true;
        this._isBlendFunctionParametersDirty = false;
        this._isBlendEquationParametersDirty = false;
        this._isBlendConstantsDirty = false;
    };
    _AlphaState.prototype.apply = function (gl) {
        if (!this.isDirty) {
            return;
        }
        // Alpha blend
        if (this._isAlphaBlendDirty) {
            if (this._alphaBlend) {
                gl.enable(gl.BLEND);
            }
            else {
                gl.disable(gl.BLEND);
            }
            this._isAlphaBlendDirty = false;
        }
        // Alpha function
        if (this._isBlendFunctionParametersDirty) {
            gl.blendFuncSeparate(this._blendFunctionParameters[0], this._blendFunctionParameters[1], this._blendFunctionParameters[2], this._blendFunctionParameters[3]);
            this._isBlendFunctionParametersDirty = false;
        }
        // Alpha equation
        if (this._isBlendEquationParametersDirty) {
            gl.blendEquationSeparate(this._blendEquationParameters[0], this._blendEquationParameters[1]);
            this._isBlendEquationParametersDirty = false;
        }
        // Constants
        if (this._isBlendConstantsDirty) {
            gl.blendColor(this._blendConstants[0], this._blendConstants[1], this._blendConstants[2], this._blendConstants[3]);
            this._isBlendConstantsDirty = false;
        }
    };
    return _AlphaState;
}());



/***/ }),

/***/ "./States/depthCullingState.ts":
/*!*************************************!*\
  !*** ./States/depthCullingState.ts ***!
  \*************************************/
/*! exports provided: _DepthCullingState */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_DepthCullingState", function() { return _DepthCullingState; });
/**
 * @hidden
 **/
var _DepthCullingState = /** @class */ (function () {
    /**
     * Initializes the state.
     */
    function _DepthCullingState() {
        this._isDepthTestDirty = false;
        this._isDepthMaskDirty = false;
        this._isDepthFuncDirty = false;
        this._isCullFaceDirty = false;
        this._isCullDirty = false;
        this._isZOffsetDirty = false;
        this._isFrontFaceDirty = false;
        this.reset();
    }
    Object.defineProperty(_DepthCullingState.prototype, "isDirty", {
        get: function () {
            return this._isDepthFuncDirty || this._isDepthTestDirty || this._isDepthMaskDirty || this._isCullFaceDirty || this._isCullDirty || this._isZOffsetDirty || this._isFrontFaceDirty;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "zOffset", {
        get: function () {
            return this._zOffset;
        },
        set: function (value) {
            if (this._zOffset === value) {
                return;
            }
            this._zOffset = value;
            this._isZOffsetDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "cullFace", {
        get: function () {
            return this._cullFace;
        },
        set: function (value) {
            if (this._cullFace === value) {
                return;
            }
            this._cullFace = value;
            this._isCullFaceDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "cull", {
        get: function () {
            return this._cull;
        },
        set: function (value) {
            if (this._cull === value) {
                return;
            }
            this._cull = value;
            this._isCullDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "depthFunc", {
        get: function () {
            return this._depthFunc;
        },
        set: function (value) {
            if (this._depthFunc === value) {
                return;
            }
            this._depthFunc = value;
            this._isDepthFuncDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "depthMask", {
        get: function () {
            return this._depthMask;
        },
        set: function (value) {
            if (this._depthMask === value) {
                return;
            }
            this._depthMask = value;
            this._isDepthMaskDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "depthTest", {
        get: function () {
            return this._depthTest;
        },
        set: function (value) {
            if (this._depthTest === value) {
                return;
            }
            this._depthTest = value;
            this._isDepthTestDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_DepthCullingState.prototype, "frontFace", {
        get: function () {
            return this._frontFace;
        },
        set: function (value) {
            if (this._frontFace === value) {
                return;
            }
            this._frontFace = value;
            this._isFrontFaceDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    _DepthCullingState.prototype.reset = function () {
        this._depthMask = true;
        this._depthTest = true;
        this._depthFunc = null;
        this._cullFace = null;
        this._cull = null;
        this._zOffset = 0;
        this._frontFace = null;
        this._isDepthTestDirty = true;
        this._isDepthMaskDirty = true;
        this._isDepthFuncDirty = false;
        this._isCullFaceDirty = false;
        this._isCullDirty = false;
        this._isZOffsetDirty = false;
        this._isFrontFaceDirty = false;
    };
    _DepthCullingState.prototype.apply = function (gl) {
        if (!this.isDirty) {
            return;
        }
        // Cull
        if (this._isCullDirty) {
            if (this.cull) {
                gl.enable(gl.CULL_FACE);
            }
            else {
                gl.disable(gl.CULL_FACE);
            }
            this._isCullDirty = false;
        }
        // Cull face
        if (this._isCullFaceDirty) {
            gl.cullFace(this.cullFace);
            this._isCullFaceDirty = false;
        }
        // Depth mask
        if (this._isDepthMaskDirty) {
            gl.depthMask(this.depthMask);
            this._isDepthMaskDirty = false;
        }
        // Depth test
        if (this._isDepthTestDirty) {
            if (this.depthTest) {
                gl.enable(gl.DEPTH_TEST);
            }
            else {
                gl.disable(gl.DEPTH_TEST);
            }
            this._isDepthTestDirty = false;
        }
        // Depth func
        if (this._isDepthFuncDirty) {
            gl.depthFunc(this.depthFunc);
            this._isDepthFuncDirty = false;
        }
        // zOffset
        if (this._isZOffsetDirty) {
            if (this.zOffset) {
                gl.enable(gl.POLYGON_OFFSET_FILL);
                gl.polygonOffset(this.zOffset, 0);
            }
            else {
                gl.disable(gl.POLYGON_OFFSET_FILL);
            }
            this._isZOffsetDirty = false;
        }
        // Front face
        if (this._isFrontFaceDirty) {
            gl.frontFace(this.frontFace);
            this._isFrontFaceDirty = false;
        }
    };
    return _DepthCullingState;
}());



/***/ }),

/***/ "./States/index.ts":
/*!*************************!*\
  !*** ./States/index.ts ***!
  \*************************/
/*! exports provided: _AlphaState, _DepthCullingState, _StencilState */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _alphaCullingState__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./alphaCullingState */ "./States/alphaCullingState.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_AlphaState", function() { return _alphaCullingState__WEBPACK_IMPORTED_MODULE_0__["_AlphaState"]; });

/* harmony import */ var _depthCullingState__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./depthCullingState */ "./States/depthCullingState.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DepthCullingState", function() { return _depthCullingState__WEBPACK_IMPORTED_MODULE_1__["_DepthCullingState"]; });

/* harmony import */ var _stencilState__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./stencilState */ "./States/stencilState.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_StencilState", function() { return _stencilState__WEBPACK_IMPORTED_MODULE_2__["_StencilState"]; });






/***/ }),

/***/ "./States/stencilState.ts":
/*!********************************!*\
  !*** ./States/stencilState.ts ***!
  \********************************/
/*! exports provided: _StencilState */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_StencilState", function() { return _StencilState; });
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Engines/constants */ "./Engines/constants.ts");

/**
 * @hidden
 **/
var _StencilState = /** @class */ (function () {
    function _StencilState() {
        this._isStencilTestDirty = false;
        this._isStencilMaskDirty = false;
        this._isStencilFuncDirty = false;
        this._isStencilOpDirty = false;
        this.reset();
    }
    Object.defineProperty(_StencilState.prototype, "isDirty", {
        get: function () {
            return this._isStencilTestDirty || this._isStencilMaskDirty || this._isStencilFuncDirty || this._isStencilOpDirty;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilFunc", {
        get: function () {
            return this._stencilFunc;
        },
        set: function (value) {
            if (this._stencilFunc === value) {
                return;
            }
            this._stencilFunc = value;
            this._isStencilFuncDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilFuncRef", {
        get: function () {
            return this._stencilFuncRef;
        },
        set: function (value) {
            if (this._stencilFuncRef === value) {
                return;
            }
            this._stencilFuncRef = value;
            this._isStencilFuncDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilFuncMask", {
        get: function () {
            return this._stencilFuncMask;
        },
        set: function (value) {
            if (this._stencilFuncMask === value) {
                return;
            }
            this._stencilFuncMask = value;
            this._isStencilFuncDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilOpStencilFail", {
        get: function () {
            return this._stencilOpStencilFail;
        },
        set: function (value) {
            if (this._stencilOpStencilFail === value) {
                return;
            }
            this._stencilOpStencilFail = value;
            this._isStencilOpDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilOpDepthFail", {
        get: function () {
            return this._stencilOpDepthFail;
        },
        set: function (value) {
            if (this._stencilOpDepthFail === value) {
                return;
            }
            this._stencilOpDepthFail = value;
            this._isStencilOpDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilOpStencilDepthPass", {
        get: function () {
            return this._stencilOpStencilDepthPass;
        },
        set: function (value) {
            if (this._stencilOpStencilDepthPass === value) {
                return;
            }
            this._stencilOpStencilDepthPass = value;
            this._isStencilOpDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilMask", {
        get: function () {
            return this._stencilMask;
        },
        set: function (value) {
            if (this._stencilMask === value) {
                return;
            }
            this._stencilMask = value;
            this._isStencilMaskDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(_StencilState.prototype, "stencilTest", {
        get: function () {
            return this._stencilTest;
        },
        set: function (value) {
            if (this._stencilTest === value) {
                return;
            }
            this._stencilTest = value;
            this._isStencilTestDirty = true;
        },
        enumerable: true,
        configurable: true
    });
    _StencilState.prototype.reset = function () {
        this._stencilTest = false;
        this._stencilMask = 0xFF;
        this._stencilFunc = _StencilState.ALWAYS;
        this._stencilFuncRef = 1;
        this._stencilFuncMask = 0xFF;
        this._stencilOpStencilFail = _StencilState.KEEP;
        this._stencilOpDepthFail = _StencilState.KEEP;
        this._stencilOpStencilDepthPass = _StencilState.REPLACE;
        this._isStencilTestDirty = true;
        this._isStencilMaskDirty = true;
        this._isStencilFuncDirty = true;
        this._isStencilOpDirty = true;
    };
    _StencilState.prototype.apply = function (gl) {
        if (!this.isDirty) {
            return;
        }
        // Stencil test
        if (this._isStencilTestDirty) {
            if (this.stencilTest) {
                gl.enable(gl.STENCIL_TEST);
            }
            else {
                gl.disable(gl.STENCIL_TEST);
            }
            this._isStencilTestDirty = false;
        }
        // Stencil mask
        if (this._isStencilMaskDirty) {
            gl.stencilMask(this.stencilMask);
            this._isStencilMaskDirty = false;
        }
        // Stencil func
        if (this._isStencilFuncDirty) {
            gl.stencilFunc(this.stencilFunc, this.stencilFuncRef, this.stencilFuncMask);
            this._isStencilFuncDirty = false;
        }
        // Stencil op
        if (this._isStencilOpDirty) {
            gl.stencilOp(this.stencilOpStencilFail, this.stencilOpDepthFail, this.stencilOpStencilDepthPass);
            this._isStencilOpDirty = false;
        }
    };
    /** Passed to depthFunction or stencilFunction to specify depth or stencil tests will always pass. i.e. Pixels will be drawn in the order they are drawn */
    _StencilState.ALWAYS = _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].ALWAYS;
    /** Passed to stencilOperation to specify that stencil value must be kept */
    _StencilState.KEEP = _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].KEEP;
    /** Passed to stencilOperation to specify that stencil value must be replaced */
    _StencilState.REPLACE = _Engines_constants__WEBPACK_IMPORTED_MODULE_0__["Constants"].REPLACE;
    return _StencilState;
}());



/***/ }),

/***/ "./abstractScene.ts":
/*!**************************!*\
  !*** ./abstractScene.ts ***!
  \**************************/
/*! exports provided: AbstractScene */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractScene", function() { return AbstractScene; });
/**
 * Base class of the scene acting as a container for the different elements composing a scene.
 * This class is dynamically extended by the different components of the scene increasing
 * flexibility and reducing coupling
 */
var AbstractScene = /** @class */ (function () {
    function AbstractScene() {
        /**
         * Gets the list of root nodes (ie. nodes with no parent)
         */
        this.rootNodes = new Array();
        /** All of the cameras added to this scene
         * @see http://doc.babylonjs.com/babylon101/cameras
         */
        this.cameras = new Array();
        /**
        * All of the lights added to this scene
        * @see http://doc.babylonjs.com/babylon101/lights
        */
        this.lights = new Array();
        /**
        * All of the (abstract) meshes added to this scene
        */
        this.meshes = new Array();
        /**
         * The list of skeletons added to the scene
         * @see http://doc.babylonjs.com/how_to/how_to_use_bones_and_skeletons
         */
        this.skeletons = new Array();
        /**
        * All of the particle systems added to this scene
        * @see http://doc.babylonjs.com/babylon101/particles
        */
        this.particleSystems = new Array();
        /**
         * Gets a list of Animations associated with the scene
         */
        this.animations = [];
        /**
        * All of the animation groups added to this scene
        * @see http://doc.babylonjs.com/how_to/group
        */
        this.animationGroups = new Array();
        /**
        * All of the multi-materials added to this scene
        * @see http://doc.babylonjs.com/how_to/multi_materials
        */
        this.multiMaterials = new Array();
        /**
        * All of the materials added to this scene
        * In the context of a Scene, it is not supposed to be modified manually.
        * Any addition or removal should be done using the addMaterial and removeMAterial Scene methods.
        * Note also that the order of the Material wihin the array is not significant and might change.
        * @see http://doc.babylonjs.com/babylon101/materials
        */
        this.materials = new Array();
        /**
         * The list of morph target managers added to the scene
         * @see http://doc.babylonjs.com/how_to/how_to_dynamically_morph_a_mesh
         */
        this.morphTargetManagers = new Array();
        /**
         * The list of geometries used in the scene.
         */
        this.geometries = new Array();
        /**
        * All of the tranform nodes added to this scene
        * In the context of a Scene, it is not supposed to be modified manually.
        * Any addition or removal should be done using the addTransformNode and removeTransformNode Scene methods.
        * Note also that the order of the TransformNode wihin the array is not significant and might change.
        * @see http://doc.babylonjs.com/how_to/transformnode
        */
        this.transformNodes = new Array();
        /**
         * ActionManagers available on the scene.
         */
        this.actionManagers = new Array();
        /**
         * Textures to keep.
         */
        this.textures = new Array();
        /**
         * Environment texture for the scene
         */
        this.environmentTexture = null;
    }
    /**
     * Adds a parser in the list of available ones
     * @param name Defines the name of the parser
     * @param parser Defines the parser to add
     */
    AbstractScene.AddParser = function (name, parser) {
        this._BabylonFileParsers[name] = parser;
    };
    /**
     * Gets a general parser from the list of avaialble ones
     * @param name Defines the name of the parser
     * @returns the requested parser or null
     */
    AbstractScene.GetParser = function (name) {
        if (this._BabylonFileParsers[name]) {
            return this._BabylonFileParsers[name];
        }
        return null;
    };
    /**
     * Adds n individual parser in the list of available ones
     * @param name Defines the name of the parser
     * @param parser Defines the parser to add
     */
    AbstractScene.AddIndividualParser = function (name, parser) {
        this._IndividualBabylonFileParsers[name] = parser;
    };
    /**
     * Gets an individual parser from the list of avaialble ones
     * @param name Defines the name of the parser
     * @returns the requested parser or null
     */
    AbstractScene.GetIndividualParser = function (name) {
        if (this._IndividualBabylonFileParsers[name]) {
            return this._IndividualBabylonFileParsers[name];
        }
        return null;
    };
    /**
     * Parser json data and populate both a scene and its associated container object
     * @param jsonData Defines the data to parse
     * @param scene Defines the scene to parse the data for
     * @param container Defines the container attached to the parsing sequence
     * @param rootUrl Defines the root url of the data
     */
    AbstractScene.Parse = function (jsonData, scene, container, rootUrl) {
        for (var parserName in this._BabylonFileParsers) {
            if (this._BabylonFileParsers.hasOwnProperty(parserName)) {
                this._BabylonFileParsers[parserName](jsonData, scene, container, rootUrl);
            }
        }
    };
    /**
     * Stores the list of available parsers in the application.
     */
    AbstractScene._BabylonFileParsers = {};
    /**
     * Stores the list of available individual parsers in the application.
     */
    AbstractScene._IndividualBabylonFileParsers = {};
    return AbstractScene;
}());



/***/ }),

/***/ "./assetContainer.ts":
/*!***************************!*\
  !*** ./assetContainer.ts ***!
  \***************************/
/*! exports provided: KeepAssets, AssetContainer */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeepAssets", function() { return KeepAssets; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AssetContainer", function() { return AssetContainer; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./abstractScene */ "./abstractScene.ts");
/* harmony import */ var _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Meshes/mesh */ "./Meshes/mesh.ts");



/**
 * Set of assets to keep when moving a scene into an asset container.
 */
var KeepAssets = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](KeepAssets, _super);
    function KeepAssets() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return KeepAssets;
}(_abstractScene__WEBPACK_IMPORTED_MODULE_1__["AbstractScene"]));

/**
 * Container with a set of assets that can be added or removed from a scene.
 */
var AssetContainer = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AssetContainer, _super);
    /**
     * Instantiates an AssetContainer.
     * @param scene The scene the AssetContainer belongs to.
     */
    function AssetContainer(scene) {
        var _this = _super.call(this) || this;
        _this.scene = scene;
        _this["sounds"] = [];
        _this["effectLayers"] = [];
        _this["layers"] = [];
        _this["lensFlareSystems"] = [];
        _this["proceduralTextures"] = [];
        _this["reflectionProbes"] = [];
        return _this;
    }
    /**
     * Adds all the assets from the container to the scene.
     */
    AssetContainer.prototype.addAllToScene = function () {
        var _this = this;
        this.cameras.forEach(function (o) {
            _this.scene.addCamera(o);
        });
        this.lights.forEach(function (o) {
            _this.scene.addLight(o);
        });
        this.meshes.forEach(function (o) {
            _this.scene.addMesh(o);
        });
        this.skeletons.forEach(function (o) {
            _this.scene.addSkeleton(o);
        });
        this.animations.forEach(function (o) {
            _this.scene.addAnimation(o);
        });
        this.animationGroups.forEach(function (o) {
            _this.scene.addAnimationGroup(o);
        });
        this.multiMaterials.forEach(function (o) {
            _this.scene.addMultiMaterial(o);
        });
        this.materials.forEach(function (o) {
            _this.scene.addMaterial(o);
        });
        this.morphTargetManagers.forEach(function (o) {
            _this.scene.addMorphTargetManager(o);
        });
        this.geometries.forEach(function (o) {
            _this.scene.addGeometry(o);
        });
        this.transformNodes.forEach(function (o) {
            _this.scene.addTransformNode(o);
        });
        this.actionManagers.forEach(function (o) {
            _this.scene.addActionManager(o);
        });
        this.textures.forEach(function (o) {
            _this.scene.addTexture(o);
        });
        this.reflectionProbes.forEach(function (o) {
            _this.scene.addReflectionProbe(o);
        });
        if (this.environmentTexture) {
            this.scene.environmentTexture = this.environmentTexture;
        }
        for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
            var component = _a[_i];
            component.addFromContainer(this);
        }
    };
    /**
     * Removes all the assets in the container from the scene
     */
    AssetContainer.prototype.removeAllFromScene = function () {
        var _this = this;
        this.cameras.forEach(function (o) {
            _this.scene.removeCamera(o);
        });
        this.lights.forEach(function (o) {
            _this.scene.removeLight(o);
        });
        this.meshes.forEach(function (o) {
            _this.scene.removeMesh(o);
        });
        this.skeletons.forEach(function (o) {
            _this.scene.removeSkeleton(o);
        });
        this.animations.forEach(function (o) {
            _this.scene.removeAnimation(o);
        });
        this.animationGroups.forEach(function (o) {
            _this.scene.removeAnimationGroup(o);
        });
        this.multiMaterials.forEach(function (o) {
            _this.scene.removeMultiMaterial(o);
        });
        this.materials.forEach(function (o) {
            _this.scene.removeMaterial(o);
        });
        this.morphTargetManagers.forEach(function (o) {
            _this.scene.removeMorphTargetManager(o);
        });
        this.geometries.forEach(function (o) {
            _this.scene.removeGeometry(o);
        });
        this.transformNodes.forEach(function (o) {
            _this.scene.removeTransformNode(o);
        });
        this.actionManagers.forEach(function (o) {
            _this.scene.removeActionManager(o);
        });
        this.textures.forEach(function (o) {
            _this.scene.removeTexture(o);
        });
        this.reflectionProbes.forEach(function (o) {
            _this.scene.removeReflectionProbe(o);
        });
        if (this.environmentTexture === this.scene.environmentTexture) {
            this.scene.environmentTexture = null;
        }
        for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
            var component = _a[_i];
            component.removeFromContainer(this);
        }
    };
    /**
     * Disposes all the assets in the container
     */
    AssetContainer.prototype.dispose = function () {
        this.cameras.forEach(function (o) {
            o.dispose();
        });
        this.cameras = [];
        this.lights.forEach(function (o) {
            o.dispose();
        });
        this.lights = [];
        this.meshes.forEach(function (o) {
            o.dispose();
        });
        this.meshes = [];
        this.skeletons.forEach(function (o) {
            o.dispose();
        });
        this.skeletons = [];
        this.animationGroups.forEach(function (o) {
            o.dispose();
        });
        this.animationGroups = [];
        this.multiMaterials.forEach(function (o) {
            o.dispose();
        });
        this.multiMaterials = [];
        this.materials.forEach(function (o) {
            o.dispose();
        });
        this.materials = [];
        this.geometries.forEach(function (o) {
            o.dispose();
        });
        this.geometries = [];
        this.transformNodes.forEach(function (o) {
            o.dispose();
        });
        this.transformNodes = [];
        this.actionManagers.forEach(function (o) {
            o.dispose();
        });
        this.actionManagers = [];
        this.textures.forEach(function (o) {
            o.dispose();
        });
        this.textures = [];
        this.reflectionProbes.forEach(function (o) {
            o.dispose();
        });
        this.reflectionProbes = [];
        if (this.environmentTexture) {
            this.environmentTexture.dispose();
            this.environmentTexture = null;
        }
        for (var _i = 0, _a = this.scene._serializableComponents; _i < _a.length; _i++) {
            var component = _a[_i];
            component.removeFromContainer(this, true);
        }
    };
    AssetContainer.prototype._moveAssets = function (sourceAssets, targetAssets, keepAssets) {
        if (!sourceAssets) {
            return;
        }
        for (var _i = 0, sourceAssets_1 = sourceAssets; _i < sourceAssets_1.length; _i++) {
            var asset = sourceAssets_1[_i];
            var move = true;
            if (keepAssets) {
                for (var _a = 0, keepAssets_1 = keepAssets; _a < keepAssets_1.length; _a++) {
                    var keepAsset = keepAssets_1[_a];
                    if (asset === keepAsset) {
                        move = false;
                        break;
                    }
                }
            }
            if (move) {
                targetAssets.push(asset);
            }
        }
    };
    /**
     * Removes all the assets contained in the scene and adds them to the container.
     * @param keepAssets Set of assets to keep in the scene. (default: empty)
     */
    AssetContainer.prototype.moveAllFromScene = function (keepAssets) {
        if (keepAssets === undefined) {
            keepAssets = new KeepAssets();
        }
        for (var key in this) {
            if (this.hasOwnProperty(key)) {
                this[key] = this[key] || (key === "environmentTexture" ? null : []);
                this._moveAssets(this.scene[key], this[key], keepAssets[key]);
            }
        }
        this.removeAllFromScene();
    };
    /**
     * Adds all meshes in the asset container to a root mesh that can be used to position all the contained meshes. The root mesh is then added to the front of the meshes in the assetContainer.
     * @returns the root mesh
     */
    AssetContainer.prototype.createRootMesh = function () {
        var rootMesh = new _Meshes_mesh__WEBPACK_IMPORTED_MODULE_2__["Mesh"]("assetContainerRootMesh", this.scene);
        this.meshes.forEach(function (m) {
            if (!m.parent) {
                rootMesh.addChild(m);
            }
        });
        this.meshes.unshift(rootMesh);
        return rootMesh;
    };
    return AssetContainer;
}(_abstractScene__WEBPACK_IMPORTED_MODULE_1__["AbstractScene"]));



/***/ }),

/***/ "./index.ts":
/*!******************!*\
  !*** ./index.ts ***!
  \******************/
/*! exports provided: AbstractScene, KeepAssets, AssetContainer, Node, Scene, SceneComponentConstants, Stage, AbstractActionManager, Action, ActionEvent, ActionManager, Condition, ValueCondition, PredicateCondition, StateCondition, SwitchBooleanAction, SetStateAction, SetValueAction, IncrementValueAction, PlayAnimationAction, StopAnimationAction, DoNothingAction, CombineAction, ExecuteCodeAction, SetParentAction, PlaySoundAction, StopSoundAction, InterpolateValueAction, Animatable, _IAnimationState, Animation, TargetedAnimation, AnimationGroup, AnimationPropertiesOverride, EasingFunction, CircleEase, BackEase, BounceEase, CubicEase, ElasticEase, ExponentialEase, PowerEase, QuadraticEase, QuarticEase, QuinticEase, SineEase, BezierCurveEase, RuntimeAnimation, AnimationEvent, AnimationKeyInterpolation, AnimationRange, Analyser, AudioEngine, AudioSceneComponent, Sound, SoundTrack, WeightedSound, Bone, BoneIKController, BoneLookController, Skeleton, CameraInputTypes, CameraInputsManager, Camera, TargetCamera, FreeCamera, FreeCameraInputsManager, TouchCamera, ArcRotateCamera, ArcRotateCameraInputsManager, DeviceOrientationCamera, FlyCamera, FlyCameraInputsManager, FollowCamera, ArcFollowCamera, FollowCameraInputsManager, GamepadCamera, UniversalCamera, VirtualJoysticksCamera, Collider, DefaultCollisionCoordinator, PickingInfo, IntersectionInfo, _MeshCollisionData, BoundingBox, BoundingInfo, BoundingSphere, Ray, AxesViewer, BoneAxesViewer, DebugLayer, PhysicsViewer, RayHelper, SkeletonViewer, Constants, InstancingAttributeInfo, DepthTextureCreationOptions, EngineCapabilities, Engine, EngineStore, NullEngineOptions, NullEngine, WebGLPipelineContext, WebGPUConstants, WebGPUEngine, WebGL2ShaderProcessor, NativeEngine, KeyboardEventTypes, KeyboardInfo, KeyboardInfoPre, PointerEventTypes, PointerInfoBase, PointerInfoPre, PointerInfo, ClipboardEventTypes, ClipboardInfo, StickValues, Gamepad, GenericPad, GamepadManager, GamepadSystemSceneComponent, Xbox360Button, Xbox360Dpad, Xbox360Pad, DualShockButton, DualShockDpad, DualShockPad, AxisDragGizmo, AxisScaleGizmo, BoundingBoxGizmo, Gizmo, GizmoManager, PlaneRotationGizmo, PositionGizmo, RotationGizmo, ScaleGizmo, LightGizmo, PlaneDragGizmo, EnvironmentHelper, PhotoDome, _forceSceneHelpersToBundle, VideoDome, EngineInstrumentation, SceneInstrumentation, _TimeToken, EffectLayer, EffectLayerSceneComponent, GlowLayer, HighlightLayer, Layer, LayerSceneComponent, LensFlare, LensFlareSystem, LensFlareSystemSceneComponent, Light, ShadowLight, DirectionalLight, HemisphericLight, PointLight, SpotLight, DefaultLoadingScreen, SceneLoaderProgressEvent, SceneLoader, SceneLoaderFlags, ColorCurves, EffectFallbacks, EffectCreationOptions, Effect, FresnelParameters, ImageProcessingConfigurationDefines, ImageProcessingConfiguration, Material, MaterialDefines, MaterialHelper, MultiMaterial, PushMaterial, ShaderMaterial, StandardMaterialDefines, StandardMaterial, BaseTexture, CubeTexture, DynamicTexture, EquiRectangularCubeTexture, HDRCubeTexture, InternalTexture, MirrorTexture, MultiRenderTarget, RawTexture, RenderTargetTexture, Texture, UniformBuffer, MaterialFlags, EffectRenderer, EffectWrapper, Scalar, Space, Axis, Color3, Color4, TmpColors, ToGammaSpace, ToLinearSpace, Epsilon, Frustum, Plane, Size, Vector2, Vector3, Vector4, Quaternion, Matrix, TmpVectors, Viewport, SphericalHarmonics, SphericalPolynomial, AbstractMesh, Buffer, VertexBuffer, CSG, Geometry, GroundMesh, TrailMesh, InstancedMesh, LinesMesh, InstancedLinesMesh, _CreationDataStorage, _InstancesBatch, Mesh, VertexData, MeshBuilder, SimplificationSettings, SimplificationQueue, SimplificationType, SimplicationQueueSceneComponent, Polygon, PolygonMeshBuilder, BaseSubMesh, SubMesh, MeshLODLevel, TransformNode, BoxBuilder, SphereBuilder, CylinderBuilder, TorusBuilder, LinesBuilder, PlaneBuilder, GroundBuilder, DataBuffer, WebGLDataBuffer, WebGPUDataBuffer, MorphTarget, MorphTargetManager, Database, BaseParticleSystem, GPUParticleSystem, Particle, ParticleHelper, ParticleSystem, _IDoNeedToBeInTheBuild, ParticleSystemSet, SolidParticle, ModelShape, DepthSortedParticle, SolidParticleSystem, SubEmitterType, SubEmitter, PhysicsEngine, PhysicsEngineSceneComponent, PhysicsHelper, PhysicsRadialExplosionEventOptions, PhysicsUpdraftEventOptions, PhysicsVortexEventOptions, PhysicsRadialImpulseFalloff, PhysicsUpdraftMode, PhysicsImpostor, PhysicsJoint, DistanceJoint, MotorEnabledJoint, HingeJoint, Hinge2Joint, AnaglyphPostProcess, BlackAndWhitePostProcess, BloomEffect, BloomMergePostProcess, BlurPostProcess, ChromaticAberrationPostProcess, CircleOfConfusionPostProcess, ColorCorrectionPostProcess, ConvolutionPostProcess, DepthOfFieldBlurPostProcess, DepthOfFieldEffectBlurLevel, DepthOfFieldEffect, DepthOfFieldMergePostProcessOptions, DepthOfFieldMergePostProcess, DisplayPassPostProcess, ExtractHighlightsPostProcess, FilterPostProcess, FxaaPostProcess, GrainPostProcess, HighlightsPostProcess, ImageProcessingPostProcess, MotionBlurPostProcess, PassPostProcess, PassCubePostProcess, PostProcess, PostProcessManager, RefractionPostProcess, SharpenPostProcess, StereoscopicInterlacePostProcess, TonemappingOperator, TonemapPostProcess, VolumetricLightScatteringPostProcess, VRDistortionCorrectionPostProcess, VRMultiviewToSingleviewPostProcess, ReflectionProbe, BoundingBoxRenderer, DepthRenderer, DepthRendererSceneComponent, EdgesRenderer, LineEdgesRenderer, GeometryBufferRenderer, GeometryBufferRendererSceneComponent, OutlineRenderer, RenderingGroup, RenderingGroupInfo, RenderingManager, UtilityLayerRenderer, Sprite, SpriteManager, SpritePackedManager, SpriteSceneComponent, _AlphaState, _DepthCullingState, _StencilState, AndOrNotEvaluator, AssetTaskState, AbstractAssetTask, AssetsProgressEvent, MeshAssetTask, TextFileAssetTask, BinaryFileAssetTask, ImageAssetTask, TextureAssetTask, CubeTextureAssetTask, HDRCubeTextureAssetTask, EquiRectangularCubeTextureAssetTask, AssetsManager, DDSTools, expandToProperty, serialize, serializeAsTexture, serializeAsColor3, serializeAsFresnelParameters, serializeAsVector2, serializeAsVector3, serializeAsMeshReference, serializeAsColorCurves, serializeAsColor4, serializeAsImageProcessingConfiguration, serializeAsQuaternion, serializeAsMatrix, serializeAsCameraReference, SerializationHelper, Deferred, EnvironmentTextureTools, MeshExploder, FilesInput, CubeMapToSphericalPolynomialTools, KhronosTextureContainer, EventState, Observer, MultiObserver, Observable, PerformanceMonitor, RollingAverage, PromisePolyfill, SceneOptimization, TextureOptimization, HardwareScalingOptimization, ShadowsOptimization, PostProcessesOptimization, LensFlaresOptimization, CustomOptimization, ParticlesOptimization, RenderTargetsOptimization, MergeMeshesOptimization, SceneOptimizerOptions, SceneOptimizer, SceneSerializer, SmartArray, SmartArrayNoDuplicate, StringDictionary, Tags, TextureTools, TGATools, Tools, className, AsyncLoop, VideoRecorder, JoystickAxis, VirtualJoystick, WorkerPool, Logger, _TypeStore, FilesInputStore, DeepCopier, PivotTools, PrecisionDate, ScreenshotTools, WebRequest, InspectableType, BRDFTextureTools, RGBDTextureTools, ColorGradient, Color3Gradient, FactorGradient, GradientHelper, PerfCounter, RetryStrategy, LoadFileError, AutoRotationBehavior, BouncingBehavior, FramingBehavior, AttachToBoxBehavior, FadeInOutBehavior, MultiPointerScaleBehavior, PointerDragBehavior, SixDofDragBehavior, ArcRotateCameraGamepadInput, ArcRotateCameraKeyboardMoveInput, ArcRotateCameraMouseWheelInput, ArcRotateCameraPointersInput, ArcRotateCameraVRDeviceOrientationInput, FlyCameraKeyboardInput, FlyCameraMouseInput, FollowCameraKeyboardMoveInput, FollowCameraMouseWheelInput, FollowCameraPointersInput, FreeCameraDeviceOrientationInput, FreeCameraGamepadInput, FreeCameraKeyboardMoveInput, FreeCameraMouseInput, FreeCameraTouchInput, FreeCameraVirtualJoystickInput, AnaglyphArcRotateCamera, AnaglyphFreeCamera, AnaglyphGamepadCamera, AnaglyphUniversalCamera, StereoscopicArcRotateCamera, StereoscopicFreeCamera, StereoscopicGamepadCamera, StereoscopicUniversalCamera, VRCameraMetrics, VRDeviceOrientationArcRotateCamera, VRDeviceOrientationFreeCamera, VRDeviceOrientationGamepadCamera, OnAfterEnteringVRObservableEvent, VRExperienceHelper, WebVRFreeCamera, WebXRCamera, WebXREnterExitUIButton, WebXREnterExitUIOptions, WebXREnterExitUI, WebXRState, WebXRExperienceHelper, WebXRInput, WebXRControllerTeleportation, WebXRControllerPointerSelection, WebXRControllerModelLoader, WebXRController, WebXRManagedOutputCanvas, WebXRSessionManager, Octree, OctreeBlock, OctreeSceneComponent, _OcclusionDataStorage, _forceTransformFeedbackToBundle, DaydreamController, GearVRController, GenericController, OculusTouchController, PoseEnabledControllerType, PoseEnabledControllerHelper, PoseEnabledController, ViveController, WebVRController, WindowsMotionController, ShadowGenerator, ShadowGeneratorSceneComponent, _BabylonLoaderRegistered, BackgroundMaterial, PBRMaterialDefines, PBRBaseMaterial, PBRBaseSimpleMaterial, PBRMaterial, PBRMetallicRoughnessMaterial, PBRSpecularGlossinessMaterial, ColorGradingTexture, RawCubeTexture, RawTexture3D, RefractionTexture, VideoTexture, HtmlElementTexture, NodeMaterialBlockTargets, NodeMaterialBlockConnectionPointTypes, NodeMaterialConnectionPoint, NodeMaterialBlock, NodeMaterialDefines, NodeMaterial, NodeMaterialSystemValues, Orientation, BezierCurve, Angle, Arc2, Path2, Path3D, Curve3, PositionNormalVertex, PositionNormalTextureVertex, DracoCompression, TiledBoxBuilder, DiscBuilder, RibbonBuilder, HemisphereBuilder, TorusKnotBuilder, PolygonBuilder, ShapeBuilder, LatheBuilder, TiledPlaneBuilder, TubeBuilder, PolyhedronBuilder, IcoSphereBuilder, DecalBuilder, RecastJSPlugin, RecastJSCrowd, BoxParticleEmitter, ConeParticleEmitter, CylinderParticleEmitter, CylinderDirectedParticleEmitter, HemisphericParticleEmitter, PointParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter, CannonJSPlugin, AmmoJSPlugin, OimoJSPlugin, PostProcessRenderEffect, PostProcessRenderPipeline, PostProcessRenderPipelineManager, PostProcessRenderPipelineManagerSceneComponent, HDRTools, PanoramaToCubeMapTools, _DDSTextureLoader, _ENVTextureLoader, _KTXTextureLoader, _TGATextureLoader, _BasisTextureLoader, CustomProceduralTexture, NoiseProceduralTexture, ProceduralTexture, ProceduralTextureSceneComponent, MultiplyBlock, AddBlock, ScaleBlock, ClampBlock, CrossBlock, DotBlock, TransformBlock, RemapBlock, NormalizeBlock, TrigonometryBlockOperations, TrigonometryBlock, ColorMergerBlock, VectorMergerBlock, ColorSplitterBlock, VectorSplitterBlock, LerpBlock, DivideBlock, SubtractBlock, StepBlock, OppositeBlock, ViewDirectionBlock, FresnelBlock, MaxBlock, MinBlock, NodeMaterialOptimizer, DefaultRenderingPipeline, LensRenderingPipeline, SSAO2RenderingPipeline, SSAORenderingPipeline, StandardRenderingPipeline, VertexOutputBlock, BonesBlock, InstancesBlock, MorphTargetsBlock, LightInformationBlock, FragmentOutputBlock, AlphaTestBlock, ImageProcessingBlock, PerturbNormalBlock, FogBlock, LightBlock, TextureBlock, ReflectionTextureBlock, InputBlock, AnimatedInputBlockTypes */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./abstractScene */ "./abstractScene.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractScene", function() { return _abstractScene__WEBPACK_IMPORTED_MODULE_0__["AbstractScene"]; });

/* harmony import */ var _Actions_index__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Actions/index */ "./Actions/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractActionManager", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["AbstractActionManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Action", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["Action"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ActionEvent", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["ActionEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ActionManager", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["ActionManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Condition", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["Condition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ValueCondition", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["ValueCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PredicateCondition", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["PredicateCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StateCondition", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["StateCondition"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SwitchBooleanAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["SwitchBooleanAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetStateAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["SetStateAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetValueAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["SetValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IncrementValueAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["IncrementValueAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlayAnimationAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["PlayAnimationAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StopAnimationAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["StopAnimationAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DoNothingAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["DoNothingAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CombineAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["CombineAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExecuteCodeAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["ExecuteCodeAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SetParentAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["SetParentAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaySoundAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["PlaySoundAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StopSoundAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["StopSoundAction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InterpolateValueAction", function() { return _Actions_index__WEBPACK_IMPORTED_MODULE_1__["InterpolateValueAction"]; });

/* harmony import */ var _Animations_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Animations/index */ "./Animations/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Animatable", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["Animatable"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_IAnimationState", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["_IAnimationState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Animation", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["Animation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TargetedAnimation", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["TargetedAnimation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationGroup", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["AnimationGroup"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationPropertiesOverride", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["AnimationPropertiesOverride"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EasingFunction", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["EasingFunction"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CircleEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["CircleEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["BackEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BounceEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["BounceEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubicEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["CubicEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ElasticEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["ElasticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExponentialEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["ExponentialEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PowerEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["PowerEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuadraticEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["QuadraticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuarticEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["QuarticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "QuinticEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["QuinticEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SineEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["SineEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurveEase", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["BezierCurveEase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RuntimeAnimation", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["RuntimeAnimation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationEvent", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["AnimationEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationKeyInterpolation", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["AnimationKeyInterpolation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimationRange", function() { return _Animations_index__WEBPACK_IMPORTED_MODULE_2__["AnimationRange"]; });

/* harmony import */ var _assetContainer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./assetContainer */ "./assetContainer.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeepAssets", function() { return _assetContainer__WEBPACK_IMPORTED_MODULE_3__["KeepAssets"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetContainer", function() { return _assetContainer__WEBPACK_IMPORTED_MODULE_3__["AssetContainer"]; });

/* harmony import */ var _Audio_index__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Audio/index */ "./Audio/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Analyser", function() { return _Audio_index__WEBPACK_IMPORTED_MODULE_4__["Analyser"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AudioEngine", function() { return _Audio_index__WEBPACK_IMPORTED_MODULE_4__["AudioEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AudioSceneComponent", function() { return _Audio_index__WEBPACK_IMPORTED_MODULE_4__["AudioSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sound", function() { return _Audio_index__WEBPACK_IMPORTED_MODULE_4__["Sound"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SoundTrack", function() { return _Audio_index__WEBPACK_IMPORTED_MODULE_4__["SoundTrack"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WeightedSound", function() { return _Audio_index__WEBPACK_IMPORTED_MODULE_4__["WeightedSound"]; });

/* harmony import */ var _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Behaviors/index */ "./Behaviors/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AutoRotationBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["AutoRotationBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BouncingBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["BouncingBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FramingBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["FramingBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AttachToBoxBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["AttachToBoxBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FadeInOutBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["FadeInOutBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiPointerScaleBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["MultiPointerScaleBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerDragBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["PointerDragBehavior"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SixDofDragBehavior", function() { return _Behaviors_index__WEBPACK_IMPORTED_MODULE_5__["SixDofDragBehavior"]; });

/* harmony import */ var _Bones_index__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Bones/index */ "./Bones/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Bone", function() { return _Bones_index__WEBPACK_IMPORTED_MODULE_6__["Bone"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneIKController", function() { return _Bones_index__WEBPACK_IMPORTED_MODULE_6__["BoneIKController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneLookController", function() { return _Bones_index__WEBPACK_IMPORTED_MODULE_6__["BoneLookController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Skeleton", function() { return _Bones_index__WEBPACK_IMPORTED_MODULE_6__["Skeleton"]; });

/* harmony import */ var _Cameras_index__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Cameras/index */ "./Cameras/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CameraInputTypes", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["CameraInputTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CameraInputsManager", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["CameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Camera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["Camera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TargetCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["TargetCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraInputsManager", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TouchCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["TouchCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraInputsManager", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DeviceOrientationCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["DeviceOrientationCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FlyCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraInputsManager", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FlyCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FollowCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcFollowCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcFollowCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraInputsManager", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FollowCameraInputsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["GamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UniversalCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["UniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualJoysticksCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["VirtualJoysticksCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraGamepadInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCameraGamepadInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraKeyboardMoveInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraMouseWheelInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCameraMouseWheelInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraPointersInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCameraPointersInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ArcRotateCameraVRDeviceOrientationInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["ArcRotateCameraVRDeviceOrientationInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraKeyboardInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FlyCameraKeyboardInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FlyCameraMouseInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FlyCameraMouseInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraKeyboardMoveInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FollowCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraMouseWheelInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FollowCameraMouseWheelInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FollowCameraPointersInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FollowCameraPointersInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraDeviceOrientationInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraDeviceOrientationInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraGamepadInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraGamepadInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraKeyboardMoveInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraKeyboardMoveInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraMouseInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraMouseInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraTouchInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraTouchInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FreeCameraVirtualJoystickInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["FreeCameraVirtualJoystickInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphArcRotateCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["AnaglyphArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphFreeCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["AnaglyphFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphGamepadCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["AnaglyphGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphUniversalCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["AnaglyphUniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicArcRotateCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["StereoscopicArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicFreeCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["StereoscopicFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicGamepadCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["StereoscopicGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicUniversalCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["StereoscopicUniversalCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRCameraMetrics", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["VRCameraMetrics"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationArcRotateCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["VRDeviceOrientationArcRotateCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationFreeCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["VRDeviceOrientationFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDeviceOrientationGamepadCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["VRDeviceOrientationGamepadCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OnAfterEnteringVRObservableEvent", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["OnAfterEnteringVRObservableEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRExperienceHelper", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["VRExperienceHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRFreeCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebVRFreeCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRCamera", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRCamera"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIButton", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXREnterExitUIButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUIOptions", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXREnterExitUIOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXREnterExitUI", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXREnterExitUI"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRState", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRExperienceHelper", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRExperienceHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRInput", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerTeleportation", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRControllerTeleportation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerPointerSelection", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRControllerPointerSelection"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRControllerModelLoader", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRControllerModelLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRController", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRManagedOutputCanvas", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRManagedOutputCanvas"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebXRSessionManager", function() { return _Cameras_index__WEBPACK_IMPORTED_MODULE_7__["WebXRSessionManager"]; });

/* harmony import */ var _Collisions_index__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Collisions/index */ "./Collisions/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Collider", function() { return _Collisions_index__WEBPACK_IMPORTED_MODULE_8__["Collider"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultCollisionCoordinator", function() { return _Collisions_index__WEBPACK_IMPORTED_MODULE_8__["DefaultCollisionCoordinator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PickingInfo", function() { return _Collisions_index__WEBPACK_IMPORTED_MODULE_8__["PickingInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IntersectionInfo", function() { return _Collisions_index__WEBPACK_IMPORTED_MODULE_8__["IntersectionInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_MeshCollisionData", function() { return _Collisions_index__WEBPACK_IMPORTED_MODULE_8__["_MeshCollisionData"]; });

/* harmony import */ var _Culling_index__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Culling/index */ "./Culling/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBox", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["BoundingBox"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingInfo", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["BoundingInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingSphere", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["BoundingSphere"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Ray", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["Ray"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Octree", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["Octree"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeBlock", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["OctreeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OctreeSceneComponent", function() { return _Culling_index__WEBPACK_IMPORTED_MODULE_9__["OctreeSceneComponent"]; });

/* harmony import */ var _Debug_index__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Debug/index */ "./Debug/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxesViewer", function() { return _Debug_index__WEBPACK_IMPORTED_MODULE_10__["AxesViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoneAxesViewer", function() { return _Debug_index__WEBPACK_IMPORTED_MODULE_10__["BoneAxesViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DebugLayer", function() { return _Debug_index__WEBPACK_IMPORTED_MODULE_10__["DebugLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsViewer", function() { return _Debug_index__WEBPACK_IMPORTED_MODULE_10__["PhysicsViewer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RayHelper", function() { return _Debug_index__WEBPACK_IMPORTED_MODULE_10__["RayHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SkeletonViewer", function() { return _Debug_index__WEBPACK_IMPORTED_MODULE_10__["SkeletonViewer"]; });

/* harmony import */ var _Engines_index__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./Engines/index */ "./Engines/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Constants", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["Constants"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancingAttributeInfo", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["InstancingAttributeInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthTextureCreationOptions", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["DepthTextureCreationOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineCapabilities", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["EngineCapabilities"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Engine", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["Engine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineStore", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["EngineStore"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NullEngineOptions", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["NullEngineOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NullEngine", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["NullEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGLPipelineContext", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["WebGLPipelineContext"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUConstants", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["WebGPUConstants"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUEngine", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["WebGPUEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGL2ShaderProcessor", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["WebGL2ShaderProcessor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NativeEngine", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["NativeEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_OcclusionDataStorage", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["_OcclusionDataStorage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceTransformFeedbackToBundle", function() { return _Engines_index__WEBPACK_IMPORTED_MODULE_11__["_forceTransformFeedbackToBundle"]; });

/* harmony import */ var _Events_index__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Events/index */ "./Events/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardEventTypes", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["KeyboardEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfo", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["KeyboardInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KeyboardInfoPre", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["KeyboardInfoPre"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerEventTypes", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["PointerEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfoBase", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["PointerInfoBase"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfoPre", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["PointerInfoPre"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointerInfo", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["PointerInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardEventTypes", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["ClipboardEventTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClipboardInfo", function() { return _Events_index__WEBPACK_IMPORTED_MODULE_12__["ClipboardInfo"]; });

/* harmony import */ var _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Gamepads/index */ "./Gamepads/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StickValues", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["StickValues"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Gamepad", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["Gamepad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericPad", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["GenericPad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadManager", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["GamepadManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GamepadSystemSceneComponent", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["GamepadSystemSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Button", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["Xbox360Button"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Dpad", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["Xbox360Dpad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Xbox360Pad", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["Xbox360Pad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockButton", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["DualShockButton"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockDpad", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["DualShockDpad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DualShockPad", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["DualShockPad"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DaydreamController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["DaydreamController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GearVRController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["GearVRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GenericController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["GenericController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OculusTouchController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["OculusTouchController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerType", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["PoseEnabledControllerType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledControllerHelper", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["PoseEnabledControllerHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PoseEnabledController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["PoseEnabledController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViveController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["ViveController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebVRController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["WebVRController"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WindowsMotionController", function() { return _Gamepads_index__WEBPACK_IMPORTED_MODULE_13__["WindowsMotionController"]; });

/* harmony import */ var _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Gizmos/index */ "./Gizmos/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxisDragGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["AxisDragGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AxisScaleGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["AxisScaleGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["BoundingBoxGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Gizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["Gizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GizmoManager", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["GizmoManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneRotationGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["PlaneRotationGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["PositionGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RotationGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["RotationGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["ScaleGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["LightGizmo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneDragGizmo", function() { return _Gizmos_index__WEBPACK_IMPORTED_MODULE_14__["PlaneDragGizmo"]; });

/* harmony import */ var _Helpers_index__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Helpers/index */ "./Helpers/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EnvironmentHelper", function() { return _Helpers_index__WEBPACK_IMPORTED_MODULE_15__["EnvironmentHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhotoDome", function() { return _Helpers_index__WEBPACK_IMPORTED_MODULE_15__["PhotoDome"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_forceSceneHelpersToBundle", function() { return _Helpers_index__WEBPACK_IMPORTED_MODULE_15__["_forceSceneHelpersToBundle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoDome", function() { return _Helpers_index__WEBPACK_IMPORTED_MODULE_15__["VideoDome"]; });

/* harmony import */ var _Instrumentation_index__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Instrumentation/index */ "./Instrumentation/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EngineInstrumentation", function() { return _Instrumentation_index__WEBPACK_IMPORTED_MODULE_16__["EngineInstrumentation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneInstrumentation", function() { return _Instrumentation_index__WEBPACK_IMPORTED_MODULE_16__["SceneInstrumentation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TimeToken", function() { return _Instrumentation_index__WEBPACK_IMPORTED_MODULE_16__["_TimeToken"]; });

/* harmony import */ var _Layers_index__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./Layers/index */ "./Layers/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectLayer", function() { return _Layers_index__WEBPACK_IMPORTED_MODULE_17__["EffectLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectLayerSceneComponent", function() { return _Layers_index__WEBPACK_IMPORTED_MODULE_17__["EffectLayerSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GlowLayer", function() { return _Layers_index__WEBPACK_IMPORTED_MODULE_17__["GlowLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HighlightLayer", function() { return _Layers_index__WEBPACK_IMPORTED_MODULE_17__["HighlightLayer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Layer", function() { return _Layers_index__WEBPACK_IMPORTED_MODULE_17__["Layer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LayerSceneComponent", function() { return _Layers_index__WEBPACK_IMPORTED_MODULE_17__["LayerSceneComponent"]; });

/* harmony import */ var _LensFlares_index__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./LensFlares/index */ "./LensFlares/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlare", function() { return _LensFlares_index__WEBPACK_IMPORTED_MODULE_18__["LensFlare"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystem", function() { return _LensFlares_index__WEBPACK_IMPORTED_MODULE_18__["LensFlareSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlareSystemSceneComponent", function() { return _LensFlares_index__WEBPACK_IMPORTED_MODULE_18__["LensFlareSystemSceneComponent"]; });

/* harmony import */ var _Lights_index__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./Lights/index */ "./Lights/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Light", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["Light"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowLight", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["ShadowLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DirectionalLight", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["DirectionalLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericLight", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["HemisphericLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointLight", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["PointLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpotLight", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["SpotLight"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGenerator", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["ShadowGenerator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowGeneratorSceneComponent", function() { return _Lights_index__WEBPACK_IMPORTED_MODULE_19__["ShadowGeneratorSceneComponent"]; });

/* harmony import */ var _Loading_index__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./Loading/index */ "./Loading/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultLoadingScreen", function() { return _Loading_index__WEBPACK_IMPORTED_MODULE_20__["DefaultLoadingScreen"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderProgressEvent", function() { return _Loading_index__WEBPACK_IMPORTED_MODULE_20__["SceneLoaderProgressEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoader", function() { return _Loading_index__WEBPACK_IMPORTED_MODULE_20__["SceneLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneLoaderFlags", function() { return _Loading_index__WEBPACK_IMPORTED_MODULE_20__["SceneLoaderFlags"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BabylonLoaderRegistered", function() { return _Loading_index__WEBPACK_IMPORTED_MODULE_20__["_BabylonLoaderRegistered"]; });

/* harmony import */ var _Materials_index__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./Materials/index */ "./Materials/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorCurves", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ColorCurves"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectFallbacks", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["EffectFallbacks"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectCreationOptions", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["EffectCreationOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Effect", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["Effect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelParameters", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["FresnelParameters"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfigurationDefines", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ImageProcessingConfigurationDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingConfiguration", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ImageProcessingConfiguration"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Material", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["Material"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialDefines", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialHelper", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MaterialHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MultiMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PushMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PushMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShaderMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ShaderMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardMaterialDefines", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["StandardMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["StandardMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["BaseTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["CubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DynamicTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["DynamicTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["EquiRectangularCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["HDRCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InternalTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["InternalTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MirrorTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MirrorTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiRenderTarget", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MultiRenderTarget"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["RawTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["RenderTargetTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Texture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["Texture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UniformBuffer", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["UniformBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaterialFlags", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MaterialFlags"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectRenderer", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["EffectRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EffectWrapper", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["EffectWrapper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BackgroundMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["BackgroundMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterialDefines", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PBRMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PBRBaseMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRBaseSimpleMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PBRBaseSimpleMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PBRMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRMetallicRoughnessMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PBRMetallicRoughnessMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PBRSpecularGlossinessMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PBRSpecularGlossinessMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradingTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ColorGradingTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawCubeTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["RawCubeTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RawTexture3D", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["RawTexture3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["RefractionTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["VideoTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HtmlElementTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["HtmlElementTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockTargets", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialBlockTargets"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlockConnectionPointTypes", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialBlockConnectionPointTypes"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialConnectionPoint", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialConnectionPoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialDefines", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialDefines"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterial", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialSystemValues", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialSystemValues"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DDSTextureLoader", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["_DDSTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_ENVTextureLoader", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["_ENVTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_KTXTextureLoader", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["_KTXTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TGATextureLoader", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["_TGATextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_BasisTextureLoader", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["_BasisTextureLoader"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomProceduralTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["CustomProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NoiseProceduralTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NoiseProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTexture", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ProceduralTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ProceduralTextureSceneComponent", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ProceduralTextureSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiplyBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MultiplyBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AddBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["AddBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScaleBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ScaleBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ClampBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ClampBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CrossBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["CrossBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DotBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["DotBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["TransformBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RemapBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["RemapBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NormalizeBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NormalizeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlockOperations", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["TrigonometryBlockOperations"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrigonometryBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["TrigonometryBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorMergerBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ColorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorMergerBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["VectorMergerBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorSplitterBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ColorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VectorSplitterBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["VectorSplitterBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LerpBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["LerpBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DivideBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["DivideBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubtractBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["SubtractBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StepBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["StepBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OppositeBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["OppositeBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ViewDirectionBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ViewDirectionBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FresnelBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["FresnelBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MaxBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MaxBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MinBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MinBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "NodeMaterialOptimizer", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["NodeMaterialOptimizer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexOutputBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["VertexOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BonesBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["BonesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancesBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["InstancesBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetsBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["MorphTargetsBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightInformationBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["LightInformationBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FragmentOutputBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["FragmentOutputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AlphaTestBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["AlphaTestBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ImageProcessingBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerturbNormalBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["PerturbNormalBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FogBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["FogBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LightBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["LightBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["TextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionTextureBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["ReflectionTextureBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InputBlock", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["InputBlock"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnimatedInputBlockTypes", function() { return _Materials_index__WEBPACK_IMPORTED_MODULE_21__["AnimatedInputBlockTypes"]; });

/* harmony import */ var _Maths_index__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./Maths/index */ "./Maths/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scalar", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Scalar"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Space", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Space"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Axis", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Axis"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Color3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color4", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Color4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpColors", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["TmpColors"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToGammaSpace", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["ToGammaSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ToLinearSpace", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["ToLinearSpace"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Epsilon", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Epsilon"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Frustum", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Frustum"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Plane", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Plane"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Size", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Size"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector2", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Vector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector3", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Vector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Vector4", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Vector4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quaternion", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Quaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Matrix", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Matrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TmpVectors", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["TmpVectors"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Viewport", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Viewport"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphericalHarmonics", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["SphericalHarmonics"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphericalPolynomial", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["SphericalPolynomial"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Orientation", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Orientation"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BezierCurve", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["BezierCurve"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Angle", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Angle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Arc2", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Arc2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path2", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Path2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Path3D", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Path3D"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Curve3", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["Curve3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalVertex", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["PositionNormalVertex"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PositionNormalTextureVertex", function() { return _Maths_index__WEBPACK_IMPORTED_MODULE_22__["PositionNormalTextureVertex"]; });

/* harmony import */ var _Meshes_index__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./Meshes/index */ "./Meshes/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["AbstractMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Buffer", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["Buffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexBuffer", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["VertexBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CSG", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["CSG"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Geometry", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["Geometry"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["GroundMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TrailMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TrailMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancedMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["InstancedMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["LinesMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InstancedLinesMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["InstancedLinesMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_CreationDataStorage", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["_CreationDataStorage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_InstancesBatch", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["_InstancesBatch"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Mesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["Mesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VertexData", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["VertexData"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["MeshBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationSettings", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["SimplificationSettings"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationQueue", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["SimplificationQueue"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplificationType", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["SimplificationType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SimplicationQueueSceneComponent", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["SimplicationQueueSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Polygon", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["Polygon"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonMeshBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["PolygonMeshBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseSubMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["BaseSubMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubMesh", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["SubMesh"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshLODLevel", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["MeshLODLevel"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TransformNode", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TransformNode"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["BoxBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["SphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["CylinderBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TorusBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LinesBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["LinesBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PlaneBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["PlaneBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GroundBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["GroundBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DataBuffer", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["DataBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGLDataBuffer", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["WebGLDataBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebGPUDataBuffer", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["WebGPUDataBuffer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DracoCompression", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["DracoCompression"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledBoxBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TiledBoxBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DiscBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["DiscBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RibbonBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["RibbonBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphereBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["HemisphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TorusKnotBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TorusKnotBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolygonBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["PolygonBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShapeBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["ShapeBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LatheBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["LatheBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TiledPlaneBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TiledPlaneBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TubeBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["TubeBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PolyhedronBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["PolyhedronBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "IcoSphereBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["IcoSphereBuilder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DecalBuilder", function() { return _Meshes_index__WEBPACK_IMPORTED_MODULE_23__["DecalBuilder"]; });

/* harmony import */ var _Morph_index__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./Morph/index */ "./Morph/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTarget", function() { return _Morph_index__WEBPACK_IMPORTED_MODULE_24__["MorphTarget"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphTargetManager", function() { return _Morph_index__WEBPACK_IMPORTED_MODULE_24__["MorphTargetManager"]; });

/* harmony import */ var _Navigation_index__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./Navigation/index */ "./Navigation/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSPlugin", function() { return _Navigation_index__WEBPACK_IMPORTED_MODULE_25__["RecastJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RecastJSCrowd", function() { return _Navigation_index__WEBPACK_IMPORTED_MODULE_25__["RecastJSCrowd"]; });

/* harmony import */ var _node__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./node */ "./node.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Node", function() { return _node__WEBPACK_IMPORTED_MODULE_26__["Node"]; });

/* harmony import */ var _Offline_index__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./Offline/index */ "./Offline/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Database", function() { return _Offline_index__WEBPACK_IMPORTED_MODULE_27__["Database"]; });

/* harmony import */ var _Particles_index__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./Particles/index */ "./Particles/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BaseParticleSystem", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["BaseParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GPUParticleSystem", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["GPUParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Particle", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["Particle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleHelper", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["ParticleHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleSystem", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["ParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_IDoNeedToBeInTheBuild", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["_IDoNeedToBeInTheBuild"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticleSystemSet", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["ParticleSystemSet"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SolidParticle", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["SolidParticle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ModelShape", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["ModelShape"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthSortedParticle", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["DepthSortedParticle"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SolidParticleSystem", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["SolidParticleSystem"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubEmitterType", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["SubEmitterType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SubEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["SubEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoxParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["BoxParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConeParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["ConeParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["CylinderParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CylinderDirectedParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["CylinderDirectedParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HemisphericParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["HemisphericParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PointParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["PointParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["SphereParticleEmitter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SphereDirectedParticleEmitter", function() { return _Particles_index__WEBPACK_IMPORTED_MODULE_28__["SphereDirectedParticleEmitter"]; });

/* harmony import */ var _Physics_index__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./Physics/index */ "./Physics/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngine", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsEngine"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsEngineSceneComponent", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsEngineSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsHelper", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialExplosionEventOptions", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsRadialExplosionEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftEventOptions", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsUpdraftEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsVortexEventOptions", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsVortexEventOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsRadialImpulseFalloff", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsRadialImpulseFalloff"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsUpdraftMode", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsUpdraftMode"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsImpostor", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsImpostor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsJoint", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["PhysicsJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DistanceJoint", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["DistanceJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotorEnabledJoint", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["MotorEnabledJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HingeJoint", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["HingeJoint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Hinge2Joint", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["Hinge2Joint"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CannonJSPlugin", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["CannonJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AmmoJSPlugin", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["AmmoJSPlugin"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OimoJSPlugin", function() { return _Physics_index__WEBPACK_IMPORTED_MODULE_29__["OimoJSPlugin"]; });

/* harmony import */ var _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./PostProcesses/index */ "./PostProcesses/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AnaglyphPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["AnaglyphPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BlackAndWhitePostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["BlackAndWhitePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BloomEffect", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["BloomEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BloomMergePostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["BloomMergePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BlurPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["BlurPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ChromaticAberrationPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["ChromaticAberrationPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CircleOfConfusionPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["CircleOfConfusionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorCorrectionPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["ColorCorrectionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ConvolutionPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["ConvolutionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldBlurPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DepthOfFieldBlurPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffectBlurLevel", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DepthOfFieldEffectBlurLevel"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldEffect", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DepthOfFieldEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcessOptions", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DepthOfFieldMergePostProcessOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthOfFieldMergePostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DepthOfFieldMergePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DisplayPassPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DisplayPassPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtractHighlightsPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["ExtractHighlightsPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilterPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["FilterPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FxaaPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["FxaaPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GrainPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["GrainPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HighlightsPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["HighlightsPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageProcessingPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["ImageProcessingPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotionBlurPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["MotionBlurPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PassPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PassPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PassCubePostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PassCubePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessManager", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PostProcessManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RefractionPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["RefractionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SharpenPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["SharpenPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StereoscopicInterlacePostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["StereoscopicInterlacePostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TonemappingOperator", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["TonemappingOperator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TonemapPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["TonemapPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VolumetricLightScatteringPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["VolumetricLightScatteringPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRDistortionCorrectionPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["VRDistortionCorrectionPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VRMultiviewToSingleviewPostProcess", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["VRMultiviewToSingleviewPostProcess"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderEffect", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PostProcessRenderEffect"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipeline", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PostProcessRenderPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManager", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PostProcessRenderPipelineManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessRenderPipelineManagerSceneComponent", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["PostProcessRenderPipelineManagerSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DefaultRenderingPipeline", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["DefaultRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensRenderingPipeline", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["LensRenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAO2RenderingPipeline", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["SSAO2RenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SSAORenderingPipeline", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["SSAORenderingPipeline"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StandardRenderingPipeline", function() { return _PostProcesses_index__WEBPACK_IMPORTED_MODULE_30__["StandardRenderingPipeline"]; });

/* harmony import */ var _Probes_index__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./Probes/index */ "./Probes/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ReflectionProbe", function() { return _Probes_index__WEBPACK_IMPORTED_MODULE_31__["ReflectionProbe"]; });

/* harmony import */ var _Rendering_index__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./Rendering/index */ "./Rendering/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BoundingBoxRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["BoundingBoxRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["DepthRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DepthRendererSceneComponent", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["DepthRendererSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EdgesRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["EdgesRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LineEdgesRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["LineEdgesRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["GeometryBufferRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GeometryBufferRendererSceneComponent", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["GeometryBufferRendererSceneComponent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OutlineRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["OutlineRenderer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingGroup", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["RenderingGroup"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingGroupInfo", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["RenderingGroupInfo"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderingManager", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["RenderingManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "UtilityLayerRenderer", function() { return _Rendering_index__WEBPACK_IMPORTED_MODULE_32__["UtilityLayerRenderer"]; });

/* harmony import */ var _scene__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./scene */ "./scene.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Scene", function() { return _scene__WEBPACK_IMPORTED_MODULE_33__["Scene"]; });

/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./sceneComponent */ "./sceneComponent.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneComponentConstants", function() { return _sceneComponent__WEBPACK_IMPORTED_MODULE_34__["SceneComponentConstants"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Stage", function() { return _sceneComponent__WEBPACK_IMPORTED_MODULE_34__["Stage"]; });

/* harmony import */ var _Sprites_index__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./Sprites/index */ "./Sprites/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sprite", function() { return _Sprites_index__WEBPACK_IMPORTED_MODULE_35__["Sprite"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpriteManager", function() { return _Sprites_index__WEBPACK_IMPORTED_MODULE_35__["SpriteManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpritePackedManager", function() { return _Sprites_index__WEBPACK_IMPORTED_MODULE_35__["SpritePackedManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SpriteSceneComponent", function() { return _Sprites_index__WEBPACK_IMPORTED_MODULE_35__["SpriteSceneComponent"]; });

/* harmony import */ var _States_index__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! ./States/index */ "./States/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_AlphaState", function() { return _States_index__WEBPACK_IMPORTED_MODULE_36__["_AlphaState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_DepthCullingState", function() { return _States_index__WEBPACK_IMPORTED_MODULE_36__["_DepthCullingState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_StencilState", function() { return _States_index__WEBPACK_IMPORTED_MODULE_36__["_StencilState"]; });

/* harmony import */ var _Misc_index__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(/*! ./Misc/index */ "./Misc/index.ts");
/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AndOrNotEvaluator", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["AndOrNotEvaluator"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetTaskState", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["AssetTaskState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AbstractAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["AbstractAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetsProgressEvent", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["AssetsProgressEvent"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["MeshAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextFileAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["TextFileAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BinaryFileAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["BinaryFileAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ImageAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["ImageAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["TextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeTextureAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["CubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRCubeTextureAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["HDRCubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EquiRectangularCubeTextureAssetTask", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["EquiRectangularCubeTextureAssetTask"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AssetsManager", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["AssetsManager"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DDSTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["DDSTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expandToProperty", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["expandToProperty"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serialize", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serialize"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsTexture", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsTexture"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor3", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsColor3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsFresnelParameters", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsFresnelParameters"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector2", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsVector2"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsVector3", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsVector3"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsMeshReference", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsMeshReference"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColorCurves", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsColorCurves"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsColor4", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsColor4"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsImageProcessingConfiguration", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsImageProcessingConfiguration"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsQuaternion", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsQuaternion"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsMatrix", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsMatrix"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "serializeAsCameraReference", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["serializeAsCameraReference"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SerializationHelper", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SerializationHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Deferred", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Deferred"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EnvironmentTextureTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["EnvironmentTextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MeshExploder", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["MeshExploder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilesInput", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["FilesInput"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CubeMapToSphericalPolynomialTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["CubeMapToSphericalPolynomialTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KhronosTextureContainer", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["KhronosTextureContainer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EventState", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["EventState"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observer", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Observer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MultiObserver", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["MultiObserver"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Observable", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Observable"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerformanceMonitor", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PerformanceMonitor"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RollingAverage", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["RollingAverage"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PromisePolyfill", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PromisePolyfill"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SceneOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["TextureOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HardwareScalingOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["HardwareScalingOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ShadowsOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["ShadowsOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PostProcessesOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PostProcessesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LensFlaresOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["LensFlaresOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["CustomOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ParticlesOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["ParticlesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RenderTargetsOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["RenderTargetsOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MergeMeshesOptimization", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["MergeMeshesOptimization"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizerOptions", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SceneOptimizerOptions"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneOptimizer", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SceneOptimizer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SceneSerializer", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SceneSerializer"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SmartArray", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SmartArray"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SmartArrayNoDuplicate", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["SmartArrayNoDuplicate"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "StringDictionary", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["StringDictionary"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Tags", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Tags"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextureTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["TextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TGATools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["TGATools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Tools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Tools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "className", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["className"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AsyncLoop", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["AsyncLoop"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VideoRecorder", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["VideoRecorder"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "JoystickAxis", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["JoystickAxis"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualJoystick", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["VirtualJoystick"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WorkerPool", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["WorkerPool"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Logger", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Logger"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "_TypeStore", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["_TypeStore"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FilesInputStore", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["FilesInputStore"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DeepCopier", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["DeepCopier"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PivotTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PivotTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PrecisionDate", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PrecisionDate"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScreenshotTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["ScreenshotTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "WebRequest", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["WebRequest"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InspectableType", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["InspectableType"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "BRDFTextureTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["BRDFTextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RGBDTextureTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["RGBDTextureTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ColorGradient", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["ColorGradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Color3Gradient", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["Color3Gradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "FactorGradient", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["FactorGradient"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GradientHelper", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["GradientHelper"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PerfCounter", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PerfCounter"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RetryStrategy", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["RetryStrategy"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LoadFileError", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["LoadFileError"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "HDRTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["HDRTools"]; });

/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PanoramaToCubeMapTools", function() { return _Misc_index__WEBPACK_IMPORTED_MODULE_37__["PanoramaToCubeMapTools"]; });









































/***/ }),

/***/ "./node.ts":
/*!*****************!*\
  !*** ./node.ts ***!
  \*****************/
/*! exports provided: Node */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Node", function() { return Node; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Misc_decorators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Misc/decorators */ "./Misc/decorators.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Misc/devTools */ "./Misc/devTools.ts");






/**
 * Node is the basic class for all scene objects (Mesh, Light, Camera.)
 */
var Node = /** @class */ (function () {
    /**
     * Creates a new Node
     * @param name the name and id to be given to this node
     * @param scene the scene this node will be added to
     * @param addToRootNodes the node will be added to scene.rootNodes
     */
    function Node(name, scene, addToRootNodes) {
        if (scene === void 0) { scene = null; }
        if (addToRootNodes === void 0) { addToRootNodes = true; }
        /**
         * Gets or sets a string used to store user defined state for the node
         */
        this.state = "";
        /**
         * Gets or sets an object used to store user defined information for the node
         */
        this.metadata = null;
        /**
         * For internal use only. Please do not use.
         */
        this.reservedDataStore = null;
        /**
         * Gets or sets a boolean used to define if the node must be serialized
         */
        this.doNotSerialize = false;
        /** @hidden */
        this._isDisposed = false;
        /**
         * Gets a list of Animations associated with the node
         */
        this.animations = new Array();
        this._ranges = {};
        /**
         * Callback raised when the node is ready to be used
         */
        this.onReady = null;
        this._isEnabled = true;
        this._isParentEnabled = true;
        this._isReady = true;
        /** @hidden */
        this._currentRenderId = -1;
        this._parentUpdateId = -1;
        /** @hidden */
        this._childUpdateId = -1;
        /** @hidden */
        this._waitingParentId = null;
        /** @hidden */
        this._cache = {};
        this._parentNode = null;
        this._children = null;
        /** @hidden */
        this._worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        /** @hidden */
        this._worldMatrixDeterminant = 0;
        /** @hidden */
        this._worldMatrixDeterminantIsDirty = true;
        /** @hidden */
        this._sceneRootNodesIndex = -1;
        this._animationPropertiesOverride = null;
        /** @hidden */
        this._isNode = true;
        /**
        * An event triggered when the mesh is disposed
        */
        this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        this._onDisposeObserver = null;
        // Behaviors
        this._behaviors = new Array();
        this.name = name;
        this.id = name;
        this._scene = (scene || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_4__["EngineStore"].LastCreatedScene);
        this.uniqueId = this._scene.getUniqueId();
        this._initCache();
        if (addToRootNodes) {
            this.addToSceneRootNodes();
        }
    }
    /**
     * Add a new node constructor
     * @param type defines the type name of the node to construct
     * @param constructorFunc defines the constructor function
     */
    Node.AddNodeConstructor = function (type, constructorFunc) {
        this._NodeConstructors[type] = constructorFunc;
    };
    /**
     * Returns a node constructor based on type name
     * @param type defines the type name
     * @param name defines the new node name
     * @param scene defines the hosting scene
     * @param options defines optional options to transmit to constructors
     * @returns the new constructor or null
     */
    Node.Construct = function (type, name, scene, options) {
        var constructorFunc = this._NodeConstructors[type];
        if (!constructorFunc) {
            return null;
        }
        return constructorFunc(name, scene, options);
    };
    /**
     * Gets a boolean indicating if the node has been disposed
     * @returns true if the node was disposed
     */
    Node.prototype.isDisposed = function () {
        return this._isDisposed;
    };
    Object.defineProperty(Node.prototype, "parent", {
        get: function () {
            return this._parentNode;
        },
        /**
         * Gets or sets the parent of the node (without keeping the current position in the scene)
         * @see https://doc.babylonjs.com/how_to/parenting
         */
        set: function (parent) {
            if (this._parentNode === parent) {
                return;
            }
            var previousParentNode = this._parentNode;
            // Remove self from list of children of parent
            if (this._parentNode && this._parentNode._children !== undefined && this._parentNode._children !== null) {
                var index = this._parentNode._children.indexOf(this);
                if (index !== -1) {
                    this._parentNode._children.splice(index, 1);
                }
                if (!parent && !this._isDisposed) {
                    this.addToSceneRootNodes();
                }
            }
            // Store new parent
            this._parentNode = parent;
            // Add as child to new parent
            if (this._parentNode) {
                if (this._parentNode._children === undefined || this._parentNode._children === null) {
                    this._parentNode._children = new Array();
                }
                this._parentNode._children.push(this);
                if (!previousParentNode) {
                    this.removeFromSceneRootNodes();
                }
            }
            // Enabled state
            this._syncParentEnabledState();
        },
        enumerable: true,
        configurable: true
    });
    Node.prototype.addToSceneRootNodes = function () {
        if (this._sceneRootNodesIndex === -1) {
            this._sceneRootNodesIndex = this._scene.rootNodes.length;
            this._scene.rootNodes.push(this);
        }
    };
    Node.prototype.removeFromSceneRootNodes = function () {
        if (this._sceneRootNodesIndex !== -1) {
            var rootNodes = this._scene.rootNodes;
            var lastIdx = rootNodes.length - 1;
            rootNodes[this._sceneRootNodesIndex] = rootNodes[lastIdx];
            rootNodes[this._sceneRootNodesIndex]._sceneRootNodesIndex = this._sceneRootNodesIndex;
            this._scene.rootNodes.pop();
            this._sceneRootNodesIndex = -1;
        }
    };
    Object.defineProperty(Node.prototype, "animationPropertiesOverride", {
        /**
         * Gets or sets the animation properties override
         */
        get: function () {
            if (!this._animationPropertiesOverride) {
                return this._scene.animationPropertiesOverride;
            }
            return this._animationPropertiesOverride;
        },
        set: function (value) {
            this._animationPropertiesOverride = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets a string idenfifying the name of the class
     * @returns "Node" string
     */
    Node.prototype.getClassName = function () {
        return "Node";
    };
    Object.defineProperty(Node.prototype, "onDispose", {
        /**
         * Sets a callback that will be raised when the node will be disposed
         */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the scene of the node
     * @returns a scene
     */
    Node.prototype.getScene = function () {
        return this._scene;
    };
    /**
     * Gets the engine of the node
     * @returns a Engine
     */
    Node.prototype.getEngine = function () {
        return this._scene.getEngine();
    };
    /**
     * Attach a behavior to the node
     * @see http://doc.babylonjs.com/features/behaviour
     * @param behavior defines the behavior to attach
     * @param attachImmediately defines that the behavior must be attached even if the scene is still loading
     * @returns the current Node
     */
    Node.prototype.addBehavior = function (behavior, attachImmediately) {
        var _this = this;
        if (attachImmediately === void 0) { attachImmediately = false; }
        var index = this._behaviors.indexOf(behavior);
        if (index !== -1) {
            return this;
        }
        behavior.init();
        if (this._scene.isLoading && !attachImmediately) {
            // We defer the attach when the scene will be loaded
            this._scene.onDataLoadedObservable.addOnce(function () {
                behavior.attach(_this);
            });
        }
        else {
            behavior.attach(this);
        }
        this._behaviors.push(behavior);
        return this;
    };
    /**
     * Remove an attached behavior
     * @see http://doc.babylonjs.com/features/behaviour
     * @param behavior defines the behavior to attach
     * @returns the current Node
     */
    Node.prototype.removeBehavior = function (behavior) {
        var index = this._behaviors.indexOf(behavior);
        if (index === -1) {
            return this;
        }
        this._behaviors[index].detach();
        this._behaviors.splice(index, 1);
        return this;
    };
    Object.defineProperty(Node.prototype, "behaviors", {
        /**
         * Gets the list of attached behaviors
         * @see http://doc.babylonjs.com/features/behaviour
         */
        get: function () {
            return this._behaviors;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets an attached behavior by name
     * @param name defines the name of the behavior to look for
     * @see http://doc.babylonjs.com/features/behaviour
     * @returns null if behavior was not found else the requested behavior
     */
    Node.prototype.getBehaviorByName = function (name) {
        for (var _i = 0, _a = this._behaviors; _i < _a.length; _i++) {
            var behavior = _a[_i];
            if (behavior.name === name) {
                return behavior;
            }
        }
        return null;
    };
    /**
     * Returns the latest update of the World matrix
     * @returns a Matrix
     */
    Node.prototype.getWorldMatrix = function () {
        if (this._currentRenderId !== this._scene.getRenderId()) {
            this.computeWorldMatrix();
        }
        return this._worldMatrix;
    };
    /** @hidden */
    Node.prototype._getWorldMatrixDeterminant = function () {
        if (this._worldMatrixDeterminantIsDirty) {
            this._worldMatrixDeterminantIsDirty = false;
            this._worldMatrixDeterminant = this._worldMatrix.determinant();
        }
        return this._worldMatrixDeterminant;
    };
    Object.defineProperty(Node.prototype, "worldMatrixFromCache", {
        /**
         * Returns directly the latest state of the mesh World matrix.
         * A Matrix is returned.
         */
        get: function () {
            return this._worldMatrix;
        },
        enumerable: true,
        configurable: true
    });
    // override it in derived class if you add new variables to the cache
    // and call the parent class method
    /** @hidden */
    Node.prototype._initCache = function () {
        this._cache = {};
        this._cache.parent = undefined;
    };
    /** @hidden */
    Node.prototype.updateCache = function (force) {
        if (!force && this.isSynchronized()) {
            return;
        }
        this._cache.parent = this.parent;
        this._updateCache();
    };
    /** @hidden */
    Node.prototype._getActionManagerForTrigger = function (trigger, initialCall) {
        if (initialCall === void 0) { initialCall = true; }
        if (!this.parent) {
            return null;
        }
        return this.parent._getActionManagerForTrigger(trigger, false);
    };
    // override it in derived class if you add new variables to the cache
    // and call the parent class method if !ignoreParentClass
    /** @hidden */
    Node.prototype._updateCache = function (ignoreParentClass) {
    };
    // override it in derived class if you add new variables to the cache
    /** @hidden */
    Node.prototype._isSynchronized = function () {
        return true;
    };
    /** @hidden */
    Node.prototype._markSyncedWithParent = function () {
        if (this._parentNode) {
            this._parentUpdateId = this._parentNode._childUpdateId;
        }
    };
    /** @hidden */
    Node.prototype.isSynchronizedWithParent = function () {
        if (!this._parentNode) {
            return true;
        }
        if (this._parentUpdateId !== this._parentNode._childUpdateId) {
            return false;
        }
        return this._parentNode.isSynchronized();
    };
    /** @hidden */
    Node.prototype.isSynchronized = function () {
        if (this._cache.parent != this._parentNode) {
            this._cache.parent = this._parentNode;
            return false;
        }
        if (this._parentNode && !this.isSynchronizedWithParent()) {
            return false;
        }
        return this._isSynchronized();
    };
    /**
     * Is this node ready to be used/rendered
     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
     * @return true if the node is ready
     */
    Node.prototype.isReady = function (completeCheck) {
        if (completeCheck === void 0) { completeCheck = false; }
        return this._isReady;
    };
    /**
     * Is this node enabled?
     * If the node has a parent, all ancestors will be checked and false will be returned if any are false (not enabled), otherwise will return true
     * @param checkAncestors indicates if this method should check the ancestors. The default is to check the ancestors. If set to false, the method will return the value of this node without checking ancestors
     * @return whether this node (and its parent) is enabled
     */
    Node.prototype.isEnabled = function (checkAncestors) {
        if (checkAncestors === void 0) { checkAncestors = true; }
        if (checkAncestors === false) {
            return this._isEnabled;
        }
        if (!this._isEnabled) {
            return false;
        }
        return this._isParentEnabled;
    };
    /** @hidden */
    Node.prototype._syncParentEnabledState = function () {
        this._isParentEnabled = this._parentNode ? this._parentNode.isEnabled() : true;
        if (this._children) {
            this._children.forEach(function (c) {
                c._syncParentEnabledState(); // Force children to update accordingly
            });
        }
    };
    /**
     * Set the enabled state of this node
     * @param value defines the new enabled state
     */
    Node.prototype.setEnabled = function (value) {
        this._isEnabled = value;
        this._syncParentEnabledState();
    };
    /**
     * Is this node a descendant of the given node?
     * The function will iterate up the hierarchy until the ancestor was found or no more parents defined
     * @param ancestor defines the parent node to inspect
     * @returns a boolean indicating if this node is a descendant of the given node
     */
    Node.prototype.isDescendantOf = function (ancestor) {
        if (this.parent) {
            if (this.parent === ancestor) {
                return true;
            }
            return this.parent.isDescendantOf(ancestor);
        }
        return false;
    };
    /** @hidden */
    Node.prototype._getDescendants = function (results, directDescendantsOnly, predicate) {
        if (directDescendantsOnly === void 0) { directDescendantsOnly = false; }
        if (!this._children) {
            return;
        }
        for (var index = 0; index < this._children.length; index++) {
            var item = this._children[index];
            if (!predicate || predicate(item)) {
                results.push(item);
            }
            if (!directDescendantsOnly) {
                item._getDescendants(results, false, predicate);
            }
        }
    };
    /**
     * Will return all nodes that have this node as ascendant
     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
     * @return all children nodes of all types
     */
    Node.prototype.getDescendants = function (directDescendantsOnly, predicate) {
        var results = new Array();
        this._getDescendants(results, directDescendantsOnly, predicate);
        return results;
    };
    /**
     * Get all child-meshes of this node
     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: false)
     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
     * @returns an array of AbstractMesh
     */
    Node.prototype.getChildMeshes = function (directDescendantsOnly, predicate) {
        var results = [];
        this._getDescendants(results, directDescendantsOnly, function (node) {
            return ((!predicate || predicate(node)) && (node.cullingStrategy !== undefined));
        });
        return results;
    };
    /**
     * Get all direct children of this node
     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered (Default: true)
     * @returns an array of Node
     */
    Node.prototype.getChildren = function (predicate, directDescendantsOnly) {
        if (directDescendantsOnly === void 0) { directDescendantsOnly = true; }
        return this.getDescendants(directDescendantsOnly, predicate);
    };
    /** @hidden */
    Node.prototype._setReady = function (state) {
        if (state === this._isReady) {
            return;
        }
        if (!state) {
            this._isReady = false;
            return;
        }
        if (this.onReady) {
            this.onReady(this);
        }
        this._isReady = true;
    };
    /**
     * Get an animation by name
     * @param name defines the name of the animation to look for
     * @returns null if not found else the requested animation
     */
    Node.prototype.getAnimationByName = function (name) {
        for (var i = 0; i < this.animations.length; i++) {
            var animation = this.animations[i];
            if (animation.name === name) {
                return animation;
            }
        }
        return null;
    };
    /**
     * Creates an animation range for this node
     * @param name defines the name of the range
     * @param from defines the starting key
     * @param to defines the end key
     */
    Node.prototype.createAnimationRange = function (name, from, to) {
        // check name not already in use
        if (!this._ranges[name]) {
            this._ranges[name] = Node._AnimationRangeFactory(name, from, to);
            for (var i = 0, nAnimations = this.animations.length; i < nAnimations; i++) {
                if (this.animations[i]) {
                    this.animations[i].createRange(name, from, to);
                }
            }
        }
    };
    /**
     * Delete a specific animation range
     * @param name defines the name of the range to delete
     * @param deleteFrames defines if animation frames from the range must be deleted as well
     */
    Node.prototype.deleteAnimationRange = function (name, deleteFrames) {
        if (deleteFrames === void 0) { deleteFrames = true; }
        for (var i = 0, nAnimations = this.animations.length; i < nAnimations; i++) {
            if (this.animations[i]) {
                this.animations[i].deleteRange(name, deleteFrames);
            }
        }
        this._ranges[name] = null; // said much faster than 'delete this._range[name]'
    };
    /**
     * Get an animation range by name
     * @param name defines the name of the animation range to look for
     * @returns null if not found else the requested animation range
     */
    Node.prototype.getAnimationRange = function (name) {
        return this._ranges[name];
    };
    /**
     * Gets the list of all animation ranges defined on this node
     * @returns an array
     */
    Node.prototype.getAnimationRanges = function () {
        var animationRanges = [];
        var name;
        for (name in this._ranges) {
            animationRanges.push(this._ranges[name]);
        }
        return animationRanges;
    };
    /**
     * Will start the animation sequence
     * @param name defines the range frames for animation sequence
     * @param loop defines if the animation should loop (false by default)
     * @param speedRatio defines the speed factor in which to run the animation (1 by default)
     * @param onAnimationEnd defines a function to be executed when the animation ended (undefined by default)
     * @returns the object created for this animation. If range does not exist, it will return null
     */
    Node.prototype.beginAnimation = function (name, loop, speedRatio, onAnimationEnd) {
        var range = this.getAnimationRange(name);
        if (!range) {
            return null;
        }
        return this._scene.beginAnimation(this, range.from, range.to, loop, speedRatio, onAnimationEnd);
    };
    /**
     * Serialize animation ranges into a JSON compatible object
     * @returns serialization object
     */
    Node.prototype.serializeAnimationRanges = function () {
        var serializationRanges = [];
        for (var name in this._ranges) {
            var localRange = this._ranges[name];
            if (!localRange) {
                continue;
            }
            var range = {};
            range.name = name;
            range.from = localRange.from;
            range.to = localRange.to;
            serializationRanges.push(range);
        }
        return serializationRanges;
    };
    /**
     * Computes the world matrix of the node
     * @param force defines if the cache version should be invalidated forcing the world matrix to be created from scratch
     * @returns the world matrix
     */
    Node.prototype.computeWorldMatrix = function (force) {
        if (!this._worldMatrix) {
            this._worldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Matrix"].Identity();
        }
        return this._worldMatrix;
    };
    /**
     * Releases resources associated with this node.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    Node.prototype.dispose = function (doNotRecurse, disposeMaterialAndTextures) {
        if (disposeMaterialAndTextures === void 0) { disposeMaterialAndTextures = false; }
        this._isDisposed = true;
        if (!doNotRecurse) {
            var nodes = this.getDescendants(true);
            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
                var node = nodes_1[_i];
                node.dispose(doNotRecurse, disposeMaterialAndTextures);
            }
        }
        if (!this.parent) {
            this.removeFromSceneRootNodes();
        }
        else {
            this.parent = null;
        }
        // Callback
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
        // Behaviors
        for (var _a = 0, _b = this._behaviors; _a < _b.length; _a++) {
            var behavior = _b[_a];
            behavior.detach();
        }
        this._behaviors = [];
    };
    /**
     * Parse animation range data from a serialization object and store them into a given node
     * @param node defines where to store the animation ranges
     * @param parsedNode defines the serialization object to read data from
     * @param scene defines the hosting scene
     */
    Node.ParseAnimationRanges = function (node, parsedNode, scene) {
        if (parsedNode.ranges) {
            for (var index = 0; index < parsedNode.ranges.length; index++) {
                var data = parsedNode.ranges[index];
                node.createAnimationRange(data.name, data.from, data.to);
            }
        }
    };
    /**
 * Return the minimum and maximum world vectors of the entire hierarchy under current node
 * @param includeDescendants Include bounding info from descendants as well (true by default)
 * @param predicate defines a callback function that can be customize to filter what meshes should be included in the list used to compute the bounding vectors
 * @returns the new bounding vectors
 */
    Node.prototype.getHierarchyBoundingVectors = function (includeDescendants, predicate) {
        if (includeDescendants === void 0) { includeDescendants = true; }
        if (predicate === void 0) { predicate = null; }
        // Ensures that all world matrix will be recomputed.
        this.getScene().incrementRenderId();
        this.computeWorldMatrix(true);
        var min;
        var max;
        var thisAbstractMesh = this;
        if (thisAbstractMesh.getBoundingInfo && thisAbstractMesh.subMeshes) {
            // If this is an abstract mesh get its bounding info
            var boundingInfo = thisAbstractMesh.getBoundingInfo();
            min = boundingInfo.boundingBox.minimumWorld.clone();
            max = boundingInfo.boundingBox.maximumWorld.clone();
        }
        else {
            min = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
            max = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
        }
        if (includeDescendants) {
            var descendants = this.getDescendants(false);
            for (var _i = 0, descendants_1 = descendants; _i < descendants_1.length; _i++) {
                var descendant = descendants_1[_i];
                var childMesh = descendant;
                childMesh.computeWorldMatrix(true);
                // Filters meshes based on custom predicate function.
                if (predicate && !predicate(childMesh)) {
                    continue;
                }
                //make sure we have the needed params to get mix and max
                if (!childMesh.getBoundingInfo || childMesh.getTotalVertices() === 0) {
                    continue;
                }
                var childBoundingInfo = childMesh.getBoundingInfo();
                var boundingBox = childBoundingInfo.boundingBox;
                var minBox = boundingBox.minimumWorld;
                var maxBox = boundingBox.maximumWorld;
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CheckExtends(minBox, min, max);
                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].CheckExtends(maxBox, min, max);
            }
        }
        return {
            min: min,
            max: max
        };
    };
    /** @hidden */
    Node._AnimationRangeFactory = function (name, from, to) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_5__["_DevTools"].WarnImport("AnimationRange");
    };
    Node._NodeConstructors = {};
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], Node.prototype, "name", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], Node.prototype, "id", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], Node.prototype, "uniqueId", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], Node.prototype, "state", void 0);
    tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"]([
        Object(_Misc_decorators__WEBPACK_IMPORTED_MODULE_2__["serialize"])()
    ], Node.prototype, "metadata", void 0);
    return Node;
}());



/***/ }),

/***/ "./scene.ts":
/*!******************!*\
  !*** ./scene.ts ***!
  \******************/
/*! exports provided: Scene */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Scene", function() { return Scene; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");
/* harmony import */ var _Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Misc/tools */ "./Misc/tools.ts");
/* harmony import */ var _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Misc/precisionDate */ "./Misc/precisionDate.ts");
/* harmony import */ var _Misc_observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Misc/observable */ "./Misc/observable.ts");
/* harmony import */ var _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Misc/smartArray */ "./Misc/smartArray.ts");
/* harmony import */ var _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Misc/stringDictionary */ "./Misc/stringDictionary.ts");
/* harmony import */ var _Misc_tags__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Misc/tags */ "./Misc/tags.ts");
/* harmony import */ var _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Maths/math.vector */ "./Maths/math.vector.ts");
/* harmony import */ var _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./Meshes/transformNode */ "./Meshes/transformNode.ts");
/* harmony import */ var _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./Meshes/abstractMesh */ "./Meshes/abstractMesh.ts");
/* harmony import */ var _Cameras_camera__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./Cameras/camera */ "./Cameras/camera.ts");
/* harmony import */ var _abstractScene__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./abstractScene */ "./abstractScene.ts");
/* harmony import */ var _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./Materials/imageProcessingConfiguration */ "./Materials/imageProcessingConfiguration.ts");
/* harmony import */ var _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Materials/uniformBuffer */ "./Materials/uniformBuffer.ts");
/* harmony import */ var _Lights_light__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./Lights/light */ "./Lights/light.ts");
/* harmony import */ var _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./Collisions/pickingInfo */ "./Collisions/pickingInfo.ts");
/* harmony import */ var _Actions_actionEvent__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./Actions/actionEvent */ "./Actions/actionEvent.ts");
/* harmony import */ var _PostProcesses_postProcessManager__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./PostProcesses/postProcessManager */ "./PostProcesses/postProcessManager.ts");
/* harmony import */ var _Rendering_renderingManager__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Rendering/renderingManager */ "./Rendering/renderingManager.ts");
/* harmony import */ var _sceneComponent__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./sceneComponent */ "./sceneComponent.ts");
/* harmony import */ var _Engines_constants__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./Engines/constants */ "./Engines/constants.ts");
/* harmony import */ var _Misc_domManagement__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./Misc/domManagement */ "./Misc/domManagement.ts");
/* harmony import */ var _Misc_logger__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./Misc/logger */ "./Misc/logger.ts");
/* harmony import */ var _Engines_engineStore__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./Engines/engineStore */ "./Engines/engineStore.ts");
/* harmony import */ var _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./Misc/devTools */ "./Misc/devTools.ts");
/* harmony import */ var _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./Inputs/scene.inputManager */ "./Inputs/scene.inputManager.ts");
/* harmony import */ var _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./Misc/perfCounter */ "./Misc/perfCounter.ts");
/* harmony import */ var _Maths_math_color__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./Maths/math.color */ "./Maths/math.color.ts");
/* harmony import */ var _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./Maths/math.frustum */ "./Maths/math.frustum.ts");
/* harmony import */ var _Misc_uniqueIdGenerator__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./Misc/uniqueIdGenerator */ "./Misc/uniqueIdGenerator.ts");






























/**
 * Represents a scene to be rendered by the engine.
 * @see http://doc.babylonjs.com/features/scene
 */
var Scene = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Scene, _super);
    /**
     * Creates a new Scene
     * @param engine defines the engine to use to render this scene
     * @param options defines the scene options
     */
    function Scene(engine, options) {
        var _this = _super.call(this) || this;
        // Members
        /** @hidden */
        _this._inputManager = new _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"](_this);
        /** Define this parameter if you are using multiple cameras and you want to specify which one should be used for pointer position */
        _this.cameraToUseForPointers = null;
        /** @hidden */
        _this._isScene = true;
        /**
         * Gets or sets a boolean that indicates if the scene must clear the render buffer before rendering a frame
         */
        _this.autoClear = true;
        /**
         * Gets or sets a boolean that indicates if the scene must clear the depth and stencil buffers before rendering a frame
         */
        _this.autoClearDepthAndStencil = true;
        /**
         * Defines the color used to clear the render buffer (Default is (0.2, 0.2, 0.3, 1.0))
         */
        _this.clearColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_27__["Color4"](0.2, 0.2, 0.3, 1.0);
        /**
         * Defines the color used to simulate the ambient color (Default is (0, 0, 0))
         */
        _this.ambientColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_27__["Color3"](0, 0, 0);
        /** @hidden */
        _this._environmentIntensity = 1;
        _this._forceWireframe = false;
        _this._forcePointsCloud = false;
        /**
         * Gets or sets a boolean indicating if animations are enabled
         */
        _this.animationsEnabled = true;
        _this._animationPropertiesOverride = null;
        /**
         * Gets or sets a boolean indicating if a constant deltatime has to be used
         * This is mostly useful for testing purposes when you do not want the animations to scale with the framerate
         */
        _this.useConstantAnimationDeltaTime = false;
        /**
         * Gets or sets a boolean indicating if the scene must keep the meshUnderPointer property updated
         * Please note that it requires to run a ray cast through the scene on every frame
         */
        _this.constantlyUpdateMeshUnderPointer = false;
        /**
         * Defines the HTML cursor to use when hovering over interactive elements
         */
        _this.hoverCursor = "pointer";
        /**
         * Defines the HTML default cursor to use (empty by default)
         */
        _this.defaultCursor = "";
        /**
         * This is used to call preventDefault() on pointer down
         * in order to block unwanted artifacts like system double clicks
         */
        _this.preventDefaultOnPointerDown = true;
        /**
         * This is used to call preventDefault() on pointer up
         * in order to block unwanted artifacts like system double clicks
         */
        _this.preventDefaultOnPointerUp = true;
        // Metadata
        /**
         * Gets or sets user defined metadata
         */
        _this.metadata = null;
        /**
         * For internal use only. Please do not use.
         */
        _this.reservedDataStore = null;
        /**
         * Use this array to add regular expressions used to disable offline support for specific urls
         */
        _this.disableOfflineSupportExceptionRules = new Array();
        /**
        * An event triggered when the scene is disposed.
        */
        _this.onDisposeObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        _this._onDisposeObserver = null;
        /**
        * An event triggered before rendering the scene (right after animations and physics)
        */
        _this.onBeforeRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        _this._onBeforeRenderObserver = null;
        /**
        * An event triggered after rendering the scene
        */
        _this.onAfterRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered after rendering the scene for an active camera (When scene.render is called this will be called after each camera)
        */
        _this.onAfterRenderCameraObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        _this._onAfterRenderObserver = null;
        /**
        * An event triggered before animating the scene
        */
        _this.onBeforeAnimationsObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered after animations processing
        */
        _this.onAfterAnimationsObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered before draw calls are ready to be sent
        */
        _this.onBeforeDrawPhaseObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered after draw calls have been sent
        */
        _this.onAfterDrawPhaseObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when the scene is ready
        */
        _this.onReadyObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered before rendering a camera
        */
        _this.onBeforeCameraRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        _this._onBeforeCameraRenderObserver = null;
        /**
        * An event triggered after rendering a camera
        */
        _this.onAfterCameraRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        _this._onAfterCameraRenderObserver = null;
        /**
        * An event triggered when active meshes evaluation is about to start
        */
        _this.onBeforeActiveMeshesEvaluationObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when active meshes evaluation is done
        */
        _this.onAfterActiveMeshesEvaluationObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when particles rendering is about to start
        * Note: This event can be trigger more than once per frame (because particles can be rendered by render target textures as well)
        */
        _this.onBeforeParticlesRenderingObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when particles rendering is done
        * Note: This event can be trigger more than once per frame (because particles can be rendered by render target textures as well)
        */
        _this.onAfterParticlesRenderingObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when SceneLoader.Append or SceneLoader.Load or SceneLoader.ImportMesh were successfully executed
        */
        _this.onDataLoadedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a camera is created
        */
        _this.onNewCameraAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a camera is removed
        */
        _this.onCameraRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a light is created
        */
        _this.onNewLightAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a light is removed
        */
        _this.onLightRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a geometry is created
        */
        _this.onNewGeometryAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a geometry is removed
        */
        _this.onGeometryRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a transform node is created
        */
        _this.onNewTransformNodeAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a transform node is removed
        */
        _this.onTransformNodeRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a mesh is created
        */
        _this.onNewMeshAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a mesh is removed
        */
        _this.onMeshRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An event triggered when a skeleton is created
         */
        _this.onNewSkeletonAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a skeleton is removed
        */
        _this.onSkeletonRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a material is created
        */
        _this.onNewMaterialAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a material is removed
        */
        _this.onMaterialRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a texture is created
        */
        _this.onNewTextureAddedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when a texture is removed
        */
        _this.onTextureRemovedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when render targets are about to be rendered
        * Can happen multiple times per frame.
        */
        _this.onBeforeRenderTargetsRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered when render targets were rendered.
        * Can happen multiple times per frame.
        */
        _this.onAfterRenderTargetsRenderObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered before calculating deterministic simulation step
        */
        _this.onBeforeStepObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
        * An event triggered after calculating deterministic simulation step
        */
        _this.onAfterStepObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * An event triggered when the activeCamera property is updated
         */
        _this.onActiveCameraChanged = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * This Observable will be triggered before rendering each renderingGroup of each rendered camera.
         * The RenderinGroupInfo class contains all the information about the context in which the observable is called
         * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)
         */
        _this.onBeforeRenderingGroupObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * This Observable will be triggered after rendering each renderingGroup of each rendered camera.
         * The RenderinGroupInfo class contains all the information about the context in which the observable is called
         * If you wish to register an Observer only for a given set of renderingGroup, use the mask with a combination of the renderingGroup index elevated to the power of two (1 for renderingGroup 0, 2 for renderingrOup1, 4 for 2 and 8 for 3)
         */
        _this.onAfterRenderingGroupObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * This Observable will when a mesh has been imported into the scene.
         */
        _this.onMeshImportedObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        // Animations
        /** @hidden */
        _this._registeredForLateAnimationBindings = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArrayNoDuplicate"](256);
        /**
         * This observable event is triggered when any ponter event is triggered. It is registered during Scene.attachControl() and it is called BEFORE the 3D engine process anything (mesh/sprite picking for instance).
         * You have the possibility to skip the process and the call to onPointerObservable by setting PointerInfoPre.skipOnPointerObservable to true
         */
        _this.onPrePointerObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Observable event triggered each time an input event is received from the rendering canvas
         */
        _this.onPointerObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        // Keyboard
        /**
         * This observable event is triggered when any keyboard event si raised and registered during Scene.attachControl()
         * You have the possibility to skip the process and the call to onKeyboardObservable by setting KeyboardInfoPre.skipOnPointerObservable to true
         */
        _this.onPreKeyboardObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        /**
         * Observable event triggered each time an keyboard event is received from the hosting window
         */
        _this.onKeyboardObservable = new _Misc_observable__WEBPACK_IMPORTED_MODULE_3__["Observable"]();
        // Coordinates system
        _this._useRightHandedSystem = false;
        // Deterministic lockstep
        _this._timeAccumulator = 0;
        _this._currentStepId = 0;
        _this._currentInternalStep = 0;
        // Fog
        _this._fogEnabled = true;
        _this._fogMode = Scene.FOGMODE_NONE;
        /**
        * Gets or sets the fog color to use
        * @see http://doc.babylonjs.com/babylon101/environment#fog
        * (Default is Color3(0.2, 0.2, 0.3))
        */
        _this.fogColor = new _Maths_math_color__WEBPACK_IMPORTED_MODULE_27__["Color3"](0.2, 0.2, 0.3);
        /**
        * Gets or sets the fog density to use
        * @see http://doc.babylonjs.com/babylon101/environment#fog
        * (Default is 0.1)
        */
        _this.fogDensity = 0.1;
        /**
        * Gets or sets the fog start distance to use
        * @see http://doc.babylonjs.com/babylon101/environment#fog
        * (Default is 0)
        */
        _this.fogStart = 0;
        /**
        * Gets or sets the fog end distance to use
        * @see http://doc.babylonjs.com/babylon101/environment#fog
        * (Default is 1000)
        */
        _this.fogEnd = 1000.0;
        // Lights
        _this._shadowsEnabled = true;
        _this._lightsEnabled = true;
        /** All of the active cameras added to this scene. */
        _this.activeCameras = new Array();
        // Textures
        _this._texturesEnabled = true;
        // Particles
        /**
        * Gets or sets a boolean indicating if particles are enabled on this scene
        */
        _this.particlesEnabled = true;
        // Sprites
        /**
        * Gets or sets a boolean indicating if sprites are enabled on this scene
        */
        _this.spritesEnabled = true;
        // Skeletons
        _this._skeletonsEnabled = true;
        // Lens flares
        /**
        * Gets or sets a boolean indicating if lens flares are enabled on this scene
        */
        _this.lensFlaresEnabled = true;
        // Collisions
        /**
        * Gets or sets a boolean indicating if collisions are enabled on this scene
        * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
        */
        _this.collisionsEnabled = true;
        /**
         * Defines the gravity applied to this scene (used only for collisions)
         * @see http://doc.babylonjs.com/babylon101/cameras,_mesh_collisions_and_gravity
         */
        _this.gravity = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"](0, -9.807, 0);
        // Postprocesses
        /**
        * Gets or sets a boolean indicating if postprocesses are enabled on this scene
        */
        _this.postProcessesEnabled = true;
        /**
         * The list of postprocesses added to the scene
         */
        _this.postProcesses = new Array();
        // Customs render targets
        /**
        * Gets or sets a boolean indicating if render targets are enabled on this scene
        */
        _this.renderTargetsEnabled = true;
        /**
        * Gets or sets a boolean indicating if next render targets must be dumped as image for debugging purposes
        * We recommend not using it and instead rely on Spector.js: http://spector.babylonjs.com
        */
        _this.dumpNextRenderTargets = false;
        /**
         * The list of user defined render targets added to the scene
         */
        _this.customRenderTargets = new Array();
        /**
         * Gets the list of meshes imported to the scene through SceneLoader
         */
        _this.importedMeshesFiles = new Array();
        // Probes
        /**
        * Gets or sets a boolean indicating if probes are enabled on this scene
        */
        _this.probesEnabled = true;
        _this._meshesForIntersections = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArrayNoDuplicate"](256);
        // Procedural textures
        /**
        * Gets or sets a boolean indicating if procedural textures are enabled on this scene
        */
        _this.proceduralTexturesEnabled = true;
        // Performance counters
        _this._totalVertices = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_26__["PerfCounter"]();
        /** @hidden */
        _this._activeIndices = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_26__["PerfCounter"]();
        /** @hidden */
        _this._activeParticles = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_26__["PerfCounter"]();
        /** @hidden */
        _this._activeBones = new _Misc_perfCounter__WEBPACK_IMPORTED_MODULE_26__["PerfCounter"]();
        /** @hidden */
        _this._animationTime = 0;
        /**
         * Gets or sets a general scale for animation speed
         * @see https://www.babylonjs-playground.com/#IBU2W7#3
         */
        _this.animationTimeScale = 1;
        _this._renderId = 0;
        _this._frameId = 0;
        _this._executeWhenReadyTimeoutId = -1;
        _this._intermediateRendering = false;
        _this._viewUpdateFlag = -1;
        _this._projectionUpdateFlag = -1;
        /** @hidden */
        _this._toBeDisposed = new Array(256);
        _this._activeRequests = new Array();
        /** @hidden */
        _this._pendingData = new Array();
        _this._isDisposed = false;
        /**
         * Gets or sets a boolean indicating that all submeshes of active meshes must be rendered
         * Use this boolean to avoid computing frustum clipping on submeshes (This could help when you are CPU bound)
         */
        _this.dispatchAllSubMeshesOfActiveMeshes = false;
        _this._activeMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArray"](256);
        _this._processedMaterials = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArray"](256);
        _this._renderTargets = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArrayNoDuplicate"](256);
        /** @hidden */
        _this._activeParticleSystems = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArray"](256);
        _this._activeSkeletons = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArrayNoDuplicate"](32);
        _this._softwareSkinnedMeshes = new _Misc_smartArray__WEBPACK_IMPORTED_MODULE_4__["SmartArrayNoDuplicate"](32);
        /** @hidden */
        _this._activeAnimatables = new Array();
        _this._transformMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Matrix"].Zero();
        /**
         * Gets or sets a boolean indicating if lights must be sorted by priority (off by default)
         * This is useful if there are more lights that the maximum simulteanous authorized
         */
        _this.requireLightSorting = false;
        /**
         * @hidden
         * Backing store of defined scene components.
         */
        _this._components = [];
        /**
         * @hidden
         * Backing store of defined scene components.
         */
        _this._serializableComponents = [];
        /**
         * List of components to register on the next registration step.
         */
        _this._transientComponents = [];
        /**
         * @hidden
         * Defines the actions happening before camera updates.
         */
        _this._beforeCameraUpdateStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening before clear the canvas.
         */
        _this._beforeClearStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions when collecting render targets for the frame.
         */
        _this._gatherRenderTargetsStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening for one camera in the frame.
         */
        _this._gatherActiveCameraRenderTargetsStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening during the per mesh ready checks.
         */
        _this._isReadyForMeshStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening before evaluate active mesh checks.
         */
        _this._beforeEvaluateActiveMeshStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening during the evaluate sub mesh checks.
         */
        _this._evaluateSubMeshStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening during the active mesh stage.
         */
        _this._activeMeshStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening during the per camera render target step.
         */
        _this._cameraDrawRenderTargetStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just before the active camera is drawing.
         */
        _this._beforeCameraDrawStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just before a render target is drawing.
         */
        _this._beforeRenderTargetDrawStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just before a rendering group is drawing.
         */
        _this._beforeRenderingGroupDrawStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just before a mesh is drawing.
         */
        _this._beforeRenderingMeshStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just after a mesh has been drawn.
         */
        _this._afterRenderingMeshStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just after a rendering group has been drawn.
         */
        _this._afterRenderingGroupDrawStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just after the active camera has been drawn.
         */
        _this._afterCameraDrawStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just after a render target has been drawn.
         */
        _this._afterRenderTargetDrawStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening just after rendering all cameras and computing intersections.
         */
        _this._afterRenderStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening when a pointer move event happens.
         */
        _this._pointerMoveStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening when a pointer down event happens.
         */
        _this._pointerDownStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * @hidden
         * Defines the actions happening when a pointer up event happens.
         */
        _this._pointerUpStage = _sceneComponent__WEBPACK_IMPORTED_MODULE_19__["Stage"].Create();
        /**
         * an optional map from Geometry Id to Geometry index in the 'geometries' array
         */
        _this.geometriesByUniqueId = null;
        _this._defaultMeshCandidates = {
            data: [],
            length: 0
        };
        _this._defaultSubMeshCandidates = {
            data: [],
            length: 0
        };
        _this._preventFreeActiveMeshesAndRenderingGroups = false;
        _this._activeMeshesFrozen = false;
        /** @hidden */
        _this._allowPostProcessClearColor = true;
        /**
         * User updatable function that will return a deterministic frame time when engine is in deterministic lock step mode
         */
        _this.getDeterministicFrameTime = function () {
            return 1000.0 / 60.0; // frame time in ms
        };
        _this._blockMaterialDirtyMechanism = false;
        _this._engine = engine || _Engines_engineStore__WEBPACK_IMPORTED_MODULE_23__["EngineStore"].LastCreatedEngine;
        if (!options || !options.virtual) {
            _Engines_engineStore__WEBPACK_IMPORTED_MODULE_23__["EngineStore"]._LastCreatedScene = _this;
            _this._engine.scenes.push(_this);
        }
        _this._uid = null;
        _this._renderingManager = new _Rendering_renderingManager__WEBPACK_IMPORTED_MODULE_18__["RenderingManager"](_this);
        if (_PostProcesses_postProcessManager__WEBPACK_IMPORTED_MODULE_17__["PostProcessManager"]) {
            _this.postProcessManager = new _PostProcesses_postProcessManager__WEBPACK_IMPORTED_MODULE_17__["PostProcessManager"](_this);
        }
        if (_Misc_domManagement__WEBPACK_IMPORTED_MODULE_21__["DomManagement"].IsWindowObjectExist()) {
            _this.attachControl();
        }
        // Uniform Buffer
        _this._createUbo();
        // Default Image processing definition
        if (_Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_12__["ImageProcessingConfiguration"]) {
            _this._imageProcessingConfiguration = new _Materials_imageProcessingConfiguration__WEBPACK_IMPORTED_MODULE_12__["ImageProcessingConfiguration"]();
        }
        _this.setDefaultCandidateProviders();
        if (options && options.useGeometryUniqueIdsMap === true) {
            _this.geometriesByUniqueId = {};
        }
        _this.useMaterialMeshMap = options && options.useGeometryUniqueIdsMap || false;
        _this.useClonedMeshhMap = options && options.useClonedMeshhMap || false;
        if (!options || !options.virtual) {
            _this._engine.onNewSceneAddedObservable.notifyObservers(_this);
        }
        return _this;
    }
    /**
     * Factory used to create the default material.
     * @param name The name of the material to create
     * @param scene The scene to create the material for
     * @returns The default material
     */
    Scene.DefaultMaterialFactory = function (scene) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("StandardMaterial");
    };
    /**
     * Factory used to create the a collision coordinator.
     * @returns The collision coordinator
     */
    Scene.CollisionCoordinatorFactory = function () {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("DefaultCollisionCoordinator");
    };
    Object.defineProperty(Scene.prototype, "environmentTexture", {
        /**
         * Texture used in all pbr material as the reflection texture.
         * As in the majority of the scene they are the same (exception for multi room and so on),
         * this is easier to reference from here than from all the materials.
         */
        get: function () {
            return this._environmentTexture;
        },
        /**
         * Texture used in all pbr material as the reflection texture.
         * As in the majority of the scene they are the same (exception for multi room and so on),
         * this is easier to set here than in all the materials.
         */
        set: function (value) {
            if (this._environmentTexture === value) {
                return;
            }
            this._environmentTexture = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "environmentIntensity", {
        /**
         * Intensity of the environment in all pbr material.
         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
         * As in the majority of the scene they are the same (exception for multi room and so on),
         * this is easier to reference from here than from all the materials.
         */
        get: function () {
            return this._environmentIntensity;
        },
        /**
         * Intensity of the environment in all pbr material.
         * This dims or reinforces the IBL lighting overall (reflection and diffuse).
         * As in the majority of the scene they are the same (exception for multi room and so on),
         * this is easier to set here than in all the materials.
         */
        set: function (value) {
            if (this._environmentIntensity === value) {
                return;
            }
            this._environmentIntensity = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "imageProcessingConfiguration", {
        /**
         * Default image processing configuration used either in the rendering
         * Forward main pass or through the imageProcessingPostProcess if present.
         * As in the majority of the scene they are the same (exception for multi camera),
         * this is easier to reference from here than from all the materials and post process.
         *
         * No setter as we it is a shared configuration, you can set the values instead.
         */
        get: function () {
            return this._imageProcessingConfiguration;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "forceWireframe", {
        get: function () {
            return this._forceWireframe;
        },
        /**
         * Gets or sets a boolean indicating if all rendering must be done in wireframe
         */
        set: function (value) {
            if (this._forceWireframe === value) {
                return;
            }
            this._forceWireframe = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "forcePointsCloud", {
        get: function () {
            return this._forcePointsCloud;
        },
        /**
         * Gets or sets a boolean indicating if all rendering must be done in point cloud
         */
        set: function (value) {
            if (this._forcePointsCloud === value) {
                return;
            }
            this._forcePointsCloud = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "animationPropertiesOverride", {
        /**
         * Gets or sets the animation properties override
         */
        get: function () {
            return this._animationPropertiesOverride;
        },
        set: function (value) {
            this._animationPropertiesOverride = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "onDispose", {
        /** Sets a function to be executed when this scene is disposed. */
        set: function (callback) {
            if (this._onDisposeObserver) {
                this.onDisposeObservable.remove(this._onDisposeObserver);
            }
            this._onDisposeObserver = this.onDisposeObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "beforeRender", {
        /** Sets a function to be executed before rendering this scene */
        set: function (callback) {
            if (this._onBeforeRenderObserver) {
                this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
            }
            if (callback) {
                this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "afterRender", {
        /** Sets a function to be executed after rendering this scene */
        set: function (callback) {
            if (this._onAfterRenderObserver) {
                this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
            }
            if (callback) {
                this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "beforeCameraRender", {
        /** Sets a function to be executed before rendering a camera*/
        set: function (callback) {
            if (this._onBeforeCameraRenderObserver) {
                this.onBeforeCameraRenderObservable.remove(this._onBeforeCameraRenderObserver);
            }
            this._onBeforeCameraRenderObserver = this.onBeforeCameraRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "afterCameraRender", {
        /** Sets a function to be executed after rendering a camera*/
        set: function (callback) {
            if (this._onAfterCameraRenderObserver) {
                this.onAfterCameraRenderObservable.remove(this._onAfterCameraRenderObserver);
            }
            this._onAfterCameraRenderObserver = this.onAfterCameraRenderObservable.add(callback);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "unTranslatedPointer", {
        /**
         * Gets the pointer coordinates without any translation (ie. straight out of the pointer event)
         */
        get: function () {
            return this._inputManager.unTranslatedPointer;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene, "DragMovementThreshold", {
        /**
         * Gets or sets the distance in pixel that you have to move to prevent some events. Default is 10 pixels
         */
        get: function () {
            return _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].DragMovementThreshold;
        },
        set: function (value) {
            _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].DragMovementThreshold = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene, "LongPressDelay", {
        /**
         * Time in milliseconds to wait to raise long press events if button is still pressed. Default is 500 ms
         */
        get: function () {
            return _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].LongPressDelay;
        },
        set: function (value) {
            _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].LongPressDelay = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene, "DoubleClickDelay", {
        /**
         * Time in milliseconds to wait to raise long press events if button is still pressed. Default is 300 ms
         */
        get: function () {
            return _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].DoubleClickDelay;
        },
        set: function (value) {
            _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].DoubleClickDelay = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene, "ExclusiveDoubleClickMode", {
        /** If you need to check double click without raising a single click at first click, enable this flag */
        get: function () {
            return _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].ExclusiveDoubleClickMode;
        },
        set: function (value) {
            _Inputs_scene_inputManager__WEBPACK_IMPORTED_MODULE_25__["InputManager"].ExclusiveDoubleClickMode = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "useRightHandedSystem", {
        get: function () {
            return this._useRightHandedSystem;
        },
        /**
        * Gets or sets a boolean indicating if the scene must use right-handed coordinates system
        */
        set: function (value) {
            if (this._useRightHandedSystem === value) {
                return;
            }
            this._useRightHandedSystem = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets the step Id used by deterministic lock step
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     * @param newStepId defines the step Id
     */
    Scene.prototype.setStepId = function (newStepId) {
        this._currentStepId = newStepId;
    };
    /**
     * Gets the step Id used by deterministic lock step
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     * @returns the step Id
     */
    Scene.prototype.getStepId = function () {
        return this._currentStepId;
    };
    /**
     * Gets the internal step used by deterministic lock step
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     * @returns the internal step
     */
    Scene.prototype.getInternalStep = function () {
        return this._currentInternalStep;
    };
    Object.defineProperty(Scene.prototype, "fogEnabled", {
        get: function () {
            return this._fogEnabled;
        },
        /**
        * Gets or sets a boolean indicating if fog is enabled on this scene
        * @see http://doc.babylonjs.com/babylon101/environment#fog
        * (Default is true)
        */
        set: function (value) {
            if (this._fogEnabled === value) {
                return;
            }
            this._fogEnabled = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "fogMode", {
        get: function () {
            return this._fogMode;
        },
        /**
        * Gets or sets the fog mode to use
        * @see http://doc.babylonjs.com/babylon101/environment#fog
        * | mode | value |
        * | --- | --- |
        * | FOGMODE_NONE | 0 |
        * | FOGMODE_EXP | 1 |
        * | FOGMODE_EXP2 | 2 |
        * | FOGMODE_LINEAR | 3 |
        */
        set: function (value) {
            if (this._fogMode === value) {
                return;
            }
            this._fogMode = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_MiscDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "shadowsEnabled", {
        get: function () {
            return this._shadowsEnabled;
        },
        /**
        * Gets or sets a boolean indicating if shadows are enabled on this scene
        */
        set: function (value) {
            if (this._shadowsEnabled === value) {
                return;
            }
            this._shadowsEnabled = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_LightDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "lightsEnabled", {
        get: function () {
            return this._lightsEnabled;
        },
        /**
        * Gets or sets a boolean indicating if lights are enabled on this scene
        */
        set: function (value) {
            if (this._lightsEnabled === value) {
                return;
            }
            this._lightsEnabled = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_LightDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "activeCamera", {
        /** Gets or sets the current active camera */
        get: function () {
            return this._activeCamera;
        },
        set: function (value) {
            if (value === this._activeCamera) {
                return;
            }
            this._activeCamera = value;
            this.onActiveCameraChanged.notifyObservers(this);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "defaultMaterial", {
        /** The default material used on meshes when no material is affected */
        get: function () {
            if (!this._defaultMaterial) {
                this._defaultMaterial = Scene.DefaultMaterialFactory(this);
            }
            return this._defaultMaterial;
        },
        /** The default material used on meshes when no material is affected */
        set: function (value) {
            this._defaultMaterial = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "texturesEnabled", {
        get: function () {
            return this._texturesEnabled;
        },
        /**
        * Gets or sets a boolean indicating if textures are enabled on this scene
        */
        set: function (value) {
            if (this._texturesEnabled === value) {
                return;
            }
            this._texturesEnabled = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_TextureDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "skeletonsEnabled", {
        get: function () {
            return this._skeletonsEnabled;
        },
        /**
        * Gets or sets a boolean indicating if skeletons are enabled on this scene
        */
        set: function (value) {
            if (this._skeletonsEnabled === value) {
                return;
            }
            this._skeletonsEnabled = value;
            this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_AttributesDirtyFlag);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "collisionCoordinator", {
        /** @hidden */
        get: function () {
            if (!this._collisionCoordinator) {
                this._collisionCoordinator = Scene.CollisionCoordinatorFactory();
                this._collisionCoordinator.init(this);
            }
            return this._collisionCoordinator;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "frustumPlanes", {
        /**
         * Gets the list of frustum planes (built from the active camera)
         */
        get: function () {
            return this._frustumPlanes;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Registers the transient components if needed.
     */
    Scene.prototype._registerTransientComponents = function () {
        // Register components that have been associated lately to the scene.
        if (this._transientComponents.length > 0) {
            for (var _i = 0, _a = this._transientComponents; _i < _a.length; _i++) {
                var component = _a[_i];
                component.register();
            }
            this._transientComponents = [];
        }
    };
    /**
     * @hidden
     * Add a component to the scene.
     * Note that the ccomponent could be registered on th next frame if this is called after
     * the register component stage.
     * @param component Defines the component to add to the scene
     */
    Scene.prototype._addComponent = function (component) {
        this._components.push(component);
        this._transientComponents.push(component);
        var serializableComponent = component;
        if (serializableComponent.addFromContainer && serializableComponent.serialize) {
            this._serializableComponents.push(serializableComponent);
        }
    };
    /**
     * @hidden
     * Gets a component from the scene.
     * @param name defines the name of the component to retrieve
     * @returns the component or null if not present
     */
    Scene.prototype._getComponent = function (name) {
        for (var _i = 0, _a = this._components; _i < _a.length; _i++) {
            var component = _a[_i];
            if (component.name === name) {
                return component;
            }
        }
        return null;
    };
    /**
     * Gets a string idenfifying the name of the class
     * @returns "Scene" string
     */
    Scene.prototype.getClassName = function () {
        return "Scene";
    };
    /**
     * @hidden
     */
    Scene.prototype._getDefaultMeshCandidates = function () {
        this._defaultMeshCandidates.data = this.meshes;
        this._defaultMeshCandidates.length = this.meshes.length;
        return this._defaultMeshCandidates;
    };
    /**
     * @hidden
     */
    Scene.prototype._getDefaultSubMeshCandidates = function (mesh) {
        this._defaultSubMeshCandidates.data = mesh.subMeshes;
        this._defaultSubMeshCandidates.length = mesh.subMeshes.length;
        return this._defaultSubMeshCandidates;
    };
    /**
     * Sets the default candidate providers for the scene.
     * This sets the getActiveMeshCandidates, getActiveSubMeshCandidates, getIntersectingSubMeshCandidates
     * and getCollidingSubMeshCandidates to their default function
     */
    Scene.prototype.setDefaultCandidateProviders = function () {
        this.getActiveMeshCandidates = this._getDefaultMeshCandidates.bind(this);
        this.getActiveSubMeshCandidates = this._getDefaultSubMeshCandidates.bind(this);
        this.getIntersectingSubMeshCandidates = this._getDefaultSubMeshCandidates.bind(this);
        this.getCollidingSubMeshCandidates = this._getDefaultSubMeshCandidates.bind(this);
    };
    Object.defineProperty(Scene.prototype, "meshUnderPointer", {
        /**
         * Gets the mesh that is currently under the pointer
         */
        get: function () {
            return this._inputManager.meshUnderPointer;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "pointerX", {
        /**
         * Gets or sets the current on-screen X position of the pointer
         */
        get: function () {
            return this._inputManager.pointerX;
        },
        set: function (value) {
            this._inputManager.pointerX = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Scene.prototype, "pointerY", {
        /**
         * Gets or sets the current on-screen Y position of the pointer
         */
        get: function () {
            return this._inputManager.pointerY;
        },
        set: function (value) {
            this._inputManager.pointerY = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the cached material (ie. the latest rendered one)
     * @returns the cached material
     */
    Scene.prototype.getCachedMaterial = function () {
        return this._cachedMaterial;
    };
    /**
     * Gets the cached effect (ie. the latest rendered one)
     * @returns the cached effect
     */
    Scene.prototype.getCachedEffect = function () {
        return this._cachedEffect;
    };
    /**
     * Gets the cached visibility state (ie. the latest rendered one)
     * @returns the cached visibility state
     */
    Scene.prototype.getCachedVisibility = function () {
        return this._cachedVisibility;
    };
    /**
     * Gets a boolean indicating if the current material / effect / visibility must be bind again
     * @param material defines the current material
     * @param effect defines the current effect
     * @param visibility defines the current visibility state
     * @returns true if one parameter is not cached
     */
    Scene.prototype.isCachedMaterialInvalid = function (material, effect, visibility) {
        if (visibility === void 0) { visibility = 1; }
        return this._cachedEffect !== effect || this._cachedMaterial !== material || this._cachedVisibility !== visibility;
    };
    /**
     * Gets the engine associated with the scene
     * @returns an Engine
     */
    Scene.prototype.getEngine = function () {
        return this._engine;
    };
    /**
     * Gets the total number of vertices rendered per frame
     * @returns the total number of vertices rendered per frame
     */
    Scene.prototype.getTotalVertices = function () {
        return this._totalVertices.current;
    };
    Object.defineProperty(Scene.prototype, "totalVerticesPerfCounter", {
        /**
         * Gets the performance counter for total vertices
         * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#instrumentation
         */
        get: function () {
            return this._totalVertices;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the total number of active indices rendered per frame (You can deduce the number of rendered triangles by dividing this number by 3)
     * @returns the total number of active indices rendered per frame
     */
    Scene.prototype.getActiveIndices = function () {
        return this._activeIndices.current;
    };
    Object.defineProperty(Scene.prototype, "totalActiveIndicesPerfCounter", {
        /**
         * Gets the performance counter for active indices
         * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#instrumentation
         */
        get: function () {
            return this._activeIndices;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the total number of active particles rendered per frame
     * @returns the total number of active particles rendered per frame
     */
    Scene.prototype.getActiveParticles = function () {
        return this._activeParticles.current;
    };
    Object.defineProperty(Scene.prototype, "activeParticlesPerfCounter", {
        /**
         * Gets the performance counter for active particles
         * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#instrumentation
         */
        get: function () {
            return this._activeParticles;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the total number of active bones rendered per frame
     * @returns the total number of active bones rendered per frame
     */
    Scene.prototype.getActiveBones = function () {
        return this._activeBones.current;
    };
    Object.defineProperty(Scene.prototype, "activeBonesPerfCounter", {
        /**
         * Gets the performance counter for active bones
         * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#instrumentation
         */
        get: function () {
            return this._activeBones;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets the array of active meshes
     * @returns an array of AbstractMesh
     */
    Scene.prototype.getActiveMeshes = function () {
        return this._activeMeshes;
    };
    /**
     * Gets the animation ratio (which is 1.0 is the scene renders at 60fps and 2 if the scene renders at 30fps, etc.)
     * @returns a number
     */
    Scene.prototype.getAnimationRatio = function () {
        return this._animationRatio !== undefined ? this._animationRatio : 1;
    };
    /**
     * Gets an unique Id for the current render phase
     * @returns a number
     */
    Scene.prototype.getRenderId = function () {
        return this._renderId;
    };
    /**
     * Gets an unique Id for the current frame
     * @returns a number
     */
    Scene.prototype.getFrameId = function () {
        return this._frameId;
    };
    /** Call this function if you want to manually increment the render Id*/
    Scene.prototype.incrementRenderId = function () {
        this._renderId++;
    };
    Scene.prototype._createUbo = function () {
        this._sceneUbo = new _Materials_uniformBuffer__WEBPACK_IMPORTED_MODULE_13__["UniformBuffer"](this._engine, undefined, true);
        this._sceneUbo.addUniform("viewProjection", 16);
        this._sceneUbo.addUniform("view", 16);
    };
    /**
     * Use this method to simulate a pointer move on a mesh
     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay
     * @param pickResult pickingInfo of the object wished to simulate pointer event on
     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)
     * @returns the current scene
     */
    Scene.prototype.simulatePointerMove = function (pickResult, pointerEventInit) {
        this._inputManager.simulatePointerMove(pickResult, pointerEventInit);
        return this;
    };
    /**
     * Use this method to simulate a pointer down on a mesh
     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay
     * @param pickResult pickingInfo of the object wished to simulate pointer event on
     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)
     * @returns the current scene
     */
    Scene.prototype.simulatePointerDown = function (pickResult, pointerEventInit) {
        this._inputManager.simulatePointerDown(pickResult, pointerEventInit);
        return this;
    };
    /**
     * Use this method to simulate a pointer up on a mesh
     * The pickResult parameter can be obtained from a scene.pick or scene.pickWithRay
     * @param pickResult pickingInfo of the object wished to simulate pointer event on
     * @param pointerEventInit pointer event state to be used when simulating the pointer event (eg. pointer id for multitouch)
     * @param doubleTap indicates that the pointer up event should be considered as part of a double click (false by default)
     * @returns the current scene
     */
    Scene.prototype.simulatePointerUp = function (pickResult, pointerEventInit, doubleTap) {
        this._inputManager.simulatePointerUp(pickResult, pointerEventInit, doubleTap);
        return this;
    };
    /**
     * Gets a boolean indicating if the current pointer event is captured (meaning that the scene has already handled the pointer down)
     * @param pointerId defines the pointer id to use in a multi-touch scenario (0 by default)
     * @returns true if the pointer was captured
     */
    Scene.prototype.isPointerCaptured = function (pointerId) {
        if (pointerId === void 0) { pointerId = 0; }
        return this._inputManager.isPointerCaptured(pointerId);
    };
    /**
    * Attach events to the canvas (To handle actionManagers triggers and raise onPointerMove, onPointerDown and onPointerUp
    * @param attachUp defines if you want to attach events to pointerup
    * @param attachDown defines if you want to attach events to pointerdown
    * @param attachMove defines if you want to attach events to pointermove
    */
    Scene.prototype.attachControl = function (attachUp, attachDown, attachMove) {
        if (attachUp === void 0) { attachUp = true; }
        if (attachDown === void 0) { attachDown = true; }
        if (attachMove === void 0) { attachMove = true; }
        this._inputManager.attachControl(attachUp, attachDown, attachMove);
    };
    /** Detaches all event handlers*/
    Scene.prototype.detachControl = function () {
        this._inputManager.detachControl();
    };
    /**
     * This function will check if the scene can be rendered (textures are loaded, shaders are compiled)
     * Delay loaded resources are not taking in account
     * @return true if all required resources are ready
     */
    Scene.prototype.isReady = function () {
        if (this._isDisposed) {
            return false;
        }
        var index;
        var engine = this.getEngine();
        // Effects
        if (!engine.areAllEffectsReady()) {
            return false;
        }
        // Pending data
        if (this._pendingData.length > 0) {
            return false;
        }
        // Meshes
        for (index = 0; index < this.meshes.length; index++) {
            var mesh = this.meshes[index];
            if (!mesh.isEnabled()) {
                continue;
            }
            if (!mesh.subMeshes || mesh.subMeshes.length === 0) {
                continue;
            }
            if (!mesh.isReady(true)) {
                return false;
            }
            var hardwareInstancedRendering = mesh.getClassName() === "InstancedMesh" || mesh.getClassName() === "InstancedLinesMesh" || engine.getCaps().instancedArrays && mesh.instances.length > 0;
            // Is Ready For Mesh
            for (var _i = 0, _a = this._isReadyForMeshStage; _i < _a.length; _i++) {
                var step = _a[_i];
                if (!step.action(mesh, hardwareInstancedRendering)) {
                    return false;
                }
            }
        }
        // Geometries
        for (index = 0; index < this.geometries.length; index++) {
            var geometry = this.geometries[index];
            if (geometry.delayLoadState === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].DELAYLOADSTATE_LOADING) {
                return false;
            }
        }
        // Post-processes
        if (this.activeCameras && this.activeCameras.length > 0) {
            for (var _b = 0, _c = this.activeCameras; _b < _c.length; _b++) {
                var camera = _c[_b];
                if (!camera.isReady(true)) {
                    return false;
                }
            }
        }
        else if (this.activeCamera) {
            if (!this.activeCamera.isReady(true)) {
                return false;
            }
        }
        // Particles
        for (var _d = 0, _e = this.particleSystems; _d < _e.length; _d++) {
            var particleSystem = _e[_d];
            if (!particleSystem.isReady()) {
                return false;
            }
        }
        return true;
    };
    /** Resets all cached information relative to material (including effect and visibility) */
    Scene.prototype.resetCachedMaterial = function () {
        this._cachedMaterial = null;
        this._cachedEffect = null;
        this._cachedVisibility = null;
    };
    /**
     * Registers a function to be called before every frame render
     * @param func defines the function to register
     */
    Scene.prototype.registerBeforeRender = function (func) {
        this.onBeforeRenderObservable.add(func);
    };
    /**
     * Unregisters a function called before every frame render
     * @param func defines the function to unregister
     */
    Scene.prototype.unregisterBeforeRender = function (func) {
        this.onBeforeRenderObservable.removeCallback(func);
    };
    /**
     * Registers a function to be called after every frame render
     * @param func defines the function to register
     */
    Scene.prototype.registerAfterRender = function (func) {
        this.onAfterRenderObservable.add(func);
    };
    /**
     * Unregisters a function called after every frame render
     * @param func defines the function to unregister
     */
    Scene.prototype.unregisterAfterRender = function (func) {
        this.onAfterRenderObservable.removeCallback(func);
    };
    Scene.prototype._executeOnceBeforeRender = function (func) {
        var _this = this;
        var execFunc = function () {
            func();
            setTimeout(function () {
                _this.unregisterBeforeRender(execFunc);
            });
        };
        this.registerBeforeRender(execFunc);
    };
    /**
     * The provided function will run before render once and will be disposed afterwards.
     * A timeout delay can be provided so that the function will be executed in N ms.
     * The timeout is using the browser's native setTimeout so time percision cannot be guaranteed.
     * @param func The function to be executed.
     * @param timeout optional delay in ms
     */
    Scene.prototype.executeOnceBeforeRender = function (func, timeout) {
        var _this = this;
        if (timeout !== undefined) {
            setTimeout(function () {
                _this._executeOnceBeforeRender(func);
            }, timeout);
        }
        else {
            this._executeOnceBeforeRender(func);
        }
    };
    /** @hidden */
    Scene.prototype._addPendingData = function (data) {
        this._pendingData.push(data);
    };
    /** @hidden */
    Scene.prototype._removePendingData = function (data) {
        var wasLoading = this.isLoading;
        var index = this._pendingData.indexOf(data);
        if (index !== -1) {
            this._pendingData.splice(index, 1);
        }
        if (wasLoading && !this.isLoading) {
            this.onDataLoadedObservable.notifyObservers(this);
        }
    };
    /**
     * Returns the number of items waiting to be loaded
     * @returns the number of items waiting to be loaded
     */
    Scene.prototype.getWaitingItemsCount = function () {
        return this._pendingData.length;
    };
    Object.defineProperty(Scene.prototype, "isLoading", {
        /**
         * Returns a boolean indicating if the scene is still loading data
         */
        get: function () {
            return this._pendingData.length > 0;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Registers a function to be executed when the scene is ready
     * @param {Function} func - the function to be executed
     */
    Scene.prototype.executeWhenReady = function (func) {
        var _this = this;
        this.onReadyObservable.add(func);
        if (this._executeWhenReadyTimeoutId !== -1) {
            return;
        }
        this._executeWhenReadyTimeoutId = setTimeout(function () {
            _this._checkIsReady();
        }, 150);
    };
    /**
     * Returns a promise that resolves when the scene is ready
     * @returns A promise that resolves when the scene is ready
     */
    Scene.prototype.whenReadyAsync = function () {
        var _this = this;
        return new Promise(function (resolve) {
            _this.executeWhenReady(function () {
                resolve();
            });
        });
    };
    /** @hidden */
    Scene.prototype._checkIsReady = function () {
        var _this = this;
        this._registerTransientComponents();
        if (this.isReady()) {
            this.onReadyObservable.notifyObservers(this);
            this.onReadyObservable.clear();
            this._executeWhenReadyTimeoutId = -1;
            return;
        }
        if (this._isDisposed) {
            this.onReadyObservable.clear();
            this._executeWhenReadyTimeoutId = -1;
            return;
        }
        this._executeWhenReadyTimeoutId = setTimeout(function () {
            _this._checkIsReady();
        }, 150);
    };
    Object.defineProperty(Scene.prototype, "animatables", {
        /**
         * Gets all animatable attached to the scene
         */
        get: function () {
            return this._activeAnimatables;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Resets the last animation time frame.
     * Useful to override when animations start running when loading a scene for the first time.
     */
    Scene.prototype.resetLastAnimationTimeFrame = function () {
        this._animationTimeLast = _Misc_precisionDate__WEBPACK_IMPORTED_MODULE_2__["PrecisionDate"].Now;
    };
    // Matrix
    /**
     * Gets the current view matrix
     * @returns a Matrix
     */
    Scene.prototype.getViewMatrix = function () {
        return this._viewMatrix;
    };
    /**
     * Gets the current projection matrix
     * @returns a Matrix
     */
    Scene.prototype.getProjectionMatrix = function () {
        return this._projectionMatrix;
    };
    /**
     * Gets the current transform matrix
     * @returns a Matrix made of View * Projection
     */
    Scene.prototype.getTransformMatrix = function () {
        return this._transformMatrix;
    };
    /**
     * Sets the current transform matrix
     * @param viewL defines the View matrix to use
     * @param projectionL defines the Projection matrix to use
     * @param viewR defines the right View matrix to use (if provided)
     * @param projectionR defines the right Projection matrix to use (if provided)
     */
    Scene.prototype.setTransformMatrix = function (viewL, projectionL, viewR, projectionR) {
        if (this._viewUpdateFlag === viewL.updateFlag && this._projectionUpdateFlag === projectionL.updateFlag) {
            return;
        }
        this._viewUpdateFlag = viewL.updateFlag;
        this._projectionUpdateFlag = projectionL.updateFlag;
        this._viewMatrix = viewL;
        this._projectionMatrix = projectionL;
        this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
        // Update frustum
        if (!this._frustumPlanes) {
            this._frustumPlanes = _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_28__["Frustum"].GetPlanes(this._transformMatrix);
        }
        else {
            _Maths_math_frustum__WEBPACK_IMPORTED_MODULE_28__["Frustum"].GetPlanesToRef(this._transformMatrix, this._frustumPlanes);
        }
        if (this._multiviewSceneUbo && this._multiviewSceneUbo.useUbo) {
            this._updateMultiviewUbo(viewR, projectionR);
        }
        else if (this._sceneUbo.useUbo) {
            this._sceneUbo.updateMatrix("viewProjection", this._transformMatrix);
            this._sceneUbo.updateMatrix("view", this._viewMatrix);
            this._sceneUbo.update();
        }
    };
    /**
     * Gets the uniform buffer used to store scene data
     * @returns a UniformBuffer
     */
    Scene.prototype.getSceneUniformBuffer = function () {
        return this._multiviewSceneUbo ? this._multiviewSceneUbo : this._sceneUbo;
    };
    /**
     * Gets an unique (relatively to the current scene) Id
     * @returns an unique number for the scene
     */
    Scene.prototype.getUniqueId = function () {
        return _Misc_uniqueIdGenerator__WEBPACK_IMPORTED_MODULE_29__["UniqueIdGenerator"].UniqueId;
    };
    /**
     * Add a mesh to the list of scene's meshes
     * @param newMesh defines the mesh to add
     * @param recursive if all child meshes should also be added to the scene
     */
    Scene.prototype.addMesh = function (newMesh, recursive) {
        var _this = this;
        if (recursive === void 0) { recursive = false; }
        this.meshes.push(newMesh);
        newMesh._resyncLightSources();
        this.onNewMeshAddedObservable.notifyObservers(newMesh);
        if (recursive) {
            newMesh.getChildMeshes().forEach(function (m) {
                _this.addMesh(m);
            });
        }
    };
    /**
     * Remove a mesh for the list of scene's meshes
     * @param toRemove defines the mesh to remove
     * @param recursive if all child meshes should also be removed from the scene
     * @returns the index where the mesh was in the mesh list
     */
    Scene.prototype.removeMesh = function (toRemove, recursive) {
        var _this = this;
        if (recursive === void 0) { recursive = false; }
        var index = this.meshes.indexOf(toRemove);
        if (index !== -1) {
            // Remove from the scene if mesh found
            this.meshes[index] = this.meshes[this.meshes.length - 1];
            this.meshes.pop();
        }
        this.onMeshRemovedObservable.notifyObservers(toRemove);
        if (recursive) {
            toRemove.getChildMeshes().forEach(function (m) {
                _this.removeMesh(m);
            });
        }
        return index;
    };
    /**
     * Add a transform node to the list of scene's transform nodes
     * @param newTransformNode defines the transform node to add
     */
    Scene.prototype.addTransformNode = function (newTransformNode) {
        newTransformNode._indexInSceneTransformNodesArray = this.transformNodes.length;
        this.transformNodes.push(newTransformNode);
        this.onNewTransformNodeAddedObservable.notifyObservers(newTransformNode);
    };
    /**
     * Remove a transform node for the list of scene's transform nodes
     * @param toRemove defines the transform node to remove
     * @returns the index where the transform node was in the transform node list
     */
    Scene.prototype.removeTransformNode = function (toRemove) {
        var index = toRemove._indexInSceneTransformNodesArray;
        if (index !== -1) {
            if (index !== this.transformNodes.length - 1) {
                var lastNode = this.transformNodes[this.transformNodes.length - 1];
                this.transformNodes[index] = lastNode;
                lastNode._indexInSceneTransformNodesArray = index;
            }
            toRemove._indexInSceneTransformNodesArray = -1;
            this.transformNodes.pop();
        }
        this.onTransformNodeRemovedObservable.notifyObservers(toRemove);
        return index;
    };
    /**
     * Remove a skeleton for the list of scene's skeletons
     * @param toRemove defines the skeleton to remove
     * @returns the index where the skeleton was in the skeleton list
     */
    Scene.prototype.removeSkeleton = function (toRemove) {
        var index = this.skeletons.indexOf(toRemove);
        if (index !== -1) {
            // Remove from the scene if found
            this.skeletons.splice(index, 1);
            this.onSkeletonRemovedObservable.notifyObservers(toRemove);
        }
        return index;
    };
    /**
     * Remove a morph target for the list of scene's morph targets
     * @param toRemove defines the morph target to remove
     * @returns the index where the morph target was in the morph target list
     */
    Scene.prototype.removeMorphTargetManager = function (toRemove) {
        var index = this.morphTargetManagers.indexOf(toRemove);
        if (index !== -1) {
            // Remove from the scene if found
            this.morphTargetManagers.splice(index, 1);
        }
        return index;
    };
    /**
     * Remove a light for the list of scene's lights
     * @param toRemove defines the light to remove
     * @returns the index where the light was in the light list
     */
    Scene.prototype.removeLight = function (toRemove) {
        var index = this.lights.indexOf(toRemove);
        if (index !== -1) {
            // Remove from meshes
            for (var _i = 0, _a = this.meshes; _i < _a.length; _i++) {
                var mesh = _a[_i];
                mesh._removeLightSource(toRemove, false);
            }
            // Remove from the scene if mesh found
            this.lights.splice(index, 1);
            this.sortLightsByPriority();
        }
        this.onLightRemovedObservable.notifyObservers(toRemove);
        return index;
    };
    /**
     * Remove a camera for the list of scene's cameras
     * @param toRemove defines the camera to remove
     * @returns the index where the camera was in the camera list
     */
    Scene.prototype.removeCamera = function (toRemove) {
        var index = this.cameras.indexOf(toRemove);
        if (index !== -1) {
            // Remove from the scene if mesh found
            this.cameras.splice(index, 1);
        }
        // Remove from activeCameras
        var index2 = this.activeCameras.indexOf(toRemove);
        if (index2 !== -1) {
            // Remove from the scene if mesh found
            this.activeCameras.splice(index2, 1);
        }
        // Reset the activeCamera
        if (this.activeCamera === toRemove) {
            if (this.cameras.length > 0) {
                this.activeCamera = this.cameras[0];
            }
            else {
                this.activeCamera = null;
            }
        }
        this.onCameraRemovedObservable.notifyObservers(toRemove);
        return index;
    };
    /**
     * Remove a particle system for the list of scene's particle systems
     * @param toRemove defines the particle system to remove
     * @returns the index where the particle system was in the particle system list
     */
    Scene.prototype.removeParticleSystem = function (toRemove) {
        var index = this.particleSystems.indexOf(toRemove);
        if (index !== -1) {
            this.particleSystems.splice(index, 1);
        }
        return index;
    };
    /**
     * Remove a animation for the list of scene's animations
     * @param toRemove defines the animation to remove
     * @returns the index where the animation was in the animation list
     */
    Scene.prototype.removeAnimation = function (toRemove) {
        var index = this.animations.indexOf(toRemove);
        if (index !== -1) {
            this.animations.splice(index, 1);
        }
        return index;
    };
    /**
     * Will stop the animation of the given target
     * @param target - the target
     * @param animationName - the name of the animation to stop (all animations will be stopped if both this and targetMask are empty)
     * @param targetMask - a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)
     */
    Scene.prototype.stopAnimation = function (target, animationName, targetMask) {
        // Do nothing as code will be provided by animation component
    };
    /**
     * Removes the given animation group from this scene.
     * @param toRemove The animation group to remove
     * @returns The index of the removed animation group
     */
    Scene.prototype.removeAnimationGroup = function (toRemove) {
        var index = this.animationGroups.indexOf(toRemove);
        if (index !== -1) {
            this.animationGroups.splice(index, 1);
        }
        return index;
    };
    /**
     * Removes the given multi-material from this scene.
     * @param toRemove The multi-material to remove
     * @returns The index of the removed multi-material
     */
    Scene.prototype.removeMultiMaterial = function (toRemove) {
        var index = this.multiMaterials.indexOf(toRemove);
        if (index !== -1) {
            this.multiMaterials.splice(index, 1);
        }
        return index;
    };
    /**
     * Removes the given material from this scene.
     * @param toRemove The material to remove
     * @returns The index of the removed material
     */
    Scene.prototype.removeMaterial = function (toRemove) {
        var index = toRemove._indexInSceneMaterialArray;
        if (index !== -1 && index < this.materials.length) {
            if (index !== this.materials.length - 1) {
                var lastMaterial = this.materials[this.materials.length - 1];
                this.materials[index] = lastMaterial;
                lastMaterial._indexInSceneMaterialArray = index;
            }
            toRemove._indexInSceneMaterialArray = -1;
            this.materials.pop();
        }
        this.onMaterialRemovedObservable.notifyObservers(toRemove);
        return index;
    };
    /**
     * Removes the given action manager from this scene.
     * @param toRemove The action manager to remove
     * @returns The index of the removed action manager
     */
    Scene.prototype.removeActionManager = function (toRemove) {
        var index = this.actionManagers.indexOf(toRemove);
        if (index !== -1) {
            this.actionManagers.splice(index, 1);
        }
        return index;
    };
    /**
     * Removes the given texture from this scene.
     * @param toRemove The texture to remove
     * @returns The index of the removed texture
     */
    Scene.prototype.removeTexture = function (toRemove) {
        var index = this.textures.indexOf(toRemove);
        if (index !== -1) {
            this.textures.splice(index, 1);
        }
        this.onTextureRemovedObservable.notifyObservers(toRemove);
        return index;
    };
    /**
     * Adds the given light to this scene
     * @param newLight The light to add
     */
    Scene.prototype.addLight = function (newLight) {
        this.lights.push(newLight);
        this.sortLightsByPriority();
        // Add light to all meshes (To support if the light is removed and then readded)
        for (var _i = 0, _a = this.meshes; _i < _a.length; _i++) {
            var mesh = _a[_i];
            if (mesh.lightSources.indexOf(newLight) === -1) {
                mesh.lightSources.push(newLight);
                mesh._resyncLightSources();
            }
        }
        this.onNewLightAddedObservable.notifyObservers(newLight);
    };
    /**
     * Sorts the list list based on light priorities
     */
    Scene.prototype.sortLightsByPriority = function () {
        if (this.requireLightSorting) {
            this.lights.sort(_Lights_light__WEBPACK_IMPORTED_MODULE_14__["Light"].CompareLightsPriority);
        }
    };
    /**
     * Adds the given camera to this scene
     * @param newCamera The camera to add
     */
    Scene.prototype.addCamera = function (newCamera) {
        this.cameras.push(newCamera);
        this.onNewCameraAddedObservable.notifyObservers(newCamera);
    };
    /**
     * Adds the given skeleton to this scene
     * @param newSkeleton The skeleton to add
     */
    Scene.prototype.addSkeleton = function (newSkeleton) {
        this.skeletons.push(newSkeleton);
        this.onNewSkeletonAddedObservable.notifyObservers(newSkeleton);
    };
    /**
     * Adds the given particle system to this scene
     * @param newParticleSystem The particle system to add
     */
    Scene.prototype.addParticleSystem = function (newParticleSystem) {
        this.particleSystems.push(newParticleSystem);
    };
    /**
     * Adds the given animation to this scene
     * @param newAnimation The animation to add
     */
    Scene.prototype.addAnimation = function (newAnimation) {
        this.animations.push(newAnimation);
    };
    /**
     * Adds the given animation group to this scene.
     * @param newAnimationGroup The animation group to add
     */
    Scene.prototype.addAnimationGroup = function (newAnimationGroup) {
        this.animationGroups.push(newAnimationGroup);
    };
    /**
     * Adds the given multi-material to this scene
     * @param newMultiMaterial The multi-material to add
     */
    Scene.prototype.addMultiMaterial = function (newMultiMaterial) {
        this.multiMaterials.push(newMultiMaterial);
    };
    /**
     * Adds the given material to this scene
     * @param newMaterial The material to add
     */
    Scene.prototype.addMaterial = function (newMaterial) {
        newMaterial._indexInSceneMaterialArray = this.materials.length;
        this.materials.push(newMaterial);
        this.onNewMaterialAddedObservable.notifyObservers(newMaterial);
    };
    /**
     * Adds the given morph target to this scene
     * @param newMorphTargetManager The morph target to add
     */
    Scene.prototype.addMorphTargetManager = function (newMorphTargetManager) {
        this.morphTargetManagers.push(newMorphTargetManager);
    };
    /**
     * Adds the given geometry to this scene
     * @param newGeometry The geometry to add
     */
    Scene.prototype.addGeometry = function (newGeometry) {
        if (this.geometriesByUniqueId) {
            this.geometriesByUniqueId[newGeometry.uniqueId] = this.geometries.length;
        }
        this.geometries.push(newGeometry);
    };
    /**
     * Adds the given action manager to this scene
     * @param newActionManager The action manager to add
     */
    Scene.prototype.addActionManager = function (newActionManager) {
        this.actionManagers.push(newActionManager);
    };
    /**
     * Adds the given texture to this scene.
     * @param newTexture The texture to add
     */
    Scene.prototype.addTexture = function (newTexture) {
        this.textures.push(newTexture);
        this.onNewTextureAddedObservable.notifyObservers(newTexture);
    };
    /**
     * Switch active camera
     * @param newCamera defines the new active camera
     * @param attachControl defines if attachControl must be called for the new active camera (default: true)
     */
    Scene.prototype.switchActiveCamera = function (newCamera, attachControl) {
        if (attachControl === void 0) { attachControl = true; }
        var canvas = this._engine.getRenderingCanvas();
        if (!canvas) {
            return;
        }
        if (this.activeCamera) {
            this.activeCamera.detachControl(canvas);
        }
        this.activeCamera = newCamera;
        if (attachControl) {
            newCamera.attachControl(canvas);
        }
    };
    /**
     * sets the active camera of the scene using its ID
     * @param id defines the camera's ID
     * @return the new active camera or null if none found.
     */
    Scene.prototype.setActiveCameraByID = function (id) {
        var camera = this.getCameraByID(id);
        if (camera) {
            this.activeCamera = camera;
            return camera;
        }
        return null;
    };
    /**
     * sets the active camera of the scene using its name
     * @param name defines the camera's name
     * @returns the new active camera or null if none found.
     */
    Scene.prototype.setActiveCameraByName = function (name) {
        var camera = this.getCameraByName(name);
        if (camera) {
            this.activeCamera = camera;
            return camera;
        }
        return null;
    };
    /**
     * get an animation group using its name
     * @param name defines the material's name
     * @return the animation group or null if none found.
     */
    Scene.prototype.getAnimationGroupByName = function (name) {
        for (var index = 0; index < this.animationGroups.length; index++) {
            if (this.animationGroups[index].name === name) {
                return this.animationGroups[index];
            }
        }
        return null;
    };
    /**
     * Get a material using its unique id
     * @param uniqueId defines the material's unique id
     * @return the material or null if none found.
     */
    Scene.prototype.getMaterialByUniqueID = function (uniqueId) {
        for (var index = 0; index < this.materials.length; index++) {
            if (this.materials[index].uniqueId === uniqueId) {
                return this.materials[index];
            }
        }
        return null;
    };
    /**
     * get a material using its id
     * @param id defines the material's ID
     * @return the material or null if none found.
     */
    Scene.prototype.getMaterialByID = function (id) {
        for (var index = 0; index < this.materials.length; index++) {
            if (this.materials[index].id === id) {
                return this.materials[index];
            }
        }
        return null;
    };
    /**
     * Gets a the last added material using a given id
     * @param id defines the material's ID
     * @return the last material with the given id or null if none found.
     */
    Scene.prototype.getLastMaterialByID = function (id) {
        for (var index = this.materials.length - 1; index >= 0; index--) {
            if (this.materials[index].id === id) {
                return this.materials[index];
            }
        }
        return null;
    };
    /**
     * Gets a material using its name
     * @param name defines the material's name
     * @return the material or null if none found.
     */
    Scene.prototype.getMaterialByName = function (name) {
        for (var index = 0; index < this.materials.length; index++) {
            if (this.materials[index].name === name) {
                return this.materials[index];
            }
        }
        return null;
    };
    /**
     * Get a texture using its unique id
     * @param uniqueId defines the texture's unique id
     * @return the texture or null if none found.
     */
    Scene.prototype.getTextureByUniqueID = function (uniqueId) {
        for (var index = 0; index < this.textures.length; index++) {
            if (this.textures[index].uniqueId === uniqueId) {
                return this.textures[index];
            }
        }
        return null;
    };
    /**
     * Gets a camera using its id
     * @param id defines the id to look for
     * @returns the camera or null if not found
     */
    Scene.prototype.getCameraByID = function (id) {
        for (var index = 0; index < this.cameras.length; index++) {
            if (this.cameras[index].id === id) {
                return this.cameras[index];
            }
        }
        return null;
    };
    /**
     * Gets a camera using its unique id
     * @param uniqueId defines the unique id to look for
     * @returns the camera or null if not found
     */
    Scene.prototype.getCameraByUniqueID = function (uniqueId) {
        for (var index = 0; index < this.cameras.length; index++) {
            if (this.cameras[index].uniqueId === uniqueId) {
                return this.cameras[index];
            }
        }
        return null;
    };
    /**
     * Gets a camera using its name
     * @param name defines the camera's name
     * @return the camera or null if none found.
     */
    Scene.prototype.getCameraByName = function (name) {
        for (var index = 0; index < this.cameras.length; index++) {
            if (this.cameras[index].name === name) {
                return this.cameras[index];
            }
        }
        return null;
    };
    /**
     * Gets a bone using its id
     * @param id defines the bone's id
     * @return the bone or null if not found
     */
    Scene.prototype.getBoneByID = function (id) {
        for (var skeletonIndex = 0; skeletonIndex < this.skeletons.length; skeletonIndex++) {
            var skeleton = this.skeletons[skeletonIndex];
            for (var boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {
                if (skeleton.bones[boneIndex].id === id) {
                    return skeleton.bones[boneIndex];
                }
            }
        }
        return null;
    };
    /**
    * Gets a bone using its id
    * @param name defines the bone's name
    * @return the bone or null if not found
    */
    Scene.prototype.getBoneByName = function (name) {
        for (var skeletonIndex = 0; skeletonIndex < this.skeletons.length; skeletonIndex++) {
            var skeleton = this.skeletons[skeletonIndex];
            for (var boneIndex = 0; boneIndex < skeleton.bones.length; boneIndex++) {
                if (skeleton.bones[boneIndex].name === name) {
                    return skeleton.bones[boneIndex];
                }
            }
        }
        return null;
    };
    /**
     * Gets a light node using its name
     * @param name defines the the light's name
     * @return the light or null if none found.
     */
    Scene.prototype.getLightByName = function (name) {
        for (var index = 0; index < this.lights.length; index++) {
            if (this.lights[index].name === name) {
                return this.lights[index];
            }
        }
        return null;
    };
    /**
     * Gets a light node using its id
     * @param id defines the light's id
     * @return the light or null if none found.
     */
    Scene.prototype.getLightByID = function (id) {
        for (var index = 0; index < this.lights.length; index++) {
            if (this.lights[index].id === id) {
                return this.lights[index];
            }
        }
        return null;
    };
    /**
     * Gets a light node using its scene-generated unique ID
     * @param uniqueId defines the light's unique id
     * @return the light or null if none found.
     */
    Scene.prototype.getLightByUniqueID = function (uniqueId) {
        for (var index = 0; index < this.lights.length; index++) {
            if (this.lights[index].uniqueId === uniqueId) {
                return this.lights[index];
            }
        }
        return null;
    };
    /**
     * Gets a particle system by id
     * @param id defines the particle system id
     * @return the corresponding system or null if none found
     */
    Scene.prototype.getParticleSystemByID = function (id) {
        for (var index = 0; index < this.particleSystems.length; index++) {
            if (this.particleSystems[index].id === id) {
                return this.particleSystems[index];
            }
        }
        return null;
    };
    /**
     * Gets a geometry using its ID
     * @param id defines the geometry's id
     * @return the geometry or null if none found.
     */
    Scene.prototype.getGeometryByID = function (id) {
        for (var index = 0; index < this.geometries.length; index++) {
            if (this.geometries[index].id === id) {
                return this.geometries[index];
            }
        }
        return null;
    };
    Scene.prototype._getGeometryByUniqueID = function (uniqueId) {
        if (this.geometriesByUniqueId) {
            var index_1 = this.geometriesByUniqueId[uniqueId];
            if (index_1 !== undefined) {
                return this.geometries[index_1];
            }
        }
        else {
            for (var index = 0; index < this.geometries.length; index++) {
                if (this.geometries[index].uniqueId === uniqueId) {
                    return this.geometries[index];
                }
            }
        }
        return null;
    };
    /**
     * Add a new geometry to this scene
     * @param geometry defines the geometry to be added to the scene.
     * @param force defines if the geometry must be pushed even if a geometry with this id already exists
     * @return a boolean defining if the geometry was added or not
     */
    Scene.prototype.pushGeometry = function (geometry, force) {
        if (!force && this._getGeometryByUniqueID(geometry.uniqueId)) {
            return false;
        }
        this.addGeometry(geometry);
        this.onNewGeometryAddedObservable.notifyObservers(geometry);
        return true;
    };
    /**
     * Removes an existing geometry
     * @param geometry defines the geometry to be removed from the scene
     * @return a boolean defining if the geometry was removed or not
     */
    Scene.prototype.removeGeometry = function (geometry) {
        var index;
        if (this.geometriesByUniqueId) {
            index = this.geometriesByUniqueId[geometry.uniqueId];
            if (index === undefined) {
                return false;
            }
        }
        else {
            index = this.geometries.indexOf(geometry);
            if (index < 0) {
                return false;
            }
        }
        if (index !== this.geometries.length - 1) {
            var lastGeometry = this.geometries[this.geometries.length - 1];
            this.geometries[index] = lastGeometry;
            if (this.geometriesByUniqueId) {
                this.geometriesByUniqueId[lastGeometry.uniqueId] = index;
                this.geometriesByUniqueId[geometry.uniqueId] = undefined;
            }
        }
        this.geometries.pop();
        this.onGeometryRemovedObservable.notifyObservers(geometry);
        return true;
    };
    /**
     * Gets the list of geometries attached to the scene
     * @returns an array of Geometry
     */
    Scene.prototype.getGeometries = function () {
        return this.geometries;
    };
    /**
     * Gets the first added mesh found of a given ID
     * @param id defines the id to search for
     * @return the mesh found or null if not found at all
     */
    Scene.prototype.getMeshByID = function (id) {
        for (var index = 0; index < this.meshes.length; index++) {
            if (this.meshes[index].id === id) {
                return this.meshes[index];
            }
        }
        return null;
    };
    /**
     * Gets a list of meshes using their id
     * @param id defines the id to search for
     * @returns a list of meshes
     */
    Scene.prototype.getMeshesByID = function (id) {
        return this.meshes.filter(function (m) {
            return m.id === id;
        });
    };
    /**
     * Gets the first added transform node found of a given ID
     * @param id defines the id to search for
     * @return the found transform node or null if not found at all.
     */
    Scene.prototype.getTransformNodeByID = function (id) {
        for (var index = 0; index < this.transformNodes.length; index++) {
            if (this.transformNodes[index].id === id) {
                return this.transformNodes[index];
            }
        }
        return null;
    };
    /**
     * Gets a transform node with its auto-generated unique id
     * @param uniqueId efines the unique id to search for
     * @return the found transform node or null if not found at all.
     */
    Scene.prototype.getTransformNodeByUniqueID = function (uniqueId) {
        for (var index = 0; index < this.transformNodes.length; index++) {
            if (this.transformNodes[index].uniqueId === uniqueId) {
                return this.transformNodes[index];
            }
        }
        return null;
    };
    /**
     * Gets a list of transform nodes using their id
     * @param id defines the id to search for
     * @returns a list of transform nodes
     */
    Scene.prototype.getTransformNodesByID = function (id) {
        return this.transformNodes.filter(function (m) {
            return m.id === id;
        });
    };
    /**
     * Gets a mesh with its auto-generated unique id
     * @param uniqueId defines the unique id to search for
     * @return the found mesh or null if not found at all.
     */
    Scene.prototype.getMeshByUniqueID = function (uniqueId) {
        for (var index = 0; index < this.meshes.length; index++) {
            if (this.meshes[index].uniqueId === uniqueId) {
                return this.meshes[index];
            }
        }
        return null;
    };
    /**
     * Gets a the last added mesh using a given id
     * @param id defines the id to search for
     * @return the found mesh or null if not found at all.
     */
    Scene.prototype.getLastMeshByID = function (id) {
        for (var index = this.meshes.length - 1; index >= 0; index--) {
            if (this.meshes[index].id === id) {
                return this.meshes[index];
            }
        }
        return null;
    };
    /**
     * Gets a the last added node (Mesh, Camera, Light) using a given id
     * @param id defines the id to search for
     * @return the found node or null if not found at all
     */
    Scene.prototype.getLastEntryByID = function (id) {
        var index;
        for (index = this.meshes.length - 1; index >= 0; index--) {
            if (this.meshes[index].id === id) {
                return this.meshes[index];
            }
        }
        for (index = this.transformNodes.length - 1; index >= 0; index--) {
            if (this.transformNodes[index].id === id) {
                return this.transformNodes[index];
            }
        }
        for (index = this.cameras.length - 1; index >= 0; index--) {
            if (this.cameras[index].id === id) {
                return this.cameras[index];
            }
        }
        for (index = this.lights.length - 1; index >= 0; index--) {
            if (this.lights[index].id === id) {
                return this.lights[index];
            }
        }
        return null;
    };
    /**
     * Gets a node (Mesh, Camera, Light) using a given id
     * @param id defines the id to search for
     * @return the found node or null if not found at all
     */
    Scene.prototype.getNodeByID = function (id) {
        var mesh = this.getMeshByID(id);
        if (mesh) {
            return mesh;
        }
        var transformNode = this.getTransformNodeByID(id);
        if (transformNode) {
            return transformNode;
        }
        var light = this.getLightByID(id);
        if (light) {
            return light;
        }
        var camera = this.getCameraByID(id);
        if (camera) {
            return camera;
        }
        var bone = this.getBoneByID(id);
        if (bone) {
            return bone;
        }
        return null;
    };
    /**
     * Gets a node (Mesh, Camera, Light) using a given name
     * @param name defines the name to search for
     * @return the found node or null if not found at all.
     */
    Scene.prototype.getNodeByName = function (name) {
        var mesh = this.getMeshByName(name);
        if (mesh) {
            return mesh;
        }
        var transformNode = this.getTransformNodeByName(name);
        if (transformNode) {
            return transformNode;
        }
        var light = this.getLightByName(name);
        if (light) {
            return light;
        }
        var camera = this.getCameraByName(name);
        if (camera) {
            return camera;
        }
        var bone = this.getBoneByName(name);
        if (bone) {
            return bone;
        }
        return null;
    };
    /**
     * Gets a mesh using a given name
     * @param name defines the name to search for
     * @return the found mesh or null if not found at all.
     */
    Scene.prototype.getMeshByName = function (name) {
        for (var index = 0; index < this.meshes.length; index++) {
            if (this.meshes[index].name === name) {
                return this.meshes[index];
            }
        }
        return null;
    };
    /**
     * Gets a transform node using a given name
     * @param name defines the name to search for
     * @return the found transform node or null if not found at all.
     */
    Scene.prototype.getTransformNodeByName = function (name) {
        for (var index = 0; index < this.transformNodes.length; index++) {
            if (this.transformNodes[index].name === name) {
                return this.transformNodes[index];
            }
        }
        return null;
    };
    /**
     * Gets a skeleton using a given id (if many are found, this function will pick the last one)
     * @param id defines the id to search for
     * @return the found skeleton or null if not found at all.
     */
    Scene.prototype.getLastSkeletonByID = function (id) {
        for (var index = this.skeletons.length - 1; index >= 0; index--) {
            if (this.skeletons[index].id === id) {
                return this.skeletons[index];
            }
        }
        return null;
    };
    /**
     * Gets a skeleton using a given auto generated unique id
     * @param  uniqueId defines the unique id to search for
     * @return the found skeleton or null if not found at all.
     */
    Scene.prototype.getSkeletonByUniqueId = function (uniqueId) {
        for (var index = 0; index < this.skeletons.length; index++) {
            if (this.skeletons[index].uniqueId === uniqueId) {
                return this.skeletons[index];
            }
        }
        return null;
    };
    /**
     * Gets a skeleton using a given id (if many are found, this function will pick the first one)
     * @param id defines the id to search for
     * @return the found skeleton or null if not found at all.
     */
    Scene.prototype.getSkeletonById = function (id) {
        for (var index = 0; index < this.skeletons.length; index++) {
            if (this.skeletons[index].id === id) {
                return this.skeletons[index];
            }
        }
        return null;
    };
    /**
     * Gets a skeleton using a given name
     * @param name defines the name to search for
     * @return the found skeleton or null if not found at all.
     */
    Scene.prototype.getSkeletonByName = function (name) {
        for (var index = 0; index < this.skeletons.length; index++) {
            if (this.skeletons[index].name === name) {
                return this.skeletons[index];
            }
        }
        return null;
    };
    /**
     * Gets a morph target manager  using a given id (if many are found, this function will pick the last one)
     * @param id defines the id to search for
     * @return the found morph target manager or null if not found at all.
     */
    Scene.prototype.getMorphTargetManagerById = function (id) {
        for (var index = 0; index < this.morphTargetManagers.length; index++) {
            if (this.morphTargetManagers[index].uniqueId === id) {
                return this.morphTargetManagers[index];
            }
        }
        return null;
    };
    /**
     * Gets a morph target using a given id (if many are found, this function will pick the first one)
     * @param id defines the id to search for
     * @return the found morph target or null if not found at all.
     */
    Scene.prototype.getMorphTargetById = function (id) {
        for (var managerIndex = 0; managerIndex < this.morphTargetManagers.length; ++managerIndex) {
            var morphTargetManager = this.morphTargetManagers[managerIndex];
            for (var index = 0; index < morphTargetManager.numTargets; ++index) {
                var target = morphTargetManager.getTarget(index);
                if (target.id === id) {
                    return target;
                }
            }
        }
        return null;
    };
    /**
     * Gets a boolean indicating if the given mesh is active
     * @param mesh defines the mesh to look for
     * @returns true if the mesh is in the active list
     */
    Scene.prototype.isActiveMesh = function (mesh) {
        return (this._activeMeshes.indexOf(mesh) !== -1);
    };
    Object.defineProperty(Scene.prototype, "uid", {
        /**
         * Return a unique id as a string which can serve as an identifier for the scene
         */
        get: function () {
            if (!this._uid) {
                this._uid = _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].RandomId();
            }
            return this._uid;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Add an externaly attached data from its key.
     * This method call will fail and return false, if such key already exists.
     * If you don't care and just want to get the data no matter what, use the more convenient getOrAddExternalDataWithFactory() method.
     * @param key the unique key that identifies the data
     * @param data the data object to associate to the key for this Engine instance
     * @return true if no such key were already present and the data was added successfully, false otherwise
     */
    Scene.prototype.addExternalData = function (key, data) {
        if (!this._externalData) {
            this._externalData = new _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_5__["StringDictionary"]();
        }
        return this._externalData.add(key, data);
    };
    /**
     * Get an externaly attached data from its key
     * @param key the unique key that identifies the data
     * @return the associated data, if present (can be null), or undefined if not present
     */
    Scene.prototype.getExternalData = function (key) {
        if (!this._externalData) {
            return null;
        }
        return this._externalData.get(key);
    };
    /**
     * Get an externaly attached data from its key, create it using a factory if it's not already present
     * @param key the unique key that identifies the data
     * @param factory the factory that will be called to create the instance if and only if it doesn't exists
     * @return the associated data, can be null if the factory returned null.
     */
    Scene.prototype.getOrAddExternalDataWithFactory = function (key, factory) {
        if (!this._externalData) {
            this._externalData = new _Misc_stringDictionary__WEBPACK_IMPORTED_MODULE_5__["StringDictionary"]();
        }
        return this._externalData.getOrAddWithFactory(key, factory);
    };
    /**
     * Remove an externaly attached data from the Engine instance
     * @param key the unique key that identifies the data
     * @return true if the data was successfully removed, false if it doesn't exist
     */
    Scene.prototype.removeExternalData = function (key) {
        return this._externalData.remove(key);
    };
    Scene.prototype._evaluateSubMesh = function (subMesh, mesh, initialMesh) {
        if (initialMesh.hasInstances || initialMesh.isAnInstance || this.dispatchAllSubMeshesOfActiveMeshes || mesh.alwaysSelectAsActiveMesh || mesh.subMeshes.length === 1 || subMesh.isInFrustum(this._frustumPlanes)) {
            for (var _i = 0, _a = this._evaluateSubMeshStage; _i < _a.length; _i++) {
                var step = _a[_i];
                step.action(mesh, subMesh);
            }
            var material = subMesh.getMaterial();
            if (material !== null && material !== undefined) {
                // Render targets
                if (material.hasRenderTargetTextures && material.getRenderTargetTextures != null) {
                    if (this._processedMaterials.indexOf(material) === -1) {
                        this._processedMaterials.push(material);
                        this._renderTargets.concatWithNoDuplicate(material.getRenderTargetTextures());
                    }
                }
                // Dispatch
                this._activeIndices.addCount(subMesh.indexCount, false);
                this._renderingManager.dispatch(subMesh, mesh, material);
            }
        }
    };
    /**
     * Clear the processed materials smart array preventing retention point in material dispose.
     */
    Scene.prototype.freeProcessedMaterials = function () {
        this._processedMaterials.dispose();
    };
    Object.defineProperty(Scene.prototype, "blockfreeActiveMeshesAndRenderingGroups", {
        /** Gets or sets a boolean blocking all the calls to freeActiveMeshes and freeRenderingGroups
         * It can be used in order to prevent going through methods freeRenderingGroups and freeActiveMeshes several times to improve performance
         * when disposing several meshes in a row or a hierarchy of meshes.
         * When used, it is the responsability of the user to blockfreeActiveMeshesAndRenderingGroups back to false.
         */
        get: function () {
            return this._preventFreeActiveMeshesAndRenderingGroups;
        },
        set: function (value) {
            if (this._preventFreeActiveMeshesAndRenderingGroups === value) {
                return;
            }
            if (value) {
                this.freeActiveMeshes();
                this.freeRenderingGroups();
            }
            this._preventFreeActiveMeshesAndRenderingGroups = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Clear the active meshes smart array preventing retention point in mesh dispose.
     */
    Scene.prototype.freeActiveMeshes = function () {
        if (this.blockfreeActiveMeshesAndRenderingGroups) {
            return;
        }
        this._activeMeshes.dispose();
        if (this.activeCamera && this.activeCamera._activeMeshes) {
            this.activeCamera._activeMeshes.dispose();
        }
        if (this.activeCameras) {
            for (var i = 0; i < this.activeCameras.length; i++) {
                var activeCamera = this.activeCameras[i];
                if (activeCamera && activeCamera._activeMeshes) {
                    activeCamera._activeMeshes.dispose();
                }
            }
        }
    };
    /**
     * Clear the info related to rendering groups preventing retention points during dispose.
     */
    Scene.prototype.freeRenderingGroups = function () {
        if (this.blockfreeActiveMeshesAndRenderingGroups) {
            return;
        }
        if (this._renderingManager) {
            this._renderingManager.freeRenderingGroups();
        }
        if (this.textures) {
            for (var i = 0; i < this.textures.length; i++) {
                var texture = this.textures[i];
                if (texture && texture.renderList) {
                    texture.freeRenderingGroups();
                }
            }
        }
    };
    /** @hidden */
    Scene.prototype._isInIntermediateRendering = function () {
        return this._intermediateRendering;
    };
    /**
     * Use this function to stop evaluating active meshes. The current list will be keep alive between frames
     * @returns the current scene
     */
    Scene.prototype.freezeActiveMeshes = function () {
        if (!this.activeCamera) {
            return this;
        }
        if (!this._frustumPlanes) {
            this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix());
        }
        this._evaluateActiveMeshes();
        this._activeMeshesFrozen = true;
        for (var index = 0; index < this._activeMeshes.length; index++) {
            this._activeMeshes.data[index]._freeze();
        }
        return this;
    };
    /**
     * Use this function to restart evaluating active meshes on every frame
     * @returns the current scene
     */
    Scene.prototype.unfreezeActiveMeshes = function () {
        for (var index = 0; index < this.meshes.length; index++) {
            var mesh = this.meshes[index];
            if (mesh._internalAbstractMeshDataInfo) {
                mesh._internalAbstractMeshDataInfo._isActive = false;
            }
        }
        for (var index = 0; index < this._activeMeshes.length; index++) {
            this._activeMeshes.data[index]._unFreeze();
        }
        this._activeMeshesFrozen = false;
        return this;
    };
    Scene.prototype._evaluateActiveMeshes = function () {
        if (this._activeMeshesFrozen && this._activeMeshes.length) {
            var len_1 = this._activeMeshes.length;
            for (var i = 0; i < len_1; i++) {
                var mesh = this._activeMeshes.data[i];
                mesh.computeWorldMatrix();
            }
            return;
        }
        if (!this.activeCamera) {
            return;
        }
        this.onBeforeActiveMeshesEvaluationObservable.notifyObservers(this);
        this.activeCamera._activeMeshes.reset();
        this._activeMeshes.reset();
        this._renderingManager.reset();
        this._processedMaterials.reset();
        this._activeParticleSystems.reset();
        this._activeSkeletons.reset();
        this._softwareSkinnedMeshes.reset();
        for (var _i = 0, _a = this._beforeEvaluateActiveMeshStage; _i < _a.length; _i++) {
            var step = _a[_i];
            step.action();
        }
        // Determine mesh candidates
        var meshes = this.getActiveMeshCandidates();
        // Check each mesh
        var len = meshes.length;
        for (var i = 0; i < len; i++) {
            var mesh = meshes.data[i];
            if (mesh.isBlocked) {
                continue;
            }
            this._totalVertices.addCount(mesh.getTotalVertices(), false);
            if (!mesh.isReady() || !mesh.isEnabled() || mesh.scaling.lengthSquared() === 0) {
                continue;
            }
            mesh.computeWorldMatrix();
            // Intersections
            if (mesh.actionManager && mesh.actionManager.hasSpecificTriggers2(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionEnterTrigger, _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionExitTrigger)) {
                this._meshesForIntersections.pushNoDuplicate(mesh);
            }
            // Switch to current LOD
            var meshToRender = this.customLODSelector ? this.customLODSelector(mesh, this.activeCamera) : mesh.getLOD(this.activeCamera);
            if (meshToRender === undefined || meshToRender === null) {
                continue;
            }
            // Compute world matrix if LOD is billboard
            if (meshToRender !== mesh && meshToRender.billboardMode !== _Meshes_transformNode__WEBPACK_IMPORTED_MODULE_8__["TransformNode"].BILLBOARDMODE_NONE) {
                meshToRender.computeWorldMatrix();
            }
            mesh._preActivate();
            if (mesh.isVisible && mesh.visibility > 0 && ((mesh.layerMask & this.activeCamera.layerMask) !== 0) && (mesh.alwaysSelectAsActiveMesh || mesh.isInFrustum(this._frustumPlanes))) {
                this._activeMeshes.push(mesh);
                this.activeCamera._activeMeshes.push(mesh);
                if (meshToRender !== mesh) {
                    meshToRender._activate(this._renderId, false);
                }
                if (mesh._activate(this._renderId, false)) {
                    if (!mesh.isAnInstance) {
                        meshToRender._internalAbstractMeshDataInfo._onlyForInstances = false;
                    }
                    meshToRender._internalAbstractMeshDataInfo._isActive = true;
                    this._activeMesh(mesh, meshToRender);
                }
                mesh._postActivate();
            }
        }
        this.onAfterActiveMeshesEvaluationObservable.notifyObservers(this);
        // Particle systems
        if (this.particlesEnabled) {
            this.onBeforeParticlesRenderingObservable.notifyObservers(this);
            for (var particleIndex = 0; particleIndex < this.particleSystems.length; particleIndex++) {
                var particleSystem = this.particleSystems[particleIndex];
                if (!particleSystem.isStarted() || !particleSystem.emitter) {
                    continue;
                }
                var emitter = particleSystem.emitter;
                if (!emitter.position || emitter.isEnabled()) {
                    this._activeParticleSystems.push(particleSystem);
                    particleSystem.animate();
                    this._renderingManager.dispatchParticles(particleSystem);
                }
            }
            this.onAfterParticlesRenderingObservable.notifyObservers(this);
        }
    };
    Scene.prototype._activeMesh = function (sourceMesh, mesh) {
        if (this._skeletonsEnabled && mesh.skeleton !== null && mesh.skeleton !== undefined) {
            if (this._activeSkeletons.pushNoDuplicate(mesh.skeleton)) {
                mesh.skeleton.prepare();
            }
            if (!mesh.computeBonesUsingShaders) {
                this._softwareSkinnedMeshes.pushNoDuplicate(mesh);
            }
        }
        for (var _i = 0, _a = this._activeMeshStage; _i < _a.length; _i++) {
            var step = _a[_i];
            step.action(sourceMesh, mesh);
        }
        if (mesh !== undefined && mesh !== null
            && mesh.subMeshes !== undefined && mesh.subMeshes !== null && mesh.subMeshes.length > 0) {
            var subMeshes = this.getActiveSubMeshCandidates(mesh);
            var len = subMeshes.length;
            for (var i = 0; i < len; i++) {
                var subMesh = subMeshes.data[i];
                this._evaluateSubMesh(subMesh, mesh, sourceMesh);
            }
        }
    };
    /**
     * Update the transform matrix to update from the current active camera
     * @param force defines a boolean used to force the update even if cache is up to date
     */
    Scene.prototype.updateTransformMatrix = function (force) {
        if (!this.activeCamera) {
            return;
        }
        this.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(force));
    };
    Scene.prototype._bindFrameBuffer = function () {
        if (this.activeCamera && this.activeCamera._multiviewTexture) {
            this.activeCamera._multiviewTexture._bindFrameBuffer();
        }
        else if (this.activeCamera && this.activeCamera.outputRenderTarget) {
            var useMultiview = this.getEngine().getCaps().multiview && this.activeCamera.outputRenderTarget && this.activeCamera.outputRenderTarget.getViewCount() > 1;
            if (useMultiview) {
                this.activeCamera.outputRenderTarget._bindFrameBuffer();
            }
            else {
                var internalTexture = this.activeCamera.outputRenderTarget.getInternalTexture();
                if (internalTexture) {
                    this.getEngine().bindFramebuffer(internalTexture);
                }
                else {
                    _Misc_logger__WEBPACK_IMPORTED_MODULE_22__["Logger"].Error("Camera contains invalid customDefaultRenderTarget");
                }
            }
        }
        else {
            this.getEngine().restoreDefaultFramebuffer(); // Restore back buffer if needed
        }
    };
    /** @hidden */
    Scene.prototype._renderForCamera = function (camera, rigParent) {
        if (camera && camera._skipRendering) {
            return;
        }
        var engine = this._engine;
        // Use _activeCamera instead of activeCamera to avoid onActiveCameraChanged
        this._activeCamera = camera;
        if (!this.activeCamera) {
            throw new Error("Active camera not set");
        }
        // Viewport
        engine.setViewport(this.activeCamera.viewport);
        // Camera
        this.resetCachedMaterial();
        this._renderId++;
        var useMultiview = this.getEngine().getCaps().multiview && camera.outputRenderTarget && camera.outputRenderTarget.getViewCount() > 1;
        if (useMultiview) {
            this.setTransformMatrix(camera._rigCameras[0].getViewMatrix(), camera._rigCameras[0].getProjectionMatrix(), camera._rigCameras[1].getViewMatrix(), camera._rigCameras[1].getProjectionMatrix());
        }
        else {
            this.updateTransformMatrix();
        }
        this.onBeforeCameraRenderObservable.notifyObservers(this.activeCamera);
        // Meshes
        this._evaluateActiveMeshes();
        // Software skinning
        for (var softwareSkinnedMeshIndex = 0; softwareSkinnedMeshIndex < this._softwareSkinnedMeshes.length; softwareSkinnedMeshIndex++) {
            var mesh = this._softwareSkinnedMeshes.data[softwareSkinnedMeshIndex];
            mesh.applySkeleton(mesh.skeleton);
        }
        // Render targets
        this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);
        if (camera.customRenderTargets && camera.customRenderTargets.length > 0) {
            this._renderTargets.concatWithNoDuplicate(camera.customRenderTargets);
        }
        if (rigParent && rigParent.customRenderTargets && rigParent.customRenderTargets.length > 0) {
            this._renderTargets.concatWithNoDuplicate(rigParent.customRenderTargets);
        }
        // Collects render targets from external components.
        for (var _i = 0, _a = this._gatherActiveCameraRenderTargetsStage; _i < _a.length; _i++) {
            var step = _a[_i];
            step.action(this._renderTargets);
        }
        if (this.renderTargetsEnabled) {
            this._intermediateRendering = true;
            var needRebind = false;
            if (this._renderTargets.length > 0) {
                _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].StartPerformanceCounter("Render targets", this._renderTargets.length > 0);
                for (var renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {
                    var renderTarget = this._renderTargets.data[renderIndex];
                    if (renderTarget._shouldRender()) {
                        this._renderId++;
                        var hasSpecialRenderTargetCamera = renderTarget.activeCamera && renderTarget.activeCamera !== this.activeCamera;
                        renderTarget.render(hasSpecialRenderTargetCamera, this.dumpNextRenderTargets);
                        needRebind = true;
                    }
                }
                _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].EndPerformanceCounter("Render targets", this._renderTargets.length > 0);
                this._renderId++;
            }
            for (var _b = 0, _c = this._cameraDrawRenderTargetStage; _b < _c.length; _b++) {
                var step = _c[_b];
                needRebind = step.action(this.activeCamera) || needRebind;
            }
            this._intermediateRendering = false;
            // Need to bind if sub-camera has an outputRenderTarget eg. for webXR
            if (this.activeCamera && this.activeCamera.outputRenderTarget) {
                needRebind = true;
            }
            // Restore framebuffer after rendering to targets
            if (needRebind) {
                this._bindFrameBuffer();
            }
        }
        this.onAfterRenderTargetsRenderObservable.notifyObservers(this);
        // Prepare Frame
        if (this.postProcessManager && !camera._multiviewTexture) {
            this.postProcessManager._prepareFrame();
        }
        // Before Camera Draw
        for (var _d = 0, _e = this._beforeCameraDrawStage; _d < _e.length; _d++) {
            var step = _e[_d];
            step.action(this.activeCamera);
        }
        // Render
        this.onBeforeDrawPhaseObservable.notifyObservers(this);
        this._renderingManager.render(null, null, true, true);
        this.onAfterDrawPhaseObservable.notifyObservers(this);
        // After Camera Draw
        for (var _f = 0, _g = this._afterCameraDrawStage; _f < _g.length; _f++) {
            var step = _g[_f];
            step.action(this.activeCamera);
        }
        // Finalize frame
        if (this.postProcessManager && !camera._multiviewTexture) {
            this.postProcessManager._finalizeFrame(camera.isIntermediate);
        }
        // Reset some special arrays
        this._renderTargets.reset();
        this.onAfterCameraRenderObservable.notifyObservers(this.activeCamera);
    };
    Scene.prototype._processSubCameras = function (camera) {
        if (camera.cameraRigMode === _Cameras_camera__WEBPACK_IMPORTED_MODULE_10__["Camera"].RIG_MODE_NONE || (camera.outputRenderTarget && camera.outputRenderTarget.getViewCount() > 1 && this.getEngine().getCaps().multiview)) {
            this._renderForCamera(camera);
            this.onAfterRenderCameraObservable.notifyObservers(camera);
            return;
        }
        if (camera._useMultiviewToSingleView) {
            this._renderMultiviewToSingleView(camera);
        }
        else {
            // rig cameras
            for (var index = 0; index < camera._rigCameras.length; index++) {
                this._renderForCamera(camera._rigCameras[index], camera);
            }
        }
        // Use _activeCamera instead of activeCamera to avoid onActiveCameraChanged
        this._activeCamera = camera;
        this.setTransformMatrix(this._activeCamera.getViewMatrix(), this._activeCamera.getProjectionMatrix());
        this.onAfterRenderCameraObservable.notifyObservers(camera);
    };
    Scene.prototype._checkIntersections = function () {
        for (var index = 0; index < this._meshesForIntersections.length; index++) {
            var sourceMesh = this._meshesForIntersections.data[index];
            if (!sourceMesh.actionManager) {
                continue;
            }
            for (var actionIndex = 0; sourceMesh.actionManager && actionIndex < sourceMesh.actionManager.actions.length; actionIndex++) {
                var action = sourceMesh.actionManager.actions[actionIndex];
                if (action.trigger === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionEnterTrigger || action.trigger === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionExitTrigger) {
                    var parameters = action.getTriggerParameter();
                    var otherMesh = parameters instanceof _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_9__["AbstractMesh"] ? parameters : parameters.mesh;
                    var areIntersecting = otherMesh.intersectsMesh(sourceMesh, parameters.usePreciseIntersection);
                    var currentIntersectionInProgress = sourceMesh._intersectionsInProgress.indexOf(otherMesh);
                    if (areIntersecting && currentIntersectionInProgress === -1) {
                        if (action.trigger === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionEnterTrigger) {
                            action._executeCurrent(_Actions_actionEvent__WEBPACK_IMPORTED_MODULE_16__["ActionEvent"].CreateNew(sourceMesh, undefined, otherMesh));
                            sourceMesh._intersectionsInProgress.push(otherMesh);
                        }
                        else if (action.trigger === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionExitTrigger) {
                            sourceMesh._intersectionsInProgress.push(otherMesh);
                        }
                    }
                    else if (!areIntersecting && currentIntersectionInProgress > -1) {
                        //They intersected, and now they don't.
                        //is this trigger an exit trigger? execute an event.
                        if (action.trigger === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionExitTrigger) {
                            action._executeCurrent(_Actions_actionEvent__WEBPACK_IMPORTED_MODULE_16__["ActionEvent"].CreateNew(sourceMesh, undefined, otherMesh));
                        }
                        //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
                        if (!sourceMesh.actionManager.hasSpecificTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionExitTrigger, function (parameter) {
                            var parameterMesh = parameter instanceof _Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_9__["AbstractMesh"] ? parameter : parameter.mesh;
                            return otherMesh === parameterMesh;
                        }) || action.trigger === _Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnIntersectionExitTrigger) {
                            sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                        }
                    }
                }
            }
        }
    };
    /** @hidden */
    Scene.prototype._advancePhysicsEngineStep = function (step) {
        // Do nothing. Code will be replaced if physics engine component is referenced
    };
    /** @hidden */
    Scene.prototype._animate = function () {
        // Nothing to do as long as Animatable have not been imported.
    };
    /** Execute all animations (for a frame) */
    Scene.prototype.animate = function () {
        if (this._engine.isDeterministicLockStep()) {
            var deltaTime = Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime)) + this._timeAccumulator;
            var defaultFPS = (60.0 / 1000.0);
            var defaultFrameTime = this.getDeterministicFrameTime();
            var stepsTaken = 0;
            var maxSubSteps = this._engine.getLockstepMaxSteps();
            var internalSteps = Math.floor(deltaTime / (1000 * defaultFPS));
            internalSteps = Math.min(internalSteps, maxSubSteps);
            do {
                this.onBeforeStepObservable.notifyObservers(this);
                // Animations
                this._animationRatio = defaultFrameTime * defaultFPS;
                this._animate();
                this.onAfterAnimationsObservable.notifyObservers(this);
                // Physics
                this._advancePhysicsEngineStep(defaultFrameTime);
                this.onAfterStepObservable.notifyObservers(this);
                this._currentStepId++;
                stepsTaken++;
                deltaTime -= defaultFrameTime;
            } while (deltaTime > 0 && stepsTaken < internalSteps);
            this._timeAccumulator = deltaTime < 0 ? 0 : deltaTime;
        }
        else {
            // Animations
            var deltaTime = this.useConstantAnimationDeltaTime ? 16 : Math.max(Scene.MinDeltaTime, Math.min(this._engine.getDeltaTime(), Scene.MaxDeltaTime));
            this._animationRatio = deltaTime * (60.0 / 1000.0);
            this._animate();
            this.onAfterAnimationsObservable.notifyObservers(this);
            // Physics
            this._advancePhysicsEngineStep(deltaTime);
        }
    };
    /**
     * Render the scene
     * @param updateCameras defines a boolean indicating if cameras must update according to their inputs (true by default)
     * @param ignoreAnimations defines a boolean indicating if animations should not be executed (false by default)
     */
    Scene.prototype.render = function (updateCameras, ignoreAnimations) {
        if (updateCameras === void 0) { updateCameras = true; }
        if (ignoreAnimations === void 0) { ignoreAnimations = false; }
        if (this.isDisposed) {
            return;
        }
        this._frameId++;
        // Register components that have been associated lately to the scene.
        this._registerTransientComponents();
        this._activeParticles.fetchNewFrame();
        this._totalVertices.fetchNewFrame();
        this._activeIndices.fetchNewFrame();
        this._activeBones.fetchNewFrame();
        this._meshesForIntersections.reset();
        this.resetCachedMaterial();
        this.onBeforeAnimationsObservable.notifyObservers(this);
        // Actions
        if (this.actionManager) {
            this.actionManager.processTrigger(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].ACTION_OnEveryFrameTrigger);
        }
        // Animations
        if (!ignoreAnimations) {
            this.animate();
        }
        // Before camera update steps
        for (var _i = 0, _a = this._beforeCameraUpdateStage; _i < _a.length; _i++) {
            var step = _a[_i];
            step.action();
        }
        // Update Cameras
        if (updateCameras) {
            if (this.activeCameras.length > 0) {
                for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
                    var camera = this.activeCameras[cameraIndex];
                    camera.update();
                    if (camera.cameraRigMode !== _Cameras_camera__WEBPACK_IMPORTED_MODULE_10__["Camera"].RIG_MODE_NONE) {
                        // rig cameras
                        for (var index = 0; index < camera._rigCameras.length; index++) {
                            camera._rigCameras[index].update();
                        }
                    }
                }
            }
            else if (this.activeCamera) {
                this.activeCamera.update();
                if (this.activeCamera.cameraRigMode !== _Cameras_camera__WEBPACK_IMPORTED_MODULE_10__["Camera"].RIG_MODE_NONE) {
                    // rig cameras
                    for (var index = 0; index < this.activeCamera._rigCameras.length; index++) {
                        this.activeCamera._rigCameras[index].update();
                    }
                }
            }
        }
        // Before render
        this.onBeforeRenderObservable.notifyObservers(this);
        var engine = this.getEngine();
        if (engine._shouldOnlyUpdateCameras()) {
            if (this.activeCameras.length) {
                for (var cameraIndex_1 = 0; cameraIndex_1 < this.activeCameras.length; cameraIndex_1++) {
                    var camera = this.activeCameras[cameraIndex_1];
                    this.setTransformMatrix(camera.getViewMatrix(), camera.getProjectionMatrix());
                }
            }
            else {
                var camera = this.activeCamera;
                this.setTransformMatrix(camera.getViewMatrix(), camera.getProjectionMatrix());
            }
            return;
        }
        // Customs render targets
        this.onBeforeRenderTargetsRenderObservable.notifyObservers(this);
        var currentActiveCamera = this.activeCamera;
        if (this.renderTargetsEnabled) {
            _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].StartPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
            this._intermediateRendering = true;
            for (var customIndex = 0; customIndex < this.customRenderTargets.length; customIndex++) {
                var renderTarget = this.customRenderTargets[customIndex];
                if (renderTarget._shouldRender()) {
                    this._renderId++;
                    this.activeCamera = renderTarget.activeCamera || this.activeCamera;
                    if (!this.activeCamera) {
                        throw new Error("Active camera not set");
                    }
                    // Viewport
                    engine.setViewport(this.activeCamera.viewport);
                    // Camera
                    this.updateTransformMatrix();
                    renderTarget.render(currentActiveCamera !== this.activeCamera, this.dumpNextRenderTargets);
                }
            }
            _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].EndPerformanceCounter("Custom render targets", this.customRenderTargets.length > 0);
            this._intermediateRendering = false;
            this._renderId++;
        }
        // Restore back buffer
        this.activeCamera = currentActiveCamera;
        this._bindFrameBuffer();
        this.onAfterRenderTargetsRenderObservable.notifyObservers(this);
        for (var _b = 0, _c = this._beforeClearStage; _b < _c.length; _b++) {
            var step = _c[_b];
            step.action();
        }
        // Clear
        if (this.autoClearDepthAndStencil || this.autoClear) {
            this._engine.clear(this.clearColor, this.autoClear || this.forceWireframe || this.forcePointsCloud, this.autoClearDepthAndStencil, this.autoClearDepthAndStencil);
        }
        // Collects render targets from external components.
        for (var _d = 0, _e = this._gatherRenderTargetsStage; _d < _e.length; _d++) {
            var step = _e[_d];
            step.action(this._renderTargets);
        }
        // Multi-cameras?
        if (this.activeCameras.length > 0) {
            for (var cameraIndex = 0; cameraIndex < this.activeCameras.length; cameraIndex++) {
                if (cameraIndex > 0) {
                    this._engine.clear(null, false, true, true);
                }
                this._processSubCameras(this.activeCameras[cameraIndex]);
            }
        }
        else {
            if (!this.activeCamera) {
                throw new Error("No camera defined");
            }
            this._processSubCameras(this.activeCamera);
        }
        // Intersection checks
        this._checkIntersections();
        // Executes the after render stage actions.
        for (var _f = 0, _g = this._afterRenderStage; _f < _g.length; _f++) {
            var step = _g[_f];
            step.action();
        }
        // After render
        if (this.afterRender) {
            this.afterRender();
        }
        this.onAfterRenderObservable.notifyObservers(this);
        // Cleaning
        if (this._toBeDisposed.length) {
            for (var index = 0; index < this._toBeDisposed.length; index++) {
                var data = this._toBeDisposed[index];
                if (data) {
                    data.dispose();
                }
            }
            this._toBeDisposed = [];
        }
        if (this.dumpNextRenderTargets) {
            this.dumpNextRenderTargets = false;
        }
        this._activeBones.addCount(0, true);
        this._activeIndices.addCount(0, true);
        this._activeParticles.addCount(0, true);
    };
    /**
     * Freeze all materials
     * A frozen material will not be updatable but should be faster to render
     */
    Scene.prototype.freezeMaterials = function () {
        for (var i = 0; i < this.materials.length; i++) {
            this.materials[i].freeze();
        }
    };
    /**
     * Unfreeze all materials
     * A frozen material will not be updatable but should be faster to render
     */
    Scene.prototype.unfreezeMaterials = function () {
        for (var i = 0; i < this.materials.length; i++) {
            this.materials[i].unfreeze();
        }
    };
    /**
     * Releases all held ressources
     */
    Scene.prototype.dispose = function () {
        this.beforeRender = null;
        this.afterRender = null;
        if (_Engines_engineStore__WEBPACK_IMPORTED_MODULE_23__["EngineStore"]._LastCreatedScene === this) {
            _Engines_engineStore__WEBPACK_IMPORTED_MODULE_23__["EngineStore"]._LastCreatedScene = null;
        }
        this.skeletons = [];
        this.morphTargetManagers = [];
        this._transientComponents = [];
        this._isReadyForMeshStage.clear();
        this._beforeEvaluateActiveMeshStage.clear();
        this._evaluateSubMeshStage.clear();
        this._activeMeshStage.clear();
        this._cameraDrawRenderTargetStage.clear();
        this._beforeCameraDrawStage.clear();
        this._beforeRenderTargetDrawStage.clear();
        this._beforeRenderingGroupDrawStage.clear();
        this._beforeRenderingMeshStage.clear();
        this._afterRenderingMeshStage.clear();
        this._afterRenderingGroupDrawStage.clear();
        this._afterCameraDrawStage.clear();
        this._afterRenderTargetDrawStage.clear();
        this._afterRenderStage.clear();
        this._beforeCameraUpdateStage.clear();
        this._beforeClearStage.clear();
        this._gatherRenderTargetsStage.clear();
        this._gatherActiveCameraRenderTargetsStage.clear();
        this._pointerMoveStage.clear();
        this._pointerDownStage.clear();
        this._pointerUpStage.clear();
        for (var _i = 0, _a = this._components; _i < _a.length; _i++) {
            var component = _a[_i];
            component.dispose();
        }
        this.importedMeshesFiles = new Array();
        if (this.stopAllAnimations) {
            this.stopAllAnimations();
        }
        this.resetCachedMaterial();
        // Smart arrays
        if (this.activeCamera) {
            this.activeCamera._activeMeshes.dispose();
            this.activeCamera = null;
        }
        this._activeMeshes.dispose();
        this._renderingManager.dispose();
        this._processedMaterials.dispose();
        this._activeParticleSystems.dispose();
        this._activeSkeletons.dispose();
        this._softwareSkinnedMeshes.dispose();
        this._renderTargets.dispose();
        this._registeredForLateAnimationBindings.dispose();
        this._meshesForIntersections.dispose();
        this._toBeDisposed = [];
        // Abort active requests
        for (var _b = 0, _c = this._activeRequests; _b < _c.length; _b++) {
            var request = _c[_b];
            request.abort();
        }
        // Events
        this.onDisposeObservable.notifyObservers(this);
        this.onDisposeObservable.clear();
        this.onBeforeRenderObservable.clear();
        this.onAfterRenderObservable.clear();
        this.onBeforeRenderTargetsRenderObservable.clear();
        this.onAfterRenderTargetsRenderObservable.clear();
        this.onAfterStepObservable.clear();
        this.onBeforeStepObservable.clear();
        this.onBeforeActiveMeshesEvaluationObservable.clear();
        this.onAfterActiveMeshesEvaluationObservable.clear();
        this.onBeforeParticlesRenderingObservable.clear();
        this.onAfterParticlesRenderingObservable.clear();
        this.onBeforeDrawPhaseObservable.clear();
        this.onAfterDrawPhaseObservable.clear();
        this.onBeforeAnimationsObservable.clear();
        this.onAfterAnimationsObservable.clear();
        this.onDataLoadedObservable.clear();
        this.onBeforeRenderingGroupObservable.clear();
        this.onAfterRenderingGroupObservable.clear();
        this.onMeshImportedObservable.clear();
        this.onBeforeCameraRenderObservable.clear();
        this.onAfterCameraRenderObservable.clear();
        this.onReadyObservable.clear();
        this.onNewCameraAddedObservable.clear();
        this.onCameraRemovedObservable.clear();
        this.onNewLightAddedObservable.clear();
        this.onLightRemovedObservable.clear();
        this.onNewGeometryAddedObservable.clear();
        this.onGeometryRemovedObservable.clear();
        this.onNewTransformNodeAddedObservable.clear();
        this.onTransformNodeRemovedObservable.clear();
        this.onNewMeshAddedObservable.clear();
        this.onMeshRemovedObservable.clear();
        this.onNewSkeletonAddedObservable.clear();
        this.onSkeletonRemovedObservable.clear();
        this.onNewMaterialAddedObservable.clear();
        this.onMaterialRemovedObservable.clear();
        this.onNewTextureAddedObservable.clear();
        this.onTextureRemovedObservable.clear();
        this.onPrePointerObservable.clear();
        this.onPointerObservable.clear();
        this.onPreKeyboardObservable.clear();
        this.onKeyboardObservable.clear();
        this.onActiveCameraChanged.clear();
        this.detachControl();
        // Detach cameras
        var canvas = this._engine.getRenderingCanvas();
        if (canvas) {
            var index;
            for (index = 0; index < this.cameras.length; index++) {
                this.cameras[index].detachControl(canvas);
            }
        }
        // Release animation groups
        while (this.animationGroups.length) {
            this.animationGroups[0].dispose();
        }
        // Release lights
        while (this.lights.length) {
            this.lights[0].dispose();
        }
        // Release meshes
        while (this.meshes.length) {
            this.meshes[0].dispose(true);
        }
        while (this.transformNodes.length) {
            this.transformNodes[0].dispose(true);
        }
        // Release cameras
        while (this.cameras.length) {
            this.cameras[0].dispose();
        }
        // Release materials
        if (this._defaultMaterial) {
            this._defaultMaterial.dispose();
        }
        while (this.multiMaterials.length) {
            this.multiMaterials[0].dispose();
        }
        while (this.materials.length) {
            this.materials[0].dispose();
        }
        // Release particles
        while (this.particleSystems.length) {
            this.particleSystems[0].dispose();
        }
        // Release postProcesses
        while (this.postProcesses.length) {
            this.postProcesses[0].dispose();
        }
        // Release textures
        while (this.textures.length) {
            this.textures[0].dispose();
        }
        // Release UBO
        this._sceneUbo.dispose();
        if (this._multiviewSceneUbo) {
            this._multiviewSceneUbo.dispose();
        }
        // Post-processes
        this.postProcessManager.dispose();
        // Remove from engine
        index = this._engine.scenes.indexOf(this);
        if (index > -1) {
            this._engine.scenes.splice(index, 1);
        }
        this._engine.wipeCaches(true);
        this._isDisposed = true;
    };
    Object.defineProperty(Scene.prototype, "isDisposed", {
        /**
         * Gets if the scene is already disposed
         */
        get: function () {
            return this._isDisposed;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Call this function to reduce memory footprint of the scene.
     * Vertex buffers will not store CPU data anymore (this will prevent picking, collisions or physics to work correctly)
     */
    Scene.prototype.clearCachedVertexData = function () {
        for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
            var mesh = this.meshes[meshIndex];
            var geometry = mesh.geometry;
            if (geometry) {
                geometry._indices = [];
                for (var vbName in geometry._vertexBuffers) {
                    if (!geometry._vertexBuffers.hasOwnProperty(vbName)) {
                        continue;
                    }
                    geometry._vertexBuffers[vbName]._buffer._data = null;
                }
            }
        }
    };
    /**
     * This function will remove the local cached buffer data from texture.
     * It will save memory but will prevent the texture from being rebuilt
     */
    Scene.prototype.cleanCachedTextureBuffer = function () {
        for (var _i = 0, _a = this.textures; _i < _a.length; _i++) {
            var baseTexture = _a[_i];
            var buffer = baseTexture._buffer;
            if (buffer) {
                baseTexture._buffer = null;
            }
        }
    };
    /**
     * Get the world extend vectors with an optional filter
     *
     * @param filterPredicate the predicate - which meshes should be included when calculating the world size
     * @returns {{ min: Vector3; max: Vector3 }} min and max vectors
     */
    Scene.prototype.getWorldExtends = function (filterPredicate) {
        var min = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"](Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
        var max = new _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"](-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
        filterPredicate = filterPredicate || (function () { return true; });
        this.meshes.filter(filterPredicate).forEach(function (mesh) {
            mesh.computeWorldMatrix(true);
            if (!mesh.subMeshes || mesh.subMeshes.length === 0 || mesh.infiniteDistance) {
                return;
            }
            var boundingInfo = mesh.getBoundingInfo();
            var minBox = boundingInfo.boundingBox.minimumWorld;
            var maxBox = boundingInfo.boundingBox.maximumWorld;
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].CheckExtends(minBox, min, max);
            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_7__["Vector3"].CheckExtends(maxBox, min, max);
        });
        return {
            min: min,
            max: max
        };
    };
    // Picking
    /**
     * Creates a ray that can be used to pick in the scene
     * @param x defines the x coordinate of the origin (on-screen)
     * @param y defines the y coordinate of the origin (on-screen)
     * @param world defines the world matrix to use if you want to pick in object space (instead of world space)
     * @param camera defines the camera to use for the picking
     * @param cameraViewSpace defines if picking will be done in view space (false by default)
     * @returns a Ray
     */
    Scene.prototype.createPickingRay = function (x, y, world, camera, cameraViewSpace) {
        if (cameraViewSpace === void 0) { cameraViewSpace = false; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Creates a ray that can be used to pick in the scene
     * @param x defines the x coordinate of the origin (on-screen)
     * @param y defines the y coordinate of the origin (on-screen)
     * @param world defines the world matrix to use if you want to pick in object space (instead of world space)
     * @param result defines the ray where to store the picking ray
     * @param camera defines the camera to use for the picking
     * @param cameraViewSpace defines if picking will be done in view space (false by default)
     * @returns the current scene
     */
    Scene.prototype.createPickingRayToRef = function (x, y, world, result, camera, cameraViewSpace) {
        if (cameraViewSpace === void 0) { cameraViewSpace = false; }
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Creates a ray that can be used to pick in the scene
     * @param x defines the x coordinate of the origin (on-screen)
     * @param y defines the y coordinate of the origin (on-screen)
     * @param camera defines the camera to use for the picking
     * @returns a Ray
     */
    Scene.prototype.createPickingRayInCameraSpace = function (x, y, camera) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Creates a ray that can be used to pick in the scene
     * @param x defines the x coordinate of the origin (on-screen)
     * @param y defines the y coordinate of the origin (on-screen)
     * @param result defines the ray where to store the picking ray
     * @param camera defines the camera to use for the picking
     * @returns the current scene
     */
    Scene.prototype.createPickingRayInCameraSpaceToRef = function (x, y, result, camera) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /** Launch a ray to try to pick a mesh in the scene
     * @param x position on screen
     * @param y position on screen
     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true
     * @param fastCheck Launch a fast check only using the bounding boxes. Can be set to null.
     * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used
     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
     * @returns a PickingInfo
     */
    Scene.prototype.pick = function (x, y, predicate, fastCheck, camera, trianglePredicate) {
        // Dummy info if picking as not been imported
        var pi = new _Collisions_pickingInfo__WEBPACK_IMPORTED_MODULE_15__["PickingInfo"]();
        pi._pickingUnavailable = true;
        return pi;
    };
    /** Use the given ray to pick a mesh in the scene
     * @param ray The ray to use to pick meshes
     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must have isPickable set to true
     * @param fastCheck Launch a fast check only using the bounding boxes. Can be set to null
     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
     * @returns a PickingInfo
     */
    Scene.prototype.pickWithRay = function (ray, predicate, fastCheck, trianglePredicate) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Launch a ray to try to pick a mesh in the scene
     * @param x X position on screen
     * @param y Y position on screen
     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true
     * @param camera camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used
     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
     * @returns an array of PickingInfo
     */
    Scene.prototype.multiPick = function (x, y, predicate, camera, trianglePredicate) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Launch a ray to try to pick a mesh in the scene
     * @param ray Ray to use
     * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true
     * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
     * @returns an array of PickingInfo
     */
    Scene.prototype.multiPickWithRay = function (ray, predicate, trianglePredicate) {
        throw _Misc_devTools__WEBPACK_IMPORTED_MODULE_24__["_DevTools"].WarnImport("Ray");
    };
    /**
     * Force the value of meshUnderPointer
     * @param mesh defines the mesh to use
     */
    Scene.prototype.setPointerOverMesh = function (mesh) {
        this._inputManager.setPointerOverMesh(mesh);
    };
    /**
     * Gets the mesh under the pointer
     * @returns a Mesh or null if no mesh is under the pointer
     */
    Scene.prototype.getPointerOverMesh = function () {
        return this._inputManager.getPointerOverMesh();
    };
    // Misc.
    /** @hidden */
    Scene.prototype._rebuildGeometries = function () {
        for (var _i = 0, _a = this.geometries; _i < _a.length; _i++) {
            var geometry = _a[_i];
            geometry._rebuild();
        }
        for (var _b = 0, _c = this.meshes; _b < _c.length; _b++) {
            var mesh = _c[_b];
            mesh._rebuild();
        }
        if (this.postProcessManager) {
            this.postProcessManager._rebuild();
        }
        for (var _d = 0, _e = this._components; _d < _e.length; _d++) {
            var component = _e[_d];
            component.rebuild();
        }
        for (var _f = 0, _g = this.particleSystems; _f < _g.length; _f++) {
            var system = _g[_f];
            system.rebuild();
        }
    };
    /** @hidden */
    Scene.prototype._rebuildTextures = function () {
        for (var _i = 0, _a = this.textures; _i < _a.length; _i++) {
            var texture = _a[_i];
            texture._rebuild();
        }
        this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_TextureDirtyFlag);
    };
    // Tags
    Scene.prototype._getByTags = function (list, tagsQuery, forEach) {
        if (tagsQuery === undefined) {
            // returns the complete list (could be done with Tags.MatchesQuery but no need to have a for-loop here)
            return list;
        }
        var listByTags = [];
        forEach = forEach || (function (item) { return; });
        for (var i in list) {
            var item = list[i];
            if (_Misc_tags__WEBPACK_IMPORTED_MODULE_6__["Tags"] && _Misc_tags__WEBPACK_IMPORTED_MODULE_6__["Tags"].MatchesQuery(item, tagsQuery)) {
                listByTags.push(item);
                forEach(item);
            }
        }
        return listByTags;
    };
    /**
     * Get a list of meshes by tags
     * @param tagsQuery defines the tags query to use
     * @param forEach defines a predicate used to filter results
     * @returns an array of Mesh
     */
    Scene.prototype.getMeshesByTags = function (tagsQuery, forEach) {
        return this._getByTags(this.meshes, tagsQuery, forEach);
    };
    /**
     * Get a list of cameras by tags
     * @param tagsQuery defines the tags query to use
     * @param forEach defines a predicate used to filter results
     * @returns an array of Camera
     */
    Scene.prototype.getCamerasByTags = function (tagsQuery, forEach) {
        return this._getByTags(this.cameras, tagsQuery, forEach);
    };
    /**
     * Get a list of lights by tags
     * @param tagsQuery defines the tags query to use
     * @param forEach defines a predicate used to filter results
     * @returns an array of Light
     */
    Scene.prototype.getLightsByTags = function (tagsQuery, forEach) {
        return this._getByTags(this.lights, tagsQuery, forEach);
    };
    /**
     * Get a list of materials by tags
     * @param tagsQuery defines the tags query to use
     * @param forEach defines a predicate used to filter results
     * @returns an array of Material
     */
    Scene.prototype.getMaterialByTags = function (tagsQuery, forEach) {
        return this._getByTags(this.materials, tagsQuery, forEach).concat(this._getByTags(this.multiMaterials, tagsQuery, forEach));
    };
    /**
     * Overrides the default sort function applied in the renderging group to prepare the meshes.
     * This allowed control for front to back rendering or reversly depending of the special needs.
     *
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param opaqueSortCompareFn The opaque queue comparison function use to sort.
     * @param alphaTestSortCompareFn The alpha test queue comparison function use to sort.
     * @param transparentSortCompareFn The transparent queue comparison function use to sort.
     */
    Scene.prototype.setRenderingOrder = function (renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn) {
        if (opaqueSortCompareFn === void 0) { opaqueSortCompareFn = null; }
        if (alphaTestSortCompareFn === void 0) { alphaTestSortCompareFn = null; }
        if (transparentSortCompareFn === void 0) { transparentSortCompareFn = null; }
        this._renderingManager.setRenderingOrder(renderingGroupId, opaqueSortCompareFn, alphaTestSortCompareFn, transparentSortCompareFn);
    };
    /**
     * Specifies whether or not the stencil and depth buffer are cleared between two rendering groups.
     *
     * @param renderingGroupId The rendering group id corresponding to its index
     * @param autoClearDepthStencil Automatically clears depth and stencil between groups if true.
     * @param depth Automatically clears depth between groups if true and autoClear is true.
     * @param stencil Automatically clears stencil between groups if true and autoClear is true.
     */
    Scene.prototype.setRenderingAutoClearDepthStencil = function (renderingGroupId, autoClearDepthStencil, depth, stencil) {
        if (depth === void 0) { depth = true; }
        if (stencil === void 0) { stencil = true; }
        this._renderingManager.setRenderingAutoClearDepthStencil(renderingGroupId, autoClearDepthStencil, depth, stencil);
    };
    /**
     * Gets the current auto clear configuration for one rendering group of the rendering
     * manager.
     * @param index the rendering group index to get the information for
     * @returns The auto clear setup for the requested rendering group
     */
    Scene.prototype.getAutoClearDepthStencilSetup = function (index) {
        return this._renderingManager.getAutoClearDepthStencilSetup(index);
    };
    Object.defineProperty(Scene.prototype, "blockMaterialDirtyMechanism", {
        /** Gets or sets a boolean blocking all the calls to markAllMaterialsAsDirty (ie. the materials won't be updated if they are out of sync) */
        get: function () {
            return this._blockMaterialDirtyMechanism;
        },
        set: function (value) {
            if (this._blockMaterialDirtyMechanism === value) {
                return;
            }
            this._blockMaterialDirtyMechanism = value;
            if (!value) { // Do a complete update
                this.markAllMaterialsAsDirty(_Engines_constants__WEBPACK_IMPORTED_MODULE_20__["Constants"].MATERIAL_AllDirtyFlag);
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Will flag all materials as dirty to trigger new shader compilation
     * @param flag defines the flag used to specify which material part must be marked as dirty
     * @param predicate If not null, it will be used to specifiy if a material has to be marked as dirty
     */
    Scene.prototype.markAllMaterialsAsDirty = function (flag, predicate) {
        if (this._blockMaterialDirtyMechanism) {
            return;
        }
        for (var _i = 0, _a = this.materials; _i < _a.length; _i++) {
            var material = _a[_i];
            if (predicate && !predicate(material)) {
                continue;
            }
            material.markAsDirty(flag);
        }
    };
    /** @hidden */
    Scene.prototype._loadFile = function (url, onSuccess, onProgress, useOfflineSupport, useArrayBuffer, onError) {
        var _this = this;
        var request = _Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].LoadFile(url, onSuccess, onProgress, useOfflineSupport ? this.offlineProvider : undefined, useArrayBuffer, onError);
        this._activeRequests.push(request);
        request.onCompleteObservable.add(function (request) {
            _this._activeRequests.splice(_this._activeRequests.indexOf(request), 1);
        });
        return request;
    };
    /** @hidden */
    Scene.prototype._loadFileAsync = function (url, useOfflineSupport, useArrayBuffer) {
        var _this = this;
        return new Promise(function (resolve, reject) {
            _this._loadFile(url, function (data) {
                resolve(data);
            }, undefined, useOfflineSupport, useArrayBuffer, function (request, exception) {
                reject(exception);
            });
        });
    };
    /** The fog is deactivated */
    Scene.FOGMODE_NONE = 0;
    /** The fog density is following an exponential function */
    Scene.FOGMODE_EXP = 1;
    /** The fog density is following an exponential function faster than FOGMODE_EXP */
    Scene.FOGMODE_EXP2 = 2;
    /** The fog density is following a linear function. */
    Scene.FOGMODE_LINEAR = 3;
    /**
     * Gets or sets the minimum deltatime when deterministic lock step is enabled
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     */
    Scene.MinDeltaTime = 1.0;
    /**
     * Gets or sets the maximum deltatime when deterministic lock step is enabled
     * @see http://doc.babylonjs.com/babylon101/animations#deterministic-lockstep
     */
    Scene.MaxDeltaTime = 1000.0;
    return Scene;
}(_abstractScene__WEBPACK_IMPORTED_MODULE_11__["AbstractScene"]));



/***/ }),

/***/ "./sceneComponent.ts":
/*!***************************!*\
  !*** ./sceneComponent.ts ***!
  \***************************/
/*! exports provided: SceneComponentConstants, Stage */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SceneComponentConstants", function() { return SceneComponentConstants; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Stage", function() { return Stage; });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../node_modules/tslib/tslib.es6.js");

/**
 * Groups all the scene component constants in one place to ease maintenance.
 * @hidden
 */
var SceneComponentConstants = /** @class */ (function () {
    function SceneComponentConstants() {
    }
    SceneComponentConstants.NAME_EFFECTLAYER = "EffectLayer";
    SceneComponentConstants.NAME_LAYER = "Layer";
    SceneComponentConstants.NAME_LENSFLARESYSTEM = "LensFlareSystem";
    SceneComponentConstants.NAME_BOUNDINGBOXRENDERER = "BoundingBoxRenderer";
    SceneComponentConstants.NAME_PARTICLESYSTEM = "ParticleSystem";
    SceneComponentConstants.NAME_GAMEPAD = "Gamepad";
    SceneComponentConstants.NAME_SIMPLIFICATIONQUEUE = "SimplificationQueue";
    SceneComponentConstants.NAME_GEOMETRYBUFFERRENDERER = "GeometryBufferRenderer";
    SceneComponentConstants.NAME_DEPTHRENDERER = "DepthRenderer";
    SceneComponentConstants.NAME_POSTPROCESSRENDERPIPELINEMANAGER = "PostProcessRenderPipelineManager";
    SceneComponentConstants.NAME_SPRITE = "Sprite";
    SceneComponentConstants.NAME_OUTLINERENDERER = "Outline";
    SceneComponentConstants.NAME_PROCEDURALTEXTURE = "ProceduralTexture";
    SceneComponentConstants.NAME_SHADOWGENERATOR = "ShadowGenerator";
    SceneComponentConstants.NAME_OCTREE = "Octree";
    SceneComponentConstants.NAME_PHYSICSENGINE = "PhysicsEngine";
    SceneComponentConstants.NAME_AUDIO = "Audio";
    SceneComponentConstants.STEP_ISREADYFORMESH_EFFECTLAYER = 0;
    SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER = 0;
    SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER = 0;
    SceneComponentConstants.STEP_ACTIVEMESH_BOUNDINGBOXRENDERER = 0;
    SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
    SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
    SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
    SceneComponentConstants.STEP_BEFORERENDERTARGETDRAW_LAYER = 0;
    SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
    SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
    SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
    SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_BOUNDINGBOXRENDERER = 1;
    SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
    SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
    SceneComponentConstants.STEP_BEFORECLEAR_PROCEDURALTEXTURE = 0;
    SceneComponentConstants.STEP_AFTERRENDERTARGETDRAW_LAYER = 0;
    SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER = 0;
    SceneComponentConstants.STEP_AFTERCAMERADRAW_LENSFLARESYSTEM = 1;
    SceneComponentConstants.STEP_AFTERCAMERADRAW_EFFECTLAYER_DRAW = 2;
    SceneComponentConstants.STEP_AFTERCAMERADRAW_LAYER = 3;
    SceneComponentConstants.STEP_AFTERRENDER_AUDIO = 0;
    SceneComponentConstants.STEP_GATHERRENDERTARGETS_SHADOWGENERATOR = 0;
    SceneComponentConstants.STEP_GATHERRENDERTARGETS_GEOMETRYBUFFERRENDERER = 1;
    SceneComponentConstants.STEP_GATHERRENDERTARGETS_DEPTHRENDERER = 2;
    SceneComponentConstants.STEP_GATHERRENDERTARGETS_POSTPROCESSRENDERPIPELINEMANAGER = 3;
    SceneComponentConstants.STEP_GATHERACTIVECAMERARENDERTARGETS_DEPTHRENDERER = 0;
    SceneComponentConstants.STEP_POINTERMOVE_SPRITE = 0;
    SceneComponentConstants.STEP_POINTERDOWN_SPRITE = 0;
    SceneComponentConstants.STEP_POINTERUP_SPRITE = 0;
    return SceneComponentConstants;
}());

/**
 * Repressentation of a stage in the scene (Basically a list of ordered steps)
 * @hidden
 */
var Stage = /** @class */ (function (_super) {
    tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](Stage, _super);
    /**
     * Hide ctor from the rest of the world.
     * @param items The items to add.
     */
    function Stage(items) {
        return _super.apply(this, items) || this;
    }
    /**
     * Creates a new Stage.
     * @returns A new instance of a Stage
     */
    Stage.Create = function () {
        return Object.create(Stage.prototype);
    };
    /**
     * Registers a step in an ordered way in the targeted stage.
     * @param index Defines the position to register the step in
     * @param component Defines the component attached to the step
     * @param action Defines the action to launch during the step
     */
    Stage.prototype.registerStep = function (index, component, action) {
        var i = 0;
        var maxIndex = Number.MAX_VALUE;
        for (; i < this.length; i++) {
            var step = this[i];
            maxIndex = step.index;
            if (index < maxIndex) {
                break;
            }
        }
        this.splice(i, 0, { index: index, component: component, action: action.bind(component) });
    };
    /**
     * Clears all the steps from the stage.
     */
    Stage.prototype.clear = function () {
        this.length = 0;
    };
    return Stage;
}(Array));



/***/ })

/******/ });
});
//# sourceMappingURL=babylon.max.js.map
