diff --git a/.eslintrc.js b/.eslintrc.js index 7380ab0..b65eb9d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,7 +13,7 @@ module.exports = { }, rules: { "no-var": "warn", - "no-unused-vars": [1, { argsIgnorePattern: "^_" }], + "no-unused-vars": ["error", { argsIgnorePattern: "^_" }], "no-multi-str": 1, "prefer-const": "warn" }, diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..914ab20 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,20 @@ +name: Tests + +on: + pull_request: + push: + branches: [master] + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: '18.x' + - run: npm ci --include=dev + - run: npm run lint + - run: npm test + - run: npm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore index 10114b1..e38f954 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store node_modules -build \ No newline at end of file +build +build_tests diff --git a/README.md b/README.md index dafdecf..8f271b3 100644 --- a/README.md +++ b/README.md @@ -19,17 +19,21 @@ Examples: - [WebGL + CSS 3D](http://acko.net/files/threestrap/multiple_renderers.html) - [VR + Controls](http://acko.net/files/threestrap/vr2.html) -# Usage +## Usage Install via npm: -``` +```sh npm install threestrap ``` Add `build/threestrap.js` to your Three.js: ```html + ``` @@ -37,7 +41,7 @@ Add `build/threestrap.js` to your Three.js: Get a threestrap context: ```javascript -var three = new Threestrap.Bootstrap(); +const three = new Threestrap.Bootstrap(); ``` This will create a full-page Three.js WebGL canvas, initialize the scene and @@ -48,7 +52,7 @@ the `three` context: ```javascript // Insert a cube -var mesh = new THREE.Mesh( +const mesh = new THREE.Mesh( new THREE.CubeGeometry(0.5, 0.5, 0.5), new THREE.MeshNormalMaterial() ); @@ -135,11 +139,6 @@ When `init` is set to false, initialization only happens when manually calling Plugins can make objects and methods available on the threestrap context, like `three.Time.now` or `three.Loop.start()`. -## Builds - -- threestrap.js: Full build (but still requires three.js) -- threestrap-core.js: Core only, requires three.js + lodash -- threestrap-extra.js: Extra plugins ## Plugins @@ -149,7 +148,7 @@ installed in the given order. Plug-in specific options are grouped under the plug-in's name: ```javascript -var three = new Threestrap.Bootstrap({ +const three = new Threestrap.Bootstrap({ plugins: ["core", "stats"], size: { width: 1280, @@ -185,7 +184,7 @@ three.off("event", handler); You can also bind events directly to object methods using `.bind`: ```javascript -var object = { +const object = { render: function (event, three) {}, yup: function (event, three) {}, redraw: function (event, three) {}, diff --git a/build/threestrap.js b/build/threestrap.js deleted file mode 100644 index f5d5e63..0000000 --- a/build/threestrap.js +++ /dev/null @@ -1,6683 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(require("THREE")); - else if(typeof define === 'function' && define.amd) - define("Threestrap", ["THREE"], factory); - else if(typeof exports === 'object') - exports["Threestrap"] = factory(require("THREE")); - else - root["Threestrap"] = factory(root["THREE"]); -})(self, function(__WEBPACK_EXTERNAL_MODULE__428__) { -return /******/ (() => { // webpackBootstrap -/******/ var __webpack_modules__ = ({ - -/***/ 466: -/***/ (function(module) { - -// stats.js - http://github.com/mrdoob/stats.js -(function(f,e){ true?module.exports=e():0})(this,function(){var f=function(){function e(a){c.appendChild(a.dom);return a}function u(a){for(var d=0;dg+1E3&&(r.update(1E3*a/(c-g),100),g=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/ -1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){k=this.end()},domElement:c,setMode:u}};f.Panel=function(e,f,l){var c=Infinity,k=0,g=Math.round,a=g(window.devicePixelRatio||1),r=80*a,h=48*a,t=3*a,v=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=h;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,h);b.fillStyle=f;b.fillText(e,t,v); -b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(h,w){c=Math.min(c,h);k=Math.max(k,h);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=f;b.fillText(g(h)+" "+e+" ("+g(c)+"-"+g(k)+")",t,v);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,g((1-h/w)*p))}}};return f}); - - -/***/ }), - -/***/ 428: -/***/ ((module) => { - -"use strict"; -module.exports = __WEBPACK_EXTERNAL_MODULE__428__; - -/***/ }) - -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ var cachedModule = __webpack_module_cache__[moduleId]; -/******/ if (cachedModule !== undefined) { -/******/ return cachedModule.exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = __webpack_module_cache__[moduleId] = { -/******/ // no module.id needed -/******/ // no module.loaded needed -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/************************************************************************/ -/******/ /* webpack/runtime/compat get default export */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => (module['default']) : -/******/ () => (module); -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (exports, definition) => { -/******/ for(var key in definition) { -/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { -/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); -/******/ } -/******/ } -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) -/******/ })(); -/******/ -/******/ /* webpack/runtime/make namespace object */ -/******/ (() => { -/******/ // define __esModule on exports -/******/ __webpack_require__.r = (exports) => { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ })(); -/******/ -/************************************************************************/ -var __webpack_exports__ = {}; -// This entry need to be wrapped in an IIFE because it need to be in strict mode. -(() => { -"use strict"; -// ESM COMPAT FLAG -__webpack_require__.r(__webpack_exports__); - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Api": () => (/* reexport */ Api), - "Binder": () => (/* reexport */ Binder), - "Bootstrap": () => (/* reexport */ Bootstrap), - "MultiRenderer": () => (/* reexport */ MultiRenderer), - "VRControls": () => (/* reexport */ VRControls), - "VRRenderer": () => (/* reexport */ VRRenderer) -}); - -;// CONCATENATED MODULE: ./src/api.js -class Api { - static apply(object) { - object.set = function (options) { - const o = this.options || {}; - - // Diff out changes - const changes = Object.entries(options).reduce(function ( - result, - [key, value] - ) { - if (o[key] !== value) result[key] = value; - return result; - }, - {}); - - this.options = Object.assign(o, changes); - - // Notify - this.trigger({ type: "change", options: options, changes: changes }); - }; - - object.get = function () { - return this.options; - }; - - object.api = function (object, context) { - if (!object) { - object = {}; - } - - // Append context argument to API methods - context && - Object.entries(object).forEach(function ([key, callback]) { - if (typeof callback === "function") { - object[key] = (...args) => callback(...args, context); - } - }); - - object.set = this.set.bind(this); - object.get = this.get.bind(this); - - return object; - }; - } -} - -// EXTERNAL MODULE: external "THREE" -var external_THREE_ = __webpack_require__(428); -;// CONCATENATED MODULE: ./src/binder.js - - -class Binder { - static bind(context, globals) { - return function (key, object) { - // Prepare object - if (!object.__binds) { - object.__binds = []; - } - - // Set base target - let fallback = context; - - if (Array.isArray(key)) { - fallback = key[0]; - key = key[1]; - } - - // Match key - const match = /^([^.:]*(?:\.[^.:]+)*)?(?::(.*))?$/.exec(key); - const path = match[1].split(/\./g); - - const name = path.pop(); - const dest = match[2] || name; - - // Whitelisted objects - const selector = path.shift(); - - let target = - { - this: object, - }[selector] || - globals[selector] || - context[selector] || - fallback; - - // Look up keys - while (target && (key = path.shift())) { - target = target[key]; - } - - // Attach event handler at last level - if (target && (target.on || target.addEventListener)) { - const callback = function (event) { - object[dest] && object[dest](event, context); - }; - - // Polyfill for both styles of event listener adders - Binder._polyfill(target, ["addEventListener", "on"], function (method) { - target[method](name, callback); - }); - - // Store bind for removal later - const bind = { target: target, name: name, callback: callback }; - object.__binds.push(bind); - - // Return callback - return callback; - } else { - throw "Cannot bind '" + key + "' in " + this.__name; - } - }; - } - - static unbind() { - return function (object) { - // Remove all binds belonging to object - if (object.__binds) { - object.__binds.forEach( - function (bind) { - // Polyfill for both styles of event listener removers - Binder._polyfill( - bind.target, - ["removeEventListener", "off"], - function (method) { - bind.target[method](bind.name, bind.callback); - } - ); - }.bind(this) - ); - - object.__binds = []; - } - }; - } - - static apply(object) { - object.trigger = Binder._trigger; - object.triggerOnce = Binder._triggerOnce; - - object.hasEventListener = external_THREE_.EventDispatcher.prototype.hasEventListener; - object.addEventListener = external_THREE_.EventDispatcher.prototype.addEventListener; - object.removeEventListener = external_THREE_.EventDispatcher.prototype.removeEventListener; - - object.on = object.addEventListener; - object.off = object.removeEventListener; - object.dispatchEvent = object.trigger; - } - - static _triggerOnce(event) { - this.trigger(event); - if (this._listeners) { - delete this._listeners[event.type]; - } - } - - static _trigger(event) { - if (this._listeners === undefined) return; - - const type = event.type; - let listeners = this._listeners[type]; - if (listeners !== undefined) { - listeners = listeners.slice(); - const length = listeners.length; - - event.target = this; - for (let i = 0; i < length; i++) { - // add original target as parameter for convenience - listeners[i].call(this, event, this); - } - } - } - - static _polyfill(object, methods, callback) { - methods.map(function (_method) { - return object.method; - }); - if (methods.length) callback(methods[0]); - } -} - -;// CONCATENATED MODULE: ./src/bootstrap.js - - - -function isString(str) { - return str && typeof str.valueOf() === "string"; -} - -class Bootstrap { - static initClass() { - this.Plugins = {}; - this.Aliases = {}; - } - - static registerPlugin(name, spec) { - const ctor = function (options) { - Bootstrap.Plugin.call(this, options); - this.__name = name; - }; - ctor.prototype = Object.assign(new Bootstrap.Plugin(), spec); - - this.Plugins[name] = ctor; - } - - static unregisterPlugin(name) { - delete this.Plugins[name]; - } - - static registerAlias(name, plugins) { - this.Aliases[name] = plugins; - } - - static unregisterAlias(name) { - delete this.Aliases[name]; - } - - constructor(options) { - if (options) { - let args = [].slice.apply(arguments); - options = {}; - - // (element, ...) - if (args[0] instanceof Node) { - const node = args[0]; - args = args.slice(1); - options.element = node; - } - - // (..., plugin, plugin, plugin) - if (isString(args[0])) { - options.plugins = args; - } else if (Array.isArray(args[0])) { - // (..., [plugin, plugin, plugin]) - options.plugins = args[0]; - } else if (args[0]) { - // (..., options) - - // else, merge any arguments on the right that have NOT been set into the - // options dict on the left. - options = Object.assign({}, args[0], options); - } - } - - // Apply defaults - const defaultOpts = { - init: true, - element: document.body, - plugins: ["core"], - aliases: {}, - plugindb: Bootstrap.Plugins || {}, - aliasdb: Bootstrap.Aliases || {}, - }; - - this.__options = Object.assign({}, defaultOpts, options || {}); - - // Hidden state - this.__inited = false; - this.__destroyed = false; - this.__installed = []; - - // Query element - let element = this.__options.element; - if (element === "" + element) { - element = document.querySelector(element); - } - - // Global context - this.plugins = {}; - this.element = element; - - // Update cycle - this.trigger = this.trigger.bind(this); - this.frame = this.frame.bind(this); - this.events = ["pre", "update", "render", "post"].map(function (type) { - return { type: type }; - }); - - // Auto-init - if (this.__options.init) { - this.init(); - } - } - - init() { - if (this.__inited) return; - this.__inited = true; - - // Install plugins - this.install(this.__options.plugins); - } - - destroy() { - if (!this.__inited) return; - if (this.__destroyed) return; - this.__destroyed = true; - - // Notify of imminent destruction - this.trigger({ type: "destroy" }); - - // Then uninstall plugins - this.uninstall(); - } - - frame() { - this.events.map(this.trigger); - } - - resolve(plugins) { - plugins = Array.isArray(plugins) ? plugins : [plugins]; - - // Resolve alias database - const o = this.__options; - const aliases = Object.assign({}, o.aliasdb, o.aliases); - - // Remove inline alias defs from plugins - const pred = function (name) { - const key = name.split(":"); - if (!key[1]) return true; - aliases[key[0]] = [key[1]]; - return false; - }; - plugins = plugins.filter(pred); - - // Unify arrays - Object.entries(aliases).forEach(function ([key, alias]) { - aliases[key] = Array.isArray(alias) ? alias : [alias]; - }); - - // Look up aliases recursively - function recurse(list, out, level) { - if (level >= 256) throw "Plug-in alias recursion detected."; - list = list.filter(pred); - list.forEach(function (name) { - const alias = aliases[name]; - if (!alias) { - out.push(name); - } else { - out = out.concat(recurse(alias, [], level + 1)); - } - }); - return out; - } - - return recurse(plugins, [], 0); - } - - install(plugins) { - plugins = Array.isArray(plugins) ? plugins : [plugins]; - - // Resolve aliases - plugins = this.resolve(plugins); - - // Install in order - plugins.forEach((name) => this.__install(name)); - - // Fire off ready event - this.__ready(); - } - - uninstall(plugins) { - if (plugins) { - plugins = Array.isArray(plugins) ? plugins : [plugins]; - - // Resolve aliases - plugins = this.resolve(plugins); - } - - // Uninstall in reverse order - (plugins || this.__installed) - .reverse() - .forEach((p) => this.__uninstall(p.__name)); - } - - __install(name) { - // Sanity check - const ctor = this.__options.plugindb[name]; - if (!ctor) - throw "[three.install] Cannot install. '" + name + "' is not registered."; - - if (this.plugins[name]) - return console.warn("[three.install] " + name + " is already installed."); - - // Construct - const Plugin = ctor; - const plugin = new Plugin(this.__options[name] || {}, name); - this.plugins[name] = plugin; - - // Install - const flag = plugin.install(this); - this.__installed.push(plugin); - - // Then notify - this.trigger({ type: "install", plugin: plugin }); - - // Allow early abort - return flag; - } - - __uninstall(name) { - // Sanity check - const plugin = isString(name) ? this.plugins[name] : name; - if (!plugin) { - console.warn("[three.uninstall] " + name + "' is not installed."); - return; - } - - name = plugin.__name; - - // Uninstall - plugin.uninstall(this); - this.__installed = this.__installed.filter((p) => p !== plugin); - delete this.plugins[name]; - - // Then notify - this.trigger({ type: "uninstall", plugin: plugin }); - } - - __ready() { - // Notify and remove event handlers - this.triggerOnce({ type: "ready" }); - } -} -Bootstrap.initClass(); - -// Plugin Creation - -Bootstrap.Plugin = function (options) { - this.options = Object.assign({}, this.defaults, options || {}); -}; - -Bootstrap.Plugin.prototype = { - listen: [], - defaults: {}, - install: function (_three) {}, - uninstall: function (_three) {}, -}; - -Binder.apply(Bootstrap.prototype); -Binder.apply(Bootstrap.Plugin.prototype); -Api.apply(Bootstrap.Plugin.prototype); - -;// CONCATENATED MODULE: ./src/aliases.js - - -Bootstrap.registerAlias("empty", [ - "fallback", - "bind", - "renderer", - "size", - "fill", - "loop", - "time", -]); - -Bootstrap.registerAlias("core", [ - "empty", - "scene", - "camera", - "render", - "warmup", -]); - -Bootstrap.registerAlias("VR", ["core", "cursor", "fullscreen", "render:vr"]); - -;// CONCATENATED MODULE: ./src/core/bind.js - - - -Bootstrap.registerPlugin("bind", { - install: function (three) { - const globals = { - three: three, - window: window, - }; - - three.bind = Binder.bind(three, globals); - three.unbind = Binder.unbind(three); - - three.bind("install:bind", this); - three.bind("uninstall:unbind", this); - }, - - uninstall: function (three) { - three.unbind(this); - - delete three.bind; - delete three.unbind; - }, - - bind: function (event, three) { - const plugin = event.plugin; - const listen = plugin.listen; - - listen && - listen.forEach(function (key) { - three.bind(key, plugin); - }); - }, - - unbind: function (event, three) { - three.unbind(event.plugin); - }, -}); - -;// CONCATENATED MODULE: ./node_modules/three/src/math/MathUtils.js -const _lut = []; - -for ( let i = 0; i < 256; i ++ ) { - - _lut[ i ] = ( i < 16 ? '0' : '' ) + ( i ).toString( 16 ); - -} - -let _seed = 1234567; - - -const DEG2RAD = Math.PI / 180; -const RAD2DEG = 180 / Math.PI; - -// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 -function generateUUID() { - - const d0 = Math.random() * 0xffffffff | 0; - const d1 = Math.random() * 0xffffffff | 0; - const d2 = Math.random() * 0xffffffff | 0; - const d3 = Math.random() * 0xffffffff | 0; - const uuid = _lut[ d0 & 0xff ] + _lut[ d0 >> 8 & 0xff ] + _lut[ d0 >> 16 & 0xff ] + _lut[ d0 >> 24 & 0xff ] + '-' + - _lut[ d1 & 0xff ] + _lut[ d1 >> 8 & 0xff ] + '-' + _lut[ d1 >> 16 & 0x0f | 0x40 ] + _lut[ d1 >> 24 & 0xff ] + '-' + - _lut[ d2 & 0x3f | 0x80 ] + _lut[ d2 >> 8 & 0xff ] + '-' + _lut[ d2 >> 16 & 0xff ] + _lut[ d2 >> 24 & 0xff ] + - _lut[ d3 & 0xff ] + _lut[ d3 >> 8 & 0xff ] + _lut[ d3 >> 16 & 0xff ] + _lut[ d3 >> 24 & 0xff ]; - - // .toUpperCase() here flattens concatenated strings to save heap memory space. - return uuid.toUpperCase(); - -} - -function clamp( value, min, max ) { - - return Math.max( min, Math.min( max, value ) ); - -} - -// compute euclidian modulo of m % n -// https://en.wikipedia.org/wiki/Modulo_operation -function euclideanModulo( n, m ) { - - return ( ( n % m ) + m ) % m; - -} - -// Linear mapping from range to range -function mapLinear( x, a1, a2, b1, b2 ) { - - return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 ); - -} - -// https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/ -function inverseLerp( x, y, value ) { - - if ( x !== y ) { - - return ( value - x ) / ( y - x ); - - } else { - - return 0; - - } - -} - -// https://en.wikipedia.org/wiki/Linear_interpolation -function lerp( x, y, t ) { - - return ( 1 - t ) * x + t * y; - -} - -// http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ -function damp( x, y, lambda, dt ) { - - return lerp( x, y, 1 - Math.exp( - lambda * dt ) ); - -} - -// https://www.desmos.com/calculator/vcsjnyz7x4 -function pingpong( x, length = 1 ) { - - return length - Math.abs( euclideanModulo( x, length * 2 ) - length ); - -} - -// http://en.wikipedia.org/wiki/Smoothstep -function smoothstep( x, min, max ) { - - if ( x <= min ) return 0; - if ( x >= max ) return 1; - - x = ( x - min ) / ( max - min ); - - return x * x * ( 3 - 2 * x ); - -} - -function smootherstep( x, min, max ) { - - if ( x <= min ) return 0; - if ( x >= max ) return 1; - - x = ( x - min ) / ( max - min ); - - return x * x * x * ( x * ( x * 6 - 15 ) + 10 ); - -} - -// Random integer from interval -function randInt( low, high ) { - - return low + Math.floor( Math.random() * ( high - low + 1 ) ); - -} - -// Random float from interval -function randFloat( low, high ) { - - return low + Math.random() * ( high - low ); - -} - -// Random float from <-range/2, range/2> interval -function randFloatSpread( range ) { - - return range * ( 0.5 - Math.random() ); - -} - -// Deterministic pseudo-random float in the interval [ 0, 1 ] -function seededRandom( s ) { - - if ( s !== undefined ) _seed = s % 2147483647; - - // Park-Miller algorithm - - _seed = _seed * 16807 % 2147483647; - - return ( _seed - 1 ) / 2147483646; - -} - -function degToRad( degrees ) { - - return degrees * DEG2RAD; - -} - -function radToDeg( radians ) { - - return radians * RAD2DEG; - -} - -function isPowerOfTwo( value ) { - - return ( value & ( value - 1 ) ) === 0 && value !== 0; - -} - -function ceilPowerOfTwo( value ) { - - return Math.pow( 2, Math.ceil( Math.log( value ) / Math.LN2 ) ); - -} - -function floorPowerOfTwo( value ) { - - return Math.pow( 2, Math.floor( Math.log( value ) / Math.LN2 ) ); - -} - -function setQuaternionFromProperEuler( q, a, b, c, order ) { - - // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles - - // rotations are applied to the axes in the order specified by 'order' - // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c' - // angles are in radians - - const cos = Math.cos; - const sin = Math.sin; - - const c2 = cos( b / 2 ); - const s2 = sin( b / 2 ); - - const c13 = cos( ( a + c ) / 2 ); - const s13 = sin( ( a + c ) / 2 ); - - const c1_3 = cos( ( a - c ) / 2 ); - const s1_3 = sin( ( a - c ) / 2 ); - - const c3_1 = cos( ( c - a ) / 2 ); - const s3_1 = sin( ( c - a ) / 2 ); - - switch ( order ) { - - case 'XYX': - q.set( c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13 ); - break; - - case 'YZY': - q.set( s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13 ); - break; - - case 'ZXZ': - q.set( s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13 ); - break; - - case 'XZX': - q.set( c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13 ); - break; - - case 'YXY': - q.set( s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13 ); - break; - - case 'ZYZ': - q.set( s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13 ); - break; - - default: - console.warn( 'THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order ); - - } - -} - - - - - - -;// CONCATENATED MODULE: ./node_modules/three/src/math/Quaternion.js - - -class Quaternion { - - constructor( x = 0, y = 0, z = 0, w = 1 ) { - - this._x = x; - this._y = y; - this._z = z; - this._w = w; - - } - - static slerp( qa, qb, qm, t ) { - - console.warn( 'THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead.' ); - return qm.slerpQuaternions( qa, qb, t ); - - } - - static slerpFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t ) { - - // fuzz-free, array-based Quaternion SLERP operation - - let x0 = src0[ srcOffset0 + 0 ], - y0 = src0[ srcOffset0 + 1 ], - z0 = src0[ srcOffset0 + 2 ], - w0 = src0[ srcOffset0 + 3 ]; - - const x1 = src1[ srcOffset1 + 0 ], - y1 = src1[ srcOffset1 + 1 ], - z1 = src1[ srcOffset1 + 2 ], - w1 = src1[ srcOffset1 + 3 ]; - - if ( t === 0 ) { - - dst[ dstOffset + 0 ] = x0; - dst[ dstOffset + 1 ] = y0; - dst[ dstOffset + 2 ] = z0; - dst[ dstOffset + 3 ] = w0; - return; - - } - - if ( t === 1 ) { - - dst[ dstOffset + 0 ] = x1; - dst[ dstOffset + 1 ] = y1; - dst[ dstOffset + 2 ] = z1; - dst[ dstOffset + 3 ] = w1; - return; - - } - - if ( w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1 ) { - - let s = 1 - t; - const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, - dir = ( cos >= 0 ? 1 : - 1 ), - sqrSin = 1 - cos * cos; - - // Skip the Slerp for tiny steps to avoid numeric problems: - if ( sqrSin > Number.EPSILON ) { - - const sin = Math.sqrt( sqrSin ), - len = Math.atan2( sin, cos * dir ); - - s = Math.sin( s * len ) / sin; - t = Math.sin( t * len ) / sin; - - } - - const tDir = t * dir; - - x0 = x0 * s + x1 * tDir; - y0 = y0 * s + y1 * tDir; - z0 = z0 * s + z1 * tDir; - w0 = w0 * s + w1 * tDir; - - // Normalize in case we just did a lerp: - if ( s === 1 - t ) { - - const f = 1 / Math.sqrt( x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0 ); - - x0 *= f; - y0 *= f; - z0 *= f; - w0 *= f; - - } - - } - - dst[ dstOffset ] = x0; - dst[ dstOffset + 1 ] = y0; - dst[ dstOffset + 2 ] = z0; - dst[ dstOffset + 3 ] = w0; - - } - - static multiplyQuaternionsFlat( dst, dstOffset, src0, srcOffset0, src1, srcOffset1 ) { - - const x0 = src0[ srcOffset0 ]; - const y0 = src0[ srcOffset0 + 1 ]; - const z0 = src0[ srcOffset0 + 2 ]; - const w0 = src0[ srcOffset0 + 3 ]; - - const x1 = src1[ srcOffset1 ]; - const y1 = src1[ srcOffset1 + 1 ]; - const z1 = src1[ srcOffset1 + 2 ]; - const w1 = src1[ srcOffset1 + 3 ]; - - dst[ dstOffset ] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1; - dst[ dstOffset + 1 ] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1; - dst[ dstOffset + 2 ] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1; - dst[ dstOffset + 3 ] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1; - - return dst; - - } - - get x() { - - return this._x; - - } - - set x( value ) { - - this._x = value; - this._onChangeCallback(); - - } - - get y() { - - return this._y; - - } - - set y( value ) { - - this._y = value; - this._onChangeCallback(); - - } - - get z() { - - return this._z; - - } - - set z( value ) { - - this._z = value; - this._onChangeCallback(); - - } - - get w() { - - return this._w; - - } - - set w( value ) { - - this._w = value; - this._onChangeCallback(); - - } - - set( x, y, z, w ) { - - this._x = x; - this._y = y; - this._z = z; - this._w = w; - - this._onChangeCallback(); - - return this; - - } - - clone() { - - return new this.constructor( this._x, this._y, this._z, this._w ); - - } - - copy( quaternion ) { - - this._x = quaternion.x; - this._y = quaternion.y; - this._z = quaternion.z; - this._w = quaternion.w; - - this._onChangeCallback(); - - return this; - - } - - setFromEuler( euler, update ) { - - if ( ! ( euler && euler.isEuler ) ) { - - throw new Error( 'THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - - } - - const x = euler._x, y = euler._y, z = euler._z, order = euler._order; - - // http://www.mathworks.com/matlabcentral/fileexchange/ - // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/ - // content/SpinCalc.m - - const cos = Math.cos; - const sin = Math.sin; - - const c1 = cos( x / 2 ); - const c2 = cos( y / 2 ); - const c3 = cos( z / 2 ); - - const s1 = sin( x / 2 ); - const s2 = sin( y / 2 ); - const s3 = sin( z / 2 ); - - switch ( order ) { - - case 'XYZ': - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; - break; - - case 'YXZ': - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; - break; - - case 'ZXY': - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; - break; - - case 'ZYX': - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; - break; - - case 'YZX': - this._x = s1 * c2 * c3 + c1 * s2 * s3; - this._y = c1 * s2 * c3 + s1 * c2 * s3; - this._z = c1 * c2 * s3 - s1 * s2 * c3; - this._w = c1 * c2 * c3 - s1 * s2 * s3; - break; - - case 'XZY': - this._x = s1 * c2 * c3 - c1 * s2 * s3; - this._y = c1 * s2 * c3 - s1 * c2 * s3; - this._z = c1 * c2 * s3 + s1 * s2 * c3; - this._w = c1 * c2 * c3 + s1 * s2 * s3; - break; - - default: - console.warn( 'THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order ); - - } - - if ( update !== false ) this._onChangeCallback(); - - return this; - - } - - setFromAxisAngle( axis, angle ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm - - // assumes axis is normalized - - const halfAngle = angle / 2, s = Math.sin( halfAngle ); - - this._x = axis.x * s; - this._y = axis.y * s; - this._z = axis.z * s; - this._w = Math.cos( halfAngle ); - - this._onChangeCallback(); - - return this; - - } - - setFromRotationMatrix( m ) { - - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - const te = m.elements, - - m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ], - m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ], - m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ], - - trace = m11 + m22 + m33; - - if ( trace > 0 ) { - - const s = 0.5 / Math.sqrt( trace + 1.0 ); - - this._w = 0.25 / s; - this._x = ( m32 - m23 ) * s; - this._y = ( m13 - m31 ) * s; - this._z = ( m21 - m12 ) * s; - - } else if ( m11 > m22 && m11 > m33 ) { - - const s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 ); - - this._w = ( m32 - m23 ) / s; - this._x = 0.25 * s; - this._y = ( m12 + m21 ) / s; - this._z = ( m13 + m31 ) / s; - - } else if ( m22 > m33 ) { - - const s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 ); - - this._w = ( m13 - m31 ) / s; - this._x = ( m12 + m21 ) / s; - this._y = 0.25 * s; - this._z = ( m23 + m32 ) / s; - - } else { - - const s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 ); - - this._w = ( m21 - m12 ) / s; - this._x = ( m13 + m31 ) / s; - this._y = ( m23 + m32 ) / s; - this._z = 0.25 * s; - - } - - this._onChangeCallback(); - - return this; - - } - - setFromUnitVectors( vFrom, vTo ) { - - // assumes direction vectors vFrom and vTo are normalized - - let r = vFrom.dot( vTo ) + 1; - - if ( r < Number.EPSILON ) { - - // vFrom and vTo point in opposite directions - - r = 0; - - if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { - - this._x = - vFrom.y; - this._y = vFrom.x; - this._z = 0; - this._w = r; - - } else { - - this._x = 0; - this._y = - vFrom.z; - this._z = vFrom.y; - this._w = r; - - } - - } else { - - // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3 - - this._x = vFrom.y * vTo.z - vFrom.z * vTo.y; - this._y = vFrom.z * vTo.x - vFrom.x * vTo.z; - this._z = vFrom.x * vTo.y - vFrom.y * vTo.x; - this._w = r; - - } - - return this.normalize(); - - } - - angleTo( q ) { - - return 2 * Math.acos( Math.abs( clamp( this.dot( q ), - 1, 1 ) ) ); - - } - - rotateTowards( q, step ) { - - const angle = this.angleTo( q ); - - if ( angle === 0 ) return this; - - const t = Math.min( 1, step / angle ); - - this.slerp( q, t ); - - return this; - - } - - identity() { - - return this.set( 0, 0, 0, 1 ); - - } - - invert() { - - // quaternion is assumed to have unit length - - return this.conjugate(); - - } - - conjugate() { - - this._x *= - 1; - this._y *= - 1; - this._z *= - 1; - - this._onChangeCallback(); - - return this; - - } - - dot( v ) { - - return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w; - - } - - lengthSq() { - - return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w; - - } - - length() { - - return Math.sqrt( this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w ); - - } - - normalize() { - - let l = this.length(); - - if ( l === 0 ) { - - this._x = 0; - this._y = 0; - this._z = 0; - this._w = 1; - - } else { - - l = 1 / l; - - this._x = this._x * l; - this._y = this._y * l; - this._z = this._z * l; - this._w = this._w * l; - - } - - this._onChangeCallback(); - - return this; - - } - - multiply( q, p ) { - - if ( p !== undefined ) { - - console.warn( 'THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead.' ); - return this.multiplyQuaternions( q, p ); - - } - - return this.multiplyQuaternions( this, q ); - - } - - premultiply( q ) { - - return this.multiplyQuaternions( q, this ); - - } - - multiplyQuaternions( a, b ) { - - // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm - - const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w; - const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w; - - this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; - this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; - this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; - this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; - - this._onChangeCallback(); - - return this; - - } - - slerp( qb, t ) { - - if ( t === 0 ) return this; - if ( t === 1 ) return this.copy( qb ); - - const x = this._x, y = this._y, z = this._z, w = this._w; - - // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ - - let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z; - - if ( cosHalfTheta < 0 ) { - - this._w = - qb._w; - this._x = - qb._x; - this._y = - qb._y; - this._z = - qb._z; - - cosHalfTheta = - cosHalfTheta; - - } else { - - this.copy( qb ); - - } - - if ( cosHalfTheta >= 1.0 ) { - - this._w = w; - this._x = x; - this._y = y; - this._z = z; - - return this; - - } - - const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta; - - if ( sqrSinHalfTheta <= Number.EPSILON ) { - - const s = 1 - t; - this._w = s * w + t * this._w; - this._x = s * x + t * this._x; - this._y = s * y + t * this._y; - this._z = s * z + t * this._z; - - this.normalize(); - this._onChangeCallback(); - - return this; - - } - - const sinHalfTheta = Math.sqrt( sqrSinHalfTheta ); - const halfTheta = Math.atan2( sinHalfTheta, cosHalfTheta ); - const ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, - ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; - - this._w = ( w * ratioA + this._w * ratioB ); - this._x = ( x * ratioA + this._x * ratioB ); - this._y = ( y * ratioA + this._y * ratioB ); - this._z = ( z * ratioA + this._z * ratioB ); - - this._onChangeCallback(); - - return this; - - } - - slerpQuaternions( qa, qb, t ) { - - return this.copy( qa ).slerp( qb, t ); - - } - - random() { - - // Derived from http://planning.cs.uiuc.edu/node198.html - // Note, this source uses w, x, y, z ordering, - // so we swap the order below. - - const u1 = Math.random(); - const sqrt1u1 = Math.sqrt( 1 - u1 ); - const sqrtu1 = Math.sqrt( u1 ); - - const u2 = 2 * Math.PI * Math.random(); - - const u3 = 2 * Math.PI * Math.random(); - - return this.set( - sqrt1u1 * Math.cos( u2 ), - sqrtu1 * Math.sin( u3 ), - sqrtu1 * Math.cos( u3 ), - sqrt1u1 * Math.sin( u2 ), - ); - - } - - equals( quaternion ) { - - return ( quaternion._x === this._x ) && ( quaternion._y === this._y ) && ( quaternion._z === this._z ) && ( quaternion._w === this._w ); - - } - - fromArray( array, offset = 0 ) { - - this._x = array[ offset ]; - this._y = array[ offset + 1 ]; - this._z = array[ offset + 2 ]; - this._w = array[ offset + 3 ]; - - this._onChangeCallback(); - - return this; - - } - - toArray( array = [], offset = 0 ) { - - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._w; - - return array; - - } - - fromBufferAttribute( attribute, index ) { - - this._x = attribute.getX( index ); - this._y = attribute.getY( index ); - this._z = attribute.getZ( index ); - this._w = attribute.getW( index ); - - return this; - - } - - _onChange( callback ) { - - this._onChangeCallback = callback; - - return this; - - } - - _onChangeCallback() {} - -} - -Quaternion.prototype.isQuaternion = true; - - - -;// CONCATENATED MODULE: ./node_modules/three/src/math/Vector3.js - - - -class Vector3 { - - constructor( x = 0, y = 0, z = 0 ) { - - this.x = x; - this.y = y; - this.z = z; - - } - - set( x, y, z ) { - - if ( z === undefined ) z = this.z; // sprite.scale.set(x,y) - - this.x = x; - this.y = y; - this.z = z; - - return this; - - } - - setScalar( scalar ) { - - this.x = scalar; - this.y = scalar; - this.z = scalar; - - return this; - - } - - setX( x ) { - - this.x = x; - - return this; - - } - - setY( y ) { - - this.y = y; - - return this; - - } - - setZ( z ) { - - this.z = z; - - return this; - - } - - setComponent( index, value ) { - - switch ( index ) { - - case 0: this.x = value; break; - case 1: this.y = value; break; - case 2: this.z = value; break; - default: throw new Error( 'index is out of range: ' + index ); - - } - - return this; - - } - - getComponent( index ) { - - switch ( index ) { - - case 0: return this.x; - case 1: return this.y; - case 2: return this.z; - default: throw new Error( 'index is out of range: ' + index ); - - } - - } - - clone() { - - return new this.constructor( this.x, this.y, this.z ); - - } - - copy( v ) { - - this.x = v.x; - this.y = v.y; - this.z = v.z; - - return this; - - } - - add( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead.' ); - return this.addVectors( v, w ); - - } - - this.x += v.x; - this.y += v.y; - this.z += v.z; - - return this; - - } - - addScalar( s ) { - - this.x += s; - this.y += s; - this.z += s; - - return this; - - } - - addVectors( a, b ) { - - this.x = a.x + b.x; - this.y = a.y + b.y; - this.z = a.z + b.z; - - return this; - - } - - addScaledVector( v, s ) { - - this.x += v.x * s; - this.y += v.y * s; - this.z += v.z * s; - - return this; - - } - - sub( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead.' ); - return this.subVectors( v, w ); - - } - - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - - return this; - - } - - subScalar( s ) { - - this.x -= s; - this.y -= s; - this.z -= s; - - return this; - - } - - subVectors( a, b ) { - - this.x = a.x - b.x; - this.y = a.y - b.y; - this.z = a.z - b.z; - - return this; - - } - - multiply( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead.' ); - return this.multiplyVectors( v, w ); - - } - - this.x *= v.x; - this.y *= v.y; - this.z *= v.z; - - return this; - - } - - multiplyScalar( scalar ) { - - this.x *= scalar; - this.y *= scalar; - this.z *= scalar; - - return this; - - } - - multiplyVectors( a, b ) { - - this.x = a.x * b.x; - this.y = a.y * b.y; - this.z = a.z * b.z; - - return this; - - } - - applyEuler( euler ) { - - if ( ! ( euler && euler.isEuler ) ) { - - console.error( 'THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.' ); - - } - - return this.applyQuaternion( _quaternion.setFromEuler( euler ) ); - - } - - applyAxisAngle( axis, angle ) { - - return this.applyQuaternion( _quaternion.setFromAxisAngle( axis, angle ) ); - - } - - applyMatrix3( m ) { - - const x = this.x, y = this.y, z = this.z; - const e = m.elements; - - this.x = e[ 0 ] * x + e[ 3 ] * y + e[ 6 ] * z; - this.y = e[ 1 ] * x + e[ 4 ] * y + e[ 7 ] * z; - this.z = e[ 2 ] * x + e[ 5 ] * y + e[ 8 ] * z; - - return this; - - } - - applyNormalMatrix( m ) { - - return this.applyMatrix3( m ).normalize(); - - } - - applyMatrix4( m ) { - - const x = this.x, y = this.y, z = this.z; - const e = m.elements; - - const w = 1 / ( e[ 3 ] * x + e[ 7 ] * y + e[ 11 ] * z + e[ 15 ] ); - - this.x = ( e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z + e[ 12 ] ) * w; - this.y = ( e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z + e[ 13 ] ) * w; - this.z = ( e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z + e[ 14 ] ) * w; - - return this; - - } - - applyQuaternion( q ) { - - const x = this.x, y = this.y, z = this.z; - const qx = q.x, qy = q.y, qz = q.z, qw = q.w; - - // calculate quat * vector - - const ix = qw * x + qy * z - qz * y; - const iy = qw * y + qz * x - qx * z; - const iz = qw * z + qx * y - qy * x; - const iw = - qx * x - qy * y - qz * z; - - // calculate result * inverse quat - - this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; - this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; - this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; - - return this; - - } - - project( camera ) { - - return this.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix ); - - } - - unproject( camera ) { - - return this.applyMatrix4( camera.projectionMatrixInverse ).applyMatrix4( camera.matrixWorld ); - - } - - transformDirection( m ) { - - // input: THREE.Matrix4 affine matrix - // vector interpreted as a direction - - const x = this.x, y = this.y, z = this.z; - const e = m.elements; - - this.x = e[ 0 ] * x + e[ 4 ] * y + e[ 8 ] * z; - this.y = e[ 1 ] * x + e[ 5 ] * y + e[ 9 ] * z; - this.z = e[ 2 ] * x + e[ 6 ] * y + e[ 10 ] * z; - - return this.normalize(); - - } - - divide( v ) { - - this.x /= v.x; - this.y /= v.y; - this.z /= v.z; - - return this; - - } - - divideScalar( scalar ) { - - return this.multiplyScalar( 1 / scalar ); - - } - - min( v ) { - - this.x = Math.min( this.x, v.x ); - this.y = Math.min( this.y, v.y ); - this.z = Math.min( this.z, v.z ); - - return this; - - } - - max( v ) { - - this.x = Math.max( this.x, v.x ); - this.y = Math.max( this.y, v.y ); - this.z = Math.max( this.z, v.z ); - - return this; - - } - - clamp( min, max ) { - - // assumes min < max, componentwise - - this.x = Math.max( min.x, Math.min( max.x, this.x ) ); - this.y = Math.max( min.y, Math.min( max.y, this.y ) ); - this.z = Math.max( min.z, Math.min( max.z, this.z ) ); - - return this; - - } - - clampScalar( minVal, maxVal ) { - - this.x = Math.max( minVal, Math.min( maxVal, this.x ) ); - this.y = Math.max( minVal, Math.min( maxVal, this.y ) ); - this.z = Math.max( minVal, Math.min( maxVal, this.z ) ); - - return this; - - } - - clampLength( min, max ) { - - const length = this.length(); - - return this.divideScalar( length || 1 ).multiplyScalar( Math.max( min, Math.min( max, length ) ) ); - - } - - floor() { - - this.x = Math.floor( this.x ); - this.y = Math.floor( this.y ); - this.z = Math.floor( this.z ); - - return this; - - } - - ceil() { - - this.x = Math.ceil( this.x ); - this.y = Math.ceil( this.y ); - this.z = Math.ceil( this.z ); - - return this; - - } - - round() { - - this.x = Math.round( this.x ); - this.y = Math.round( this.y ); - this.z = Math.round( this.z ); - - return this; - - } - - roundToZero() { - - this.x = ( this.x < 0 ) ? Math.ceil( this.x ) : Math.floor( this.x ); - this.y = ( this.y < 0 ) ? Math.ceil( this.y ) : Math.floor( this.y ); - this.z = ( this.z < 0 ) ? Math.ceil( this.z ) : Math.floor( this.z ); - - return this; - - } - - negate() { - - this.x = - this.x; - this.y = - this.y; - this.z = - this.z; - - return this; - - } - - dot( v ) { - - return this.x * v.x + this.y * v.y + this.z * v.z; - - } - - // TODO lengthSquared? - - lengthSq() { - - return this.x * this.x + this.y * this.y + this.z * this.z; - - } - - length() { - - return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); - - } - - manhattanLength() { - - return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ); - - } - - normalize() { - - return this.divideScalar( this.length() || 1 ); - - } - - setLength( length ) { - - return this.normalize().multiplyScalar( length ); - - } - - lerp( v, alpha ) { - - this.x += ( v.x - this.x ) * alpha; - this.y += ( v.y - this.y ) * alpha; - this.z += ( v.z - this.z ) * alpha; - - return this; - - } - - lerpVectors( v1, v2, alpha ) { - - this.x = v1.x + ( v2.x - v1.x ) * alpha; - this.y = v1.y + ( v2.y - v1.y ) * alpha; - this.z = v1.z + ( v2.z - v1.z ) * alpha; - - return this; - - } - - cross( v, w ) { - - if ( w !== undefined ) { - - console.warn( 'THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead.' ); - return this.crossVectors( v, w ); - - } - - return this.crossVectors( this, v ); - - } - - crossVectors( a, b ) { - - const ax = a.x, ay = a.y, az = a.z; - const bx = b.x, by = b.y, bz = b.z; - - this.x = ay * bz - az * by; - this.y = az * bx - ax * bz; - this.z = ax * by - ay * bx; - - return this; - - } - - projectOnVector( v ) { - - const denominator = v.lengthSq(); - - if ( denominator === 0 ) return this.set( 0, 0, 0 ); - - const scalar = v.dot( this ) / denominator; - - return this.copy( v ).multiplyScalar( scalar ); - - } - - projectOnPlane( planeNormal ) { - - _vector.copy( this ).projectOnVector( planeNormal ); - - return this.sub( _vector ); - - } - - reflect( normal ) { - - // reflect incident vector off plane orthogonal to normal - // normal is assumed to have unit length - - return this.sub( _vector.copy( normal ).multiplyScalar( 2 * this.dot( normal ) ) ); - - } - - angleTo( v ) { - - const denominator = Math.sqrt( this.lengthSq() * v.lengthSq() ); - - if ( denominator === 0 ) return Math.PI / 2; - - const theta = this.dot( v ) / denominator; - - // clamp, to handle numerical problems - - return Math.acos( clamp( theta, - 1, 1 ) ); - - } - - distanceTo( v ) { - - return Math.sqrt( this.distanceToSquared( v ) ); - - } - - distanceToSquared( v ) { - - const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; - - return dx * dx + dy * dy + dz * dz; - - } - - manhattanDistanceTo( v ) { - - return Math.abs( this.x - v.x ) + Math.abs( this.y - v.y ) + Math.abs( this.z - v.z ); - - } - - setFromSpherical( s ) { - - return this.setFromSphericalCoords( s.radius, s.phi, s.theta ); - - } - - setFromSphericalCoords( radius, phi, theta ) { - - const sinPhiRadius = Math.sin( phi ) * radius; - - this.x = sinPhiRadius * Math.sin( theta ); - this.y = Math.cos( phi ) * radius; - this.z = sinPhiRadius * Math.cos( theta ); - - return this; - - } - - setFromCylindrical( c ) { - - return this.setFromCylindricalCoords( c.radius, c.theta, c.y ); - - } - - setFromCylindricalCoords( radius, theta, y ) { - - this.x = radius * Math.sin( theta ); - this.y = y; - this.z = radius * Math.cos( theta ); - - return this; - - } - - setFromMatrixPosition( m ) { - - const e = m.elements; - - this.x = e[ 12 ]; - this.y = e[ 13 ]; - this.z = e[ 14 ]; - - return this; - - } - - setFromMatrixScale( m ) { - - const sx = this.setFromMatrixColumn( m, 0 ).length(); - const sy = this.setFromMatrixColumn( m, 1 ).length(); - const sz = this.setFromMatrixColumn( m, 2 ).length(); - - this.x = sx; - this.y = sy; - this.z = sz; - - return this; - - } - - setFromMatrixColumn( m, index ) { - - return this.fromArray( m.elements, index * 4 ); - - } - - setFromMatrix3Column( m, index ) { - - return this.fromArray( m.elements, index * 3 ); - - } - - equals( v ) { - - return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) ); - - } - - fromArray( array, offset = 0 ) { - - this.x = array[ offset ]; - this.y = array[ offset + 1 ]; - this.z = array[ offset + 2 ]; - - return this; - - } - - toArray( array = [], offset = 0 ) { - - array[ offset ] = this.x; - array[ offset + 1 ] = this.y; - array[ offset + 2 ] = this.z; - - return array; - - } - - fromBufferAttribute( attribute, index, offset ) { - - if ( offset !== undefined ) { - - console.warn( 'THREE.Vector3: offset has been removed from .fromBufferAttribute().' ); - - } - - this.x = attribute.getX( index ); - this.y = attribute.getY( index ); - this.z = attribute.getZ( index ); - - return this; - - } - - random() { - - this.x = Math.random(); - this.y = Math.random(); - this.z = Math.random(); - - return this; - - } - - randomDirection() { - - // Derived from https://mathworld.wolfram.com/SpherePointPicking.html - - const u = ( Math.random() - 0.5 ) * 2; - const t = Math.random() * Math.PI * 2; - const f = Math.sqrt( 1 - u ** 2 ); - - this.x = f * Math.cos( t ); - this.y = f * Math.sin( t ); - this.z = u; - - return this; - - } - - *[ Symbol.iterator ]() { - - yield this.x; - yield this.y; - yield this.z; - - } - -} - -Vector3.prototype.isVector3 = true; - -const _vector = /*@__PURE__*/ new Vector3(); -const _quaternion = /*@__PURE__*/ new Quaternion(); - - - -;// CONCATENATED MODULE: ./node_modules/three/src/math/Matrix4.js - - -class Matrix4 { - - constructor() { - - this.elements = [ - - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - - ]; - - if ( arguments.length > 0 ) { - - console.error( 'THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.' ); - - } - - } - - set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - - const te = this.elements; - - te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; - te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; - te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; - te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; - - return this; - - } - - identity() { - - this.set( - - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - clone() { - - return new Matrix4().fromArray( this.elements ); - - } - - copy( m ) { - - const te = this.elements; - const me = m.elements; - - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; - te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; - te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; - te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; - - return this; - - } - - copyPosition( m ) { - - const te = this.elements, me = m.elements; - - te[ 12 ] = me[ 12 ]; - te[ 13 ] = me[ 13 ]; - te[ 14 ] = me[ 14 ]; - - return this; - - } - - setFromMatrix3( m ) { - - const me = m.elements; - - this.set( - - me[ 0 ], me[ 3 ], me[ 6 ], 0, - me[ 1 ], me[ 4 ], me[ 7 ], 0, - me[ 2 ], me[ 5 ], me[ 8 ], 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - extractBasis( xAxis, yAxis, zAxis ) { - - xAxis.setFromMatrixColumn( this, 0 ); - yAxis.setFromMatrixColumn( this, 1 ); - zAxis.setFromMatrixColumn( this, 2 ); - - return this; - - } - - makeBasis( xAxis, yAxis, zAxis ) { - - this.set( - xAxis.x, yAxis.x, zAxis.x, 0, - xAxis.y, yAxis.y, zAxis.y, 0, - xAxis.z, yAxis.z, zAxis.z, 0, - 0, 0, 0, 1 - ); - - return this; - - } - - extractRotation( m ) { - - // this method does not support reflection matrices - - const te = this.elements; - const me = m.elements; - - const scaleX = 1 / _v1.setFromMatrixColumn( m, 0 ).length(); - const scaleY = 1 / _v1.setFromMatrixColumn( m, 1 ).length(); - const scaleZ = 1 / _v1.setFromMatrixColumn( m, 2 ).length(); - - te[ 0 ] = me[ 0 ] * scaleX; - te[ 1 ] = me[ 1 ] * scaleX; - te[ 2 ] = me[ 2 ] * scaleX; - te[ 3 ] = 0; - - te[ 4 ] = me[ 4 ] * scaleY; - te[ 5 ] = me[ 5 ] * scaleY; - te[ 6 ] = me[ 6 ] * scaleY; - te[ 7 ] = 0; - - te[ 8 ] = me[ 8 ] * scaleZ; - te[ 9 ] = me[ 9 ] * scaleZ; - te[ 10 ] = me[ 10 ] * scaleZ; - te[ 11 ] = 0; - - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; - - return this; - - } - - makeRotationFromEuler( euler ) { - - if ( ! ( euler && euler.isEuler ) ) { - - console.error( 'THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.' ); - - } - - const te = this.elements; - - const x = euler.x, y = euler.y, z = euler.z; - const a = Math.cos( x ), b = Math.sin( x ); - const c = Math.cos( y ), d = Math.sin( y ); - const e = Math.cos( z ), f = Math.sin( z ); - - if ( euler.order === 'XYZ' ) { - - const ae = a * e, af = a * f, be = b * e, bf = b * f; - - te[ 0 ] = c * e; - te[ 4 ] = - c * f; - te[ 8 ] = d; - - te[ 1 ] = af + be * d; - te[ 5 ] = ae - bf * d; - te[ 9 ] = - b * c; - - te[ 2 ] = bf - ae * d; - te[ 6 ] = be + af * d; - te[ 10 ] = a * c; - - } else if ( euler.order === 'YXZ' ) { - - const ce = c * e, cf = c * f, de = d * e, df = d * f; - - te[ 0 ] = ce + df * b; - te[ 4 ] = de * b - cf; - te[ 8 ] = a * d; - - te[ 1 ] = a * f; - te[ 5 ] = a * e; - te[ 9 ] = - b; - - te[ 2 ] = cf * b - de; - te[ 6 ] = df + ce * b; - te[ 10 ] = a * c; - - } else if ( euler.order === 'ZXY' ) { - - const ce = c * e, cf = c * f, de = d * e, df = d * f; - - te[ 0 ] = ce - df * b; - te[ 4 ] = - a * f; - te[ 8 ] = de + cf * b; - - te[ 1 ] = cf + de * b; - te[ 5 ] = a * e; - te[ 9 ] = df - ce * b; - - te[ 2 ] = - a * d; - te[ 6 ] = b; - te[ 10 ] = a * c; - - } else if ( euler.order === 'ZYX' ) { - - const ae = a * e, af = a * f, be = b * e, bf = b * f; - - te[ 0 ] = c * e; - te[ 4 ] = be * d - af; - te[ 8 ] = ae * d + bf; - - te[ 1 ] = c * f; - te[ 5 ] = bf * d + ae; - te[ 9 ] = af * d - be; - - te[ 2 ] = - d; - te[ 6 ] = b * c; - te[ 10 ] = a * c; - - } else if ( euler.order === 'YZX' ) { - - const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - - te[ 0 ] = c * e; - te[ 4 ] = bd - ac * f; - te[ 8 ] = bc * f + ad; - - te[ 1 ] = f; - te[ 5 ] = a * e; - te[ 9 ] = - b * e; - - te[ 2 ] = - d * e; - te[ 6 ] = ad * f + bc; - te[ 10 ] = ac - bd * f; - - } else if ( euler.order === 'XZY' ) { - - const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - - te[ 0 ] = c * e; - te[ 4 ] = - f; - te[ 8 ] = d * e; - - te[ 1 ] = ac * f + bd; - te[ 5 ] = a * e; - te[ 9 ] = ad * f - bc; - - te[ 2 ] = bc * f - ad; - te[ 6 ] = b * e; - te[ 10 ] = bd * f + ac; - - } - - // bottom row - te[ 3 ] = 0; - te[ 7 ] = 0; - te[ 11 ] = 0; - - // last column - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; - - return this; - - } - - makeRotationFromQuaternion( q ) { - - return this.compose( _zero, q, _one ); - - } - - lookAt( eye, target, up ) { - - const te = this.elements; - - _z.subVectors( eye, target ); - - if ( _z.lengthSq() === 0 ) { - - // eye and target are in the same position - - _z.z = 1; - - } - - _z.normalize(); - _x.crossVectors( up, _z ); - - if ( _x.lengthSq() === 0 ) { - - // up and z are parallel - - if ( Math.abs( up.z ) === 1 ) { - - _z.x += 0.0001; - - } else { - - _z.z += 0.0001; - - } - - _z.normalize(); - _x.crossVectors( up, _z ); - - } - - _x.normalize(); - _y.crossVectors( _z, _x ); - - te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; - te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; - te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; - - return this; - - } - - multiply( m, n ) { - - if ( n !== undefined ) { - - console.warn( 'THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead.' ); - return this.multiplyMatrices( m, n ); - - } - - return this.multiplyMatrices( this, m ); - - } - - premultiply( m ) { - - return this.multiplyMatrices( m, this ); - - } - - multiplyMatrices( a, b ) { - - const ae = a.elements; - const be = b.elements; - const te = this.elements; - - const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; - const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; - const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; - const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; - - const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; - const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; - const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; - const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; - - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; - - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; - - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; - - te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; - - return this; - - } - - multiplyScalar( s ) { - - const te = this.elements; - - te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; - te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; - te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; - te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; - - return this; - - } - - determinant() { - - const te = this.elements; - - const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; - const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; - const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; - const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - - //TODO: make this more efficient - //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm ) - - return ( - n41 * ( - + n14 * n23 * n32 - - n13 * n24 * n32 - - n14 * n22 * n33 - + n12 * n24 * n33 - + n13 * n22 * n34 - - n12 * n23 * n34 - ) + - n42 * ( - + n11 * n23 * n34 - - n11 * n24 * n33 - + n14 * n21 * n33 - - n13 * n21 * n34 - + n13 * n24 * n31 - - n14 * n23 * n31 - ) + - n43 * ( - + n11 * n24 * n32 - - n11 * n22 * n34 - - n14 * n21 * n32 - + n12 * n21 * n34 - + n14 * n22 * n31 - - n12 * n24 * n31 - ) + - n44 * ( - - n13 * n22 * n31 - - n11 * n23 * n32 - + n11 * n22 * n33 - + n13 * n21 * n32 - - n12 * n21 * n33 - + n12 * n23 * n31 - ) - - ); - - } - - transpose() { - - const te = this.elements; - let tmp; - - tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; - tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; - tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; - - tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; - tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; - tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; - - return this; - - } - - setPosition( x, y, z ) { - - const te = this.elements; - - if ( x.isVector3 ) { - - te[ 12 ] = x.x; - te[ 13 ] = x.y; - te[ 14 ] = x.z; - - } else { - - te[ 12 ] = x; - te[ 13 ] = y; - te[ 14 ] = z; - - } - - return this; - - } - - invert() { - - // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm - const te = this.elements, - - n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ], - n12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ], - n13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ], - n14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ], - - t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, - t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, - t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, - t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; - - const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; - - if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - - const detInv = 1 / det; - - te[ 0 ] = t11 * detInv; - te[ 1 ] = ( n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44 ) * detInv; - te[ 2 ] = ( n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44 ) * detInv; - te[ 3 ] = ( n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43 ) * detInv; - - te[ 4 ] = t12 * detInv; - te[ 5 ] = ( n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44 ) * detInv; - te[ 6 ] = ( n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44 ) * detInv; - te[ 7 ] = ( n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43 ) * detInv; - - te[ 8 ] = t13 * detInv; - te[ 9 ] = ( n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44 ) * detInv; - te[ 10 ] = ( n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44 ) * detInv; - te[ 11 ] = ( n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43 ) * detInv; - - te[ 12 ] = t14 * detInv; - te[ 13 ] = ( n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34 ) * detInv; - te[ 14 ] = ( n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34 ) * detInv; - te[ 15 ] = ( n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33 ) * detInv; - - return this; - - } - - scale( v ) { - - const te = this.elements; - const x = v.x, y = v.y, z = v.z; - - te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; - te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; - te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; - te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; - - return this; - - } - - getMaxScaleOnAxis() { - - const te = this.elements; - - const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; - const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; - const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; - - return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); - - } - - makeTranslation( x, y, z ) { - - this.set( - - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1 - - ); - - return this; - - } - - makeRotationX( theta ) { - - const c = Math.cos( theta ), s = Math.sin( theta ); - - this.set( - - 1, 0, 0, 0, - 0, c, - s, 0, - 0, s, c, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - makeRotationY( theta ) { - - const c = Math.cos( theta ), s = Math.sin( theta ); - - this.set( - - c, 0, s, 0, - 0, 1, 0, 0, - - s, 0, c, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - makeRotationZ( theta ) { - - const c = Math.cos( theta ), s = Math.sin( theta ); - - this.set( - - c, - s, 0, 0, - s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - makeRotationAxis( axis, angle ) { - - // Based on http://www.gamedev.net/reference/articles/article1199.asp - - const c = Math.cos( angle ); - const s = Math.sin( angle ); - const t = 1 - c; - const x = axis.x, y = axis.y, z = axis.z; - const tx = t * x, ty = t * y; - - this.set( - - tx * x + c, tx * y - s * z, tx * z + s * y, 0, - tx * y + s * z, ty * y + c, ty * z - s * x, 0, - tx * z - s * y, ty * z + s * x, t * z * z + c, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - makeScale( x, y, z ) { - - this.set( - - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - makeShear( xy, xz, yx, yz, zx, zy ) { - - this.set( - - 1, yx, zx, 0, - xy, 1, zy, 0, - xz, yz, 1, 0, - 0, 0, 0, 1 - - ); - - return this; - - } - - compose( position, quaternion, scale ) { - - const te = this.elements; - - const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; - const x2 = x + x, y2 = y + y, z2 = z + z; - const xx = x * x2, xy = x * y2, xz = x * z2; - const yy = y * y2, yz = y * z2, zz = z * z2; - const wx = w * x2, wy = w * y2, wz = w * z2; - - const sx = scale.x, sy = scale.y, sz = scale.z; - - te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; - te[ 1 ] = ( xy + wz ) * sx; - te[ 2 ] = ( xz - wy ) * sx; - te[ 3 ] = 0; - - te[ 4 ] = ( xy - wz ) * sy; - te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; - te[ 6 ] = ( yz + wx ) * sy; - te[ 7 ] = 0; - - te[ 8 ] = ( xz + wy ) * sz; - te[ 9 ] = ( yz - wx ) * sz; - te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; - te[ 11 ] = 0; - - te[ 12 ] = position.x; - te[ 13 ] = position.y; - te[ 14 ] = position.z; - te[ 15 ] = 1; - - return this; - - } - - decompose( position, quaternion, scale ) { - - const te = this.elements; - - let sx = _v1.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); - const sy = _v1.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); - const sz = _v1.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); - - // if determine is negative, we need to invert one scale - const det = this.determinant(); - if ( det < 0 ) sx = - sx; - - position.x = te[ 12 ]; - position.y = te[ 13 ]; - position.z = te[ 14 ]; - - // scale the rotation part - _m1.copy( this ); - - const invSX = 1 / sx; - const invSY = 1 / sy; - const invSZ = 1 / sz; - - _m1.elements[ 0 ] *= invSX; - _m1.elements[ 1 ] *= invSX; - _m1.elements[ 2 ] *= invSX; - - _m1.elements[ 4 ] *= invSY; - _m1.elements[ 5 ] *= invSY; - _m1.elements[ 6 ] *= invSY; - - _m1.elements[ 8 ] *= invSZ; - _m1.elements[ 9 ] *= invSZ; - _m1.elements[ 10 ] *= invSZ; - - quaternion.setFromRotationMatrix( _m1 ); - - scale.x = sx; - scale.y = sy; - scale.z = sz; - - return this; - - } - - makePerspective( left, right, top, bottom, near, far ) { - - if ( far === undefined ) { - - console.warn( 'THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.' ); - - } - - const te = this.elements; - const x = 2 * near / ( right - left ); - const y = 2 * near / ( top - bottom ); - - const a = ( right + left ) / ( right - left ); - const b = ( top + bottom ) / ( top - bottom ); - const c = - ( far + near ) / ( far - near ); - const d = - 2 * far * near / ( far - near ); - - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = - 1; te[ 15 ] = 0; - - return this; - - } - - makeOrthographic( left, right, top, bottom, near, far ) { - - const te = this.elements; - const w = 1.0 / ( right - left ); - const h = 1.0 / ( top - bottom ); - const p = 1.0 / ( far - near ); - - const x = ( right + left ) * w; - const y = ( top + bottom ) * h; - const z = ( far + near ) * p; - - te[ 0 ] = 2 * w; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = - x; - te[ 1 ] = 0; te[ 5 ] = 2 * h; te[ 9 ] = 0; te[ 13 ] = - y; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = - 2 * p; te[ 14 ] = - z; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; - - return this; - - } - - equals( matrix ) { - - const te = this.elements; - const me = matrix.elements; - - for ( let i = 0; i < 16; i ++ ) { - - if ( te[ i ] !== me[ i ] ) return false; - - } - - return true; - - } - - fromArray( array, offset = 0 ) { - - for ( let i = 0; i < 16; i ++ ) { - - this.elements[ i ] = array[ i + offset ]; - - } - - return this; - - } - - toArray( array = [], offset = 0 ) { - - const te = this.elements; - - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; - - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - - array[ offset + 8 ] = te[ 8 ]; - array[ offset + 9 ] = te[ 9 ]; - array[ offset + 10 ] = te[ 10 ]; - array[ offset + 11 ] = te[ 11 ]; - - array[ offset + 12 ] = te[ 12 ]; - array[ offset + 13 ] = te[ 13 ]; - array[ offset + 14 ] = te[ 14 ]; - array[ offset + 15 ] = te[ 15 ]; - - return array; - - } - -} - -Matrix4.prototype.isMatrix4 = true; - -const _v1 = /*@__PURE__*/ new Vector3(); -const _m1 = /*@__PURE__*/ new Matrix4(); -const _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 ); -const _one = /*@__PURE__*/ new Vector3( 1, 1, 1 ); -const _x = /*@__PURE__*/ new Vector3(); -const _y = /*@__PURE__*/ new Vector3(); -const _z = /*@__PURE__*/ new Vector3(); - - - -;// CONCATENATED MODULE: ./node_modules/three/src/core/EventDispatcher.js -/** - * https://github.com/mrdoob/eventdispatcher.js/ - */ - -class EventDispatcher { - - addEventListener( type, listener ) { - - if ( this._listeners === undefined ) this._listeners = {}; - - const listeners = this._listeners; - - if ( listeners[ type ] === undefined ) { - - listeners[ type ] = []; - - } - - if ( listeners[ type ].indexOf( listener ) === - 1 ) { - - listeners[ type ].push( listener ); - - } - - } - - hasEventListener( type, listener ) { - - if ( this._listeners === undefined ) return false; - - const listeners = this._listeners; - - return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1; - - } - - removeEventListener( type, listener ) { - - if ( this._listeners === undefined ) return; - - const listeners = this._listeners; - const listenerArray = listeners[ type ]; - - if ( listenerArray !== undefined ) { - - const index = listenerArray.indexOf( listener ); - - if ( index !== - 1 ) { - - listenerArray.splice( index, 1 ); - - } - - } - - } - - dispatchEvent( event ) { - - if ( this._listeners === undefined ) return; - - const listeners = this._listeners; - const listenerArray = listeners[ event.type ]; - - if ( listenerArray !== undefined ) { - - event.target = this; - - // Make a copy, in case listeners are removed while iterating. - const array = listenerArray.slice( 0 ); - - for ( let i = 0, l = array.length; i < l; i ++ ) { - - array[ i ].call( this, event ); - - } - - event.target = null; - - } - - } - -} - - - - -;// CONCATENATED MODULE: ./node_modules/three/src/math/Euler.js - - - - - -const _matrix = /*@__PURE__*/ new Matrix4(); -const Euler_quaternion = /*@__PURE__*/ new Quaternion(); - -class Euler { - - constructor( x = 0, y = 0, z = 0, order = Euler.DefaultOrder ) { - - this._x = x; - this._y = y; - this._z = z; - this._order = order; - - } - - get x() { - - return this._x; - - } - - set x( value ) { - - this._x = value; - this._onChangeCallback(); - - } - - get y() { - - return this._y; - - } - - set y( value ) { - - this._y = value; - this._onChangeCallback(); - - } - - get z() { - - return this._z; - - } - - set z( value ) { - - this._z = value; - this._onChangeCallback(); - - } - - get order() { - - return this._order; - - } - - set order( value ) { - - this._order = value; - this._onChangeCallback(); - - } - - set( x, y, z, order = this._order ) { - - this._x = x; - this._y = y; - this._z = z; - this._order = order; - - this._onChangeCallback(); - - return this; - - } - - clone() { - - return new this.constructor( this._x, this._y, this._z, this._order ); - - } - - copy( euler ) { - - this._x = euler._x; - this._y = euler._y; - this._z = euler._z; - this._order = euler._order; - - this._onChangeCallback(); - - return this; - - } - - setFromRotationMatrix( m, order = this._order, update = true ) { - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - const te = m.elements; - const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; - const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; - const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - - switch ( order ) { - - case 'XYZ': - - this._y = Math.asin( clamp( m13, - 1, 1 ) ); - - if ( Math.abs( m13 ) < 0.9999999 ) { - - this._x = Math.atan2( - m23, m33 ); - this._z = Math.atan2( - m12, m11 ); - - } else { - - this._x = Math.atan2( m32, m22 ); - this._z = 0; - - } - - break; - - case 'YXZ': - - this._x = Math.asin( - clamp( m23, - 1, 1 ) ); - - if ( Math.abs( m23 ) < 0.9999999 ) { - - this._y = Math.atan2( m13, m33 ); - this._z = Math.atan2( m21, m22 ); - - } else { - - this._y = Math.atan2( - m31, m11 ); - this._z = 0; - - } - - break; - - case 'ZXY': - - this._x = Math.asin( clamp( m32, - 1, 1 ) ); - - if ( Math.abs( m32 ) < 0.9999999 ) { - - this._y = Math.atan2( - m31, m33 ); - this._z = Math.atan2( - m12, m22 ); - - } else { - - this._y = 0; - this._z = Math.atan2( m21, m11 ); - - } - - break; - - case 'ZYX': - - this._y = Math.asin( - clamp( m31, - 1, 1 ) ); - - if ( Math.abs( m31 ) < 0.9999999 ) { - - this._x = Math.atan2( m32, m33 ); - this._z = Math.atan2( m21, m11 ); - - } else { - - this._x = 0; - this._z = Math.atan2( - m12, m22 ); - - } - - break; - - case 'YZX': - - this._z = Math.asin( clamp( m21, - 1, 1 ) ); - - if ( Math.abs( m21 ) < 0.9999999 ) { - - this._x = Math.atan2( - m23, m22 ); - this._y = Math.atan2( - m31, m11 ); - - } else { - - this._x = 0; - this._y = Math.atan2( m13, m33 ); - - } - - break; - - case 'XZY': - - this._z = Math.asin( - clamp( m12, - 1, 1 ) ); - - if ( Math.abs( m12 ) < 0.9999999 ) { - - this._x = Math.atan2( m32, m22 ); - this._y = Math.atan2( m13, m11 ); - - } else { - - this._x = Math.atan2( - m23, m33 ); - this._y = 0; - - } - - break; - - default: - - console.warn( 'THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); - - } - - this._order = order; - - if ( update === true ) this._onChangeCallback(); - - return this; - - } - - setFromQuaternion( q, order, update ) { - - _matrix.makeRotationFromQuaternion( q ); - - return this.setFromRotationMatrix( _matrix, order, update ); - - } - - setFromVector3( v, order = this._order ) { - - return this.set( v.x, v.y, v.z, order ); - - } - - reorder( newOrder ) { - - // WARNING: this discards revolution information -bhouston - - Euler_quaternion.setFromEuler( this ); - - return this.setFromQuaternion( Euler_quaternion, newOrder ); - - } - - equals( euler ) { - - return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); - - } - - fromArray( array ) { - - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; - - this._onChangeCallback(); - - return this; - - } - - toArray( array = [], offset = 0 ) { - - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._order; - - return array; - - } - - toVector3( optionalResult ) { - - if ( optionalResult ) { - - return optionalResult.set( this._x, this._y, this._z ); - - } else { - - return new Vector3( this._x, this._y, this._z ); - - } - - } - - _onChange( callback ) { - - this._onChangeCallback = callback; - - return this; - - } - - _onChangeCallback() {} - -} - -Euler.prototype.isEuler = true; - -Euler.DefaultOrder = 'XYZ'; -Euler.RotationOrders = [ 'XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX' ]; - - - -;// CONCATENATED MODULE: ./node_modules/three/src/core/Layers.js -class Layers { - - constructor() { - - this.mask = 1 | 0; - - } - - set( channel ) { - - this.mask = ( 1 << channel | 0 ) >>> 0; - - } - - enable( channel ) { - - this.mask |= 1 << channel | 0; - - } - - enableAll() { - - this.mask = 0xffffffff | 0; - - } - - toggle( channel ) { - - this.mask ^= 1 << channel | 0; - - } - - disable( channel ) { - - this.mask &= ~ ( 1 << channel | 0 ); - - } - - disableAll() { - - this.mask = 0; - - } - - test( layers ) { - - return ( this.mask & layers.mask ) !== 0; - - } - - isEnabled( channel ) { - - return ( this.mask & ( 1 << channel | 0 ) ) !== 0; - - } - -} - - - - -;// CONCATENATED MODULE: ./node_modules/three/src/math/Matrix3.js -class Matrix3 { - - constructor() { - - this.elements = [ - - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - - ]; - - if ( arguments.length > 0 ) { - - console.error( 'THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.' ); - - } - - } - - set( n11, n12, n13, n21, n22, n23, n31, n32, n33 ) { - - const te = this.elements; - - te[ 0 ] = n11; te[ 1 ] = n21; te[ 2 ] = n31; - te[ 3 ] = n12; te[ 4 ] = n22; te[ 5 ] = n32; - te[ 6 ] = n13; te[ 7 ] = n23; te[ 8 ] = n33; - - return this; - - } - - identity() { - - this.set( - - 1, 0, 0, - 0, 1, 0, - 0, 0, 1 - - ); - - return this; - - } - - copy( m ) { - - const te = this.elements; - const me = m.elements; - - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; - te[ 3 ] = me[ 3 ]; te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; - te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; te[ 8 ] = me[ 8 ]; - - return this; - - } - - extractBasis( xAxis, yAxis, zAxis ) { - - xAxis.setFromMatrix3Column( this, 0 ); - yAxis.setFromMatrix3Column( this, 1 ); - zAxis.setFromMatrix3Column( this, 2 ); - - return this; - - } - - setFromMatrix4( m ) { - - const me = m.elements; - - this.set( - - me[ 0 ], me[ 4 ], me[ 8 ], - me[ 1 ], me[ 5 ], me[ 9 ], - me[ 2 ], me[ 6 ], me[ 10 ] - - ); - - return this; - - } - - multiply( m ) { - - return this.multiplyMatrices( this, m ); - - } - - premultiply( m ) { - - return this.multiplyMatrices( m, this ); - - } - - multiplyMatrices( a, b ) { - - const ae = a.elements; - const be = b.elements; - const te = this.elements; - - const a11 = ae[ 0 ], a12 = ae[ 3 ], a13 = ae[ 6 ]; - const a21 = ae[ 1 ], a22 = ae[ 4 ], a23 = ae[ 7 ]; - const a31 = ae[ 2 ], a32 = ae[ 5 ], a33 = ae[ 8 ]; - - const b11 = be[ 0 ], b12 = be[ 3 ], b13 = be[ 6 ]; - const b21 = be[ 1 ], b22 = be[ 4 ], b23 = be[ 7 ]; - const b31 = be[ 2 ], b32 = be[ 5 ], b33 = be[ 8 ]; - - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31; - te[ 3 ] = a11 * b12 + a12 * b22 + a13 * b32; - te[ 6 ] = a11 * b13 + a12 * b23 + a13 * b33; - - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31; - te[ 4 ] = a21 * b12 + a22 * b22 + a23 * b32; - te[ 7 ] = a21 * b13 + a22 * b23 + a23 * b33; - - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31; - te[ 5 ] = a31 * b12 + a32 * b22 + a33 * b32; - te[ 8 ] = a31 * b13 + a32 * b23 + a33 * b33; - - return this; - - } - - multiplyScalar( s ) { - - const te = this.elements; - - te[ 0 ] *= s; te[ 3 ] *= s; te[ 6 ] *= s; - te[ 1 ] *= s; te[ 4 ] *= s; te[ 7 ] *= s; - te[ 2 ] *= s; te[ 5 ] *= s; te[ 8 ] *= s; - - return this; - - } - - determinant() { - - const te = this.elements; - - const a = te[ 0 ], b = te[ 1 ], c = te[ 2 ], - d = te[ 3 ], e = te[ 4 ], f = te[ 5 ], - g = te[ 6 ], h = te[ 7 ], i = te[ 8 ]; - - return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g; - - } - - invert() { - - const te = this.elements, - - n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], - n12 = te[ 3 ], n22 = te[ 4 ], n32 = te[ 5 ], - n13 = te[ 6 ], n23 = te[ 7 ], n33 = te[ 8 ], - - t11 = n33 * n22 - n32 * n23, - t12 = n32 * n13 - n33 * n12, - t13 = n23 * n12 - n22 * n13, - - det = n11 * t11 + n21 * t12 + n31 * t13; - - if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - - const detInv = 1 / det; - - te[ 0 ] = t11 * detInv; - te[ 1 ] = ( n31 * n23 - n33 * n21 ) * detInv; - te[ 2 ] = ( n32 * n21 - n31 * n22 ) * detInv; - - te[ 3 ] = t12 * detInv; - te[ 4 ] = ( n33 * n11 - n31 * n13 ) * detInv; - te[ 5 ] = ( n31 * n12 - n32 * n11 ) * detInv; - - te[ 6 ] = t13 * detInv; - te[ 7 ] = ( n21 * n13 - n23 * n11 ) * detInv; - te[ 8 ] = ( n22 * n11 - n21 * n12 ) * detInv; - - return this; - - } - - transpose() { - - let tmp; - const m = this.elements; - - tmp = m[ 1 ]; m[ 1 ] = m[ 3 ]; m[ 3 ] = tmp; - tmp = m[ 2 ]; m[ 2 ] = m[ 6 ]; m[ 6 ] = tmp; - tmp = m[ 5 ]; m[ 5 ] = m[ 7 ]; m[ 7 ] = tmp; - - return this; - - } - - getNormalMatrix( matrix4 ) { - - return this.setFromMatrix4( matrix4 ).invert().transpose(); - - } - - transposeIntoArray( r ) { - - const m = this.elements; - - r[ 0 ] = m[ 0 ]; - r[ 1 ] = m[ 3 ]; - r[ 2 ] = m[ 6 ]; - r[ 3 ] = m[ 1 ]; - r[ 4 ] = m[ 4 ]; - r[ 5 ] = m[ 7 ]; - r[ 6 ] = m[ 2 ]; - r[ 7 ] = m[ 5 ]; - r[ 8 ] = m[ 8 ]; - - return this; - - } - - setUvTransform( tx, ty, sx, sy, rotation, cx, cy ) { - - const c = Math.cos( rotation ); - const s = Math.sin( rotation ); - - this.set( - sx * c, sx * s, - sx * ( c * cx + s * cy ) + cx + tx, - - sy * s, sy * c, - sy * ( - s * cx + c * cy ) + cy + ty, - 0, 0, 1 - ); - - return this; - - } - - scale( sx, sy ) { - - const te = this.elements; - - te[ 0 ] *= sx; te[ 3 ] *= sx; te[ 6 ] *= sx; - te[ 1 ] *= sy; te[ 4 ] *= sy; te[ 7 ] *= sy; - - return this; - - } - - rotate( theta ) { - - const c = Math.cos( theta ); - const s = Math.sin( theta ); - - const te = this.elements; - - const a11 = te[ 0 ], a12 = te[ 3 ], a13 = te[ 6 ]; - const a21 = te[ 1 ], a22 = te[ 4 ], a23 = te[ 7 ]; - - te[ 0 ] = c * a11 + s * a21; - te[ 3 ] = c * a12 + s * a22; - te[ 6 ] = c * a13 + s * a23; - - te[ 1 ] = - s * a11 + c * a21; - te[ 4 ] = - s * a12 + c * a22; - te[ 7 ] = - s * a13 + c * a23; - - return this; - - } - - translate( tx, ty ) { - - const te = this.elements; - - te[ 0 ] += tx * te[ 2 ]; te[ 3 ] += tx * te[ 5 ]; te[ 6 ] += tx * te[ 8 ]; - te[ 1 ] += ty * te[ 2 ]; te[ 4 ] += ty * te[ 5 ]; te[ 7 ] += ty * te[ 8 ]; - - return this; - - } - - equals( matrix ) { - - const te = this.elements; - const me = matrix.elements; - - for ( let i = 0; i < 9; i ++ ) { - - if ( te[ i ] !== me[ i ] ) return false; - - } - - return true; - - } - - fromArray( array, offset = 0 ) { - - for ( let i = 0; i < 9; i ++ ) { - - this.elements[ i ] = array[ i + offset ]; - - } - - return this; - - } - - toArray( array = [], offset = 0 ) { - - const te = this.elements; - - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - - array[ offset + 3 ] = te[ 3 ]; - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; - array[ offset + 8 ] = te[ 8 ]; - - return array; - - } - - clone() { - - return new this.constructor().fromArray( this.elements ); - - } - -} - -Matrix3.prototype.isMatrix3 = true; - - - -;// CONCATENATED MODULE: ./node_modules/three/src/core/Object3D.js - - - - - - - - - -let _object3DId = 0; - -const Object3D_v1 = /*@__PURE__*/ new Vector3(); -const _q1 = /*@__PURE__*/ new Quaternion(); -const Object3D_m1 = /*@__PURE__*/ new Matrix4(); -const _target = /*@__PURE__*/ new Vector3(); - -const _position = /*@__PURE__*/ new Vector3(); -const _scale = /*@__PURE__*/ new Vector3(); -const Object3D_quaternion = /*@__PURE__*/ new Quaternion(); - -const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 ); -const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 ); -const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 ); - -const _addedEvent = { type: 'added' }; -const _removedEvent = { type: 'removed' }; - -class Object3D extends EventDispatcher { - - constructor() { - - super(); - - Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - - this.uuid = generateUUID(); - - this.name = ''; - this.type = 'Object3D'; - - this.parent = null; - this.children = []; - - this.up = Object3D.DefaultUp.clone(); - - const position = new Vector3(); - const rotation = new Euler(); - const quaternion = new Quaternion(); - const scale = new Vector3( 1, 1, 1 ); - - function onRotationChange() { - - quaternion.setFromEuler( rotation, false ); - - } - - function onQuaternionChange() { - - rotation.setFromQuaternion( quaternion, undefined, false ); - - } - - rotation._onChange( onRotationChange ); - quaternion._onChange( onQuaternionChange ); - - Object.defineProperties( this, { - position: { - configurable: true, - enumerable: true, - value: position - }, - rotation: { - configurable: true, - enumerable: true, - value: rotation - }, - quaternion: { - configurable: true, - enumerable: true, - value: quaternion - }, - scale: { - configurable: true, - enumerable: true, - value: scale - }, - modelViewMatrix: { - value: new Matrix4() - }, - normalMatrix: { - value: new Matrix3() - } - } ); - - this.matrix = new Matrix4(); - this.matrixWorld = new Matrix4(); - - this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate; - this.matrixWorldNeedsUpdate = false; - - this.layers = new Layers(); - this.visible = true; - - this.castShadow = false; - this.receiveShadow = false; - - this.frustumCulled = true; - this.renderOrder = 0; - - this.animations = []; - - this.userData = {}; - - } - - onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} - - onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} - - applyMatrix4( matrix ) { - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - this.matrix.premultiply( matrix ); - - this.matrix.decompose( this.position, this.quaternion, this.scale ); - - } - - applyQuaternion( q ) { - - this.quaternion.premultiply( q ); - - return this; - - } - - setRotationFromAxisAngle( axis, angle ) { - - // assumes axis is normalized - - this.quaternion.setFromAxisAngle( axis, angle ); - - } - - setRotationFromEuler( euler ) { - - this.quaternion.setFromEuler( euler, true ); - - } - - setRotationFromMatrix( m ) { - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - this.quaternion.setFromRotationMatrix( m ); - - } - - setRotationFromQuaternion( q ) { - - // assumes q is normalized - - this.quaternion.copy( q ); - - } - - rotateOnAxis( axis, angle ) { - - // rotate object on axis in object space - // axis is assumed to be normalized - - _q1.setFromAxisAngle( axis, angle ); - - this.quaternion.multiply( _q1 ); - - return this; - - } - - rotateOnWorldAxis( axis, angle ) { - - // rotate object on axis in world space - // axis is assumed to be normalized - // method assumes no rotated parent - - _q1.setFromAxisAngle( axis, angle ); - - this.quaternion.premultiply( _q1 ); - - return this; - - } - - rotateX( angle ) { - - return this.rotateOnAxis( _xAxis, angle ); - - } - - rotateY( angle ) { - - return this.rotateOnAxis( _yAxis, angle ); - - } - - rotateZ( angle ) { - - return this.rotateOnAxis( _zAxis, angle ); - - } - - translateOnAxis( axis, distance ) { - - // translate object by distance along axis in object space - // axis is assumed to be normalized - - Object3D_v1.copy( axis ).applyQuaternion( this.quaternion ); - - this.position.add( Object3D_v1.multiplyScalar( distance ) ); - - return this; - - } - - translateX( distance ) { - - return this.translateOnAxis( _xAxis, distance ); - - } - - translateY( distance ) { - - return this.translateOnAxis( _yAxis, distance ); - - } - - translateZ( distance ) { - - return this.translateOnAxis( _zAxis, distance ); - - } - - localToWorld( vector ) { - - return vector.applyMatrix4( this.matrixWorld ); - - } - - worldToLocal( vector ) { - - return vector.applyMatrix4( Object3D_m1.copy( this.matrixWorld ).invert() ); - - } - - lookAt( x, y, z ) { - - // This method does not support objects having non-uniformly-scaled parent(s) - - if ( x.isVector3 ) { - - _target.copy( x ); - - } else { - - _target.set( x, y, z ); - - } - - const parent = this.parent; - - this.updateWorldMatrix( true, false ); - - _position.setFromMatrixPosition( this.matrixWorld ); - - if ( this.isCamera || this.isLight ) { - - Object3D_m1.lookAt( _position, _target, this.up ); - - } else { - - Object3D_m1.lookAt( _target, _position, this.up ); - - } - - this.quaternion.setFromRotationMatrix( Object3D_m1 ); - - if ( parent ) { - - Object3D_m1.extractRotation( parent.matrixWorld ); - _q1.setFromRotationMatrix( Object3D_m1 ); - this.quaternion.premultiply( _q1.invert() ); - - } - - } - - add( object ) { - - if ( arguments.length > 1 ) { - - for ( let i = 0; i < arguments.length; i ++ ) { - - this.add( arguments[ i ] ); - - } - - return this; - - } - - if ( object === this ) { - - console.error( 'THREE.Object3D.add: object can\'t be added as a child of itself.', object ); - return this; - - } - - if ( object && object.isObject3D ) { - - if ( object.parent !== null ) { - - object.parent.remove( object ); - - } - - object.parent = this; - this.children.push( object ); - - object.dispatchEvent( _addedEvent ); - - } else { - - console.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object ); - - } - - return this; - - } - - remove( object ) { - - if ( arguments.length > 1 ) { - - for ( let i = 0; i < arguments.length; i ++ ) { - - this.remove( arguments[ i ] ); - - } - - return this; - - } - - const index = this.children.indexOf( object ); - - if ( index !== - 1 ) { - - object.parent = null; - this.children.splice( index, 1 ); - - object.dispatchEvent( _removedEvent ); - - } - - return this; - - } - - removeFromParent() { - - const parent = this.parent; - - if ( parent !== null ) { - - parent.remove( this ); - - } - - return this; - - } - - clear() { - - for ( let i = 0; i < this.children.length; i ++ ) { - - const object = this.children[ i ]; - - object.parent = null; - - object.dispatchEvent( _removedEvent ); - - } - - this.children.length = 0; - - return this; - - - } - - attach( object ) { - - // adds object as a child of this, while maintaining the object's world transform - - // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - - this.updateWorldMatrix( true, false ); - - Object3D_m1.copy( this.matrixWorld ).invert(); - - if ( object.parent !== null ) { - - object.parent.updateWorldMatrix( true, false ); - - Object3D_m1.multiply( object.parent.matrixWorld ); - - } - - object.applyMatrix4( Object3D_m1 ); - - this.add( object ); - - object.updateWorldMatrix( false, true ); - - return this; - - } - - getObjectById( id ) { - - return this.getObjectByProperty( 'id', id ); - - } - - getObjectByName( name ) { - - return this.getObjectByProperty( 'name', name ); - - } - - getObjectByProperty( name, value ) { - - if ( this[ name ] === value ) return this; - - for ( let i = 0, l = this.children.length; i < l; i ++ ) { - - const child = this.children[ i ]; - const object = child.getObjectByProperty( name, value ); - - if ( object !== undefined ) { - - return object; - - } - - } - - return undefined; - - } - - getWorldPosition( target ) { - - this.updateWorldMatrix( true, false ); - - return target.setFromMatrixPosition( this.matrixWorld ); - - } - - getWorldQuaternion( target ) { - - this.updateWorldMatrix( true, false ); - - this.matrixWorld.decompose( _position, target, _scale ); - - return target; - - } - - getWorldScale( target ) { - - this.updateWorldMatrix( true, false ); - - this.matrixWorld.decompose( _position, Object3D_quaternion, target ); - - return target; - - } - - getWorldDirection( target ) { - - this.updateWorldMatrix( true, false ); - - const e = this.matrixWorld.elements; - - return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); - - } - - raycast( /* raycaster, intersects */ ) {} - - traverse( callback ) { - - callback( this ); - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].traverse( callback ); - - } - - } - - traverseVisible( callback ) { - - if ( this.visible === false ) return; - - callback( this ); - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].traverseVisible( callback ); - - } - - } - - traverseAncestors( callback ) { - - const parent = this.parent; - - if ( parent !== null ) { - - callback( parent ); - - parent.traverseAncestors( callback ); - - } - - } - - updateMatrix() { - - this.matrix.compose( this.position, this.quaternion, this.scale ); - - this.matrixWorldNeedsUpdate = true; - - } - - updateMatrixWorld( force ) { - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - if ( this.matrixWorldNeedsUpdate || force ) { - - if ( this.parent === null ) { - - this.matrixWorld.copy( this.matrix ); - - } else { - - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - - } - - this.matrixWorldNeedsUpdate = false; - - force = true; - - } - - // update children - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].updateMatrixWorld( force ); - - } - - } - - updateWorldMatrix( updateParents, updateChildren ) { - - const parent = this.parent; - - if ( updateParents === true && parent !== null ) { - - parent.updateWorldMatrix( true, false ); - - } - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - if ( this.parent === null ) { - - this.matrixWorld.copy( this.matrix ); - - } else { - - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - - } - - // update children - - if ( updateChildren === true ) { - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].updateWorldMatrix( false, true ); - - } - - } - - } - - toJSON( meta ) { - - // meta is a string when called from JSON.stringify - const isRootObject = ( meta === undefined || typeof meta === 'string' ); - - const output = {}; - - // meta is a hash used to collect geometries, materials. - // not providing it implies that this is the root object - // being serialized. - if ( isRootObject ) { - - // initialize meta obj - meta = { - geometries: {}, - materials: {}, - textures: {}, - images: {}, - shapes: {}, - skeletons: {}, - animations: {} - }; - - output.metadata = { - version: 4.5, - type: 'Object', - generator: 'Object3D.toJSON' - }; - - } - - // standard Object3D serialization - - const object = {}; - - object.uuid = this.uuid; - object.type = this.type; - - if ( this.name !== '' ) object.name = this.name; - if ( this.castShadow === true ) object.castShadow = true; - if ( this.receiveShadow === true ) object.receiveShadow = true; - if ( this.visible === false ) object.visible = false; - if ( this.frustumCulled === false ) object.frustumCulled = false; - if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData; - - object.layers = this.layers.mask; - object.matrix = this.matrix.toArray(); - - if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - - // object specific properties - - if ( this.isInstancedMesh ) { - - object.type = 'InstancedMesh'; - object.count = this.count; - object.instanceMatrix = this.instanceMatrix.toJSON(); - if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); - - } - - // - - function serialize( library, element ) { - - if ( library[ element.uuid ] === undefined ) { - - library[ element.uuid ] = element.toJSON( meta ); - - } - - return element.uuid; - - } - - if ( this.isScene ) { - - if ( this.background ) { - - if ( this.background.isColor ) { - - object.background = this.background.toJSON(); - - } else if ( this.background.isTexture ) { - - object.background = this.background.toJSON( meta ).uuid; - - } - - } - - if ( this.environment && this.environment.isTexture ) { - - object.environment = this.environment.toJSON( meta ).uuid; - - } - - } else if ( this.isMesh || this.isLine || this.isPoints ) { - - object.geometry = serialize( meta.geometries, this.geometry ); - - const parameters = this.geometry.parameters; - - if ( parameters !== undefined && parameters.shapes !== undefined ) { - - const shapes = parameters.shapes; - - if ( Array.isArray( shapes ) ) { - - for ( let i = 0, l = shapes.length; i < l; i ++ ) { - - const shape = shapes[ i ]; - - serialize( meta.shapes, shape ); - - } - - } else { - - serialize( meta.shapes, shapes ); - - } - - } - - } - - if ( this.isSkinnedMesh ) { - - object.bindMode = this.bindMode; - object.bindMatrix = this.bindMatrix.toArray(); - - if ( this.skeleton !== undefined ) { - - serialize( meta.skeletons, this.skeleton ); - - object.skeleton = this.skeleton.uuid; - - } - - } - - if ( this.material !== undefined ) { - - if ( Array.isArray( this.material ) ) { - - const uuids = []; - - for ( let i = 0, l = this.material.length; i < l; i ++ ) { - - uuids.push( serialize( meta.materials, this.material[ i ] ) ); - - } - - object.material = uuids; - - } else { - - object.material = serialize( meta.materials, this.material ); - - } - - } - - // - - if ( this.children.length > 0 ) { - - object.children = []; - - for ( let i = 0; i < this.children.length; i ++ ) { - - object.children.push( this.children[ i ].toJSON( meta ).object ); - - } - - } - - // - - if ( this.animations.length > 0 ) { - - object.animations = []; - - for ( let i = 0; i < this.animations.length; i ++ ) { - - const animation = this.animations[ i ]; - - object.animations.push( serialize( meta.animations, animation ) ); - - } - - } - - if ( isRootObject ) { - - const geometries = extractFromCache( meta.geometries ); - const materials = extractFromCache( meta.materials ); - const textures = extractFromCache( meta.textures ); - const images = extractFromCache( meta.images ); - const shapes = extractFromCache( meta.shapes ); - const skeletons = extractFromCache( meta.skeletons ); - const animations = extractFromCache( meta.animations ); - - if ( geometries.length > 0 ) output.geometries = geometries; - if ( materials.length > 0 ) output.materials = materials; - if ( textures.length > 0 ) output.textures = textures; - if ( images.length > 0 ) output.images = images; - if ( shapes.length > 0 ) output.shapes = shapes; - if ( skeletons.length > 0 ) output.skeletons = skeletons; - if ( animations.length > 0 ) output.animations = animations; - - } - - output.object = object; - - return output; - - // extract data from the cache hash - // remove metadata on each item - // and return as array - function extractFromCache( cache ) { - - const values = []; - for ( const key in cache ) { - - const data = cache[ key ]; - delete data.metadata; - values.push( data ); - - } - - return values; - - } - - } - - clone( recursive ) { - - return new this.constructor().copy( this, recursive ); - - } - - copy( source, recursive = true ) { - - this.name = source.name; - - this.up.copy( source.up ); - - this.position.copy( source.position ); - this.rotation.order = source.rotation.order; - this.quaternion.copy( source.quaternion ); - this.scale.copy( source.scale ); - - this.matrix.copy( source.matrix ); - this.matrixWorld.copy( source.matrixWorld ); - - this.matrixAutoUpdate = source.matrixAutoUpdate; - this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - - this.layers.mask = source.layers.mask; - this.visible = source.visible; - - this.castShadow = source.castShadow; - this.receiveShadow = source.receiveShadow; - - this.frustumCulled = source.frustumCulled; - this.renderOrder = source.renderOrder; - - this.userData = JSON.parse( JSON.stringify( source.userData ) ); - - if ( recursive === true ) { - - for ( let i = 0; i < source.children.length; i ++ ) { - - const child = source.children[ i ]; - this.add( child.clone() ); - - } - - } - - return this; - - } - -} - -Object3D.DefaultUp = new Vector3( 0, 1, 0 ); -Object3D.DefaultMatrixAutoUpdate = true; - -Object3D.prototype.isObject3D = true; - - - -;// CONCATENATED MODULE: ./node_modules/three/src/cameras/Camera.js - - - -class Camera extends Object3D { - - constructor() { - - super(); - - this.type = 'Camera'; - - this.matrixWorldInverse = new Matrix4(); - - this.projectionMatrix = new Matrix4(); - this.projectionMatrixInverse = new Matrix4(); - - } - - copy( source, recursive ) { - - super.copy( source, recursive ); - - this.matrixWorldInverse.copy( source.matrixWorldInverse ); - - this.projectionMatrix.copy( source.projectionMatrix ); - this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); - - return this; - - } - - getWorldDirection( target ) { - - this.updateWorldMatrix( true, false ); - - const e = this.matrixWorld.elements; - - return target.set( - e[ 8 ], - e[ 9 ], - e[ 10 ] ).normalize(); - - } - - updateMatrixWorld( force ) { - - super.updateMatrixWorld( force ); - - this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - - } - - updateWorldMatrix( updateParents, updateChildren ) { - - super.updateWorldMatrix( updateParents, updateChildren ); - - this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - - } - - clone() { - - return new this.constructor().copy( this ); - - } - -} - -Camera.prototype.isCamera = true; - - - -;// CONCATENATED MODULE: ./node_modules/three/src/cameras/OrthographicCamera.js - - -class OrthographicCamera extends Camera { - - constructor( left = - 1, right = 1, top = 1, bottom = - 1, near = 0.1, far = 2000 ) { - - super(); - - this.type = 'OrthographicCamera'; - - this.zoom = 1; - this.view = null; - - this.left = left; - this.right = right; - this.top = top; - this.bottom = bottom; - - this.near = near; - this.far = far; - - this.updateProjectionMatrix(); - - } - - copy( source, recursive ) { - - super.copy( source, recursive ); - - this.left = source.left; - this.right = source.right; - this.top = source.top; - this.bottom = source.bottom; - this.near = source.near; - this.far = source.far; - - this.zoom = source.zoom; - this.view = source.view === null ? null : Object.assign( {}, source.view ); - - return this; - - } - - setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - - if ( this.view === null ) { - - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; - - } - - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; - - this.updateProjectionMatrix(); - - } - - clearViewOffset() { - - if ( this.view !== null ) { - - this.view.enabled = false; - - } - - this.updateProjectionMatrix(); - - } - - updateProjectionMatrix() { - - const dx = ( this.right - this.left ) / ( 2 * this.zoom ); - const dy = ( this.top - this.bottom ) / ( 2 * this.zoom ); - const cx = ( this.right + this.left ) / 2; - const cy = ( this.top + this.bottom ) / 2; - - let left = cx - dx; - let right = cx + dx; - let top = cy + dy; - let bottom = cy - dy; - - if ( this.view !== null && this.view.enabled ) { - - const scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom; - const scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom; - - left += scaleW * this.view.offsetX; - right = left + scaleW * this.view.width; - top -= scaleH * this.view.offsetY; - bottom = top - scaleH * this.view.height; - - } - - this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far ); - - this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); - - } - - toJSON( meta ) { - - const data = super.toJSON( meta ); - - data.object.zoom = this.zoom; - data.object.left = this.left; - data.object.right = this.right; - data.object.top = this.top; - data.object.bottom = this.bottom; - data.object.near = this.near; - data.object.far = this.far; - - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - - return data; - - } - -} - -OrthographicCamera.prototype.isOrthographicCamera = true; - - - -;// CONCATENATED MODULE: ./src/core/camera.js - - - - - -Bootstrap.registerPlugin("camera", { - defaults: { - near: 0.01, - far: 10000, - - type: "perspective", - fov: 60, - aspect: null, - - // type: 'orthographic', - left: -1, - right: 1, - bottom: -1, - top: 1, - - klass: null, - parameters: null, - }, - - listen: ["resize", "this.change"], - - install: function (three) { - three.Camera = this.api(); - three.camera = null; - - this.aspect = 1; - this.change({}, three); - }, - - uninstall: function (three) { - delete three.Camera; - delete three.camera; - }, - - change: function (event, three) { - const o = this.options; - const old = three.camera; - - if (!three.camera || event.changes.type || event.changes.klass) { - const klass = - o.klass || - { - perspective: external_THREE_.PerspectiveCamera, - orthographic: OrthographicCamera, - }[o.type] || - Camera; - - three.camera = o.parameters ? new klass(o.parameters) : new klass(); - } - - Object.entries(o).forEach( - function ([key]) { - if (Object.prototype.hasOwnProperty.call(three.camera, key)) - three.camera[key] = o[key]; - }.bind(this) - ); - - this.update(three); - - old === three.camera || - three.trigger({ - type: "camera", - camera: three.camera, - }); - }, - - resize: function (event, three) { - this.aspect = event.viewWidth / Math.max(1, event.viewHeight); - - this.update(three); - }, - - update: function (three) { - three.camera.aspect = this.options.aspect || this.aspect; - three.camera.updateProjectionMatrix(); - }, -}); - -;// CONCATENATED MODULE: ./src/core/fallback.js - - -Bootstrap.registerPlugin("fallback", { - defaults: { - force: false, - fill: true, - begin: - '
' + - '
', - end: "
", - message: - "This example requires WebGL
" + - 'Visit get.webgl.org for more info', - }, - - install: function (three) { - let cnv, gl; - try { - cnv = document.createElement("canvas"); - gl = cnv.getContext("webgl") || cnv.getContext("experimental-webgl"); - if (!gl || this.options.force) { - throw "WebGL unavailable."; - } - three.fallback = false; - } catch (e) { - const message = this.options.message; - const begin = this.options.begin; - const end = this.options.end; - const fill = this.options.fill; - - const div = document.createElement("div"); - div.innerHTML = begin + message + end; - - this.children = []; - - while (div.childNodes.length > 0) { - this.children.push(div.firstChild); - three.element.appendChild(div.firstChild); - } - - if (fill) { - three.install("fill"); - } - - this.div = div; - three.fallback = true; - return false; // Abort install - } - }, - - uninstall: function (three) { - if (this.children) { - this.children.forEach(function (child) { - child.parentNode.removeChild(child); - }); - this.children = null; - } - - delete three.fallback; - }, -}); - -;// CONCATENATED MODULE: ./src/core/fill.js - - -Bootstrap.registerPlugin("fill", { - defaults: { - block: true, - body: true, - layout: true, - }, - - install: function (three) { - function is(element) { - const h = element.style.height; - return h == "auto" || h == ""; - } - - function set(element) { - element.style.height = "100%"; - element.style.margin = 0; - element.style.padding = 0; - return element; - } - - if (this.options.body && three.element == document.body) { - // Fix body height if we're naked - this.applied = [three.element, document.documentElement] - .filter(is) - .map(set); - } - - if (this.options.block && three.canvas) { - three.canvas.style.display = "block"; - this.block = true; - } - - if (this.options.layout && three.element) { - const style = window.getComputedStyle(three.element); - if (style.position == "static") { - three.element.style.position = "relative"; - this.layout = true; - } - } - }, - - uninstall: function (three) { - if (this.applied) { - const set = function (element) { - element.style.height = ""; - element.style.margin = ""; - element.style.padding = ""; - return element; - }; - - this.applied.map(set); - delete this.applied; - } - - if (this.block && three.canvas) { - three.canvas.style.display = ""; - delete this.block; - } - - if (this.layout && three.element) { - three.element.style.position = ""; - delete this.layout; - } - }, - - change: function (three) { - this.uninstall(three); - this.install(three); - }, -}); - -;// CONCATENATED MODULE: ./src/core/loop.js - - -Bootstrap.registerPlugin("loop", { - defaults: { - start: true, - each: 1, - }, - - listen: ["ready"], - - install: function (three) { - this.running = false; - this.lastRequestId = null; - - three.Loop = this.api( - { - start: this.start.bind(this), - stop: this.stop.bind(this), - running: false, - window: window, - }, - three - ); - - this.events = ["pre", "update", "render", "post"].map(function (type) { - return { type: type }; - }); - }, - - uninstall: function (three) { - this.stop(three); - }, - - ready: function (event, three) { - if (this.options.start) this.start(three); - }, - - start: function (three) { - if (this.running) return; - - three.Loop.running = this.running = true; - - const trigger = three.trigger.bind(three); - const loop = function () { - if (!this.running) return; - this.lastRequestId = three.Loop.window.requestAnimationFrame(loop); - this.events.map(trigger); - }.bind(this); - - this.lastRequestId = three.Loop.window.requestAnimationFrame(loop); - - three.trigger({ type: "start" }); - }, - - stop: function (three) { - if (!this.running) return; - three.Loop.running = this.running = false; - - three.Loop.window.cancelAnimationFrame(this.lastRequestId); - this.lastRequestId = null; - - three.trigger({ type: "stop" }); - }, -}); - -;// CONCATENATED MODULE: ./src/core/render.js - - -Bootstrap.registerPlugin("render", { - listen: ["render"], - - render: function (event, three) { - if (three.scene && three.camera) { - three.renderer.render(three.scene, three.camera); - } - }, -}); - -;// CONCATENATED MODULE: ./src/core/renderer.js - - - -Bootstrap.registerPlugin("renderer", { - defaults: { - klass: external_THREE_.WebGL1Renderer, - parameters: { - depth: true, - stencil: true, - preserveDrawingBuffer: true, - antialias: true, - }, - }, - - listen: ["resize"], - - install: function (three) { - // Instantiate Three renderer - const renderer = (three.renderer = new this.options.klass( - this.options.parameters - )); - three.canvas = renderer.domElement; - - // Add to DOM - three.element.appendChild(renderer.domElement); - }, - - uninstall: function (three) { - // Remove from DOM - three.element.removeChild(three.renderer.domElement); - - delete three.renderer; - delete three.canvas; - }, - - resize: function (event, three) { - const renderer = three.renderer; - const el = renderer.domElement; - - // Resize renderer to render size if it's a canvas - if (el && el.tagName == "CANVAS") { - renderer.setSize(event.renderWidth, event.renderHeight, false); - } - // Or view size if it's just a DOM element or multi-renderer - else { - if (renderer.setRenderSize) { - renderer.setRenderSize(event.renderWidth, event.renderHeight); - } - renderer.setSize(event.viewWidth, event.viewHeight, false); - } - }, -}); - -;// CONCATENATED MODULE: ./src/core/scene.js - - - -Bootstrap.registerPlugin("scene", { - install: function (three) { - three.scene = new external_THREE_.Scene(); - }, - - uninstall: function (three) { - delete three.scene; - }, -}); - -;// CONCATENATED MODULE: ./src/core/size.js - - -Bootstrap.registerPlugin("size", { - defaults: { - width: null, - height: null, - aspect: null, - scale: 1, - maxRenderWidth: Infinity, - maxRenderHeight: Infinity, - devicePixelRatio: true, - }, - - listen: [ - "window.resize:queue", - "element.resize:queue", - "this.change:queue", - "ready:resize", - "pre:pre", - ], - - install: function (three) { - three.Size = this.api({ - renderWidth: 0, - renderHeight: 0, - viewWidth: 0, - viewHeight: 0, - }); - - this.resized = false; - }, - - uninstall: function (three) { - delete three.Size; - }, - - queue: function (_event, _three) { - this.resized = true; - }, - - pre: function (event, three) { - if (!this.resized) return; - this.resized = false; - this.resize(event, three); - }, - - resize: function (event, three) { - const options = this.options; - const element = three.element; - const renderer = three.renderer; - - let w, - h, - ew, - eh, - rw, - rh, - aspect, - ratio, - ml = 0, - mt = 0; - - // Measure element - w = ew = - options.width === undefined || options.width == null - ? element.offsetWidth || element.innerWidth || 0 - : options.width; - - h = eh = - options.height === undefined || options.height == null - ? element.offsetHeight || element.innerHeight || 0 - : options.height; - - // Force aspect ratio - aspect = w / h; - if (options.aspect) { - if (options.aspect > aspect) { - h = Math.round(w / options.aspect); - mt = Math.floor((eh - h) / 2); - } else { - w = Math.round(h * options.aspect); - ml = Math.floor((ew - w) / 2); - } - aspect = w / h; - } - - // Get device pixel ratio - ratio = 1; - if (options.devicePixelRatio && typeof window != "undefined") { - ratio = window.devicePixelRatio || 1; - } - - // Apply scale and resolution max - rw = Math.round( - Math.min(w * ratio * options.scale, options.maxRenderWidth) - ); - rh = Math.round( - Math.min(h * ratio * options.scale, options.maxRenderHeight) - ); - - // Retain aspect ratio - const raspect = rw / rh; - if (raspect > aspect) { - rw = Math.round(rh * aspect); - } else { - rh = Math.round(rw / aspect); - } - - // Measure final pixel ratio - ratio = rh / h; - - // Resize and position renderer element - const style = renderer.domElement.style; - style.width = w + "px"; - style.height = h + "px"; - style.marginLeft = ml + "px"; - style.marginTop = mt + "px"; - - // Notify - Object.assign(three.Size, { - renderWidth: rw, - renderHeight: rh, - viewWidth: w, - viewHeight: h, - aspect: aspect, - pixelRatio: ratio, - }); - - three.trigger({ - type: "resize", - renderWidth: rw, - renderHeight: rh, - viewWidth: w, - viewHeight: h, - aspect: aspect, - pixelRatio: ratio, - }); - }, -}); - -;// CONCATENATED MODULE: ./src/core/time.js - - -Bootstrap.registerPlugin("time", { - defaults: { - speed: 1, // Clock speed - warmup: 0, // Wait N frames before starting clock - timeout: 1, // Timeout in seconds. Pause if no tick happens in this time. - }, - - listen: ["pre:tick", "this.change"], - - now: function () { - return +new Date() / 1000; - }, - - install: function (three) { - three.Time = this.api({ - now: this.now(), // Time since 1970 in seconds - - clock: 0, // Adjustable clock that counts up from 0 seconds - step: 1 / 60, // Clock step in seconds - - frames: 0, // Framenumber - time: 0, // Real time in seconds - delta: 1 / 60, // Frame step in seconds - - average: 0, // Average frame time in seconds - fps: 0, // Average frames per second - }); - - this.last = 0; - this.time = 0; - this.clock = 0; - this.wait = this.options.warmup; - - this.clockStart = 0; - this.timeStart = 0; - }, - - tick: function (event, three) { - const speed = this.options.speed; - const timeout = this.options.timeout; - - const api = three.Time; - const now = (api.now = this.now()); - const last = this.last; - let time = this.time; - let clock = this.clock; - - if (last) { - let delta = (api.delta = now - last); - const average = api.average || delta; - - if (delta > timeout) { - delta = 0; - } - - const step = delta * speed; - - time += delta; - clock += step; - - if (api.frames > 0) { - api.average = average + (delta - average) * 0.1; - api.fps = 1 / average; - } - - api.step = step; - api.clock = clock - this.clockStart; - api.time = time - this.timeStart; - - api.frames++; - - if (this.wait-- > 0) { - this.clockStart = clock; - this.timeStart = time; - api.clock = 0; - api.step = 1e-100; - } - } - - this.last = now; - this.clock = clock; - this.time = time; - }, - - uninstall: function (three) { - delete three.Time; - }, -}); - -;// CONCATENATED MODULE: ./src/core/warmup.js - - -Bootstrap.registerPlugin("warmup", { - defaults: { - delay: 2, - }, - - listen: ["ready", "post"], - - ready: function (event, three) { - three.renderer.domElement.style.visibility = "hidden"; - this.frame = 0; - this.hidden = true; - }, - - post: function (event, three) { - if (this.hidden && this.frame >= this.options.delay) { - three.renderer.domElement.style.visibility = "visible"; - this.hidden = false; - } - this.frame++; - }, -}); - -;// CONCATENATED MODULE: ./src/core/index.js - - - - - - - - - - - - -;// CONCATENATED MODULE: ./src/extra/controls.js - - - -Bootstrap.registerPlugin("controls", { - listen: ["update", "resize", "camera", "this.change"], - - defaults: { - klass: null, - parameters: {}, - }, - - install: function (three) { - if (!this.options.klass) throw "Must provide class for `controls.klass`"; - - three.controls = null; - - this._camera = three.camera || new external_THREE_.PerspectiveCamera(); - this.change(null, three); - }, - - uninstall: function (three) { - delete three.controls; - }, - - change: function (event, three) { - if (this.options.klass) { - if (!event || event.changes.klass) { - three.controls = new this.options.klass( - this._camera, - three.renderer.domElement - ); - } - - Object.assign(three.controls, this.options.parameters); - } else { - three.controls = null; - } - }, - - update: function (event, three) { - const delta = (three.Time && three.Time.delta) || 1 / 60; - const vr = three.VR && three.VR.state; - - if (three.controls.vr) three.controls.vr(vr); - three.controls.update(delta); - }, - - camera: function (event, three) { - three.controls.object = this._camera = event.camera; - }, - - resize: function (event, three) { - three.controls.handleResize && three.controls.handleResize(); - }, -}); - -;// CONCATENATED MODULE: ./src/extra/cursor.js - - -Bootstrap.registerPlugin("cursor", { - listen: [ - "update", - "this.change", - "install:change", - "uninstall:change", - "element.mousemove", - "vr", - ], - - defaults: { - cursor: null, - hide: false, - timeout: 3, - }, - - install: function (three) { - this.timeout = this.options.timeout; - this.element = three.element; - this.change(null, three); - }, - - uninstall: function (three) { - delete three.controls; - }, - - change: function (event, three) { - this.applyCursor(three); - }, - - mousemove: function (event, three) { - if (this.options.hide) { - this.applyCursor(three); - this.timeout = +this.options.timeout || 0; - } - }, - - update: function (event, three) { - const delta = (three.Time && three.Time.delta) || 1 / 60; - - if (this.options.hide) { - this.timeout -= delta; - if (this.timeout < 0) { - this.applyCursor(three, "none"); - } - } - }, - - vr: function (event, three) { - this.hide = event.active && !event.hmd.fake; - this.applyCursor(three); - }, - - applyCursor: function (three, cursor) { - const auto = three.controls ? "move" : ""; - cursor = cursor || this.options.cursor || auto; - if (this.hide) cursor = "none"; - if (this.cursor != cursor) { - this.element.style.cursor = cursor; - } - }, -}); - -;// CONCATENATED MODULE: ./src/extra/fullscreen.js - - -Bootstrap.registerPlugin("fullscreen", { - defaults: { - key: "f", - }, - - listen: ["ready", "update"], - - install: function (three) { - three.Fullscreen = this.api( - { - active: false, - toggle: this.toggle.bind(this), - }, - three - ); - }, - - uninstall: function (three) { - delete three.Fullscreen; - }, - - ready: function (event, three) { - document.body.addEventListener( - "keypress", - function (event) { - if ( - this.options.key && - event.charCode == this.options.key.charCodeAt(0) - ) { - this.toggle(three); - } - }.bind(this) - ); - - const changeHandler = function () { - const active = - !!document.fullscreenElement || - !!document.mozFullScreenElement || - !!document.webkitFullscreenElement || - !!document.msFullscreenElement; - three.Fullscreen.active = this.active = active; - three.trigger({ - type: "fullscreen", - active: active, - }); - }.bind(this); - document.addEventListener("fullscreenchange", changeHandler, false); - document.addEventListener("webkitfullscreenchange", changeHandler, false); - document.addEventListener("mozfullscreenchange", changeHandler, false); - }, - - toggle: function (three) { - const canvas = three.canvas; - const options = - three.VR && three.VR.active ? { vrDisplay: three.VR.hmd } : {}; - - if (!this.active) { - if (canvas.requestFullScreen) { - canvas.requestFullScreen(options); - } else if (canvas.msRequestFullScreen) { - canvas.msRequestFullscreen(options); - } else if (canvas.webkitRequestFullscreen) { - canvas.webkitRequestFullscreen(options); - } else if (canvas.mozRequestFullScreen) { - canvas.mozRequestFullScreen(options); // s vs S - } - } else { - if (document.exitFullscreen) { - document.exitFullscreen(); - } else if (document.msExitFullscreen) { - document.msExitFullscreen(); - } else if (document.webkitExitFullscreen) { - document.webkitExitFullscreen(); - } else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); // s vs S - } - } - }, -}); - -// EXTERNAL MODULE: ./node_modules/stats.js/build/stats.min.js -var stats_min = __webpack_require__(466); -var stats_min_default = /*#__PURE__*/__webpack_require__.n(stats_min); -;// CONCATENATED MODULE: ./src/extra/stats.js - - - -Bootstrap.registerPlugin("stats", { - listen: ["pre", "post"], - - install: function (three) { - const stats = (this.stats = new (stats_min_default())()); - const style = stats.domElement.style; - - style.position = "absolute"; - style.top = style.left = 0; - three.element.appendChild(stats.domElement); - - three.stats = stats; - }, - - uninstall: function (three) { - this.stats.domElement.remove() - delete three.stats; - }, - - pre: function (_event, _three) { - this.stats.begin(); - }, - - post: function (_event, _three) { - this.stats.end(); - }, -}); - -;// CONCATENATED MODULE: ./src/extra/ui.js - - -Bootstrap.registerPlugin("ui", { - defaults: { - theme: "white", - style: - ".threestrap-ui { position: absolute; bottom: 5px; right: 5px; float: left; }" + - ".threestrap-ui button { border: 0; background: none;" + - " vertical-align: middle; font-weight: bold; } " + - ".threestrap-ui .glyphicon { top: 2px; font-weight: bold; } " + - "@media (max-width: 640px) { .threestrap-ui button { font-size: 120% } }" + - ".threestrap-white button { color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 1), " + - "0 1px 3px rgba(0, 0, 0, 1); }" + - ".threestrap-black button { color: #000; text-shadow: 0 0px 1px rgba(255, 255, 255, 1), " + - "0 0px 2px rgba(255, 255, 255, 1), " + - "0 0px 2px rgba(255, 255, 255, 1) }", - }, - - listen: ["fullscreen"], - - markup: function (three, theme, style) { - let url = - "//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css"; - if (location.href.match(/^file:\/\//)) url = "http://" + url; - - const buttons = []; - - if (three.Fullscreen) { - buttons.push( - '" - ); - } - if (three.VR) { - buttons.push(''); - } - - return ( - '" + - '
' + - buttons.join("\n") + - "
" - ); - }, - - install: function (three) { - const ui = (this.ui = document.createElement("div")); - ui.innerHTML = this.markup(three, this.options.theme, this.options.style); - document.body.appendChild(ui); - - const fullscreen = (this.ui.fullscreen = - ui.querySelector("button.fullscreen")); - if (fullscreen) { - three.bind([fullscreen, "click:goFullscreen"], this); - } - - const vr = (this.ui.vr = ui.querySelector("button.vr")); - if (vr && three.VR) { - three.VR.set({ mode: "2d" }); - three.bind([vr, "click:goVR"], this); - } - }, - - fullscreen: function (event, three) { - this.ui.style.display = event.active ? "none" : "block"; - if (!event.active) three.VR && three.VR.set({ mode: "2d" }); - }, - - goFullscreen: function (event, three) { - if (three.Fullscreen) { - three.Fullscreen.toggle(); - } - }, - - goVR: function (event, three) { - if (three.VR) { - three.VR.set({ mode: "auto" }); - three.Fullscreen.toggle(); - } - }, - - uninstall: function (_three) { - document.body.removeChild(this.ui); - }, -}); - -;// CONCATENATED MODULE: ./src/renderers/VRRenderer.js -/** - * VRRenderer - * - * @author wwwtyro https://github.com/wwwtyro - * @author unconed https://github.com/unconed - */ - - - -class VRRenderer { - constructor(renderer, hmd) { - this.renderer = renderer; - - this.right = new Vector3(); - this.cameraLeft = new external_THREE_.PerspectiveCamera(); - this.cameraRight = new external_THREE_.PerspectiveCamera(); - - const et = hmd.getEyeTranslation("left"); - this.halfIPD = new Vector3(et.x, et.y, et.z).length(); - this.fovLeft = hmd.getRecommendedEyeFieldOfView("left"); - this.fovRight = hmd.getRecommendedEyeFieldOfView("right"); - } - - FovToNDCScaleOffset(fov) { - const pxscale = 2.0 / (fov.leftTan + fov.rightTan); - const pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5; - const pyscale = 2.0 / (fov.upTan + fov.downTan); - const pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5; - return { - scale: [pxscale, pyscale], - offset: [pxoffset, pyoffset], - }; - } - - FovPortToProjection( - matrix, - fov, - rightHanded /* = true */, - zNear /* = 0.01 */, - zFar /* = 10000.0 */ - ) { - rightHanded = rightHanded === undefined ? true : rightHanded; - zNear = zNear === undefined ? 0.01 : zNear; - zFar = zFar === undefined ? 10000.0 : zFar; - const handednessScale = rightHanded ? -1.0 : 1.0; - const m = matrix.elements; - const scaleAndOffset = this.FovToNDCScaleOffset(fov); - m[0 * 4 + 0] = scaleAndOffset.scale[0]; - m[0 * 4 + 1] = 0.0; - m[0 * 4 + 2] = scaleAndOffset.offset[0] * handednessScale; - m[0 * 4 + 3] = 0.0; - m[1 * 4 + 0] = 0.0; - m[1 * 4 + 1] = scaleAndOffset.scale[1]; - m[1 * 4 + 2] = -scaleAndOffset.offset[1] * handednessScale; - m[1 * 4 + 3] = 0.0; - m[2 * 4 + 0] = 0.0; - m[2 * 4 + 1] = 0.0; - m[2 * 4 + 2] = (zFar / (zNear - zFar)) * -handednessScale; - m[2 * 4 + 3] = (zFar * zNear) / (zNear - zFar); - m[3 * 4 + 0] = 0.0; - m[3 * 4 + 1] = 0.0; - m[3 * 4 + 2] = handednessScale; - m[3 * 4 + 3] = 0.0; - matrix.transpose(); - } - - FovToProjection( - matrix, - fov, - rightHanded /* = true */, - zNear /* = 0.01 */, - zFar /* = 10000.0 */ - ) { - const fovPort = { - upTan: Math.tan((fov.upDegrees * Math.PI) / 180.0), - downTan: Math.tan((fov.downDegrees * Math.PI) / 180.0), - leftTan: Math.tan((fov.leftDegrees * Math.PI) / 180.0), - rightTan: Math.tan((fov.rightDegrees * Math.PI) / 180.0), - }; - return this.FovPortToProjection(matrix, fovPort, rightHanded, zNear, zFar); - } - - render(scene, camera) { - this.FovToProjection( - this.cameraLeft.projectionMatrix, - this.fovLeft, - true, - camera.near, - camera.far - ); - this.FovToProjection( - this.cameraRight.projectionMatrix, - this.fovRight, - true, - camera.near, - camera.far - ); - - this.right.set(this.halfIPD, 0, 0); - this.right.applyQuaternion(camera.quaternion); - - this.cameraLeft.position.copy(camera.position).sub(this.right); - this.cameraRight.position.copy(camera.position).add(this.right); - - this.cameraLeft.quaternion.copy(camera.quaternion); - this.cameraRight.quaternion.copy(camera.quaternion); - - const dpr = this.renderer.devicePixelRatio || 1; - const width = this.renderer.domElement.width / 2 / dpr; - const height = this.renderer.domElement.height / dpr; - - this.renderer.enableScissorTest(true); - - this.renderer.setViewport(0, 0, width, height); - this.renderer.setScissor(0, 0, width, height); - this.renderer.render(scene, this.cameraLeft); - - this.renderer.setViewport(width, 0, width, height); - this.renderer.setScissor(width, 0, width, height); - this.renderer.render(scene, this.cameraRight); - } -} - -;// CONCATENATED MODULE: ./src/extra/vr.js - - - -/* -VR sensor / HMD hookup. -*/ -Bootstrap.registerPlugin("vr", { - defaults: { - mode: "auto", // 'auto', '2d' - device: null, - fov: 80, // emulated FOV for fallback - }, - - listen: ["window.load", "pre", "render", "resize", "this.change"], - - install: function (three) { - three.VR = this.api( - { - active: false, - devices: [], - hmd: null, - sensor: null, - renderer: null, - state: null, - }, - three - ); - }, - - uninstall: function (three) { - delete three.VR; - }, - - mocks: function (three, fov, def) { - // Fake VR device for cardboard / desktop - - // Interpuppilary distance - const ipd = 0.03; - - // Symmetric eye FOVs (Cardboard style) - const getEyeTranslation = function (key) { - return { left: { x: -ipd, y: 0, z: 0 }, right: { x: ipd, y: 0, z: 0 } }[ - key - ]; - }; - const getRecommendedEyeFieldOfView = function (key) { - const camera = three.camera; - const aspect = (camera && camera.aspect) || 16 / 9; - const fov2 = (fov || (camera && camera.fov) || def) / 2; - const fovX = - (Math.atan((Math.tan((fov2 * Math.PI) / 180) * aspect) / 2) * 180) / - Math.PI; - const fovY = fov2; - - return { - left: { - rightDegrees: fovX, - leftDegrees: fovX, - downDegrees: fovY, - upDegrees: fovY, - }, - right: { - rightDegrees: fovX, - leftDegrees: fovX, - downDegrees: fovY, - upDegrees: fovY, - }, - }[key]; - }; - // Will be replaced with orbit controls or device orientation controls by VRControls - const getState = function () { - return {}; - }; - - return [ - { - fake: true, - force: 1, - deviceId: "emu", - deviceName: "Emulated", - getEyeTranslation: getEyeTranslation, - getRecommendedEyeFieldOfView: getRecommendedEyeFieldOfView, - }, - { - force: 2, - getState: getState, - }, - ]; - }, - - load: function (event, three) { - const callback = function (devs) { - this.callback(devs, three); - }.bind(this); - - if (navigator.getVRDevices) { - navigator.getVRDevices().then(callback); - } else if (navigator.mozGetVRDevices) { - navigator.mozGetVRDevices(callback); - } else { - console.warn("No native VR support detected."); - callback(this.mocks(three, this.options.fov, this.defaults.fov), three); - } - }, - - callback: function (vrdevs, three) { - let hmd, sensor; - - const HMD = window.HMDVRDevice || function () {}; - const SENSOR = window.PositionSensorVRDevice || function () {}; - - // Export list of devices - vrdevs = three.VR.devices = vrdevs || three.VR.devices; - - // Get HMD device - const deviceId = this.options.device; - let dev; - - for (let i = 0; i < vrdevs.length; ++i) { - dev = vrdevs[i]; - if (dev.force == 1 || dev instanceof HMD) { - if (deviceId && deviceId != dev.deviceId) continue; - hmd = dev; - break; - } - } - - if (hmd) { - // Get sensor device - let dev; - for (let i = 0; i < vrdevs.length; ++i) { - dev = vrdevs[i]; - if ( - dev.force == 2 || - (dev instanceof SENSOR && dev.hardwareUnitId == hmd.hardwareUnitId) - ) { - sensor = dev; - break; - } - } - - this.hookup(hmd, sensor, three); - } - }, - - hookup: function (hmd, sensor, three) { - if (!VRRenderer) console.log("VRRenderer not found"); - const klass = VRRenderer || function () {}; - - this.renderer = new klass(three.renderer, hmd); - this.hmd = hmd; - this.sensor = sensor; - - three.VR.renderer = this.renderer; - three.VR.hmd = hmd; - three.VR.sensor = sensor; - - console.log("VRRenderer", hmd.deviceName); - }, - - change: function (event, three) { - if (event.changes.device) { - this.callback(null, three); - } - this.pre(event, three); - }, - - pre: function (event, three) { - const last = this.active; - - // Global active flag - const active = (this.active = this.renderer && this.options.mode != "2d"); - three.VR.active = active; - - // Load sensor state - if (active && this.sensor) { - const state = this.sensor.getState(); - three.VR.state = state; - } else { - three.VR.state = null; - } - - // Notify if VR state changed - if (last != this.active) { - three.trigger({ - type: "vr", - active: active, - hmd: this.hmd, - sensor: this.sensor, - }); - } - }, - - resize: function (_event, _three) { - if (this.active) { - // Reinit HMD projection - this.renderer.initialize(); - } - }, - - render: function (event, three) { - if (three.scene && three.camera) { - const renderer = this.active ? this.renderer : three.renderer; - - if (this.last != renderer) { - if (renderer == three.renderer) { - // Cleanup leftover renderer state when swapping back to normal - const dpr = renderer.getPixelRatio(); - const width = renderer.domElement.width / dpr; - const height = renderer.domElement.height / dpr; - renderer.setScissorTest(false); - renderer.setViewport(0, 0, width, height); - } - } - - this.last = renderer; - - renderer.render(three.scene, three.camera); - } - }, -}); - -;// CONCATENATED MODULE: ./src/extra/index.js - - - - - - - -;// CONCATENATED MODULE: ./src/renderers/MultiRenderer.js -/** - * Allows a stack of renderers to be treated as a single renderer. - * @author Gheric Speiginer - */ - - -class MultiRenderer { - constructor(parameters) { - console.log("MultiRenderer", external_THREE_.REVISION); - - this.domElement = document.createElement("div"); - this.domElement.style.position = "relative"; - - this.renderers = []; - this._renderSizeSet = false; - - const rendererClasses = parameters.renderers || []; - const rendererParameters = parameters.parameters || []; - - // elements are stacked back-to-front - for (let i = 0; i < rendererClasses.length; i++) { - const renderer = new rendererClasses[i](rendererParameters[i]); - renderer.domElement.style.position = "absolute"; - renderer.domElement.style.top = "0px"; - renderer.domElement.style.left = "0px"; - this.domElement.appendChild(renderer.domElement); - this.renderers.push(renderer); - } - } - - setSize(w, h) { - this.domElement.style.width = w + "px"; - this.domElement.style.height = h + "px"; - - for (let i = 0; i < this.renderers.length; i++) { - const renderer = this.renderers[i]; - const el = renderer.domElement; - - if (!this._renderSizeSet || (el && el.tagName !== "CANVAS")) { - renderer.setSize(w, h); - } - - el.style.width = w + "px"; - el.style.height = h + "px"; - } - } - - setRenderSize(rw, rh) { - this._renderSizeSet = true; - - for (let i = 0; i < this.renderers.length; i++) { - const renderer = this.renderers[i]; - const el = renderer.domElement; - - if (el && el.tagName === "CANVAS") { - renderer.setSize(rw, rh, false); - } - } - } - - render(scene, camera) { - for (let i = 0; i < this.renderers.length; i++) { - this.renderers[i].render(scene, camera); - } - } -} - -;// CONCATENATED MODULE: ./src/renderers/index.js - - - -;// CONCATENATED MODULE: ./src/controls/VRControls.js -/** - * @author dmarcos / https://github.com/dmarcos - * @author mrdoob / http://mrdoob.com - * - * VRControls from - * https://cdn.jsdelivr.net/npm/three@0.93.0/examples/js/controls/VRControls.js. - * Added here so that the existing VR examples still work... this will stay - * until we get everything upgraded to the modern three.js approach to VR. See - * https://threejs.org/docs/index.html#manual/en/introduction/How-to-create-VR-content - * for more info. - */ - - - -class VRControls { - constructor(object, onError) { - this.object = object; - this.standingMatrix = new Matrix4(); - this.frameData = null; - - if ("VRFrameData" in window) { - // eslint-disable-next-line no-undef - this.frameData = new VRFrameData(); - } - - function gotVRDisplays(displays) { - this.vrDisplays = displays; - - if (displays.length > 0) { - this.vrDisplay = displays[0]; - } else { - if (onError) onError("VR input not available."); - } - } - - if (navigator.getVRDisplays) { - navigator - .getVRDisplays() - .then(gotVRDisplays) - .catch(function () { - console.warn("VRControls: Unable to get VR Displays"); - }); - } - - // the Rift SDK returns the position in meters - // this scale factor allows the user to define how meters - // are converted to scene units. - - this.scale = 1; - - // If true will use "standing space" coordinate system where y=0 is the - // floor and x=0, z=0 is the center of the room. - this.standing = false; - - // Distance from the users eyes to the floor in meters. Used when - // standing=true but the VRDisplay doesn't provide stageParameters. - this.userHeight = 1.6; - } - - getVRDisplay() { - return this.vrDisplay; - } - - setVRDisplay(value) { - this.vrDisplay = value; - } - - getVRDisplays() { - console.warn("VRControls: getVRDisplays() is being deprecated."); - return this.vrDisplays; - } - - getStandingMatrix() { - return this.standingMatrix; - } - - update() { - if (this.vrDisplay) { - let pose; - - if (this.vrDisplay.getFrameData) { - this.vrDisplay.getFrameData(this.frameData); - pose = this.frameData.pose; - } else if (this.vrDisplay.getPose) { - pose = this.vrDisplay.getPose(); - } - - if (pose.orientation !== null) { - this.object.quaternion.fromArray(pose.orientation); - } - - if (pose.position !== null) { - this.object.position.fromArray(pose.position); - } else { - this.object.position.set(0, 0, 0); - } - - if (this.standing) { - if (this.vrDisplay.stageParameters) { - this.object.updateMatrix(); - - this.standingMatrix.fromArray( - this.vrDisplay.stageParameters.sittingToStandingTransform - ); - this.object.applyMatrix(this.standingMatrix); - } else { - this.object.position.setY(this.object.position.y + this.userHeight); - } - } - - this.object.position.multiplyScalar(this.scale); - } - } - - dispose() { - this.vrDisplay = null; - } -} - -;// CONCATENATED MODULE: ./src/index.js - - - - - - -// These should probably be in their own build! - - - - - - - - - - - -})(); - -/******/ return __webpack_exports__; -/******/ })() -; -}); -//# sourceMappingURL=threestrap.js.map \ No newline at end of file diff --git a/build/threestrap.min.js b/build/threestrap.min.js deleted file mode 100644 index 53db0ad..0000000 --- a/build/threestrap.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("THREE")):"function"==typeof define&&define.amd?define("Threestrap",["THREE"],e):"object"==typeof exports?exports.Threestrap=e(require("THREE")):t.Threestrap=e(t.THREE)}(self,(function(t){return(()=>{var e={466:function(t){var e;t.exports=((e=function(){function t(t){return n.appendChild(t.dom),t}function i(t){for(var e=0;ea+1e3&&(h.update(1e3*o/(t-a),100),a=t,o=0,c)){var e=performance.memory;c.update(e.usedJSHeapSize/1048576,e.jsHeapSizeLimit/1048576)}return t},update:function(){r=this.end()},domElement:n,setMode:i}}).Panel=function(t,e,i){var s=1/0,n=0,r=Math.round,a=r(window.devicePixelRatio||1),o=80*a,h=48*a,l=3*a,c=2*a,u=3*a,d=15*a,m=74*a,p=30*a,y=document.createElement("canvas");y.width=o,y.height=h,y.style.cssText="width:80px;height:48px";var f=y.getContext("2d");return f.font="bold "+9*a+"px Helvetica,Arial,sans-serif",f.textBaseline="top",f.fillStyle=i,f.fillRect(0,0,o,h),f.fillStyle=e,f.fillText(t,l,c),f.fillRect(u,d,m,p),f.fillStyle=i,f.globalAlpha=.9,f.fillRect(u,d,m,p),{dom:y,update:function(h,g){s=Math.min(s,h),n=Math.max(n,h),f.fillStyle=i,f.globalAlpha=1,f.fillRect(0,0,o,d),f.fillStyle=e,f.fillText(r(h)+" "+t+" ("+r(s)+"-"+r(n)+")",l,c),f.drawImage(y,u+a,d,m-a,p,u,d,m-a,p),f.fillRect(u+m-a,d,a,p),f.fillStyle=i,f.globalAlpha=.9,f.fillRect(u+m-a,d,a,r((1-h/g)*p))}}},e)},428:e=>{"use strict";e.exports=t}},i={};function s(t){var n=i[t];if(void 0!==n)return n.exports;var r=i[t]={exports:{}};return e[t].call(r.exports,r,r.exports,s),r.exports}s.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return s.d(e,{a:e}),e},s.d=(t,e)=>{for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var n={};return(()=>{"use strict";s.r(n),s.d(n,{Api:()=>t,Binder:()=>i,Bootstrap:()=>a,MultiRenderer:()=>X,VRControls:()=>Z,VRRenderer:()=>Y});class t{static apply(t){t.set=function(t){const e=this.options||{},i=Object.entries(t).reduce((function(t,[i,s]){return e[i]!==s&&(t[i]=s),t}),{});this.options=Object.assign(e,i),this.trigger({type:"change",options:t,changes:i})},t.get=function(){return this.options},t.api=function(t,e){return t||(t={}),e&&Object.entries(t).forEach((function([i,s]){"function"==typeof s&&(t[i]=(...t)=>s(...t,e))})),t.set=this.set.bind(this),t.get=this.get.bind(this),t}}}var e=s(428);class i{static bind(t,e){return function(s,n){n.__binds||(n.__binds=[]);let r=t;Array.isArray(s)&&(r=s[0],s=s[1]);const a=/^([^.:]*(?:\.[^.:]+)*)?(?::(.*))?$/.exec(s),o=a[1].split(/\./g),h=o.pop(),l=a[2]||h,c=o.shift();let u={this:n}[c]||e[c]||t[c]||r;for(;u&&(s=o.shift());)u=u[s];if(u&&(u.on||u.addEventListener)){const e=function(e){n[l]&&n[l](e,t)};i._polyfill(u,["addEventListener","on"],(function(t){u[t](h,e)}));const s={target:u,name:h,callback:e};return n.__binds.push(s),e}throw"Cannot bind '"+s+"' in "+this.__name}}static unbind(){return function(t){t.__binds&&(t.__binds.forEach(function(t){i._polyfill(t.target,["removeEventListener","off"],(function(e){t.target[e](t.name,t.callback)}))}.bind(this)),t.__binds=[])}}static apply(t){t.trigger=i._trigger,t.triggerOnce=i._triggerOnce,t.hasEventListener=e.EventDispatcher.prototype.hasEventListener,t.addEventListener=e.EventDispatcher.prototype.addEventListener,t.removeEventListener=e.EventDispatcher.prototype.removeEventListener,t.on=t.addEventListener,t.off=t.removeEventListener,t.dispatchEvent=t.trigger}static _triggerOnce(t){this.trigger(t),this._listeners&&delete this._listeners[t.type]}static _trigger(t){if(void 0===this._listeners)return;const e=t.type;let i=this._listeners[e];if(void 0!==i){i=i.slice();const e=i.length;t.target=this;for(let s=0;s=256)throw"Plug-in alias recursion detected.";return(e=e.filter(s)).forEach((function(e){const s=i[e];s?n=n.concat(t(s,[],r+1)):n.push(e)})),n}(t,[],0)}install(t){t=Array.isArray(t)?t:[t],(t=this.resolve(t)).forEach((t=>this.__install(t))),this.__ready()}uninstall(t){t&&(t=Array.isArray(t)?t:[t],t=this.resolve(t)),(t||this.__installed).reverse().forEach((t=>this.__uninstall(t.__name)))}__install(t){const e=this.__options.plugindb[t];if(!e)throw"[three.install] Cannot install. '"+t+"' is not registered.";if(this.plugins[t])return console.warn("[three.install] "+t+" is already installed.");const i=new e(this.__options[t]||{},t);this.plugins[t]=i;const s=i.install(this);return this.__installed.push(i),this.trigger({type:"install",plugin:i}),s}__uninstall(t){const e=r(t)?this.plugins[t]:t;e?(t=e.__name,e.uninstall(this),this.__installed=this.__installed.filter((t=>t!==e)),delete this.plugins[t],this.trigger({type:"uninstall",plugin:e})):console.warn("[three.uninstall] "+t+"' is not installed.")}__ready(){this.triggerOnce({type:"ready"})}}a.initClass(),a.Plugin=function(t){this.options=Object.assign({},this.defaults,t||{})},a.Plugin.prototype={listen:[],defaults:{},install:function(t){},uninstall:function(t){}},i.apply(a.prototype),i.apply(a.Plugin.prototype),t.apply(a.Plugin.prototype),a.registerAlias("empty",["fallback","bind","renderer","size","fill","loop","time"]),a.registerAlias("core",["empty","scene","camera","render","warmup"]),a.registerAlias("VR",["core","cursor","fullscreen","render:vr"]),a.registerPlugin("bind",{install:function(t){const e={three:t,window};t.bind=i.bind(t,e),t.unbind=i.unbind(t),t.bind("install:bind",this),t.bind("uninstall:unbind",this)},uninstall:function(t){t.unbind(this),delete t.bind,delete t.unbind},bind:function(t,e){const i=t.plugin,s=i.listen;s&&s.forEach((function(t){e.bind(t,i)}))},unbind:function(t,e){e.unbind(t.plugin)}});const o=[];for(let t=0;t<256;t++)o[t]=(t<16?"0":"")+t.toString(16);Math.PI,Math.PI;function h(t,e,i){return Math.max(e,Math.min(i,t))}class l{constructor(t=0,e=0,i=0,s=1){this._x=t,this._y=e,this._z=i,this._w=s}static slerp(t,e,i,s){return console.warn("THREE.Quaternion: Static .slerp() has been deprecated. Use qm.slerpQuaternions( qa, qb, t ) instead."),i.slerpQuaternions(t,e,s)}static slerpFlat(t,e,i,s,n,r,a){let o=i[s+0],h=i[s+1],l=i[s+2],c=i[s+3];const u=n[r+0],d=n[r+1],m=n[r+2],p=n[r+3];if(0===a)return t[e+0]=o,t[e+1]=h,t[e+2]=l,void(t[e+3]=c);if(1===a)return t[e+0]=u,t[e+1]=d,t[e+2]=m,void(t[e+3]=p);if(c!==p||o!==u||h!==d||l!==m){let t=1-a;const e=o*u+h*d+l*m+c*p,i=e>=0?1:-1,s=1-e*e;if(s>Number.EPSILON){const n=Math.sqrt(s),r=Math.atan2(n,e*i);t=Math.sin(t*r)/n,a=Math.sin(a*r)/n}const n=a*i;if(o=o*t+u*n,h=h*t+d*n,l=l*t+m*n,c=c*t+p*n,t===1-a){const t=1/Math.sqrt(o*o+h*h+l*l+c*c);o*=t,h*=t,l*=t,c*=t}}t[e]=o,t[e+1]=h,t[e+2]=l,t[e+3]=c}static multiplyQuaternionsFlat(t,e,i,s,n,r){const a=i[s],o=i[s+1],h=i[s+2],l=i[s+3],c=n[r],u=n[r+1],d=n[r+2],m=n[r+3];return t[e]=a*m+l*c+o*d-h*u,t[e+1]=o*m+l*u+h*c-a*d,t[e+2]=h*m+l*d+a*u-o*c,t[e+3]=l*m-a*c-o*u-h*d,t}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get w(){return this._w}set w(t){this._w=t,this._onChangeCallback()}set(t,e,i,s){return this._x=t,this._y=e,this._z=i,this._w=s,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this._onChangeCallback(),this}setFromEuler(t,e){if(!t||!t.isEuler)throw new Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");const i=t._x,s=t._y,n=t._z,r=t._order,a=Math.cos,o=Math.sin,h=a(i/2),l=a(s/2),c=a(n/2),u=o(i/2),d=o(s/2),m=o(n/2);switch(r){case"XYZ":this._x=u*l*c+h*d*m,this._y=h*d*c-u*l*m,this._z=h*l*m+u*d*c,this._w=h*l*c-u*d*m;break;case"YXZ":this._x=u*l*c+h*d*m,this._y=h*d*c-u*l*m,this._z=h*l*m-u*d*c,this._w=h*l*c+u*d*m;break;case"ZXY":this._x=u*l*c-h*d*m,this._y=h*d*c+u*l*m,this._z=h*l*m+u*d*c,this._w=h*l*c-u*d*m;break;case"ZYX":this._x=u*l*c-h*d*m,this._y=h*d*c+u*l*m,this._z=h*l*m-u*d*c,this._w=h*l*c+u*d*m;break;case"YZX":this._x=u*l*c+h*d*m,this._y=h*d*c+u*l*m,this._z=h*l*m-u*d*c,this._w=h*l*c-u*d*m;break;case"XZY":this._x=u*l*c-h*d*m,this._y=h*d*c-u*l*m,this._z=h*l*m+u*d*c,this._w=h*l*c+u*d*m;break;default:console.warn("THREE.Quaternion: .setFromEuler() encountered an unknown order: "+r)}return!1!==e&&this._onChangeCallback(),this}setFromAxisAngle(t,e){const i=e/2,s=Math.sin(i);return this._x=t.x*s,this._y=t.y*s,this._z=t.z*s,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(t){const e=t.elements,i=e[0],s=e[4],n=e[8],r=e[1],a=e[5],o=e[9],h=e[2],l=e[6],c=e[10],u=i+a+c;if(u>0){const t=.5/Math.sqrt(u+1);this._w=.25/t,this._x=(l-o)*t,this._y=(n-h)*t,this._z=(r-s)*t}else if(i>a&&i>c){const t=2*Math.sqrt(1+i-a-c);this._w=(l-o)/t,this._x=.25*t,this._y=(s+r)/t,this._z=(n+h)/t}else if(a>c){const t=2*Math.sqrt(1+a-i-c);this._w=(n-h)/t,this._x=(s+r)/t,this._y=.25*t,this._z=(o+l)/t}else{const t=2*Math.sqrt(1+c-i-a);this._w=(r-s)/t,this._x=(n+h)/t,this._y=(o+l)/t,this._z=.25*t}return this._onChangeCallback(),this}setFromUnitVectors(t,e){let i=t.dot(e)+1;return iMath.abs(t.z)?(this._x=-t.y,this._y=t.x,this._z=0,this._w=i):(this._x=0,this._y=-t.z,this._z=t.y,this._w=i)):(this._x=t.y*e.z-t.z*e.y,this._y=t.z*e.x-t.x*e.z,this._z=t.x*e.y-t.y*e.x,this._w=i),this.normalize()}angleTo(t){return 2*Math.acos(Math.abs(h(this.dot(t),-1,1)))}rotateTowards(t,e){const i=this.angleTo(t);if(0===i)return this;const s=Math.min(1,e/i);return this.slerp(t,s),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this._onChangeCallback(),this}multiply(t,e){return void 0!==e?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(t,e)):this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const i=t._x,s=t._y,n=t._z,r=t._w,a=e._x,o=e._y,h=e._z,l=e._w;return this._x=i*l+r*a+s*h-n*o,this._y=s*l+r*o+n*a-i*h,this._z=n*l+r*h+i*o-s*a,this._w=r*l-i*a-s*o-n*h,this._onChangeCallback(),this}slerp(t,e){if(0===e)return this;if(1===e)return this.copy(t);const i=this._x,s=this._y,n=this._z,r=this._w;let a=r*t._w+i*t._x+s*t._y+n*t._z;if(a<0?(this._w=-t._w,this._x=-t._x,this._y=-t._y,this._z=-t._z,a=-a):this.copy(t),a>=1)return this._w=r,this._x=i,this._y=s,this._z=n,this;const o=1-a*a;if(o<=Number.EPSILON){const t=1-e;return this._w=t*r+e*this._w,this._x=t*i+e*this._x,this._y=t*s+e*this._y,this._z=t*n+e*this._z,this.normalize(),this._onChangeCallback(),this}const h=Math.sqrt(o),l=Math.atan2(h,a),c=Math.sin((1-e)*l)/h,u=Math.sin(e*l)/h;return this._w=r*c+this._w*u,this._x=i*c+this._x*u,this._y=s*c+this._y*u,this._z=n*c+this._z*u,this._onChangeCallback(),this}slerpQuaternions(t,e,i){return this.copy(t).slerp(e,i)}random(){const t=Math.random(),e=Math.sqrt(1-t),i=Math.sqrt(t),s=2*Math.PI*Math.random(),n=2*Math.PI*Math.random();return this.set(e*Math.cos(s),i*Math.sin(n),i*Math.cos(n),e*Math.sin(s))}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w}fromArray(t,e=0){return this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t}fromBufferAttribute(t,e){return this._x=t.getX(e),this._y=t.getY(e),this._z=t.getZ(e),this._w=t.getW(e),this}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}}l.prototype.isQuaternion=!0;class c{constructor(t=0,e=0,i=0){this.x=t,this.y=e,this.z=i}set(t,e,i){return void 0===i&&(i=this.z),this.x=t,this.y=e,this.z=i,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t,e){return void 0!==e?(console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(t,e)):(this.x+=t.x,this.y+=t.y,this.z+=t.z,this)}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t,e){return void 0!==e?(console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(t,e)):(this.x-=t.x,this.y-=t.y,this.z-=t.z,this)}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t,e){return void 0!==e?(console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(t,e)):(this.x*=t.x,this.y*=t.y,this.z*=t.z,this)}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return t&&t.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order."),this.applyQuaternion(d.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(d.setFromAxisAngle(t,e))}applyMatrix3(t){const e=this.x,i=this.y,s=this.z,n=t.elements;return this.x=n[0]*e+n[3]*i+n[6]*s,this.y=n[1]*e+n[4]*i+n[7]*s,this.z=n[2]*e+n[5]*i+n[8]*s,this}applyNormalMatrix(t){return this.applyMatrix3(t).normalize()}applyMatrix4(t){const e=this.x,i=this.y,s=this.z,n=t.elements,r=1/(n[3]*e+n[7]*i+n[11]*s+n[15]);return this.x=(n[0]*e+n[4]*i+n[8]*s+n[12])*r,this.y=(n[1]*e+n[5]*i+n[9]*s+n[13])*r,this.z=(n[2]*e+n[6]*i+n[10]*s+n[14])*r,this}applyQuaternion(t){const e=this.x,i=this.y,s=this.z,n=t.x,r=t.y,a=t.z,o=t.w,h=o*e+r*s-a*i,l=o*i+a*e-n*s,c=o*s+n*i-r*e,u=-n*e-r*i-a*s;return this.x=h*o+u*-n+l*-a-c*-r,this.y=l*o+u*-r+c*-n-h*-a,this.z=c*o+u*-a+h*-r-l*-n,this}project(t){return this.applyMatrix4(t.matrixWorldInverse).applyMatrix4(t.projectionMatrix)}unproject(t){return this.applyMatrix4(t.projectionMatrixInverse).applyMatrix4(t.matrixWorld)}transformDirection(t){const e=this.x,i=this.y,s=this.z,n=t.elements;return this.x=n[0]*e+n[4]*i+n[8]*s,this.y=n[1]*e+n[5]*i+n[9]*s,this.z=n[2]*e+n[6]*i+n[10]*s,this.normalize()}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this}divideScalar(t){return this.multiplyScalar(1/t)}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this}clamp(t,e){return this.x=Math.max(t.x,Math.min(e.x,this.x)),this.y=Math.max(t.y,Math.min(e.y,this.y)),this.z=Math.max(t.z,Math.min(e.z,this.z)),this}clampScalar(t,e){return this.x=Math.max(t,Math.min(e,this.x)),this.y=Math.max(t,Math.min(e,this.y)),this.z=Math.max(t,Math.min(e,this.z)),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(Math.max(t,Math.min(e,i)))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=this.x<0?Math.ceil(this.x):Math.floor(this.x),this.y=this.y<0?Math.ceil(this.y):Math.floor(this.y),this.z=this.z<0?Math.ceil(this.z):Math.floor(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this.z=t.z+(e.z-t.z)*i,this}cross(t,e){return void 0!==e?(console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),this.crossVectors(t,e)):this.crossVectors(this,t)}crossVectors(t,e){const i=t.x,s=t.y,n=t.z,r=e.x,a=e.y,o=e.z;return this.x=s*o-n*a,this.y=n*r-i*o,this.z=i*a-s*r,this}projectOnVector(t){const e=t.lengthSq();if(0===e)return this.set(0,0,0);const i=t.dot(this)/e;return this.copy(t).multiplyScalar(i)}projectOnPlane(t){return u.copy(this).projectOnVector(t),this.sub(u)}reflect(t){return this.sub(u.copy(t).multiplyScalar(2*this.dot(t)))}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(h(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y,s=this.z-t.z;return e*e+i*i+s*s}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)}setFromSpherical(t){return this.setFromSphericalCoords(t.radius,t.phi,t.theta)}setFromSphericalCoords(t,e,i){const s=Math.sin(e)*t;return this.x=s*Math.sin(i),this.y=Math.cos(e)*t,this.z=s*Math.cos(i),this}setFromCylindrical(t){return this.setFromCylindricalCoords(t.radius,t.theta,t.y)}setFromCylindricalCoords(t,e,i){return this.x=t*Math.sin(e),this.y=i,this.z=t*Math.cos(e),this}setFromMatrixPosition(t){const e=t.elements;return this.x=e[12],this.y=e[13],this.z=e[14],this}setFromMatrixScale(t){const e=this.setFromMatrixColumn(t,0).length(),i=this.setFromMatrixColumn(t,1).length(),s=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=i,this.z=s,this}setFromMatrixColumn(t,e){return this.fromArray(t.elements,4*e)}setFromMatrix3Column(t,e){return this.fromArray(t.elements,3*e)}equals(t){return t.x===this.x&&t.y===this.y&&t.z===this.z}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this.z=t[e+2],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t}fromBufferAttribute(t,e,i){return void 0!==i&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute()."),this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=2*(Math.random()-.5),e=Math.random()*Math.PI*2,i=Math.sqrt(1-t**2);return this.x=i*Math.cos(e),this.y=i*Math.sin(e),this.z=t,this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}c.prototype.isVector3=!0;const u=new c,d=new l;class m{constructor(){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],arguments.length>0&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")}set(t,e,i,s,n,r,a,o,h,l,c,u,d,m,p,y){const f=this.elements;return f[0]=t,f[4]=e,f[8]=i,f[12]=s,f[1]=n,f[5]=r,f[9]=a,f[13]=o,f[2]=h,f[6]=l,f[10]=c,f[14]=u,f[3]=d,f[7]=m,f[11]=p,f[15]=y,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return(new m).fromArray(this.elements)}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],e[9]=i[9],e[10]=i[10],e[11]=i[11],e[12]=i[12],e[13]=i[13],e[14]=i[14],e[15]=i[15],this}copyPosition(t){const e=this.elements,i=t.elements;return e[12]=i[12],e[13]=i[13],e[14]=i[14],this}setFromMatrix3(t){const e=t.elements;return this.set(e[0],e[3],e[6],0,e[1],e[4],e[7],0,e[2],e[5],e[8],0,0,0,0,1),this}extractBasis(t,e,i){return t.setFromMatrixColumn(this,0),e.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this}makeBasis(t,e,i){return this.set(t.x,e.x,i.x,0,t.y,e.y,i.y,0,t.z,e.z,i.z,0,0,0,0,1),this}extractRotation(t){const e=this.elements,i=t.elements,s=1/p.setFromMatrixColumn(t,0).length(),n=1/p.setFromMatrixColumn(t,1).length(),r=1/p.setFromMatrixColumn(t,2).length();return e[0]=i[0]*s,e[1]=i[1]*s,e[2]=i[2]*s,e[3]=0,e[4]=i[4]*n,e[5]=i[5]*n,e[6]=i[6]*n,e[7]=0,e[8]=i[8]*r,e[9]=i[9]*r,e[10]=i[10]*r,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromEuler(t){t&&t.isEuler||console.error("THREE.Matrix4: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");const e=this.elements,i=t.x,s=t.y,n=t.z,r=Math.cos(i),a=Math.sin(i),o=Math.cos(s),h=Math.sin(s),l=Math.cos(n),c=Math.sin(n);if("XYZ"===t.order){const t=r*l,i=r*c,s=a*l,n=a*c;e[0]=o*l,e[4]=-o*c,e[8]=h,e[1]=i+s*h,e[5]=t-n*h,e[9]=-a*o,e[2]=n-t*h,e[6]=s+i*h,e[10]=r*o}else if("YXZ"===t.order){const t=o*l,i=o*c,s=h*l,n=h*c;e[0]=t+n*a,e[4]=s*a-i,e[8]=r*h,e[1]=r*c,e[5]=r*l,e[9]=-a,e[2]=i*a-s,e[6]=n+t*a,e[10]=r*o}else if("ZXY"===t.order){const t=o*l,i=o*c,s=h*l,n=h*c;e[0]=t-n*a,e[4]=-r*c,e[8]=s+i*a,e[1]=i+s*a,e[5]=r*l,e[9]=n-t*a,e[2]=-r*h,e[6]=a,e[10]=r*o}else if("ZYX"===t.order){const t=r*l,i=r*c,s=a*l,n=a*c;e[0]=o*l,e[4]=s*h-i,e[8]=t*h+n,e[1]=o*c,e[5]=n*h+t,e[9]=i*h-s,e[2]=-h,e[6]=a*o,e[10]=r*o}else if("YZX"===t.order){const t=r*o,i=r*h,s=a*o,n=a*h;e[0]=o*l,e[4]=n-t*c,e[8]=s*c+i,e[1]=c,e[5]=r*l,e[9]=-a*l,e[2]=-h*l,e[6]=i*c+s,e[10]=t-n*c}else if("XZY"===t.order){const t=r*o,i=r*h,s=a*o,n=a*h;e[0]=o*l,e[4]=-c,e[8]=h*l,e[1]=t*c+n,e[5]=r*l,e[9]=i*c-s,e[2]=s*c-i,e[6]=a*l,e[10]=n*c+t}return e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromQuaternion(t){return this.compose(f,t,g)}lookAt(t,e,i){const s=this.elements;return b.subVectors(t,e),0===b.lengthSq()&&(b.z=1),b.normalize(),x.crossVectors(i,b),0===x.lengthSq()&&(1===Math.abs(i.z)?b.x+=1e-4:b.z+=1e-4,b.normalize(),x.crossVectors(i,b)),x.normalize(),_.crossVectors(b,x),s[0]=x.x,s[4]=_.x,s[8]=b.x,s[1]=x.y,s[5]=_.y,s[9]=b.y,s[2]=x.z,s[6]=_.z,s[10]=b.z,this}multiply(t,e){return void 0!==e?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(t,e)):this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,s=e.elements,n=this.elements,r=i[0],a=i[4],o=i[8],h=i[12],l=i[1],c=i[5],u=i[9],d=i[13],m=i[2],p=i[6],y=i[10],f=i[14],g=i[3],x=i[7],_=i[11],b=i[15],v=s[0],M=s[4],w=s[8],z=s[12],k=s[1],E=s[5],R=s[9],C=s[13],S=s[2],F=s[6],A=s[10],P=s[14],V=s[3],O=s[7],j=s[11],D=s[15];return n[0]=r*v+a*k+o*S+h*V,n[4]=r*M+a*E+o*F+h*O,n[8]=r*w+a*R+o*A+h*j,n[12]=r*z+a*C+o*P+h*D,n[1]=l*v+c*k+u*S+d*V,n[5]=l*M+c*E+u*F+d*O,n[9]=l*w+c*R+u*A+d*j,n[13]=l*z+c*C+u*P+d*D,n[2]=m*v+p*k+y*S+f*V,n[6]=m*M+p*E+y*F+f*O,n[10]=m*w+p*R+y*A+f*j,n[14]=m*z+p*C+y*P+f*D,n[3]=g*v+x*k+_*S+b*V,n[7]=g*M+x*E+_*F+b*O,n[11]=g*w+x*R+_*A+b*j,n[15]=g*z+x*C+_*P+b*D,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[4]*=t,e[8]*=t,e[12]*=t,e[1]*=t,e[5]*=t,e[9]*=t,e[13]*=t,e[2]*=t,e[6]*=t,e[10]*=t,e[14]*=t,e[3]*=t,e[7]*=t,e[11]*=t,e[15]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[4],s=t[8],n=t[12],r=t[1],a=t[5],o=t[9],h=t[13],l=t[2],c=t[6],u=t[10],d=t[14];return t[3]*(+n*o*c-s*h*c-n*a*u+i*h*u+s*a*d-i*o*d)+t[7]*(+e*o*d-e*h*u+n*r*u-s*r*d+s*h*l-n*o*l)+t[11]*(+e*h*c-e*a*d-n*r*c+i*r*d+n*a*l-i*h*l)+t[15]*(-s*a*l-e*o*c+e*a*u+s*r*c-i*r*u+i*o*l)}transpose(){const t=this.elements;let e;return e=t[1],t[1]=t[4],t[4]=e,e=t[2],t[2]=t[8],t[8]=e,e=t[6],t[6]=t[9],t[9]=e,e=t[3],t[3]=t[12],t[12]=e,e=t[7],t[7]=t[13],t[13]=e,e=t[11],t[11]=t[14],t[14]=e,this}setPosition(t,e,i){const s=this.elements;return t.isVector3?(s[12]=t.x,s[13]=t.y,s[14]=t.z):(s[12]=t,s[13]=e,s[14]=i),this}invert(){const t=this.elements,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],a=t[5],o=t[6],h=t[7],l=t[8],c=t[9],u=t[10],d=t[11],m=t[12],p=t[13],y=t[14],f=t[15],g=c*y*h-p*u*h+p*o*d-a*y*d-c*o*f+a*u*f,x=m*u*h-l*y*h-m*o*d+r*y*d+l*o*f-r*u*f,_=l*p*h-m*c*h+m*a*d-r*p*d-l*a*f+r*c*f,b=m*c*o-l*p*o-m*a*u+r*p*u+l*a*y-r*c*y,v=e*g+i*x+s*_+n*b;if(0===v)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const M=1/v;return t[0]=g*M,t[1]=(p*u*n-c*y*n-p*s*d+i*y*d+c*s*f-i*u*f)*M,t[2]=(a*y*n-p*o*n+p*s*h-i*y*h-a*s*f+i*o*f)*M,t[3]=(c*o*n-a*u*n-c*s*h+i*u*h+a*s*d-i*o*d)*M,t[4]=x*M,t[5]=(l*y*n-m*u*n+m*s*d-e*y*d-l*s*f+e*u*f)*M,t[6]=(m*o*n-r*y*n-m*s*h+e*y*h+r*s*f-e*o*f)*M,t[7]=(r*u*n-l*o*n+l*s*h-e*u*h-r*s*d+e*o*d)*M,t[8]=_*M,t[9]=(m*c*n-l*p*n-m*i*d+e*p*d+l*i*f-e*c*f)*M,t[10]=(r*p*n-m*a*n+m*i*h-e*p*h-r*i*f+e*a*f)*M,t[11]=(l*a*n-r*c*n-l*i*h+e*c*h+r*i*d-e*a*d)*M,t[12]=b*M,t[13]=(l*p*s-m*c*s+m*i*u-e*p*u-l*i*y+e*c*y)*M,t[14]=(m*a*s-r*p*s-m*i*o+e*p*o+r*i*y-e*a*y)*M,t[15]=(r*c*s-l*a*s+l*i*o-e*c*o-r*i*u+e*a*u)*M,this}scale(t){const e=this.elements,i=t.x,s=t.y,n=t.z;return e[0]*=i,e[4]*=s,e[8]*=n,e[1]*=i,e[5]*=s,e[9]*=n,e[2]*=i,e[6]*=s,e[10]*=n,e[3]*=i,e[7]*=s,e[11]*=n,this}getMaxScaleOnAxis(){const t=this.elements,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],s=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,s))}makeTranslation(t,e,i){return this.set(1,0,0,t,0,1,0,e,0,0,1,i,0,0,0,1),this}makeRotationX(t){const e=Math.cos(t),i=Math.sin(t);return this.set(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1),this}makeRotationY(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1),this}makeRotationZ(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(t,e){const i=Math.cos(e),s=Math.sin(e),n=1-i,r=t.x,a=t.y,o=t.z,h=n*r,l=n*a;return this.set(h*r+i,h*a-s*o,h*o+s*a,0,h*a+s*o,l*a+i,l*o-s*r,0,h*o-s*a,l*o+s*r,n*o*o+i,0,0,0,0,1),this}makeScale(t,e,i){return this.set(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1),this}makeShear(t,e,i,s,n,r){return this.set(1,i,n,0,t,1,r,0,e,s,1,0,0,0,0,1),this}compose(t,e,i){const s=this.elements,n=e._x,r=e._y,a=e._z,o=e._w,h=n+n,l=r+r,c=a+a,u=n*h,d=n*l,m=n*c,p=r*l,y=r*c,f=a*c,g=o*h,x=o*l,_=o*c,b=i.x,v=i.y,M=i.z;return s[0]=(1-(p+f))*b,s[1]=(d+_)*b,s[2]=(m-x)*b,s[3]=0,s[4]=(d-_)*v,s[5]=(1-(u+f))*v,s[6]=(y+g)*v,s[7]=0,s[8]=(m+x)*M,s[9]=(y-g)*M,s[10]=(1-(u+p))*M,s[11]=0,s[12]=t.x,s[13]=t.y,s[14]=t.z,s[15]=1,this}decompose(t,e,i){const s=this.elements;let n=p.set(s[0],s[1],s[2]).length();const r=p.set(s[4],s[5],s[6]).length(),a=p.set(s[8],s[9],s[10]).length();this.determinant()<0&&(n=-n),t.x=s[12],t.y=s[13],t.z=s[14],y.copy(this);const o=1/n,h=1/r,l=1/a;return y.elements[0]*=o,y.elements[1]*=o,y.elements[2]*=o,y.elements[4]*=h,y.elements[5]*=h,y.elements[6]*=h,y.elements[8]*=l,y.elements[9]*=l,y.elements[10]*=l,e.setFromRotationMatrix(y),i.x=n,i.y=r,i.z=a,this}makePerspective(t,e,i,s,n,r){void 0===r&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");const a=this.elements,o=2*n/(e-t),h=2*n/(i-s),l=(e+t)/(e-t),c=(i+s)/(i-s),u=-(r+n)/(r-n),d=-2*r*n/(r-n);return a[0]=o,a[4]=0,a[8]=l,a[12]=0,a[1]=0,a[5]=h,a[9]=c,a[13]=0,a[2]=0,a[6]=0,a[10]=u,a[14]=d,a[3]=0,a[7]=0,a[11]=-1,a[15]=0,this}makeOrthographic(t,e,i,s,n,r){const a=this.elements,o=1/(e-t),h=1/(i-s),l=1/(r-n),c=(e+t)*o,u=(i+s)*h,d=(r+n)*l;return a[0]=2*o,a[4]=0,a[8]=0,a[12]=-c,a[1]=0,a[5]=2*h,a[9]=0,a[13]=-u,a[2]=0,a[6]=0,a[10]=-2*l,a[14]=-d,a[3]=0,a[7]=0,a[11]=0,a[15]=1,this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<16;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<16;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t[e+9]=i[9],t[e+10]=i[10],t[e+11]=i[11],t[e+12]=i[12],t[e+13]=i[13],t[e+14]=i[14],t[e+15]=i[15],t}}m.prototype.isMatrix4=!0;const p=new c,y=new m,f=new c(0,0,0),g=new c(1,1,1),x=new c,_=new c,b=new c;const v=new m,M=new l;class w{constructor(t=0,e=0,i=0,s=w.DefaultOrder){this._x=t,this._y=e,this._z=i,this._order=s}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get order(){return this._order}set order(t){this._order=t,this._onChangeCallback()}set(t,e,i,s=this._order){return this._x=t,this._y=e,this._z=i,this._order=s,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(t){return this._x=t._x,this._y=t._y,this._z=t._z,this._order=t._order,this._onChangeCallback(),this}setFromRotationMatrix(t,e=this._order,i=!0){const s=t.elements,n=s[0],r=s[4],a=s[8],o=s[1],l=s[5],c=s[9],u=s[2],d=s[6],m=s[10];switch(e){case"XYZ":this._y=Math.asin(h(a,-1,1)),Math.abs(a)<.9999999?(this._x=Math.atan2(-c,m),this._z=Math.atan2(-r,n)):(this._x=Math.atan2(d,l),this._z=0);break;case"YXZ":this._x=Math.asin(-h(c,-1,1)),Math.abs(c)<.9999999?(this._y=Math.atan2(a,m),this._z=Math.atan2(o,l)):(this._y=Math.atan2(-u,n),this._z=0);break;case"ZXY":this._x=Math.asin(h(d,-1,1)),Math.abs(d)<.9999999?(this._y=Math.atan2(-u,m),this._z=Math.atan2(-r,l)):(this._y=0,this._z=Math.atan2(o,n));break;case"ZYX":this._y=Math.asin(-h(u,-1,1)),Math.abs(u)<.9999999?(this._x=Math.atan2(d,m),this._z=Math.atan2(o,n)):(this._x=0,this._z=Math.atan2(-r,l));break;case"YZX":this._z=Math.asin(h(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-c,l),this._y=Math.atan2(-u,n)):(this._x=0,this._y=Math.atan2(a,m));break;case"XZY":this._z=Math.asin(-h(r,-1,1)),Math.abs(r)<.9999999?(this._x=Math.atan2(d,l),this._y=Math.atan2(a,n)):(this._x=Math.atan2(-c,m),this._y=0);break;default:console.warn("THREE.Euler: .setFromRotationMatrix() encountered an unknown order: "+e)}return this._order=e,!0===i&&this._onChangeCallback(),this}setFromQuaternion(t,e,i){return v.makeRotationFromQuaternion(t),this.setFromRotationMatrix(v,e,i)}setFromVector3(t,e=this._order){return this.set(t.x,t.y,t.z,e)}reorder(t){return M.setFromEuler(this),this.setFromQuaternion(M,t)}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._order===this._order}fromArray(t){return this._x=t[0],this._y=t[1],this._z=t[2],void 0!==t[3]&&(this._order=t[3]),this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._order,t}toVector3(t){return t?t.set(this._x,this._y,this._z):new c(this._x,this._y,this._z)}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}}w.prototype.isEuler=!0,w.DefaultOrder="XYZ",w.RotationOrders=["XYZ","YZX","ZXY","XZY","YXZ","ZYX"];class z{constructor(){this.mask=1}set(t){this.mask=(1<>>0}enable(t){this.mask|=1<0&&console.error("THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.")}set(t,e,i,s,n,r,a,o,h){const l=this.elements;return l[0]=t,l[1]=s,l[2]=a,l[3]=e,l[4]=n,l[5]=o,l[6]=i,l[7]=r,l[8]=h,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this}extractBasis(t,e,i){return t.setFromMatrix3Column(this,0),e.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(t){const e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,s=e.elements,n=this.elements,r=i[0],a=i[3],o=i[6],h=i[1],l=i[4],c=i[7],u=i[2],d=i[5],m=i[8],p=s[0],y=s[3],f=s[6],g=s[1],x=s[4],_=s[7],b=s[2],v=s[5],M=s[8];return n[0]=r*p+a*g+o*b,n[3]=r*y+a*x+o*v,n[6]=r*f+a*_+o*M,n[1]=h*p+l*g+c*b,n[4]=h*y+l*x+c*v,n[7]=h*f+l*_+c*M,n[2]=u*p+d*g+m*b,n[5]=u*y+d*x+m*v,n[8]=u*f+d*_+m*M,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],a=t[5],o=t[6],h=t[7],l=t[8];return e*r*l-e*a*h-i*n*l+i*a*o+s*n*h-s*r*o}invert(){const t=this.elements,e=t[0],i=t[1],s=t[2],n=t[3],r=t[4],a=t[5],o=t[6],h=t[7],l=t[8],c=l*r-a*h,u=a*o-l*n,d=h*n-r*o,m=e*c+i*u+s*d;if(0===m)return this.set(0,0,0,0,0,0,0,0,0);const p=1/m;return t[0]=c*p,t[1]=(s*h-l*i)*p,t[2]=(a*i-s*r)*p,t[3]=u*p,t[4]=(l*e-s*o)*p,t[5]=(s*n-a*e)*p,t[6]=d*p,t[7]=(i*o-h*e)*p,t[8]=(r*e-i*n)*p,this}transpose(){let t;const e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this}getNormalMatrix(t){return this.setFromMatrix4(t).invert().transpose()}transposeIntoArray(t){const e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this}setUvTransform(t,e,i,s,n,r,a){const o=Math.cos(n),h=Math.sin(n);return this.set(i*o,i*h,-i*(o*r+h*a)+r+t,-s*h,s*o,-s*(-h*r+o*a)+a+e,0,0,1),this}scale(t,e){const i=this.elements;return i[0]*=t,i[3]*=t,i[6]*=t,i[1]*=e,i[4]*=e,i[7]*=e,this}rotate(t){const e=Math.cos(t),i=Math.sin(t),s=this.elements,n=s[0],r=s[3],a=s[6],o=s[1],h=s[4],l=s[7];return s[0]=e*n+i*o,s[3]=e*r+i*h,s[6]=e*a+i*l,s[1]=-i*n+e*o,s[4]=-i*r+e*h,s[7]=-i*a+e*l,this}translate(t,e){const i=this.elements;return i[0]+=t*i[2],i[3]+=t*i[5],i[6]+=t*i[8],i[1]+=e*i[2],i[4]+=e*i[5],i[7]+=e*i[8],this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<9;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<9;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t}clone(){return(new this.constructor).fromArray(this.elements)}}k.prototype.isMatrix3=!0;let E=0;const R=new c,C=new l,S=new m,F=new c,A=new c,P=new c,V=new l,O=new c(1,0,0),j=new c(0,1,0),D=new c(0,0,1),T={type:"added"},W={type:"removed"};class q extends class{addEventListener(t,e){void 0===this._listeners&&(this._listeners={});const i=this._listeners;void 0===i[t]&&(i[t]=[]),-1===i[t].indexOf(e)&&i[t].push(e)}hasEventListener(t,e){if(void 0===this._listeners)return!1;const i=this._listeners;return void 0!==i[t]&&-1!==i[t].indexOf(e)}removeEventListener(t,e){if(void 0===this._listeners)return;const i=this._listeners[t];if(void 0!==i){const t=i.indexOf(e);-1!==t&&i.splice(t,1)}}dispatchEvent(t){if(void 0===this._listeners)return;const e=this._listeners[t.type];if(void 0!==e){t.target=this;const i=e.slice(0);for(let e=0,s=i.length;e>8&255]+o[t>>16&255]+o[t>>24&255]+"-"+o[255&e]+o[e>>8&255]+"-"+o[e>>16&15|64]+o[e>>24&255]+"-"+o[63&i|128]+o[i>>8&255]+"-"+o[i>>16&255]+o[i>>24&255]+o[255&s]+o[s>>8&255]+o[s>>16&255]+o[s>>24&255]).toUpperCase()}(),this.name="",this.type="Object3D",this.parent=null,this.children=[],this.up=q.DefaultUp.clone();const t=new c,e=new w,i=new l,s=new c(1,1,1);e._onChange((function(){i.setFromEuler(e,!1)})),i._onChange((function(){e.setFromQuaternion(i,void 0,!1)})),Object.defineProperties(this,{position:{configurable:!0,enumerable:!0,value:t},rotation:{configurable:!0,enumerable:!0,value:e},quaternion:{configurable:!0,enumerable:!0,value:i},scale:{configurable:!0,enumerable:!0,value:s},modelViewMatrix:{value:new m},normalMatrix:{value:new k}}),this.matrix=new m,this.matrixWorld=new m,this.matrixAutoUpdate=q.DefaultMatrixAutoUpdate,this.matrixWorldNeedsUpdate=!1,this.layers=new z,this.visible=!0,this.castShadow=!1,this.receiveShadow=!1,this.frustumCulled=!0,this.renderOrder=0,this.animations=[],this.userData={}}onBeforeRender(){}onAfterRender(){}applyMatrix4(t){this.matrixAutoUpdate&&this.updateMatrix(),this.matrix.premultiply(t),this.matrix.decompose(this.position,this.quaternion,this.scale)}applyQuaternion(t){return this.quaternion.premultiply(t),this}setRotationFromAxisAngle(t,e){this.quaternion.setFromAxisAngle(t,e)}setRotationFromEuler(t){this.quaternion.setFromEuler(t,!0)}setRotationFromMatrix(t){this.quaternion.setFromRotationMatrix(t)}setRotationFromQuaternion(t){this.quaternion.copy(t)}rotateOnAxis(t,e){return C.setFromAxisAngle(t,e),this.quaternion.multiply(C),this}rotateOnWorldAxis(t,e){return C.setFromAxisAngle(t,e),this.quaternion.premultiply(C),this}rotateX(t){return this.rotateOnAxis(O,t)}rotateY(t){return this.rotateOnAxis(j,t)}rotateZ(t){return this.rotateOnAxis(D,t)}translateOnAxis(t,e){return R.copy(t).applyQuaternion(this.quaternion),this.position.add(R.multiplyScalar(e)),this}translateX(t){return this.translateOnAxis(O,t)}translateY(t){return this.translateOnAxis(j,t)}translateZ(t){return this.translateOnAxis(D,t)}localToWorld(t){return t.applyMatrix4(this.matrixWorld)}worldToLocal(t){return t.applyMatrix4(S.copy(this.matrixWorld).invert())}lookAt(t,e,i){t.isVector3?F.copy(t):F.set(t,e,i);const s=this.parent;this.updateWorldMatrix(!0,!1),A.setFromMatrixPosition(this.matrixWorld),this.isCamera||this.isLight?S.lookAt(A,F,this.up):S.lookAt(F,A,this.up),this.quaternion.setFromRotationMatrix(S),s&&(S.extractRotation(s.matrixWorld),C.setFromRotationMatrix(S),this.quaternion.premultiply(C.invert()))}add(t){if(arguments.length>1){for(let t=0;t1){for(let t=0;t0){s.children=[];for(let e=0;e0){s.animations=[];for(let e=0;e0&&(i.geometries=e),s.length>0&&(i.materials=s),n.length>0&&(i.textures=n),a.length>0&&(i.images=a),o.length>0&&(i.shapes=o),h.length>0&&(i.skeletons=h),l.length>0&&(i.animations=l)}return i.object=s,i;function r(t){const e=[];for(const i in t){const s=t[i];delete s.metadata,e.push(s)}return e}}clone(t){return(new this.constructor).copy(this,t)}copy(t,e=!0){if(this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.rotation.order=t.rotation.order,this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(let e=0;e
',end:"
",message:'This example requires WebGL
Visit get.webgl.org for more info'},install:function(t){let e,i;try{if(e=document.createElement("canvas"),i=e.getContext("webgl")||e.getContext("experimental-webgl"),!i||this.options.force)throw"WebGL unavailable.";t.fallback=!1}catch(e){const i=this.options.message,s=this.options.begin,n=this.options.end,r=this.options.fill,a=document.createElement("div");for(a.innerHTML=s+i+n,this.children=[];a.childNodes.length>0;)this.children.push(a.firstChild),t.element.appendChild(a.firstChild);return r&&t.install("fill"),this.div=a,t.fallback=!0,!1}},uninstall:function(t){this.children&&(this.children.forEach((function(t){t.parentNode.removeChild(t)})),this.children=null),delete t.fallback}}),a.registerPlugin("fill",{defaults:{block:!0,body:!0,layout:!0},install:function(t){if(this.options.body&&t.element==document.body&&(this.applied=[t.element,document.documentElement].filter((function(t){const e=t.style.height;return"auto"==e||""==e})).map((function(t){return t.style.height="100%",t.style.margin=0,t.style.padding=0,t}))),this.options.block&&t.canvas&&(t.canvas.style.display="block",this.block=!0),this.options.layout&&t.element){"static"==window.getComputedStyle(t.element).position&&(t.element.style.position="relative",this.layout=!0)}},uninstall:function(t){if(this.applied){const t=function(t){return t.style.height="",t.style.margin="",t.style.padding="",t};this.applied.map(t),delete this.applied}this.block&&t.canvas&&(t.canvas.style.display="",delete this.block),this.layout&&t.element&&(t.element.style.position="",delete this.layout)},change:function(t){this.uninstall(t),this.install(t)}}),a.registerPlugin("loop",{defaults:{start:!0,each:1},listen:["ready"],install:function(t){this.running=!1,this.lastRequestId=null,t.Loop=this.api({start:this.start.bind(this),stop:this.stop.bind(this),running:!1,window},t),this.events=["pre","update","render","post"].map((function(t){return{type:t}}))},uninstall:function(t){this.stop(t)},ready:function(t,e){this.options.start&&this.start(e)},start:function(t){if(this.running)return;t.Loop.running=this.running=!0;const e=t.trigger.bind(t),i=function(){this.running&&(this.lastRequestId=t.Loop.window.requestAnimationFrame(i),this.events.map(e))}.bind(this);this.lastRequestId=t.Loop.window.requestAnimationFrame(i),t.trigger({type:"start"})},stop:function(t){this.running&&(t.Loop.running=this.running=!1,t.Loop.window.cancelAnimationFrame(this.lastRequestId),this.lastRequestId=null,t.trigger({type:"stop"}))}}),a.registerPlugin("render",{listen:["render"],render:function(t,e){e.scene&&e.camera&&e.renderer.render(e.scene,e.camera)}}),a.registerPlugin("renderer",{defaults:{klass:e.WebGL1Renderer,parameters:{depth:!0,stencil:!0,preserveDrawingBuffer:!0,antialias:!0}},listen:["resize"],install:function(t){const e=t.renderer=new this.options.klass(this.options.parameters);t.canvas=e.domElement,t.element.appendChild(e.domElement)},uninstall:function(t){t.element.removeChild(t.renderer.domElement),delete t.renderer,delete t.canvas},resize:function(t,e){const i=e.renderer,s=i.domElement;s&&"CANVAS"==s.tagName?i.setSize(t.renderWidth,t.renderHeight,!1):(i.setRenderSize&&i.setRenderSize(t.renderWidth,t.renderHeight),i.setSize(t.viewWidth,t.viewHeight,!1))}}),a.registerPlugin("scene",{install:function(t){t.scene=new e.Scene},uninstall:function(t){delete t.scene}}),a.registerPlugin("size",{defaults:{width:null,height:null,aspect:null,scale:1,maxRenderWidth:1/0,maxRenderHeight:1/0,devicePixelRatio:!0},listen:["window.resize:queue","element.resize:queue","this.change:queue","ready:resize","pre:pre"],install:function(t){t.Size=this.api({renderWidth:0,renderHeight:0,viewWidth:0,viewHeight:0}),this.resized=!1},uninstall:function(t){delete t.Size},queue:function(t,e){this.resized=!0},pre:function(t,e){this.resized&&(this.resized=!1,this.resize(t,e))},resize:function(t,e){const i=this.options,s=e.element,n=e.renderer;let r,a,o,h,l,c,u,d,m=0,p=0;r=o=void 0===i.width||null==i.width?s.offsetWidth||s.innerWidth||0:i.width,a=h=void 0===i.height||null==i.height?s.offsetHeight||s.innerHeight||0:i.height,u=r/a,i.aspect&&(i.aspect>u?(a=Math.round(r/i.aspect),p=Math.floor((h-a)/2)):(r=Math.round(a*i.aspect),m=Math.floor((o-r)/2)),u=r/a),d=1,i.devicePixelRatio&&"undefined"!=typeof window&&(d=window.devicePixelRatio||1),l=Math.round(Math.min(r*d*i.scale,i.maxRenderWidth)),c=Math.round(Math.min(a*d*i.scale,i.maxRenderHeight));l/c>u?l=Math.round(c*u):c=Math.round(l/u),d=c/a;const y=n.domElement.style;y.width=r+"px",y.height=a+"px",y.marginLeft=m+"px",y.marginTop=p+"px",Object.assign(e.Size,{renderWidth:l,renderHeight:c,viewWidth:r,viewHeight:a,aspect:u,pixelRatio:d}),e.trigger({type:"resize",renderWidth:l,renderHeight:c,viewWidth:r,viewHeight:a,aspect:u,pixelRatio:d})}}),a.registerPlugin("time",{defaults:{speed:1,warmup:0,timeout:1},listen:["pre:tick","this.change"],now:function(){return+new Date/1e3},install:function(t){t.Time=this.api({now:this.now(),clock:0,step:1/60,frames:0,time:0,delta:1/60,average:0,fps:0}),this.last=0,this.time=0,this.clock=0,this.wait=this.options.warmup,this.clockStart=0,this.timeStart=0},tick:function(t,e){const i=this.options.speed,s=this.options.timeout,n=e.Time,r=n.now=this.now(),a=this.last;let o=this.time,h=this.clock;if(a){let t=n.delta=r-a;const e=n.average||t;t>s&&(t=0);const l=t*i;o+=t,h+=l,n.frames>0&&(n.average=e+.1*(t-e),n.fps=1/e),n.step=l,n.clock=h-this.clockStart,n.time=o-this.timeStart,n.frames++,this.wait-- >0&&(this.clockStart=h,this.timeStart=o,n.clock=0,n.step=1e-100)}this.last=r,this.clock=h,this.time=o},uninstall:function(t){delete t.Time}}),a.registerPlugin("warmup",{defaults:{delay:2},listen:["ready","post"],ready:function(t,e){e.renderer.domElement.style.visibility="hidden",this.frame=0,this.hidden=!0},post:function(t,e){this.hidden&&this.frame>=this.options.delay&&(e.renderer.domElement.style.visibility="visible",this.hidden=!1),this.frame++}}),a.registerPlugin("controls",{listen:["update","resize","camera","this.change"],defaults:{klass:null,parameters:{}},install:function(t){if(!this.options.klass)throw"Must provide class for `controls.klass`";t.controls=null,this._camera=t.camera||new e.PerspectiveCamera,this.change(null,t)},uninstall:function(t){delete t.controls},change:function(t,e){this.options.klass?(t&&!t.changes.klass||(e.controls=new this.options.klass(this._camera,e.renderer.domElement)),Object.assign(e.controls,this.options.parameters)):e.controls=null},update:function(t,e){const i=e.Time&&e.Time.delta||1/60,s=e.VR&&e.VR.state;e.controls.vr&&e.controls.vr(s),e.controls.update(i)},camera:function(t,e){e.controls.object=this._camera=t.camera},resize:function(t,e){e.controls.handleResize&&e.controls.handleResize()}}),a.registerPlugin("cursor",{listen:["update","this.change","install:change","uninstall:change","element.mousemove","vr"],defaults:{cursor:null,hide:!1,timeout:3},install:function(t){this.timeout=this.options.timeout,this.element=t.element,this.change(null,t)},uninstall:function(t){delete t.controls},change:function(t,e){this.applyCursor(e)},mousemove:function(t,e){this.options.hide&&(this.applyCursor(e),this.timeout=+this.options.timeout||0)},update:function(t,e){const i=e.Time&&e.Time.delta||1/60;this.options.hide&&(this.timeout-=i,this.timeout<0&&this.applyCursor(e,"none"))},vr:function(t,e){this.hide=t.active&&!t.hmd.fake,this.applyCursor(e)},applyCursor:function(t,e){const i=t.controls?"move":"";e=e||this.options.cursor||i,this.hide&&(e="none"),this.cursor!=e&&(this.element.style.cursor=e)}}),a.registerPlugin("fullscreen",{defaults:{key:"f"},listen:["ready","update"],install:function(t){t.Fullscreen=this.api({active:!1,toggle:this.toggle.bind(this)},t)},uninstall:function(t){delete t.Fullscreen},ready:function(t,e){document.body.addEventListener("keypress",function(t){this.options.key&&t.charCode==this.options.key.charCodeAt(0)&&this.toggle(e)}.bind(this));const i=function(){const t=!!(document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement);e.Fullscreen.active=this.active=t,e.trigger({type:"fullscreen",active:t})}.bind(this);document.addEventListener("fullscreenchange",i,!1),document.addEventListener("webkitfullscreenchange",i,!1),document.addEventListener("mozfullscreenchange",i,!1)},toggle:function(t){const e=t.canvas,i=t.VR&&t.VR.active?{vrDisplay:t.VR.hmd}:{};this.active?document.exitFullscreen?document.exitFullscreen():document.msExitFullscreen?document.msExitFullscreen():document.webkitExitFullscreen?document.webkitExitFullscreen():document.mozCancelFullScreen&&document.mozCancelFullScreen():e.requestFullScreen?e.requestFullScreen(i):e.msRequestFullScreen?e.msRequestFullscreen(i):e.webkitRequestFullscreen?e.webkitRequestFullscreen(i):e.mozRequestFullScreen&&e.mozRequestFullScreen(i)}});var I=s(466),N=s.n(I);a.registerPlugin("stats",{listen:["pre","post"],install:function(t){const e=this.stats=new(N()),i=e.domElement.style;i.position="absolute",i.top=i.left=0,t.element.appendChild(e.domElement),t.stats=e},uninstall:function(t){this.stats.domElement.remove(),delete t.stats},pre:function(t,e){this.stats.begin()},post:function(t,e){this.stats.end()}}),a.registerPlugin("ui",{defaults:{theme:"white",style:".threestrap-ui { position: absolute; bottom: 5px; right: 5px; float: left; }.threestrap-ui button { border: 0; background: none; vertical-align: middle; font-weight: bold; } .threestrap-ui .glyphicon { top: 2px; font-weight: bold; } @media (max-width: 640px) { .threestrap-ui button { font-size: 120% } }.threestrap-white button { color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 1), 0 1px 3px rgba(0, 0, 0, 1); }.threestrap-black button { color: #000; text-shadow: 0 0px 1px rgba(255, 255, 255, 1), 0 0px 2px rgba(255, 255, 255, 1), 0 0px 2px rgba(255, 255, 255, 1) }"},listen:["fullscreen"],markup:function(t,e,i){let s="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css";location.href.match(/^file:\/\//)&&(s="http://"+s);const n=[];return t.Fullscreen&&n.push(''),t.VR&&n.push(''),'
'+n.join("\n")+"
"},install:function(t){const e=this.ui=document.createElement("div");e.innerHTML=this.markup(t,this.options.theme,this.options.style),document.body.appendChild(e);const i=this.ui.fullscreen=e.querySelector("button.fullscreen");i&&t.bind([i,"click:goFullscreen"],this);const s=this.ui.vr=e.querySelector("button.vr");s&&t.VR&&(t.VR.set({mode:"2d"}),t.bind([s,"click:goVR"],this))},fullscreen:function(t,e){this.ui.style.display=t.active?"none":"block",t.active||e.VR&&e.VR.set({mode:"2d"})},goFullscreen:function(t,e){e.Fullscreen&&e.Fullscreen.toggle()},goVR:function(t,e){e.VR&&(e.VR.set({mode:"auto"}),e.Fullscreen.toggle())},uninstall:function(t){document.body.removeChild(this.ui)}});class Y{constructor(t,i){this.renderer=t,this.right=new c,this.cameraLeft=new e.PerspectiveCamera,this.cameraRight=new e.PerspectiveCamera;const s=i.getEyeTranslation("left");this.halfIPD=new c(s.x,s.y,s.z).length(),this.fovLeft=i.getRecommendedEyeFieldOfView("left"),this.fovRight=i.getRecommendedEyeFieldOfView("right")}FovToNDCScaleOffset(t){const e=2/(t.leftTan+t.rightTan),i=(t.leftTan-t.rightTan)*e*.5,s=2/(t.upTan+t.downTan);return{scale:[e,s],offset:[i,(t.upTan-t.downTan)*s*.5]}}FovPortToProjection(t,e,i,s,n){s=void 0===s?.01:s,n=void 0===n?1e4:n;const r=(i=void 0===i||i)?-1:1,a=t.elements,o=this.FovToNDCScaleOffset(e);a[0]=o.scale[0],a[1]=0,a[2]=o.offset[0]*r,a[3]=0,a[4]=0,a[5]=o.scale[1],a[6]=-o.offset[1]*r,a[7]=0,a[8]=0,a[9]=0,a[10]=n/(s-n)*-r,a[11]=n*s/(s-n),a[12]=0,a[13]=0,a[14]=r,a[15]=0,t.transpose()}FovToProjection(t,e,i,s,n){const r={upTan:Math.tan(e.upDegrees*Math.PI/180),downTan:Math.tan(e.downDegrees*Math.PI/180),leftTan:Math.tan(e.leftDegrees*Math.PI/180),rightTan:Math.tan(e.rightDegrees*Math.PI/180)};return this.FovPortToProjection(t,r,i,s,n)}render(t,e){this.FovToProjection(this.cameraLeft.projectionMatrix,this.fovLeft,!0,e.near,e.far),this.FovToProjection(this.cameraRight.projectionMatrix,this.fovRight,!0,e.near,e.far),this.right.set(this.halfIPD,0,0),this.right.applyQuaternion(e.quaternion),this.cameraLeft.position.copy(e.position).sub(this.right),this.cameraRight.position.copy(e.position).add(this.right),this.cameraLeft.quaternion.copy(e.quaternion),this.cameraRight.quaternion.copy(e.quaternion);const i=this.renderer.devicePixelRatio||1,s=this.renderer.domElement.width/2/i,n=this.renderer.domElement.height/i;this.renderer.enableScissorTest(!0),this.renderer.setViewport(0,0,s,n),this.renderer.setScissor(0,0,s,n),this.renderer.render(t,this.cameraLeft),this.renderer.setViewport(s,0,s,n),this.renderer.setScissor(s,0,s,n),this.renderer.render(t,this.cameraRight)}}a.registerPlugin("vr",{defaults:{mode:"auto",device:null,fov:80},listen:["window.load","pre","render","resize","this.change"],install:function(t){t.VR=this.api({active:!1,devices:[],hmd:null,sensor:null,renderer:null,state:null},t)},uninstall:function(t){delete t.VR},mocks:function(t,e,i){return[{fake:!0,force:1,deviceId:"emu",deviceName:"Emulated",getEyeTranslation:function(t){return{left:{x:-.03,y:0,z:0},right:{x:.03,y:0,z:0}}[t]},getRecommendedEyeFieldOfView:function(s){const n=t.camera,r=n&&n.aspect||16/9,a=(e||n&&n.fov||i)/2,o=180*Math.atan(Math.tan(a*Math.PI/180)*r/2)/Math.PI;return{left:{rightDegrees:o,leftDegrees:o,downDegrees:a,upDegrees:a},right:{rightDegrees:o,leftDegrees:o,downDegrees:a,upDegrees:a}}[s]}},{force:2,getState:function(){return{}}}]},load:function(t,e){const i=function(t){this.callback(t,e)}.bind(this);navigator.getVRDevices?navigator.getVRDevices().then(i):navigator.mozGetVRDevices?navigator.mozGetVRDevices(i):(console.warn("No native VR support detected."),i(this.mocks(e,this.options.fov,this.defaults.fov),e))},callback:function(t,e){let i,s;const n=window.HMDVRDevice||function(){},r=window.PositionSensorVRDevice||function(){};t=e.VR.devices=t||e.VR.devices;const a=this.options.device;let o;for(let e=0;e0?this.vrDisplay=t[0]:e&&e("VR input not available.")})).catch((function(){console.warn("VRControls: Unable to get VR Displays")})),this.scale=1,this.standing=!1,this.userHeight=1.6}getVRDisplay(){return this.vrDisplay}setVRDisplay(t){this.vrDisplay=t}getVRDisplays(){return console.warn("VRControls: getVRDisplays() is being deprecated."),this.vrDisplays}getStandingMatrix(){return this.standingMatrix}update(){if(this.vrDisplay){let t;this.vrDisplay.getFrameData?(this.vrDisplay.getFrameData(this.frameData),t=this.frameData.pose):this.vrDisplay.getPose&&(t=this.vrDisplay.getPose()),null!==t.orientation&&this.object.quaternion.fromArray(t.orientation),null!==t.position?this.object.position.fromArray(t.position):this.object.position.set(0,0,0),this.standing&&(this.vrDisplay.stageParameters?(this.object.updateMatrix(),this.standingMatrix.fromArray(this.vrDisplay.stageParameters.sittingToStandingTransform),this.object.applyMatrix(this.standingMatrix)):this.object.position.setY(this.object.position.y+this.userHeight)),this.object.position.multiplyScalar(this.scale)}}dispose(){this.vrDisplay=null}}})(),n})()})); -//# sourceMappingURL=threestrap.min.js.map \ No newline at end of file diff --git a/examples/basic_cube.html b/examples/basic_cube.html index 32dbcbd..f53a242 100644 --- a/examples/basic_cube.html +++ b/examples/basic_cube.html @@ -5,9 +5,12 @@ Threestrap - Basic Cubes + - - +
diff --git a/examples/controls_orbit_cube.html b/examples/controls_orbit_cube.html index 6a3d1e7..9d489b5 100644 --- a/examples/controls_orbit_cube.html +++ b/examples/controls_orbit_cube.html @@ -5,13 +5,16 @@ Threestrap - Camera Orbit Controls - +