(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_COPY_SRC = 4;
    WebGPUConstants.GPUBufferUsage_COPY_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_COPY_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_COPY_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_COPY_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_COPY_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_COPY_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_COPY_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_COPY_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_COPY_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_COPY_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_COPY_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_COPY_SRC | _WebGPU_webgpuConstants__WEBPACK_IMPORTED_MODULE_9__["WebGPUConstants"].GPUBufferUsage_COPY_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
